Python(オセロ14_数手先を評価するロジック)
■数手先の盤上などの情報を得る。
以前3手先の勝ち筋を評価するロジックを試した。そのときはPowershellで作ったけど、3手先を拡張してx手先の評価ができるようにした。
コードは下のような感じ。
まず、現在の盤上と残りの手のリストを入れて、置くことができる場所を評価して、置くことができるならその場所とそこに置いたときの次の盤の状態を返す。
def nextBoardList(board, tempBlankList, currentturn):
nextBoardList = []
correspondPosList = []
tempboard = board.copy()
tempList_tobeChanged = []
changeStNum_List = []
for stone_pos_temp in tempBlankList:
stList_tobeChanged_temp = checkReversible(board, stone_pos_temp, currentturn)
if len(stList_tobeChanged_temp) >= 1:
tempList_tobeChanged.append(stone_pos_temp)
tempboard[stone_pos_temp[0], stone_pos_temp[1]] = currentturn
for pos in stList_tobeChanged_temp:
tempboard[pos[0], pos[1]] = currentturn
nextBoardList.append(tempboard)
correspondPosList.append(stone_pos_temp)
tempboard = board.copy()
return (correspondPosList, nextBoardList)
これを使って、得られた次の盤上と使った手を除いた残りの手のリストで再帰的に次の盤上を求めていく。次の手と盤の状態をツリー状に入れていく。
def searchTree(self, board, tempBlankList, turn, depth):
if depth == 0:
return []
moveList, boardList = s78_cm.nextBoardList(board, tempBlankList, turn)
tree = []
nextTurn = (
"●" if turn == "○"
else "○"
)
for i in range(len(moveList)):
move = moveList[i]
next_board = boardList[i]
nextBlankList = tempBlankList.copy()
nextBlankList.remove(move)
children = self.searchTree(next_board, nextBlankList, nextTurn, depth - 1)
tree.append((move, next_board, children))
return tree
正しく動いているかデバッグで検証。まず、初回の配置から1手目では4つの置ける場所がある。

変数の中身を見ると、置ける場所として[3, 4], [4, 3], [5, 6], [6, 5] とあるので正しくチェックできているよう。

次に上記の4つの手から、それぞれに3手ずつある。相手の手番となる。

[3, 4]に置いた場合は、その次の手として[3, 3], [3, 5], [5, 3]が挙げられている。これも上の位置と合っているよう。2手先を読む状態で、4 + 12 = 16 の盤上を持つことになる。

このように3手先、4手先と増やしていくと次のように変数に持つ盤上は増えていく。
3手:72
4手:316
5手:1712
6手:9912
7手:65004
8手:455220
8手先では、得られるまでに2、3分かかるけど、序盤の手が限られている中でこれだけかかるなら、ゲーム中盤など選択肢が増えた中では1手を求めるのに数十分かかりそう。現実的に使えるのは5手先、7手先ぐらいまでのような気がする。
何手か先の盤上を考慮して次の1手を決めることができれば、現在の盤上の情報だけとはまた違った考えのロジックが組めそう。情報量が多くなり時間もかかるだろうから、それに見合ったものになるかはおいといて。

