Batch脚本开发井字棋(Tic Tac Toe)的变量更新与代码精简问题
问题1:胜负判定失效原因及修复
你出现判定错误是两个核心问题导致的:
- 所有
_win系列变量仅在初始化:setvar的时候计算过一次,后续玩家落子更新_f1~_f9后,没有重新更新_win变量的值,自然判定不会生效。 - 你给
_win2~_win8用了set /a加法运算,字符X/O参与数值运算会被识别为0,最终结果永远是数字,不可能等于XXX/OOO字符串,属于逻辑错误。
修复方案:
- 先把
:setvar里所有_win变量的set /a都改成普通字符串拼接,统一格式:
set _win1=!_f7!!_f8!!_f9! set _win2=!_f4!!_f5!!_f6! set _win3=!_f1!!_f2!!_f3! set _win4=!_f7!!_f4!!_f1! set _win5=!_f8!!_f5!!_f2! set _win6=!_f9!!_f6!!_f3! set _win7=!_f7!!_f5!!_f3! set _win8=!_f9!!_f5!!_f1!
- 可以把这段
_win变量更新逻辑单独抽成:update_win子程序,每次玩家落子完成后、调用:check判定前先调用一次,把最新的棋盘格状态同步到获胜线变量里即可。
问题2:冗余代码用for循环精简
2.1 精简玩家落子逻辑
你原有player1turn和player2turn逻辑完全一致,还写了9个重复的if判断,可以合并为通用子程序,用for逻辑替代重复判断:
:: 调用规则:call :playerturn 1 对应玩家1回合,call :playerturn 2 对应玩家2回合 :playerturn set "player_num=%~1" choice /c 123456789 /n /m "!_player%player_num%!, it's your turn!" set "pos=!errorlevel!" :: 检查落子位置是否未被占用 if !_f%pos%! equ %pos% ( set "_f%pos%=!_player%player_num%symbol!" goto :eof ) else ( :: 位置已被占用,让当前玩家重新选择 goto :playerturn )
直接删除原来的两个玩家回合子程序即可,同时还修复了你原有代码里玩家2选了占用位置直接跳转玩家1回合的逻辑错误。
2.2 精简胜负判定逻辑
原有:check里8个重复的if判断可以直接用for循环遍历:
:check :: 先更新最新的获胜线状态 call :update_win for /l %%i in (1,1,8) do ( if "!_win%%i!"=="!_player1symbol!!_player1symbol!!_player1symbol!" ( echo !_player1! 获胜!游戏结束 pause exit ) if "!_win%%i!"=="!_player2symbol!!_player2symbol!!_player2symbol!" ( echo !_player2! 获胜!游戏结束 pause exit ) ) :: 额外补充平局判定 set "filled=0" for /l %%i in (1,1,9) do ( if not !_f%%i! equ %%i set /a filled+=1 ) if !filled! equ 9 ( echo 平局!游戏结束 pause exit ) goto :eof
2.3 精简主循环逻辑
原有main里手动写的轮流落子逻辑可以替换为死循环自动轮转:
:main setlocal enabledelayedexpansion call :setup cls call :setvar :game_loop cls call :map call :playerturn 1 call :check cls call :map call :playerturn 2 call :check goto :game_loop
注意删除原有main里重复的setlocal语句,避免覆盖外层的延迟扩展配置。
内容的提问来源于stack exchange,提问作者aphel
相关产品推荐
相关产品推荐

