-
Notifications
You must be signed in to change notification settings - Fork 0
/
HalfGoGame.py
119 lines (103 loc) · 3.51 KB
/
HalfGoGame.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import numpy as np
from HalfGoLogic import Board, EMPTY, BANNED, WHITE, BLACK, CORNER
class HalfGoGame():
def __init__(self, n):
self.n = n
def getInitBoard(self):
# return initial board (numpy board)
b = Board(self.n)
return np.array(b.pieces)
def getBoardSize(self):
# (a,b) tuple
return (self.n, self.n)
def getActionSize(self):
"""
use in:
for action in range(getActionsize)
return:
total number of valid action
Note:
somehow there is self.n*self.n + 1 in all Othello and Gobang
Implementation, why?
Answer:
64 notes in the final layer of CNN,
need to +1 for the bias
this is why return self.n*self.n + 1
"""
return self.n*self.n + 1
def getNextState(self, board, player, action, turn = 0):
# if player takes action on board, return next (board,player)
# action must be a valid move
# 2 = (2,0)
# currently action = an Integer
if action == self.n*self.n:
return (board, -player)
b = Board(self.n)
b.pieces = np.copy(board)
#even in string representation, we concat column by column
#picese are grouped by column
move = (action%self.n, action//self.n,) #(column, row) (int(a/b))
b.execute_move(move, player)
return (b.pieces, -player)
def getValidMoves(self, board, player):
# return a fixed size binary vector
# moves, on the same ROWWWWWWWWWWW are grouped together
valids = [0]*self.getActionSize()
b = Board(self.n)
b.pieces = np.copy(board)
legalMoves = b.get_legal_moves(player) #in the form (column, row)
if len(legalMoves)==0:
valids[-1]=1
return np.array(valids)
for x, y in legalMoves:
valids[self.n*y+x]=1 #since all rows are grouped together
return np.array(valids)
def getGameEnded(self, board, player, turn):
"""
Input:
board: cannoical board
player: int, 1 = white, -1 = black
turn: [0.......23] = 24 turns in total = for i in range(0,24)
return:
0 nothing
1 player Won
-1 player Lost
"""
b = Board(self.n)
b.pieces = np.copy(board)
if turn < 24: #4: for adding turn parameter
return 0
else:
if b.countDiff(player) > 0:
return 1
elif b.countDiff == 0:
return 1e-4 #tie condiitiion
return -1
def getCanonicalForm(self, board, player):
"""
Input:
Board,
player: the perspective
return:
current situation of the board in the player's point of view
1 = friendly army
-1 = enemy
Yes! this is correct understanding
"""
# return player*board
board = np.array(board).reshape(8,8)
result = player*board
result[result == -3] = CORNER
if player == BLACK:
result = np.rot90(result, k = 2)
return result#.flatten()
def stringRepresentation(self, board):
# 8x8 numpy array (canonical board)
return board.tostring()
def actionGameToReferee(self, action):
x = action % 8
y = action // 8
return (int(x),int(y))
def actionRefereeToGame(self, action):
x,y = action
return y*8+x