Powershell(オセロ005_オブジェクト指向で作成_各クラスの引数、戻し値など)
■前回の設計をもとにオブジェクト指向で試作した。
オブジェクト指向の考え方で、前回、クラス、データ、機能について考えた。今回、実際に作る中で重複している内容やわざわざ機能として作る必要がなさそうなものなど、適宜修正して試作品を作ってみた。
まず、ボード(Board)については下のようなデータ、機能とした。
class Board {
$boardData
Board() {...}
[String]showBoard($boardData) {...}
[String]sumResult($boardData, $result)
{...}
}
8×8の盤上のデータ(boardData)
→ 8行目、8列目の部分の判定などのため、9行目、9列目などが必要となるので、10×10の2次元配列として準備。
→ Board()の部分(コンストラクタ)でクラスのインスタンスを作成する際に初期化。
表示機能(showBoard)
→ 盤上のデータを引数として入力し、文字列(String)として戻す。行区切りに改行コードを適宜はさんだ1つの文字列とする。文字列を戻した後、本文のコードで表示や保存を行う。
保存機能(saveBoard)
→ 保存自体は、対象の後ろにパイプライン(|)とOut-file $textfile -Appendを付け加えれば簡単に実現できるので機能として切り出すのは省略。
結果集計の機能(sumResult)
→ 結果の集計は、最終的な盤上のデータの形から分かるので、盤上のデータを引数として入力、また、白が勝ったとか引き分けの結果($result)を更新したいので、それも引数として入れる。集計処理をした後、結果を含んだ文字列として戻す。
次に、プレイヤー(Player)は下の通り。
class Player {
$playerColor
$logic
Player($color, $logicNum) {...}
[String]thinkPlace($boardData) {...}
[String]placeStone($boardData) {...}
[String[][]]reverseStones($position, $boardData) {...}
}
石を置く場所を考える機能(thinkPlace)
→ 場所を決めるのに盤上のデータが必要なので、引数として入力、置く場所(3行目、3列目なら"33")を戻す。
石を置く機能(placeStone)
→ 場所を決めるのに盤上のデータが必要なので、引数として入力、置く場所を戻す。
→ 自動で石を置く場合は、上の「石を置く場所を考える機能」が必要だろうけど、人が入力する場合には、考える機能はいらない。代わりに、誤った入力をはじくような機能が必要になる。今は、「石を置く場所を考える機能」を自動で石を置く場合、「石を置く機能」を人が入力する場合としてコードを組んだけど、これらは一つにできるかもしれない。
石を裏返すロジックの機能(reverseStones)
→ バッチファイルベースで使用した石を裏返すロジックをそのまま使った。置く石の場所と盤上のデータを入れて、裏返した後の盤上のデータを戻す。
ここに加えて、石の色($playerColor)と今後の拡張のための石を置くにあたって採用するロジック($logic)をプレイヤークラスのデータとして追加した。Player($color, $logicNum)で初期化を行う。
最後に、上のBoard, Playerクラスの中で使用するため、盤上のデータが同じであるか判定する機能(compareBoard)と盤上のデータをコピーする機能(copyBoard)を切り出して、Utilityクラスとした。
Class Utility
{
static [Boolean]compareBoard($tempBoard, $boardData) {...}
static [String[][]]copyBoard($boardData) {...}
}
これらの機能はstatic(静的)なものとした。下で、本文のコード部分をのせるけど、本来クラスの機能を使用するには、クラスの宣言を行い実体となるものを作る必要がある。staticなものは、それを行う必要がないので、使い勝手がよい(ただ、逆にどこで使われているか、コードを見ただけでは分かりづらくなるけど)。
これらのクラスは下の方に記載してもいいようで、本文のコードをファイルの頭に持ってきた(下図)。$othboard = [Board]::new()などの部分で、Board、Playerのクラスを宣言し、それらの機能を使用できるようにしている。
動くところまで確認できたけど、石を置く機能の部分の修正やコメント追加をもう少し行うつもり。
$textfile="text.txt"
$result = @(0,0,0)
for ($i=1; $i -le 5000 ; $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
while($true) {
if ($turn -eq $playerA) {
#$position = $playerA.placeStone($othboard.boardData)
$position = $playerA.thinkPlace($othboard.boardData)
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.thinkPlace($othboard.boardData)
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])
class Board {
... (データ、機能は上の通り)
}
class Player {
... (データ、機能は上の通り)
}
class Utility
{
... (データ、機能は上の通り)
}