最后,为了保持游戏界面整齐好看,我会在每行用一个竖线作为结尾,并在最后结束行循环:
printf '%s\n' "|" # 显示出行分隔符 printf ' %s\n' "-----------------------------------------" # 结束行循环 done printf '\n\n'
完整的 plough 代码如下:
plough() { r=0 printf '\n\n' printf '%s' " a b c d e f g h i j" printf '\n %s\n' "-----------------------------------------" for row in $(seq 0 9); do printf '%d ' "$row" for col in $(seq 0 9); do ((r+=1)) is_null_field $r printf '%s \e[33m%s\e[0m ' "|" "${room[$r]}" done printf '%s\n' "|" printf ' %s\n' "-----------------------------------------" done printf '\n\n' }
我花了点时间来思考,is_null_field 的具体功能是什么。让我们来看看,它到底能做些什么。在最开始,我们需要游戏有一个固定的状态。你可以随便选择个初始值,可以是一个数字或者任意字符。我最后决定,所有单元格的初始值为一个点(. ),因为我觉得,这样会让游戏界面更好看。下面就是这一函数的完整代码:
is_null_field() { local e=$1 # 在数组 room 中,我们已经用过循环变量 'r' 了,这次我们用 'e' if [[ -z "${room[$e]}" ]];then room[$r]="." #这里用点(.)来初始化每一个单元格 fi }
现在,我已经初始化了所有的格子,现在只要用一个很简单的函数就能得出当前游戏中还有多少单元格可以操作:
get_free_fields() { free_fields=0 # 初始化变量 for n in $(seq 1 ${#room[@]}); do if [[ "${room[$n]}" = "." ]]; then # 检查当前单元格是否等于初始值(.),结果为真,则记为空余格子。 ((free_fields+=1)) fi done }
这是显示出来的游戏界面,[a-j] 为列,[0-9] 为行。
Minefield
创建玩家逻辑
玩家操作背后的逻辑在于,先从 stdin 中读取数据作为坐标,然后再找出对应位置实际包含的值。这里用到了 Bash 的参数扩展,来设法得到行列数。然后将代表列数的字母传给分支语句,从而得到其对应的列数。为了更好地理解这一过程,可以看看下面这段代码中,变量 o 所对应的值。 举个例子,玩家输入了 c3 ,这时 Bash 将其分成两个字符:c 和 3 。为了简单起见,我跳过了如何处理无效输入的部分。
colm=${opt:0:1} # 得到第一个字符,一个字母 ro=${opt:1:1} # 得到第二个字符,一个整数 case $colm in a ) o=1;; # 最后,通过字母得到对应列数。 b ) o=2;; c ) o=3;; d ) o=4;; e ) o=5;; f ) o=6;; g ) o=7;; h ) o=8;; i ) o=9;; j ) o=10;; esac
下面的代码会计算用户所选单元格实际对应的数字,然后将结果储存在变量中。
(编辑:ASP站长网)
|