仕上がり図
前回の記事の元に、石を置ける位置を判定する機能を実装しました。
機能は、以局面(8×8配列)と手番(先手:後手)を引き数に渡すことにより、石を置ける位置を探索するというものです。ここでは例として以下のような局面と、手番:黒石を与えます。
a b c d e f g h --------------------------------- 1 | | | | | | | | | --------------------------------- 2 | | | | | | | | | --------------------------------- 3 | | | | | | | | | --------------------------------- 4 | | | | ● | ○ | | | | --------------------------------- 5 | | | | ○ | ● | | | | --------------------------------- 6 | | | | | | | | | --------------------------------- 7 | | | | | | | | | --------------------------------- 8 | | | | | | | | | ---------------------------------
結果は以下のようになりました。。記号の意味は、「■」が石を置ける場所、「-」がひっくり返されうる石を示します。予定通り、石を置ける候補が4か所正しく示されています。
a b c d e f g h --------------------------------- 1 | | | | | | | | | --------------------------------- 2 | | | | | | | | | --------------------------------- 3 | | | | | ■ | | | | --------------------------------- 4 | | | | ● | - | ■ | | | --------------------------------- 5 | | | ■ | - | ● | | | | --------------------------------- 6 | | | | ■ | | | | | --------------------------------- 7 | | | | | | | | | --------------------------------- 8 | | | | | | | | | ---------------------------------
関数詳細
ソースコードも載せておきます。関数「search_newstone_positions_all」がその関数で、returnとして、上記のような局面図(diagram_possibility_all)と、置ける位置ごとの置いた場合の局面図のリスト(diagram_possibilities)を返します。
#石を置ける位置を探索 #diagramが局面、turnが手番 def search_newstone_position_all(diagram, turn): diagram_possibility_all = diagram.copy() diagram_possibilities = [] possibilities = 0 #opturnは相手の手番を示す。 if turn == 1: opturn = 2 else: opturn = 1 #各行・列の座標について順に確認ついて for column in range(0,8): for row in range(0,8): #全方位を探索し、石を置けるかどうかの判定結果(possible)と石を置いた時の局面(new_diagram)を取得。(後述) possible, new_diagram = search_all_directions(diagram, row, column, turn, opturn) if possible == True: #局面をリストに追加 diagram_possibilities.append(new_diagram) possibilities += 1 #石を置ける場所とひっくり返されうる場所の値を3以上にしておくことで、maximum処理で上記局面図が得られる。 diagram_possibility_all = np.maximum(new_diagram, diagram_possibility_all) return diagram_possibility_all, diagram_possibilities
「search_all_directions」のソースコードです。こちらはコードだらだらしてがかっこ悪いので、今後修正するかもしれません。各座標について8方位(左上、上、右上、左、右、左下、下、右下)を探索し、石が置けるかどうかを判定、置ける場合は置いた場合の局面を取得します。
#石を置ける位置を全方位探索 def search_all_directions(diagram, row, column, turn, opturn): directions = np.zeros(8) new_diagram = diagram.copy() new_diagram_temp = diagram.copy() possible = False if diagram[row,column] != 0: return possible, new_diagram else: #左上 if(column > 1 and row > 1): if(diagram[row-1, column-1] == opturn): directions[0] = 1 new_diagram_temp[row-1,column-1] = turn + 2 for i in range(2,9): if(row-i>=0 and column-i>=0): if(diagram[row-i,column-i]==0): new_diagram_temp = new_diagram.copy() break elif(diagram[row-i,column-i]==opturn): new_diagram_temp[row-i,column-i] = turn + 2 else: new_diagram = new_diagram_temp.copy() new_diagram[row,column] = turn + 4 new_diagram_temp = new_diagram.copy() directions[0] = 2 possible = True break else: new_diagram_temp = new_diagram.copy() break #上 if(row > 1): if(diagram[row-1, column] == opturn): directions[1] = 1 new_diagram_temp[row-1,column] = turn + 2 for i in range(2,9): if(row-i>=0): if(diagram[row-i,column]==0): new_diagram_temp = new_diagram.copy() break elif(diagram[row-i,column]==opturn): new_diagram_temp[row-i,column] = turn + 2 else: new_diagram = new_diagram_temp.copy() new_diagram[row,column] = turn + 4 new_diagram_temp = new_diagram.copy() directions[1] = 2 possible = True break else: new_diagram_temp = new_diagram.copy() break #右上 if(column < 6 and row > 1): if(diagram[row-1, column+1] == opturn): directions[2] = 1 new_diagram_temp[row-1,column+1] = turn + 2 for i in range(2,9): if(row-i>=0 and column+i<=7): if(diagram[row-i,column+i]==0): new_diagram_temp = new_diagram.copy() break elif(diagram[row-i,column+i]==opturn): new_diagram_temp[row-i,column+i] = turn + 2 else: new_diagram = new_diagram_temp.copy() new_diagram[row,column] = turn + 4 new_diagram_temp = new_diagram.copy() directions[2] = 2 possible = True break else: new_diagram_temp = new_diagram.copy() break #左 if(column > 1): if(diagram[row, column-1] == opturn): directions[3] = 1 new_diagram_temp[row,column-1] = turn + 2 for i in range(2,9): if(column-i>=0): if(diagram[row,column-i]==0): new_diagram_temp = new_diagram.copy() break elif(diagram[row,column-i]==opturn): new_diagram_temp[row,column-i] = turn + 2 else: new_diagram = new_diagram_temp.copy() new_diagram[row,column] = turn + 4 new_diagram_temp = new_diagram.copy() directions[3] = 2 possible = True break else: new_diagram_temp = new_diagram.copy() break #右 if(column < 6): if(diagram[row, column+1] == opturn): directions[4] = 1 new_diagram_temp[row,column+1] = turn + 2 for i in range(2,9): if(column+i<=7): if(diagram[row,column+i]==0): new_diagram_temp = new_diagram.copy() break elif(diagram[row,column+i]==opturn): new_diagram_temp[row,column+i] = turn + 2 else: new_diagram = new_diagram_temp.copy() new_diagram[row,column] = turn + 4 new_diagram_temp = new_diagram.copy() directions[4] = 2 possible = True break else: new_diagram_temp = new_diagram.copy() break #左下 if(column > 1 and row < 6): if(diagram[row+1, column-1] == opturn): directions[5] = 1 new_diagram_temp[row+1,column-1] = turn + 2 for i in range(2,9): if(row+i<=7 and column-i>=0): if(diagram[row+i,column-i]==0): new_diagram_temp = new_diagram.copy() break elif(diagram[row+i,column-i]==opturn): new_diagram_temp[row+i,column-i] = turn + 2 else: new_diagram = new_diagram_temp.copy() new_diagram[row,column] = turn + 4 new_diagram_temp = new_diagram.copy() directions[5] = 2 possible = True break else: new_diagram_temp = new_diagram.copy() break #下 if(row < 6): if(diagram[row+1, column] == opturn): directions[6] = 1 new_diagram_temp[row+1,column] = turn + 2 for i in range(2,9): if(row+i<=7): if(diagram[row+i,column]==0): new_diagram_temp = new_diagram.copy() break elif(diagram[row+i,column]==opturn): new_diagram_temp[row+i,column] = turn + 2 else: new_diagram = new_diagram_temp.copy() new_diagram[row,column] = turn + 4 new_diagram_temp = new_diagram.copy() directions[6] = 2 possible = True break else: new_diagram_temp = new_diagram.copy() break #右下 if(column < 6 and row < 6): if(diagram[row+1, column+1] == opturn): directions[7] = 1 new_diagram_temp[row+1,column+1] = turn + 2 for i in range(2,9): if(row+i<=7 and column+i<=7): if(diagram[row+i,column+i]==0): new_diagram_temp = new_diagram.copy() break elif(diagram[row+i,column+i]==opturn): new_diagram_temp[row+i,column+i] = turn + 2 else: new_diagram = new_diagram_temp.copy() new_diagram[row,column] = turn + 4 new_diagram_temp = new_diagram.copy() directions[5] = 2 possible = True break else: new_diagram_temp = new_diagram.copy() break if possible == True: pass #print(columnArray[column],rowArray[row],directions) #print(diagram) #print(new_diagram) return possible, new_diagram