bash shell实现2048小游戏详解
目录
- 前言
- 重要变量
- 功能函数
- 退出处理
- print_board
- generate_piece
- push_pieces
- apply_push
- check_moves
- key_react
- save_game和reload_game
- end_game
- 完整脚本
前言
最近在github上看到一个用bash shell实现2048小游戏的脚本感觉挺有意思的,就自己仿照他的样子稍作修改再实现了一遍我的实现,并记录下实现的详细过程。
脚本的运行如图:
重要变量
- board 是一个整型数组,用来存储所有格子中的当前数值,它的下标即从0到总格子数减1,与界面中的格子从左到右,再从上到下,一一对应。数组的所有元素,在全新的游戏开始时用0初始化,而载入游戏时,用存档目录中的文件初始化。
- pieces 用来储存当前界面中所有非零的格子数。
- score 用来储存当前的得分总数。
- flag_skip 用来防止一个格子在同一回合中被操作两次。
- moves 用来测试游戏还能不能被操作,是否已经输掉游戏。
- ESC 作为Escape屏幕控制码,在输出颜色格式的时候使用,\e或者\033等都可以。
- header 也就是界面的标题,介绍性质的,可以自己定义
- start_time 记录程序开始的时间
这四个变量作为默认值,可以通过选项改变
- board_size 即游戏界面的每边的大小,限制在3至9之间
- target 即游戏成功的目标,可以自己设定,但需要是2的幂
- reload_flag 即是否载入存档
- config_dir 即存档文件的目标目录
- last_added 即最新生成的块的位置
- first_round 即第一个生成的块的位置。因为游戏最开始必须要生成两个块,而我定义用黄色表现这两个块以及用黄色表示以后每次最新生成的块。
- index_max 因为数组的下标从0开始,所以定义这个变量为游戏界面的每边的大小减一
- fields_total 即游戏界面中格子的总数
定义一个数组用来储存各个数字的颜色表现,搭配前面定义的$ESC构成Escape屏幕控制码,64及以上添加了高亮和白底,这些可以自行修改。
功能函数
退出处理
这里调用end_game函数处理INT信号,亦即使用ctrl+c
发出退出请求,由end_game进行退出流程。
print_board
83 function print_board(){84 clear85 printf "**************************************************************\n"86 printf "***********************$header*************************\n"87 printf "*$ESC[1;5;33mpieces=%-11d target=%-11d score=%-12d$ESC[0m*\n" $pieces $target $score88 printf "**************************************************************\n"89 echo90 printf "/------"91 for((row=1;row<=index_max;row++))92 do93 printf "+------"94 done95 printf '\\\n'96 for((row=0;row<=index_max;row++))97 do98 printf "|"99 for((line=0;line<=index_max;line++))100 do101 if let ${board[$row*$board_size+$line]}102 then103 if let '(last_added==(row*board_size+line))|(first_round==(row*board_size+line))'104 then105 printf "$ESC[1;33m %4d $ESC[0m|" ${board[$row*$board_size+$line]}106 else107 printf "$ESC[${colors[${board[$row*$board_size+$line]}]}m %4d $ESC[0m|" ${board[$row*$board_size+$line]}108 fi109 else110 printf " |"111 fi112 done113 if ((row!=index_max))114 then115 printf "\n|------"116 for((r=1;r<=index_max;r++))117 do118 printf "+------"119 done120 printf "|\n"121 fi122 done123 printf '\n\\------'124 for((row=1;row<=index_max;row++))125 do126 printf "+------"127 done128 printf "/\n"129 }
print_board函数用来打印游戏界面
86至88行打印台头
90至95行及123至128行分别打印游戏界面的
和
96至122行用一个双重循环遍历整个界面,外循环row即行,内循环line即列。
- 其中101行用来判断当前位置的格子内的值是否为0,若非零则输出。103行是在格子内的值非零的情况下,判断是否为最新生成的块或第一回合的块,如果是的话,用特定的黄色输出,如果不是的话,则按前面定义好的数值对应的颜色输出。
- 113至121行用来输出界面每两行中间的
generate_piece
function generate_piece(){137 while true138 do139 ((pos=RANDOM%fields_total))140 let ${board[$pos]} ||{ let value=RANDOM%10?2:4;board[$pos]=$value;last_added=$pos;break;}141 done142 ((pieces++))143 }
generate_piece函数用来生成块
- 139行随机生成块位置
- 140行先判断生成的块的位置是否有非零值,如果没有的话就生成2或4作为该块的值,并跳出循环。
- 142行将当前界面中所有非零格子数加一
push_pieces
155 function push_pieces(){156 case $4 in157 "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 esac174 if ((board[$first]))175 then176 if ((board[$second]))177 then178 let flag_skip=1179 fi180 if ((board[$first]==board[$second]))181 then182 if [ -z $5 ]183 then184 let board[$first]*=2185 if ((board[$first]==target))186 then187 end_game 1188 fi189 let board[$second]=0190 let pieces-=1191 let change=1192 let score+=${board[$first]}193 else194 let moves++195 fi196 fi197 else198 if ((board[$second]))199 then200 if [ -z $5 ]201 then202 let board[$first]=${board[$second]}203 let board[$second]=0204 let change=1205 else206 let moves++207 fi208 fi209 fi210 }
push_pieces函数处理游戏操作,即接受到上下左右的操作信号时,处理格子内的数值。
它接受五个参数,参数1、2、3用来确定first及second的位置,参数4用来确定上下左右的操作信号,参数5用来确认是否只是测试而不改变游戏状态。
它的基本逻辑是,first格子作为容器存放处理后的数值,second格子则提供值等待处理。
174行判断first内是否存在非零值,如果存在非零值的话:
- 176至179行判断如果second存在非零值的话,就只处理这一次,防止重复处理。
- 180至196行判断,如果first和second内的值相同的话,就相加,并把结果存在first内。
如果first内不存在非零值的话:
- 189至209行判断,如果second内存在非零值,则将其移到first内。
182及200行,配合check_moves函数测试是否还有可以进行的操作,不改变当前游戏状态。
apply_push
212 function apply_push(){213 for((i=0;i<=index_max;i++))214 do215 for((j=0;j<=index_max;j++))216 do217 let flag_skip=0218 let increment_max=index_max-j219 for((k=1;k<=increment_max;k++))220 do221 if ((flag_skip))222 then223 break224 fi225 push_pieces $i $j $k $1 $2226 done227 done228 done229 }
apply_push函数遍历整个界面并调用push_pieces函数处理游戏操作。
- 上下操作时,i代表列,j代表行。向上时,它的逻辑是从上到下,从左到右。向下时,它的逻辑是从下到上,从左到右。
- 左右操作时,i代表行,j代表列。向左时,它的逻辑是从左到右,从上到下。向右时,它的逻辑是从右到左,从上到下。
check_moves
230 function check_moves(){231 let moves=0232 apply_push "up" fake233 apply_push "down" fake234 apply_push "left" fake235 apply_push "right" fake}
check_moves函数用来测试是否还有可以进行的操作,如果没有的话,游戏失败。
key_react
237 function key_react(){238 let change=0239 read -d '' -sn 1240 if [ "$REPLY" = "$ESC" ]241 then242 read -d '' -sn 1243 if [ "$REPLY" = "[" ]244 then245 read -d '' -sn 1246 case $REPLY in247 A)248 apply_push up;;249 B)250 apply_push down;;251 C)252 apply_push right;;253 D)254 apply_push left;;255 esac256 fi257 else258 case $REPLY in259 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 esac277 fi278 }
key_react函数用来读取键盘操作,并调用apply_push进行相应处理。
例如↑键,它的控制码是\e[A,239、242、245行分别读取\e
[
A
,并在接下来进行判断。同时258至276行表示,也接受kjhl
和wsad
作为上下左右。
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 then294 return295 else296 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**2303 let index_max=board_size-1304 fi305 }
这两个函数分别利用数据流重定向生成存储文件,和从文件中读取数据以载入上次游戏,其他没什么好说的了。
end_game
312 function end_game(){313 stty echo314 end_time=`date +%s`315 let total_time=end_time-start_time316 duration=`date -u -d @${total_time} +%T`317 print_board318 printf "Your score: $score\n"319 printf "Your game lasted $duration.\n"320 if (($1))321 then322 printf "Congratulations you have achieved $target!\n"323 exit 0324 fi325 if [ ! -z $2 ]326 then327 read -n1 -p "Do you want to overwrite saved game?[Y|N]: "328 if [ "$REPLY" = "Y" ]||[ "$REPLY" = "y" ]329 then330 save_game331 printf "\nGame saved! Use -r option next to load this game.\n"332 exit 0333 else334 printf "\nGame not saved!\n"335 exit 0336 fi337 fi338 printf "\nYou have lost, better luck next time.\n"339 exit 0340 }
end_game函数处理游戏的结束。
- 320至324行,它接受一个非零的参数1来表示游戏达成目标。
- 325至337行,即表示在使用
ctrl+c
主动结束游戏的情况下,询问是否存储。 - 338、339行,表示游戏失败。
344 while getopts ":b:t:l:rhv" opt345 do346 case $opt in347 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 0359 ;;360 r)361 let reload_flag=1362 ;;363 h)364 help $0365 exit 0366 ;;367 v)368 version369 exit 0370 ;;371 \?)372 printf "Invalid option -$opt, please $0 -h\n">&2373 exit 1374 ;;375 :) 376 printf "Option -$opt requires an argument, please $0 -h\n">&2377 exit 1378 ;;379 esac380 done
334至380行,即利用getopts处理相关选项,-l我并没有实现,主要是懒的。至于help和version函数没什么好说的。353行,利用grep的返回值测试-t选项所指定的target是否符合2的幂。
382 let index_max=board_size-1383 let fields_total=board_size**2384 385 for((index=0;index<fields_total;index++))386 do387 let board[$index]=0388 done389 generate_piece390 let first_round=$last_added391 generate_piece392 if ((reload_flag))393 then394 reload_game395 fi396 397 while true398 do399 print_board400 key_react401 let change&&generate_piece402 let first_round=-1403 if ((pieces==fields_total))404 then405 check_moves406 if ((moves==0))407 then408 end_game 0409 fi410 fi411 done
- 385至388行初始化board数组。
- 389至391行,产生第一回合的两个块。
- 392至395行,判断是否载入上次存储的游戏。
- 403至410行,判断游戏是否失败。
完整脚本
1 #!/bin/bash2 3 4 #help information5 function help(){6 cat <<EOF7 --------------------------------------------------------------------------------------------------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 file13 -r -- reload the previous game14 -h -- help information15 -v -- version information16 ---------------------------------------------------------------------------------------------------17 EOF18 }19 20 #version information21 function version(){22 cat <<EOF23 ----------------------------------------------------------------------------------------------------24 Name: bash204825 Version: 1.0026 Author: goddog31227 ----------------------------------------------------------------------------------------------------28 EOF29 }30 ###########################31 #some important variables##32 ###########################33 declare -ia board #this array keep all values for each piece on the board34 declare -i pieces=0 #number of pieces present on board35 declare -i score=0 #store the current score36 declare -i flag_skip #flag that prevents doing more than one operation on single field in one step37 declare -i moves #store number of possible moves to determine are you lost the game or not38 declare ESC=$'\e' #escape byte39 declare header="Bash 2048 v1.0" #print on the top of screen40 41 #start time of the program42 declare -i start_time=$(date +%s)43 44 45 #############################################46 #default config, some can modify by options##47 #############################################48 declare -i board_size=449 declare -i target=204850 declare -i reload_flag=051 declare config_dir="$HOME/.bash2048"52 53 54 ################################55 ##temp variables for once game##56 ################################57 declare last_added #the piece latest generated58 declare first_round #the piece that generate in the first round59 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 colors66 colors[2]=32 #green text67 colors[4]=34 #blue text68 colors[8]=33 #yellow text69 colors[16]=36 #cyan text70 colors[32]=35 #purple text71 72 colors[64]="1;47;32" #white background green text73 colors[128]="1;47;34" #white background bule text74 colors[256]="1;47;33" #white background yellow text75 colors[512]="1;47;36" #white background cyan text76 colors[1024]="1;47;35" #white background purple text77 colors[2048]="1;41;32" #red background green text78 79 80 trap "end_game 0 1" INT #handle INT signal81 82 #print current status of the game, the last added piece are red text83 function print_board(){84 clear85 printf "**************************************************************\n"86 printf "***********************$header*************************\n"87 printf "*$ESC[1;5;33mpieces=%-11d target=%-11d score=%-12d$ESC[0m*\n" $pieces $target $score88 printf "**************************************************************\n"89 echo90 printf "/------"91 for((row=1;row<=index_max;row++))92 do93 printf "+------"94 done95 printf '\\\n'96 for((row=0;row<=index_max;row++))97 do98 printf "|"99 for((line=0;line<=index_max;line++))100 do101 if let ${board[$row*$board_size+$line]}102 then103 if let '(last_added==(row*board_size+line))|(first_round==(row*board_size+line))'104 then105 printf "$ESC[1;33m %4d $ESC[0m|" ${board[$row*$board_size+$line]}106 else107 printf "$ESC[${colors[${board[$row*$board_size+$line]}]}m %4d $ESC[0m|" ${board[$row*$board_size+$line]}108 fi109 else110 printf " |"111 fi112 done113 if ((row!=index_max))114 then115 printf "\n|------"116 for((r=1;r<=index_max;r++))117 do118 printf "+------"119 done120 printf "|\n"121 fi122 done123 printf '\n\\------'124 for((row=1;row<=index_max;row++))125 do126 printf "+------"127 done128 printf "/\n"129 }130 131 #generate new piece on board132 #generate a pos133 #generate a value in board[pos]134 #update last_added135 #update pieces136 function generate_piece(){137 while true138 do139 ((pos=RANDOM%fields_total))140 let ${board[$pos]} ||{ let value=RANDOM%10?2:4;board[$pos]=$value;last_added=$pos;break;}141 done142 ((pieces++))143 }144 145 #perform push operation between two pieces146 #variables:147 # $1:push position, for horizontal push is column,for vertical is row148 # $2:recipient piece, this will store result if moving or join149 # $3:originator piece, after moving or join this piece will left empty150 # $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_moves152 # $board:the status of the game board153 # $change:indicates if the board was changed this round154 # $flag_skip:indicates the recipient piece cannot be modified further155 function push_pieces(){156 case $4 in157 "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 esac174 if ((board[$first]))175 then176 if ((board[$second]))177 then178 let flag_skip=1179 fi180 if ((board[$first]==board[$second]))181 then182 if [ -z $5 ]183 then184 let board[$first]*=2185 if ((board[$first]==target))186 then187 end_game 1188 fi189 let board[$second]=0190 let pieces-=1191 let change=1192 let score+=${board[$first]}193 else194 let moves++195 fi196 fi197 else198 if ((board[$second]))199 then200 if [ -z $5 ]201 then202 let board[$first]=${board[$second]}203 let board[$second]=0204 let change=1205 else206 let moves++207 fi208 fi209 fi210 }211 212 function apply_push(){213 for((i=0;i<=index_max;i++))214 do215 for((j=0;j<=index_max;j++))216 do217 let flag_skip=0218 let increment_max=index_max-j219 for((k=1;k<=increment_max;k++))220 do221 if ((flag_skip))222 then223 break224 fi225 push_pieces $i $j $k $1 $2226 done227 done228 done229 }230 function check_moves(){231 let moves=0232 apply_push "up" fake233 apply_push "down" fake234 apply_push "left" fake235 apply_push "right" fake236 }237 function key_react(){238 let change=0239 read -d '' -sn 1240 if [ "$REPLY" = "$ESC" ]241 then242 read -d '' -sn 1243 if [ "$REPLY" = "[" ]244 then245 read -d '' -sn 1246 case $REPLY in247 A)248 apply_push up;;249 B)250 apply_push down;;251 C)252 apply_push right;;253 D)254 apply_push left;;255 esac256 fi257 else258 case $REPLY in259 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 esac277 fi278 }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 then294 return295 else296 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**2303 let index_max=board_size-1304 fi305 }306 307 308 #print game duration309 #print total score310 #print end or achieve information311 #choose save game or not312 function end_game(){313 stty echo314 end_time=`date +%s`315 let total_time=end_time-start_time316 duration=`date -u -d @${total_time} +%T`317 print_board318 printf "Your score: $score\n"319 printf "Your game lasted $duration.\n"320 if (($1))321 then322 printf "Congratulations you have achieved $target!\n"323 exit 0324 fi325 if [ ! -z $2 ]326 then327 read -n1 -p "Do you want to overwrite saved game?[Y|N]: "328 if [ "$REPLY" = "Y" ]||[ "$REPLY" = "y" ]329 then330 save_game331 printf "\nGame saved! Use -r option next to load this game.\n"332 exit 0333 else334 printf "\nGame not saved!\n"335 exit 0336 fi337 fi338 printf "\nYou have lost, better luck next time.\n"339 exit 0340 }341 342 343 #parse command line options344 while getopts ":b:t:l:rhv" opt345 do346 case $opt in347 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 0359 ;;360 r)361 let reload_flag=1362 ;;363 h)364 help $0365 exit 0366 ;;367 v)368 version369 exit 0370 ;;371 \?)372 printf "Invalid option -$opt, please $0 -h\n">&2373 exit 1374 ;;375 :) 376 printf "Option -$opt requires an argument, please $0 -h\n">&2377 exit 1378 ;;379 esac380 done381 382 let index_max=board_size-1383 let fields_total=board_size**2384 385 for((index=0;index<fields_total;index++))386 do387 let board[$index]=0388 done389 generate_piece390 let first_round=$last_added391 generate_piece392 if ((reload_flag))393 then394 reload_game395 fi396 397 while true398 do399 print_board400 key_react401 let change&&generate_piece402 let first_round=-1403 if ((pieces==fields_total))404 then405 check_moves406 if ((moves==0))407 then408 end_game 0409 fi410 fi411 done
bash shell实现2048小游戏详解相关推荐
- 【C语言】扫雷小游戏详解
[C语言]扫雷小游戏详解 前言: 还记得大明湖畔的夏雨荷,电脑课上的扫雷吗? ---------------------------是 他 吗--------------------------- 没 ...
- 100行实现《贪吃蛇》小游戏详解(Qt)
目录 游戏说明 游戏效果展示 游戏代码详解 关键数据结构 初始化游戏界面 游戏部分 提示部分 蛇逻辑 小蛇的初始化 边界判断 蛇吃食物判断 随机生成食物 是否撞到自己 小蛇的移动 游戏主体逻辑 定时 ...
- c语言字符游动程序,C语言实现扫雷小游戏详解
本文实例为大家分享了C语言实现扫雷小游戏的具体代码,供大家参考,具体内容如下 一.实现功能 首先显示一个小菜单,选择是否玩游戏.当用户选择退出时,程序运行结束,当用户选择玩游戏时,将提示用户输入扫雷位 ...
- java闯关小游戏+详解+完整源代码+测试结果
小游戏面向对象 一,问题分析 计算机输出字符串,玩家根据计算输出的内容重复输入,如果输入正确,进入一下关的练习 该过程记录玩家的积分,定义游戏的关卡,定义游戏的规则 1.1定义游戏的规则 游戏的关卡 ...
- HTML+Javascript制作拼图小游戏详解(一)
本文章将分享一个来自前端菜鸟突发奇想的拼图游戏制作方法以及实现过程. 话不多说,先上图. 首先我们需要写好网页的基本布局(此处涉及简单的HTML和CSS知识). 网页一共分为三个区域,左侧时间显示区, ...
- python小项目——2048小游戏(详解)
2048游戏 原版游戏地址 第一部分 导入所需要的库 第二部分 确认游戏键位设置,并和对应的操作关联 第三部分 获取用户输入的值,并直到有效键位 第四部分 对矩阵的应用,减少代码量 第五部分 创建棋盘 ...
- html+css+js适合前端小白的实战全解(超详细)——2048小游戏(三)
续上一小节,我们回到newgame()这个函数,我们之前只做了init()内函数,相当于一个初始化操作 现在,我们需要再随机两个两个生成数字. 随机生成数字在这个游戏里会经常出现,用户移动一步,也会产 ...
- html+css+js适合前端小白的实战全解(超详细)——2048小游戏(二)
续上一小节,我们可以发现每一个grid-cell上的数字初始时并不在格子里. 这些数字可以随着玩家的操作而移动 我们可以想象:初始时每一个格子上的数为0,他们并不显示 ↓ 只有当grid-cell ...
- 取石子游戏详解NIM
取石子游戏详解NIM 分类: 编程之美2014-09-13 09:38 478人阅读 评论(3) 收藏 举报 编程之美 目录(?)[+] http://blog.csdn.net/pipisorry/ ...
最新文章
- php判断邮箱是否合法性,php验证邮箱地址合法性
- iOS Sprite Kit教程之场景的切换
- ArrayList源码分析(基于JDK1.6)
- 灵活强大的构建系统Gradle
- python支持向量机分类器怎么用_可视化SVM分类器开源实现的python代码
- 为什么我会弃Java,选择了Kotlin——专访《Java编程思想》作者 Bruce Eckel
- jsp 基本语法学习笔记
- Linux内核发包软件,pktgen--内核态发包工具
- C语言实现字符串转数字(包括负数)
- 代理记账公司能够为企业客户提供哪些服务
- 四层协议和七层协议详解
- php PDO连接mysql
- 示例代码-协方差,黎曼协方差计算.
- 给定一个包含非负整数的 m x n 网格,请找出一条从左上角到右下角的路径, 使得路径上的数字总和为最小。 说明:每次只能向下或者向右移动一步。
- vmware全屏后退出全屏快捷键
- Python - 面向对象编程 - 实战(5)
- 淘晶驰串口屏入门(五)下拉框 选择文本 动画 视频 外部图片
- 联想小新一键恢复小孔_联想小新一键恢复小孔 联想小新笔记本怎么一键恢复...
- 自然语言处理nlp:SnowNLP自主训练情感分析模型
- 教师资格证是计算机考试地点,教师资格证考试必须有计算机模块证吗?
热门文章
- 数据挖掘综合应用:房屋售价预测案例
- “破产清算”的拉夏贝尔,不会是最后一个
- jQuery中的Ajax(全)
- 自制车速记录仪「GitHub 热点速览 v.21.31」
- 微软为什么能在中国所向披靡 雁鸣
- MFC单项选择题标准化考试系统
- 如何办理《网络出版服务许可证》
- 计算机二级access分数分布_全国计算机等级考试2017年上半年二级ACCESS数据库成绩查询...
- 【洛谷】P1747 好奇怪的游戏(bfs)
- Python中的Numpy、SciPy、MatPlotLib安装教程