bash shell实现2048小游戏详解

前言

 最近在github上看到一个用bash shell实现2048小游戏的脚本感觉挺有意思的,就自己仿照他的样子稍作修改再实现了一遍我的实现,并记录下实现的详细过程。
 脚本的运行如图:
在这里插入图片描述

重要变量

在这里插入图片描述

  1. board 是一个整型数组,用来存储所有格子中的当前数值,它的下标即从0到总格子数减1,与界面中的格子从左到右,再从上到下,一一对应。数组的所有元素,在全新的游戏开始时用0初始化,而载入游戏时,用存档目录中的文件初始化。
  2. pieces 用来储存当前界面中所有非零的格子数。
  3. score 用来储存当前的得分总数。
  4. flag_skip 用来防止一个格子在同一回合中被操作两次。
  5. moves 用来测试游戏还能不能被操作,是否已经输掉游戏。
  6. ESC 作为Escape屏幕控制码,在输出颜色格式的时候使用,\e或者\033等都可以。
  7. header 也就是界面的标题,介绍性质的,可以自己定义
  8. start_time 记录程序开始的时间

在这里插入图片描述这四个变量作为默认值,可以通过选项改变

  1. board_size 即游戏界面的每边的大小,限制在3至9之间
  2. target 即游戏成功的目标,可以自己设定,但需要是2的幂
  3. reload_flag 即是否载入存档
  4. config_dir 即存档文件的目标目录

在这里插入图片描述

  1. last_added 即最新生成的块的位置
  2. first_round 即第一个生成的块的位置。因为游戏最开始必须要生成两个块,而我定义用黄色表现这两个块以及用黄色表示以后每次最新生成的块。
  3. index_max 因为数组的下标从0开始,所以定义这个变量为游戏界面的每边的大小减一
  4. fields_total 即游戏界面中格子的总数

在这里插入图片描述
 定义一个数组用来储存各个数字的颜色表现,搭配前面定义的$ESC构成Escape屏幕控制码,64及以上添加了高亮白底,这些可以自行修改。


功能函数


退出处理

在这里插入图片描述 这里调用end_game函数处理INT信号,亦即使用ctrl+c发出退出请求,由end_game进行退出流程。


print_board
83	function print_board(){
    84		clear
    85		printf "**************************************************************\n"
    86		printf "***********************$header*************************\n"
    87		printf "*$ESC[1;5;33mpieces=%-11d   target=%-11d   score=%-12d$ESC[0m*\n" $pieces $target $score
    88		printf "**************************************************************\n"
    89		echo
    90		printf "/------"
    91		for((row=1;row<=index_max;row++))
    92		do
    93			printf "+------"
    94		done
    95		printf '\\\n'
    96		for((row=0;row<=index_max;row++))
    97		do
    98			printf "|"
    99			for((line=0;line<=index_max;line++))
   100			do
   101				if let ${board[$row*$board_size+$line]}
   102				then
   103					if let '(last_added==(row*board_size+line))|(first_round==(row*board_size+line))'
   104					then
   105						printf "$ESC[1;33m %4d $ESC[0m|" ${board[$row*$board_size+$line]}
   106					else
   107						printf "$ESC[${colors[${board[$row*$board_size+$line]}]}m %4d $ESC[0m|" ${board[$row*$board_size+$line]}
   108					fi
   109				else
   110					printf "      |"
   111				fi
   112			done
   113			if ((row!=index_max))
   114			then
   115				printf "\n|------"
   116				for((r=1;r<=index_max;r++))
   117				do
   118					printf "+------"
   119				done
   120				printf "|\n"
   121			fi
   122		done
   123		printf '\n\\------'
   124		for((row=1;row<=index_max;row++))
   125		do
   126			printf "+------"
   127		done
   128		printf "/\n"
   129	}

print_board函数用来打印游戏界面

  • 86至88行打印台头
    在这里插入图片描述

  • 90至95行及123至128行分别打印游戏界面的
    在这里插入图片描述
    在这里插入图片描述

  • 96至122行用一个双重循环遍历整个界面,外循环row即行,内循环line即列。

    1. 其中101行用来判断当前位置的格子内的值是否为0,若非零则输出。103行是在格子内的值非零的情况下,判断是否为最新生成的块或第一回合的块,如果是的话,用特定的黄色输出,如果不是的话,则按前面定义好的数值对应的颜色输出。
    2. 113至121行用来输出界面每两行中间的在这里插入图片描述

generate_piece
function generate_piece(){
   137		while true
   138		do
   139			((pos=RANDOM%fields_total))
   140			let ${board[$pos]} ||{ let value=RANDOM%10?2:4;board[$pos]=$value;last_added=$pos;break;}
   141		done
   142		((pieces++))
   143	}

generate_piece函数用来生成块

  • 139行随机生成块位置
  • 140行先判断生成的块的位置是否有非零值,如果没有的话就生成2或4作为该块的值,并跳出循环。
  • 142行将当前界面中所有非零格子数加一

push_pieces
155	function push_pieces(){
   156		case $4 in
   157		"up")
   158			let "first=$2*$board_size+$1"
   159			let "second=($2+$3)*$board_size+$1"
   160			;;
   161		"down")
   162			let "first=($index_max-$2)*$board_size+$1"
   163			let "second=($index_max-$2-$3)*$board_size+$1"
   164			;;
   165		"left")
   166			let "first=$1*$board_size+$2"
   167			let "second=$1*$board_size+$2+$3"
   168			;;
   169		"right")
   170			let "first=$1*$board_size+($index_max-$2)"
   171			let "second=($1*$board_size)+($index_max-$2-$3)"
   172			;;
   173		esac
   174		if ((board[$first]))
   175		then
   176			if ((board[$second]))
   177			then
   178				let flag_skip=1
   179			fi
   180			if ((board[$first]==board[$second]))
   181			then
   182				if [ -z $5 ]
   183				then
   184					let board[$first]*=2
   185					if ((board[$first]==target))
   186					then
   187						end_game 1
   188					fi
   189					let board[$second]=0
   190					let pieces-=1
   191					let change=1
   192					let score+=${board[$first]}
   193				else
   194					let moves++
   195				fi
   196			fi
   197		else
   198			if ((board[$second]))
   199			then
   200				if [ -z $5 ]
   201				then
   202					let board[$first]=${board[$second]}
   203					let board[$second]=0
   204					let change=1
   205				else
   206					let moves++
   207				fi
   208			fi
   209		fi
   210	}

push_pieces函数处理游戏操作,即接受到上下左右的操作信号时,处理格子内的数值。
它接受五个参数,参数1、2、3用来确定first及second的位置,参数4用来确定上下左右的操作信号,参数5用来确认是否只是测试而不改变游戏状态。
它的基本逻辑是,first格子作为容器存放处理后的数值,second格子则提供值等待处理。

  1. 174行判断first内是否存在非零值,如果存在非零值的话:

    • 176至179行判断如果second存在非零值的话,就只处理这一次,防止重复处理。
    • 180至196行判断,如果firstsecond内的值相同的话,就相加,并把结果存在first内。
  2. 如果first内不存在非零值的话:

    • 189至209行判断,如果second内存在非零值,则将其移到first内。
  3. 182及200行,配合check_moves函数测试是否还有可以进行的操作,不改变当前游戏状态。


apply_push
212	function apply_push(){
   213		for((i=0;i<=index_max;i++))
   214		do
   215			for((j=0;j<=index_max;j++))
   216			do
   217				let flag_skip=0
   218				let increment_max=index_max-j
   219				for((k=1;k<=increment_max;k++))
   220				do
   221					if ((flag_skip))
   222					then
   223						break
   224					fi
   225					push_pieces $i $j $k $1 $2
   226				done
   227			done
   228		done
   229	}

apply_push函数遍历整个界面并调用push_pieces函数处理游戏操作。

  1. 上下操作时,i代表列,j代表行。向上时,它的逻辑是从上到下,从左到右。向下时,它的逻辑是从下到上,从左到右。
  2. 左右操作时,i代表行,j代表列。向左时,它的逻辑是从左到右,从上到下。向右时,它的逻辑是从右到左,从上到下。

check_moves
 230	function check_moves(){
   231		let moves=0
   232		apply_push "up" fake
   233		apply_push "down" fake
   234		apply_push "left" fake
   235		apply_push "right" fake
   }

check_moves函数用来测试是否还有可以进行的操作,如果没有的话,游戏失败。


key_react
 237	function key_react(){
   238		let change=0
   239		read -d '' -sn 1
   240		if [ "$REPLY" = "$ESC" ]
   241		then
   242			read -d '' -sn 1
   243			if [ "$REPLY" = "[" ]
   244			then
   245				read -d '' -sn 1
   246				case $REPLY in
   247				A)
   248					apply_push up;;
   249				B)
   250					apply_push down;;
   251				C)
   252					apply_push right;;
   253				D)
   254					apply_push left;;
   255				esac
   256			fi
   257		else
   258			case $REPLY in
   259			k)
   260				apply_push up;;
   261			j)
   262				apply_push down;;
   263			h)
   264				apply_push left;;
   265			l)
   266				apply_push right;;
   267	
   268			w)
   269				apply_push up;;
   270			s)
   271				apply_push down;;
   272			a)
   273				apply_push left;;
   274			d)
   275				apply_push right;;
   276			esac
   277		fi
   278	}

key_react函数用来读取键盘操作,并调用apply_push进行相应处理。
例如↑键,它的控制码是\e[A,239、242、245行分别读取\e [ A,并在接下来进行判断。同时258至276行表示,也接受kjhlwsad作为上下左右。


save_game和reload_game
280	function save_game(){
   281		rm -rf "$config_dir"
   282		mkdir -p "$config_dir"
   283		echo "${board[*]}">"$config_dir/board"
   284		echo "$board_size">"$config_dir/board_size"
   285		echo "$pieces">"$config_dir/pieces"
   286		echo "$target">"$config_dir/target"
   287		echo "$score">"$config_dir/score"
   288		echo "$first_round">"$config_dir/first_round"
   289	}
   290	
   291	function reload_game(){
   292		if [ ! -d "$config_dir" ]
   293		then
   294			return
   295		else
   296			board=(`cat "$config_dir/board"`)
   297			board_size=`cat "$config_dir/board_size"`
   298			pieces=`cat "$config_dir/pieces"`
   299			target=`cat "$config_dir/target"`
   300			score=`cat "$config_dir/score"`
   301			first_round=`cat "$config_dir/first_round"`
   302			let fields_total=board_size**2
   303			let index_max=board_size-1
   304		fi
   305	}

这两个函数分别利用数据流重定向生成存储文件,和从文件中读取数据以载入上次游戏,其他没什么好说的了。


end_game
312	function end_game(){
   313		stty echo
   314		end_time=`date +%s`
   315		let total_time=end_time-start_time
   316		duration=`date -u -d @${total_time} +%T`
   317		print_board
   318		printf "Your score: $score\n"
   319		printf "Your game lasted $duration.\n"
   320		if (($1))
   321		then
   322			printf "Congratulations you have achieved $target!\n"
   323			exit 0
   324		fi
   325		if [ ! -z $2 ]
   326		then
   327			read -n1 -p "Do you want to overwrite saved game?[Y|N]: "
   328			if [ "$REPLY" = "Y" ]||[ "$REPLY" = "y" ]
   329			then
   330				save_game
   331				printf "\nGame saved! Use -r option next to load this game.\n"
   332				exit 0
   333			else
   334				printf "\nGame not saved!\n"
   335				exit 0
   336			fi
   337		fi
   338		printf "\nYou have lost, better luck next time.\n"
   339		exit 0
   340	}

end_game函数处理游戏的结束。

  1. 320至324行,它接受一个非零的参数1来表示游戏达成目标。
  2. 325至337行,即表示在使用ctrl+c主动结束游戏的情况下,询问是否存储。
  3. 338、339行,表示游戏失败。

 344	while getopts ":b:t:l:rhv" opt
   345	do
   346		case $opt in
   347		b)
   348			let board_size="$OPTARG"
   349			let '(board_size>=3)&(board_size<=9)'||{ printf "Invalid board size, please choose size between 3 and 9\n";exit 1;}
   350			;;
   351		t)
   352			let target="$OPTARG"
   353			printf "obase=2;$target\n"|bc|grep  -e '^1[^1]*$'
   354			let $? && { printf "Invalid target, have to be power of two\n";exit 1;}
   355			;;
   356		l)
   357			echo "This function have not be implement."
   358			exit 0
   359			;;
   360		r)
   361			let reload_flag=1
   362			;;
   363		h)
   364			help $0
   365			exit 0
   366			;;
   367		v)
   368			version
   369			exit 0
   370			;;
   371		\?)
   372			printf "Invalid option -$opt, please $0 -h\n">&2
   373			exit 1
   374			;;
   375		:)	
   376			printf "Option -$opt requires an argument, please $0 -h\n">&2
   377			exit 1
   378			;;
   379		esac
   380	done

334至380行,即利用getopts处理相关选项,-l我并没有实现,主要是懒的。至于help和version函数没什么好说的。353行,利用grep的返回值测试-t选项所指定的target是否符合2的幂。


 382	let index_max=board_size-1
   383	let fields_total=board_size**2
   384	
   385	for((index=0;index<fields_total;index++))
   386	do
   387		let board[$index]=0
   388	done
   389	generate_piece
   390	let first_round=$last_added
   391	generate_piece
   392	if ((reload_flag))
   393	then
   394		reload_game
   395	fi
   396	
   397	while true
   398	do
   399		print_board
   400		key_react
   401		let change&&generate_piece
   402		let first_round=-1
   403		if ((pieces==fields_total))
   404		then
   405			check_moves
   406			if ((moves==0))
   407			then
   408				end_game 0
   409			fi
   410		fi
   411	done
  • 385至388行初始化board数组。
  • 389至391行,产生第一回合的两个块。
  • 392至395行,判断是否载入上次存储的游戏。
  • 403至410行,判断游戏是否失败。

完整脚本

     1	#!/bin/bash
     2	
     3	
     4	#help information
     5	function help(){
     6		cat <<EOF
     7	--------------------------------------------------------------------------------------------------
     8	Usage: $1 [-b INTEGER] [-t INTEGER] [-l FILE] [-r] [-h] [-v]
     9	
    10		-b INTEGER	--	specify game board size (sizes 3-9 allowed)
    11		-t INTEGER	--	specify target score to win (needs to be power of 2)
    12		-l FILE		--	logged debug information to specified file
    13		-r		--	reload the previous game
    14		-h		--	help information
    15		-v		--	version information
    16	---------------------------------------------------------------------------------------------------
    17	EOF
    18	}
    19	
    20	#version information
    21	function version(){
    22		cat <<EOF
    23	----------------------------------------------------------------------------------------------------
    24	Name: bash2048
    25	Version: 1.00
    26	Author: goddog312
    27	----------------------------------------------------------------------------------------------------
    28	EOF
    29	}
    30	###########################
    31	#some important variables##
    32	###########################
    33	declare -ia board		#this array keep all values for each piece on the board
    34	declare -i pieces=0		#number of pieces present on board
    35	declare -i score=0		#store the current score
    36	declare -i flag_skip		#flag that prevents doing more than one operation on single field in one step
    37	declare -i moves		#store number of possible moves to determine are you lost the game or not
    38	declare ESC=$'\e'		#escape byte
    39	declare header="Bash 2048 v1.0"	#print on the top of screen
    40	
    41	#start time of the program
    42	declare -i start_time=$(date +%s)
    43	
    44	
    45	#############################################
    46	#default config, some can modify by options##
    47	#############################################
    48	declare -i board_size=4
    49	declare -i target=2048
    50	declare -i reload_flag=0
    51	declare config_dir="$HOME/.bash2048"
    52	
    53	
    54	################################
    55	##temp variables for once game##
    56	################################
    57	declare last_added		#the piece latest generated
    58	declare first_round		#the piece that generate in the first round
    59	declare -i index_max=$[$board_size-1]
    60	declare -i fields_total=$[$board_size*$board_size]
    61	
    62	########################
    63	#for colorizing number##
    64	########################
    65	declare -a colors
    66	colors[2]=32		#green text
    67	colors[4]=34		#blue text
    68	colors[8]=33		#yellow text
    69	colors[16]=36		#cyan text
    70	colors[32]=35		#purple text
    71	
    72	colors[64]="1;47;32"	#white background green text
    73	colors[128]="1;47;34"	#white background bule text
    74	colors[256]="1;47;33"	#white background yellow text
    75	colors[512]="1;47;36"	#white background cyan text
    76	colors[1024]="1;47;35"	#white background purple text
    77	colors[2048]="1;41;32"	#red background green text
    78	
    79	
    80	trap "end_game 0 1" INT	#handle INT signal
    81	
    82	#print current status of the game, the last added piece are red text
    83	function print_board(){
    84		clear
    85		printf "**************************************************************\n"
    86		printf "***********************$header*************************\n"
    87		printf "*$ESC[1;5;33mpieces=%-11d   target=%-11d   score=%-12d$ESC[0m*\n" $pieces $target $score
    88		printf "**************************************************************\n"
    89		echo
    90		printf "/------"
    91		for((row=1;row<=index_max;row++))
    92		do
    93			printf "+------"
    94		done
    95		printf '\\\n'
    96		for((row=0;row<=index_max;row++))
    97		do
    98			printf "|"
    99			for((line=0;line<=index_max;line++))
   100			do
   101				if let ${board[$row*$board_size+$line]}
   102				then
   103					if let '(last_added==(row*board_size+line))|(first_round==(row*board_size+line))'
   104					then
   105						printf "$ESC[1;33m %4d $ESC[0m|" ${board[$row*$board_size+$line]}
   106					else
   107						printf "$ESC[${colors[${board[$row*$board_size+$line]}]}m %4d $ESC[0m|" ${board[$row*$board_size+$line]}
   108					fi
   109				else
   110					printf "      |"
   111				fi
   112			done
   113			if ((row!=index_max))
   114			then
   115				printf "\n|------"
   116				for((r=1;r<=index_max;r++))
   117				do
   118					printf "+------"
   119				done
   120				printf "|\n"
   121			fi
   122		done
   123		printf '\n\\------'
   124		for((row=1;row<=index_max;row++))
   125		do
   126			printf "+------"
   127		done
   128		printf "/\n"
   129	}
   130	
   131	#generate new piece on board
   132	#generate a pos
   133	#generate a value in board[pos]
   134	#update last_added
   135	#update pieces
   136	function generate_piece(){
   137		while true
   138		do
   139			((pos=RANDOM%fields_total))
   140			let ${board[$pos]} ||{ let value=RANDOM%10?2:4;board[$pos]=$value;last_added=$pos;break;}
   141		done
   142		((pieces++))
   143	}
   144	
   145	#perform push operation between two pieces
   146	#variables:
   147	#		$1:push position, for horizontal push is column,for vertical is row
   148	#		$2:recipient piece, this will store result if moving or join
   149	#		$3:originator piece, after moving or join this piece will left empty
   150	#		$4:direction of push, can be either "up" , "donw" , "left" or "right"
   151	#		$5:if anything was passed, do not perform the push, but only update number of valid moves. Used for function check_moves
   152	#		$board:the status of the game board
   153	#		$change:indicates if the board was changed this round
   154	#		$flag_skip:indicates the recipient piece cannot be modified further
   155	function push_pieces(){
   156		case $4 in
   157		"up")
   158			let "first=$2*$board_size+$1"
   159			let "second=($2+$3)*$board_size+$1"
   160			;;
   161		"down")
   162			let "first=($index_max-$2)*$board_size+$1"
   163			let "second=($index_max-$2-$3)*$board_size+$1"
   164			;;
   165		"left")
   166			let "first=$1*$board_size+$2"
   167			let "second=$1*$board_size+$2+$3"
   168			;;
   169		"right")
   170			let "first=$1*$board_size+($index_max-$2)"
   171			let "second=($1*$board_size)+($index_max-$2-$3)"
   172			;;
   173		esac
   174		if ((board[$first]))
   175		then
   176			if ((board[$second]))
   177			then
   178				let flag_skip=1
   179			fi
   180			if ((board[$first]==board[$second]))
   181			then
   182				if [ -z $5 ]
   183				then
   184					let board[$first]*=2
   185					if ((board[$first]==target))
   186					then
   187						end_game 1
   188					fi
   189					let board[$second]=0
   190					let pieces-=1
   191					let change=1
   192					let score+=${board[$first]}
   193				else
   194					let moves++
   195				fi
   196			fi
   197		else
   198			if ((board[$second]))
   199			then
   200				if [ -z $5 ]
   201				then
   202					let board[$first]=${board[$second]}
   203					let board[$second]=0
   204					let change=1
   205				else
   206					let moves++
   207				fi
   208			fi
   209		fi
   210	}
   211	
   212	function apply_push(){
   213		for((i=0;i<=index_max;i++))
   214		do
   215			for((j=0;j<=index_max;j++))
   216			do
   217				let flag_skip=0
   218				let increment_max=index_max-j
   219				for((k=1;k<=increment_max;k++))
   220				do
   221					if ((flag_skip))
   222					then
   223						break
   224					fi
   225					push_pieces $i $j $k $1 $2
   226				done
   227			done
   228		done
   229	}
   230	function check_moves(){
   231		let moves=0
   232		apply_push "up" fake
   233		apply_push "down" fake
   234		apply_push "left" fake
   235		apply_push "right" fake
   236	}
   237	function key_react(){
   238		let change=0
   239		read -d '' -sn 1
   240		if [ "$REPLY" = "$ESC" ]
   241		then
   242			read -d '' -sn 1
   243			if [ "$REPLY" = "[" ]
   244			then
   245				read -d '' -sn 1
   246				case $REPLY in
   247				A)
   248					apply_push up;;
   249				B)
   250					apply_push down;;
   251				C)
   252					apply_push right;;
   253				D)
   254					apply_push left;;
   255				esac
   256			fi
   257		else
   258			case $REPLY in
   259			k)
   260				apply_push up;;
   261			j)
   262				apply_push down;;
   263			h)
   264				apply_push left;;
   265			l)
   266				apply_push right;;
   267	
   268			w)
   269				apply_push up;;
   270			s)
   271				apply_push down;;
   272			a)
   273				apply_push left;;
   274			d)
   275				apply_push right;;
   276			esac
   277		fi
   278	}
   279	
   280	function save_game(){
   281		rm -rf "$config_dir"
   282		mkdir -p "$config_dir"
   283		echo "${board[*]}">"$config_dir/board"
   284		echo "$board_size">"$config_dir/board_size"
   285		echo "$pieces">"$config_dir/pieces"
   286		echo "$target">"$config_dir/target"
   287		echo "$score">"$config_dir/score"
   288		echo "$first_round">"$config_dir/first_round"
   289	}
   290	
   291	function reload_game(){
   292		if [ ! -d "$config_dir" ]
   293		then
   294			return
   295		else
   296			board=(`cat "$config_dir/board"`)
   297			board_size=`cat "$config_dir/board_size"`
   298			pieces=`cat "$config_dir/pieces"`
   299			target=`cat "$config_dir/target"`
   300			score=`cat "$config_dir/score"`
   301			first_round=`cat "$config_dir/first_round"`
   302			let fields_total=board_size**2
   303			let index_max=board_size-1
   304		fi
   305	}
   306	
   307	
   308	#print game duration
   309	#print total score
   310	#print end or achieve information
   311	#choose save game or not
   312	function end_game(){
   313		stty echo
   314		end_time=`date +%s`
   315		let total_time=end_time-start_time
   316		duration=`date -u -d @${total_time} +%T`
   317		print_board
   318		printf "Your score: $score\n"
   319		printf "Your game lasted $duration.\n"
   320		if (($1))
   321		then
   322			printf "Congratulations you have achieved $target!\n"
   323			exit 0
   324		fi
   325		if [ ! -z $2 ]
   326		then
   327			read -n1 -p "Do you want to overwrite saved game?[Y|N]: "
   328			if [ "$REPLY" = "Y" ]||[ "$REPLY" = "y" ]
   329			then
   330				save_game
   331				printf "\nGame saved! Use -r option next to load this game.\n"
   332				exit 0
   333			else
   334				printf "\nGame not saved!\n"
   335				exit 0
   336			fi
   337		fi
   338		printf "\nYou have lost, better luck next time.\n"
   339		exit 0
   340	}
   341	
   342	
   343	#parse command line options
   344	while getopts ":b:t:l:rhv" opt
   345	do
   346		case $opt in
   347		b)
   348			let board_size="$OPTARG"
   349			let '(board_size>=3)&(board_size<=9)'||{ printf "Invalid board size, please choose size between 3 and 9\n";exit 1;}
   350			;;
   351		t)
   352			let target="$OPTARG"
   353			printf "obase=2;$target\n"|bc|grep  -e '^1[^1]*$'
   354			let $? && { printf "Invalid target, have to be power of two\n";exit 1;}
   355			;;
   356		l)
   357			echo "This function have not be implement."
   358			exit 0
   359			;;
   360		r)
   361			let reload_flag=1
   362			;;
   363		h)
   364			help $0
   365			exit 0
   366			;;
   367		v)
   368			version
   369			exit 0
   370			;;
   371		\?)
   372			printf "Invalid option -$opt, please $0 -h\n">&2
   373			exit 1
   374			;;
   375		:)	
   376			printf "Option -$opt requires an argument, please $0 -h\n">&2
   377			exit 1
   378			;;
   379		esac
   380	done
   381	
   382	let index_max=board_size-1
   383	let fields_total=board_size**2
   384	
   385	for((index=0;index<fields_total;index++))
   386	do
   387		let board[$index]=0
   388	done
   389	generate_piece
   390	let first_round=$last_added
   391	generate_piece
   392	if ((reload_flag))
   393	then
   394		reload_game
   395	fi
   396	
   397	while true
   398	do
   399		print_board
   400		key_react
   401		let change&&generate_piece
   402		let first_round=-1
   403		if ((pieces==fields_total))
   404		then
   405			check_moves
   406			if ((moves==0))
   407			then
   408				end_game 0
   409			fi
   410		fi
   411	done
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值