打ち手候補判定機能実装

仕上がり図

前回の記事の元に、石を置ける位置を判定する機能を実装しました。
機能は、以局面(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

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA