バッチファイル(オセロ010_コメント_終)
■コードを整理して、コメントをつける。
バッチファイルでオセロのプログラムを組むのは前回まででできたので、最後にコードを見直してコメントをつけておく。バッチファイルでは、remでそれ以降の1行分はコメントとなるらしいので、都度remをつけてコメントを入れておく。
最終的なコードは下記のもの。一端これで終了。
(少しコード修正したので、新しいバグを入れていないことをいのるばかり)
@echo off rem ==============================Start Setting============================== echo Start Othello echo If there is no place for stone, input "pass" set position=00 set line=0 set row=0 set turnchangeflag=0 set trialnum=1 set player=A set playerBtrial=0 rem %1 is command line parameter. If something is set, file is created and data is saved. rem ------------------------------ if "%1"=="" ( rem No save ) else ( echo Filename:"%1.txt" ) rem ------------------------------ rem /l:optional symbol, %%n:variable within for code、(1,1,8):(start number, increase, end number) rem initial setting on field, stone (white:〇, black:●), space:_ rem ------------------------------ for /l %%n in (0,1,9) do ( for /l %%m in (0,1,9) do ( set array[%%n][%%m]=_ ) ) set array[4][4]=〇 set array[4][5]=● set array[5][4]=● set array[5][5]=〇 rem ------------------------------ rem initial display for field rem ------------------------------ setlocal enabledelayedexpansion for /l %%n in (1,1,8) do ( echo !array[%%n][1]!!array[%%n][2]!!array[%%n][3]!!array[%%n][4]!!array[%%n][5]!!array[%%n][6]!!array[%%n][7]!!array[%%n][8]! ) rem ------------------------------ rem ==============================Start Setting============================== rem ==============================Playing Othello============================== :trial set checkcnt=1 set turnchangeflag=0 rem If field is all filled, go to "result". if %trialnum% gtr 60 ( goto :result ) rem Wait for player A input. Player B automatically sets a stone. rem ------------------------------ if %player%==A ( set /P position="Player A: " ) else if %player%==B ( set /a playerBtrial=playerBtrial+1 set /a line=%random%8/32767+1 set /a row=%random%8/32767+1 ) ) if %player%==B ( if %playerBtrial% gtr 300 ( set /a turnchangeflag=turnchangeflag+1 set player=A set position=pass ) else ( set position=%line%,%row% ) ) rem ------------------------------ rem Trim space (half-width, full-width) before or after characters. rem ------------------------------ :TRIM if "%position:~0,1%"==" " ( SET position=%position:~1% GOTO TRIM ) if "%position:~-1%"==" " ( SET position=%position:~0,-1% GOTO TRIM ) if "%position:~0,1%"==" " ( SET position=%position:~1% GOTO TRIM ) if "%position:~-1%"==" " ( SET position=%position:~0,-1% GOTO TRIM ) rem ------------------------------ if "%position%"=="" ( goto :trial ) rem If pass is inputted, player turn is changed and flag (turnchangeflag) is increased, and if it exceeds 2, go to "result". rem Otherwise, first and end character is used from input string rem ------------------------------ if "%position%"=="pass" ( set /a turnchangeflag=turnchangeflag+1 if %turnchangeflag% gtr 0 ( goto :result ) else if %player%==A ( set player=B goto :trial ) else if %player%==B ( set player=A goto :trial ) ) else ( set line=%position:~0,1% set row=%position:~-1% ) rem ------------------------------ rem Check if stone is placed within the field or if stone is already placed on the position. rem ------------------------------ if %line% gtr 8 ( goto :trial ) if %row% gtr 8 ( goto :trial ) if %line% lss 1 ( goto :trial ) if %row% lss 1 ( goto :trial ) if not !array[%line%][%row%]!==_ ( goto :trial ) rem ------------------------------ rem ==============================Reverse Logic============================== :check set startline=%line% set startrow=%row% set opponentstonenum=0 :checkline rem Check direction depends on checkcnt number (i.e. 1 means up, 2 means upper right …) rem ------------------------------ if %checkcnt%==1 ( set /a startline=startline-1 ) else if %checkcnt%==2 ( set /a startline=startline-1 set /a startrow=startrow+1 ) else if %checkcnt%==3 ( set /a startrow=startrow+1 ) else if %checkcnt%==4 ( set /a startline=startline+1 set /a startrow=startrow+1 ) else if %checkcnt%==5 ( set /a startline=startline+1 ) else if %checkcnt%==6 ( set /a startline=startline+1 set /a startrow=startrow-1 ) else if %checkcnt%==7 ( set /a startrow=startrow-1 ) else if %checkcnt%==8 ( set /a startline=startline-1 set /a startrow=startrow-1 ) else ( rem ------------------------------ rem If there is reversible stone, flag (turnchangeflag) will be 1 and the following code is executed. rem ------------------------------ if %turnchangeflag%==1 ( set /a trialnum=trialnum+1 echo Trialnum:%trialnum%, Player:%player%, %position% for /l %%n in (1,1,8) do ( echo !array[%%n][1]!!array[%%n][2]!!array[%%n][3]!!array[%%n][4]!!array[%%n][5]!!array[%%n][6]!!array[%%n][7]!!array[%%n][8]! ) if "%1"=="" ( rem No save ) else ( echo Trialnum:%trialnum%, Player:%player%, %position% >> "%1.txt" for /l %%n in (1,1,8) do ( echo !array[%%n][1]!!array[%%n][2]!!array[%%n][3]!!array[%%n][4]!!array[%%n][5]!!array[%%n][6]!!array[%%n][7]!!array[%%n][8]! >> "%1.txt" ) ) if %player%==A ( set player=B ) else if %player%==B ( set player=A ) rem ------------------------------ ) goto :trial ) rem If position to be checked is space (_), go to next direction. rem If counterpart stone, check one further position with flag(opponentstonenum) up. rem If own stone with flag(opponentstonenum) of 1 or more, reverse stones. rem If there is one reversible stone, change player (increase flag(turnchangeflag)) rem ------------------------------ if %player%==A ( if !array[%startline%][%startrow%]!==_ ( set /a checkcnt=checkcnt+1 goto :check ) else if !array[%startline%][%startrow%]!==● ( set /a opponentstonenum=opponentstonenum+1 goto :checkline ) else if !array[%startline%][%startrow%]!==〇 ( if %opponentstonenum% geq 1 ( if %checkcnt%==1 ( for /l %%n in (%startline%,1,%line%) do ( set array[%%n][%startrow%]=〇 ) ) else if %checkcnt%==2 ( for /l %%n in (%startline%,1,%line%) do ( set array[%%n][!startrow!]=〇 set /a startrow=startrow-1 ) ) else if %checkcnt%==3 ( for /l %%n in (%row%,1,%startrow%) do ( set array[%startline%][%%n]=〇 ) ) else if %checkcnt%==4 ( for /l %%n in (%startline%,-1,%line%) do ( set array[%%n][!startrow!]=〇 set /a startrow=startrow-1 ) ) else if %checkcnt%==5 ( for /l %%n in (%line%,1,%startline%) do ( set array[%%n][%startrow%]=〇 ) ) else if %checkcnt%==6 ( for /l %%n in (%startline%,-1,%line%) do ( set array[%%n][!startrow!]=〇 set /a startrow=startrow+1 ) ) else if %checkcnt%==7 ( for /l %%n in (%startrow%,1,%row%) do ( set array[%startline%][%%n]=〇 ) ) else if %checkcnt%==8 ( for /l %%n in (%startline%,1,%line%) do ( set array[%%n][!startrow!]=〇 set /a startrow=startrow+1 ) ) set turnchangeflag=1 ) set /a checkcnt=checkcnt+1 goto :check ) rem ------------------------------ ) rem Basically same as Player A rem Flag(playerBtrial) to check a position in which stone can be placed is reset. rem ------------------------------ if %player%==B ( if !array[%startline%][%startrow%]!==_ ( set /a checkcnt=checkcnt+1 goto :check ) else if !array[%startline%][%startrow%]!==〇 ( set /a opponentstonenum=opponentstonenum+1 goto :checkline ) else if !array[%startline%][%startrow%]!==● ( if %opponentstonenum% geq 1 ( if %checkcnt%==1 ( for /l %%n in (%startline%,1,%line%) do ( set array[%%n][%startrow%]=● ) ) else if %checkcnt%==2 ( for /l %%n in (%startline%,1,%line%) do ( set array[%%n][!startrow!]=● set /a startrow=startrow-1 ) ) else if %checkcnt%==3 ( for /l %%n in (%row%,1,%startrow%) do ( set array[%startline%][%%n]=● ) ) else if %checkcnt%==4 ( for /l %%n in (%startline%,-1,%line%) do ( set array[%%n][!startrow!]=● set /a startrow=startrow-1 ) ) else if %checkcnt%==5 ( for /l %%n in (%line%,1,%startline%) do ( set array[%%n][%startrow%]=● ) ) else if %checkcnt%==6 ( for /l %%n in (%startline%,-1,%line%) do ( set array[%%n][!startrow!]=● set /a startrow=startrow+1 ) ) else if %checkcnt%==7 ( for /l %%n in (%startrow%,1,%row%) do ( set array[%startline%][%%n]=● ) ) else if %checkcnt%==8 ( for /l %%n in (%startline%,1,%line%) do ( set array[%%n][!startrow!]=● set /a startrow=startrow+1 ) ) set turnchangeflag=1 set playerBtrial=0 ) set /a checkcnt=checkcnt+1 goto :check ) ) rem ------------------------------ rem ==============================Reverse Logic============================== rem ==============================Playing Othello============================== rem ==============================Display Result============================== :result rem Calcuate numbers of white and black stones. rem ------------------------------ set whitecnt=0 set blackcnt=0 for /l %%n in (1,1,8) do ( for /l %%m in (1,1,8) do ( if !array[%%n][%%m]!==〇 ( set /a whitecnt=whitecnt+1 ) else if !array[%%n][%%m]!==● ( set /a blackcnt=blackcnt+1 ) ) ) rem ------------------------------ rem Display in command line and save them if necessary. rem ------------------------------ if %whitecnt% gtr %blackcnt% ( echo Player A win (A:%whitecnt%, B:%blackcnt%^) ) else if %whitecnt% equ %blackcnt% ( echo Draw (A:%whitecnt%, B:%blackcnt%^) ) else if %whitecnt% lss %blackcnt% ( echo Player B win (A:%whitecnt%, B:%blackcnt%^) ) if "%1"=="" ( rem No save ) else ( if %whitecnt% gtr %blackcnt% ( echo Player A win (A:%whitecnt%, B:%blackcnt%^) >> "%1.txt" ) else if %whitecnt% equ %blackcnt% ( echo Draw (A:%whitecnt%, B:%blackcnt%^) >> "%1.txt" ) else if %whitecnt% lss %blackcnt% ( echo Player B win (A:%whitecnt%, B:%blackcnt%^) >> "%1.txt" ) ) rem ------------------------------ rem ==============================Display Result==============================
バッチファイルでは、if文やfor文中の変数の更新が、遅延環境変数といった宣言をしないとうまく反映されないので、かなり使い勝手が悪い。普通はバッチファイルを使って複雑なプログラムをしないと思うけど、もともとMicrosoft windowsについている身近なものなので試してみた。
コマンドプロンプトではpingやipconfigなどネットワーク関連のものもあるので、パソコンのネットワークの状況を把握するコードなど、もう少しパソコン自体に関連することの方が向いているのかな。今後はそっちを試してみようか...。