# ========================================================================= # [Board]クラス: オセロの盤(10×10マス (黒("●")、白("〇")、空欄("_")のどれか。)、表示の機能、結果集計機能 # [Player]クラス: プレイヤー(白か黒、ロジックを持つ)、石を置く機能、裏返す機能 # $turn: 順番(player AかB) # $endflag: ゲーム終了を判断するフラグ(passが両プレイヤーから連続した場合に終了) # $trialnum: 現在、何手目かのカウント(無効となる場所に石を置いたときはカウントされない) # ========================================================================= # ========================================================================= # 結果表示用 $result(黒、白、引き分けの数) # 手順の記録の保存 text.txt # ========================================================================= $TEXTFILE="text.txt" $GAME_NUM = 20 $result = @(0,0,0) # 複数回ゲームを行う for ($i=1; $i -le $GAME_NUM ; $i++) { $othboard = [Board]::new() $playerA = [Player]::new("〇", 0) $playerB = [Player]::new("●", 0) $turn = $playerA $endflag = 0 $trialnum = 0 echo ("Game:"+$i+"| Start Othello") | Out-file $TEXTFILE -Append $othboard.showBoard($othboard.boardData) | Out-file $TEXTFILE -Append # 1ゲームの中、石を置く処理を繰り返す。 while($true) { if ($turn -eq $playerA) { $position = $playerA.placeStone($othboard.boardData,$playerA.logic) if ($position -eq "pass") { $endflag += $endflag + 1 $turn = $playerB } else { $othboard.boardData = $playerA.reverseStones($position, $othboard.boardData) $trialnum++ $turn = $playerB } } elseif ($turn -eq $playerB) { #$position = $playerB.placeStone($othboard.boardData) $position = $playerB.placeStone($othboard.boardData,$playerB.logic) if ($position -eq "pass") { $endflag += $endflag + 1 $turn = $playerA } else { $othboard.boardData = $playerB.reverseStones($position, $othboard.boardData) $trialnum++ $turn = $playerA } } echo ("=====Trial:"+$trialnum+"=====") | Out-file $TEXTFILE -Append [String]$str = $othboard.showBoard($othboard.boardData) echo ($str) | Out-file $TEXTFILE -Append if ($endflag -ge 2) { break } elseif ($trialnum -ge 60) { break } } [String]$str = $othboard.sumResult($othboard.boardData, $result) echo ($str + "Game:"+$i+"| End Othello") echo ($str + "Game:"+$i+"| End Othello") | Out-file $TEXTFILE -Append } echo ("●"+$result[0]+"vs〇"+$result[1]+"vsE"+$result[2]) ############################################################## ## [Board]クラス: # コンストラクタ # 表示の機能:[String]showBoard($boardData) # 結果集計機能:[String]sumResult($boardData, $result) ############################################################## class Board { $boardData #コンストラクタ、盤上のデータを初期化 Board() { $this.boardData=@( @('_','_','_','_','_','_','_','_','_','_'), @('_','_','_','_','_','_','_','_','_','_'), @('_','_','_','_','_','_','_','_','_','_'), @('_','_','_','_','_','_','_','_','_','_'), @('_','_','_','_','〇','●','_','_','_','_'), @('_','_','_','_','●','〇','_','_','_','_'), @('_','_','_','_','_','_','_','_','_','_'), @('_','_','_','_','_','_','_','_','_','_'), @('_','_','_','_','_','_','_','_','_','_'), @('_','_','_','_','_','_','_','_','_','_') ) } #盤上のデータ表示(引数:盤上のデータ、戻し値:現在の盤上を示した文字列) [String]showBoard($boardData) { [String]$boardStr="" for ($n=1; $n -lt 8; $n++) { $boardStr+=$boardData[$n][1]+$boardData[$n][2]+$boardData[$n][3]+$boardData[$n][4]+$boardData[$n][5]+$boardData[$n][6]+$boardData[$n][7]+$boardData[$n][8]+"`r`n" } $boardStr+=$boardData[$n][1]+$boardData[$n][2]+$boardData[$n][3]+$boardData[$n][4]+$boardData[$n][5]+$boardData[$n][6]+$boardData[$n][7]+$boardData[$n][8] return $boardStr } #結果集計、白の石と黒の石のカウントとresultの勝敗を1つ増やす(引数:盤上のデータ、戻し値:結果として表示する文字列) [String]sumResult($boardData, $result) { $whitecnt = 0 $blackcnt = 0 for ($n=1; $n -le 8; $n++) { for ($m=1; $m -le 8; $m++) { if ($boardData[$n][$m] -eq "●") { $blackcnt++ } elseif ($boardData[$n][$m] -eq "〇") { $whitecnt++ } } } if ($blackcnt -gt $whitecnt) { $result[0]++ } elseif ($blackcnt -lt $whitecnt) { $result[1]++ } elseif ($blackcnt -eq $whitecnt) { $result[2]++ } return ("●"+$blackcnt+"vs〇"+$whitecnt) } } ############################################################## ## [Player]クラス: # コンストラクタ # 石を置く機能:[String]placeStone($boardData, $logic_num)(手動入力の場合、[String]placeStone($boardData)) # 裏返す機能:[String[][]]reverseStones($position, $boardData) ############################################################## class Player { $playerColor $logic #コンストラクタ、プレイヤーデータを初期化 Player($color, $logicNum) { $this.playerColor = $color $this.logic = $logicNum } #石を置く処理(引数:盤上のデータ、ロジックの番号、戻し値:石を置く場所の文字列(11~88)) [String]placeStone($boardData, $logic_num) { $logic_num = $this.logic $position ="00" $blankArray=@() $inputArray=@() for ($n=1; $n -le 8; $n++) { for ($m=1; $m -le 8; $m++) { if ($boardData[$n][$m] -eq '_') { $blankArray+= [string]$n + [string]$m }else{ } } } if ($blankArray.count -eq 0) { $position = "pass" } else{ if ($blankArray.count -eq 1) { $inputArray = $blankArray } else { if ($logic_num -eq 0) { $inputArray = get-random -input $blankArray -count ([int]::MaxValue) }elseif ($logic_num -eq 1){ }elseif ($logic_num -eq 2){ }elseif ($logic_num -eq 3){ }else{ } } foreach ($position in $inputArray) { $tempBoard = [Utility]::copyBoard($boardData) $tempClass = [Player]::new($this.playercolor, $this.logic) $tempClass.reverseStones($position, $tempBoard) $canBeReversed = [Utility]::compareBoard($tempBoard, $boardData) if($canBeReversed) { $position = "pass" } else { break } } } return $position } #石を置く処理(引数:盤上のデータ、戻し値:石を置く場所の文字列(11~88)) [String]placeStone($boardData) { $position='00' while ($true) { $position = Read-Host ("Player ("+$this.playerColor+")") if($position -eq "pass") { break } elseif($position.length -le 1) { } else { $line=$position.substring(0,1) $row=$position.substring(1,1) if (($line -ge 1) -And ($line -le 8) -And ($row -ge 1) -And ($row -le 8)) { if ($boardData[$line][$row] -eq "_") { $tempBoard = [Utility]::copyBoard($boardData) $tempClass = [Player]::new($this.playercolor, $this.logic) $tempClass.reverseStones($position, $tempBoard) $canBeReversed = [Utility]::compareBoard($tempBoard, $boardData) if($canBeReversed) { } else { break } } } } } return $position } #石を裏返す処理(引数:石を置く場所、盤上のデータ、戻し値:裏返した後の盤上のデータ) [String[][]]reverseStones($position, $boardData) { if ($position -eq "pass") { return $boardData } for ($checkcnt=0; $checkcnt -lt 8; $checkcnt++) { $line=$position.substring(0,1) $row=$position.substring(1,1) [Int]$startline=$line [Int]$startrow=$row [Int]$opponentstonenum=0 for ($extension=0; $extension -lt 8; $extension++) { if ($checkcnt -eq 0) { $startline=$startline-1 } elseif ($checkcnt -eq 1) { $startline=$startline-1 $startrow=$startrow+1 } elseif ($checkcnt -eq 2) { $startrow=$startrow+1 } elseif ($checkcnt -eq 3) { $startline=$startline+1 $startrow=$startrow+1 } elseif ($checkcnt -eq 4) { $startline=$startline+1 } elseif ($checkcnt -eq 5) { $startline=$startline+1 $startrow=$startrow-1 } elseif ($checkcnt -eq 6) { $startrow=$startrow-1 } elseif ($checkcnt -eq 7) { $startline=$startline-1 $startrow=$startrow-1 } else { } if ($boardData[$startline][$startrow] -eq "_") { break } elseif ($boardData[$startline][$startrow] -ne $this.playerColor) { $opponentstonenum=$opponentstonenum+1 } elseif ($boardData[$startline][$startrow] -eq $this.playerColor) { if ($opponentstonenum -ge 1) { if ($checkcnt -eq 0) { for ($startline;$startline -le $line;$startline++) { $boardData[$startline][$startrow]=$this.playerColor } break } elseif ($checkcnt -eq 1) { for ($startline;$startline -le $line;$startline++) { $boardData[$startline][$startrow]=$this.playerColor $startrow=$startrow-1 } break } elseif ($checkcnt -eq 2) { for ($startrow;$startrow -ge $row;$startrow--) { $boardData[$startline][$startrow]=$this.playerColor } break } elseif ($checkcnt -eq 3) { for ($startrow;$startrow -ge $row;$startrow--) { $boardData[$startline][$startrow]=$this.playerColor $startline=$startline-1 } break } elseif ($checkcnt -eq 4) { for ($startline;$startline -ge $line;$startline--) { $boardData[$startline][$startrow]=$this.playerColor } break } elseif ($checkcnt -eq 5) { for ($startline;$startline -ge $line;$startline--) { $boardData[$startline][$startrow]=$this.playerColor $startrow=$startrow+1 } break } elseif ($checkcnt -eq 6) { for ($startrow;$startrow -le $row;$startrow++) { $boardData[$startline][$startrow]=$this.playerColor } break } elseif ($checkcnt -eq 7) { for ($startrow;$startrow -le $row;$startrow++) { $boardData[$startline][$startrow]=$this.playerColor $startline=$startline+1 } break } } else { break } } } } return $boardData } } ############################################################## ## [Utility]クラス: # 盤上のデータを比較する機能:[Boolean]compareBoard($tempBoard, $boardData) # 盤上のデータをコピーする機能:[String[][]]copyBoard($boardData) ############################################################## Class Utility { #盤上のデータを比較する機能(引数:盤上データ、盤上のデータ、戻し値:一致するかどうか($true, $false)) static [Boolean]compareBoard($tempBoard, $boardData) { for ($n=1; $n -le 8; $n++) { for ($m=1; $m -le 8; $m++) { if ($boardData[$n][$m] -eq $tempBoard[$n][$m]) { }else{ return $false } } } return $true } #盤上のデータをコピーする機能(引数:盤上のデータ、戻し値:コピーした盤上のデータ(配列は参照型なので、別の2次元配列を準備して戻す)) static [String[][]]copyBoard($boardData) { $tempBoard=@( @('_','_','_','_','_','_','_','_','_','_'), @('_','_','_','_','_','_','_','_','_','_'), @('_','_','_','_','_','_','_','_','_','_'), @('_','_','_','_','_','_','_','_','_','_'), @('_','_','_','_','_','_','_','_','_','_'), @('_','_','_','_','_','_','_','_','_','_'), @('_','_','_','_','_','_','_','_','_','_'), @('_','_','_','_','_','_','_','_','_','_'), @('_','_','_','_','_','_','_','_','_','_'), @('_','_','_','_','_','_','_','_','_','_') ) for ($n=1; $n -le 8; $n++) { for ($m=1; $m -le 8; $m++) { $tempBoard[$n][$m] = $boardData[$n][$m] } } return $tempBoard } }