random
This commit is contained in:
parent
6b69bbc116
commit
b657036355
@ -17,15 +17,19 @@ def _alphabeta(
|
|||||||
alpha=-math.inf,
|
alpha=-math.inf,
|
||||||
beta=math.inf,
|
beta=math.inf,
|
||||||
depth: int = 3,
|
depth: int = 3,
|
||||||
|
shouldStop = lambda: False
|
||||||
) -> tuple[float, Any]:
|
) -> tuple[float, Any]:
|
||||||
|
|
||||||
wantMax = (board.next_player != color)
|
wantMax = (board.next_player == color)
|
||||||
if depth == 0 or board.is_game_over():
|
if depth == 0 or board.is_game_over():
|
||||||
return heuristic(board, color), move
|
return heuristic(board, color), move
|
||||||
|
|
||||||
if wantMax:
|
if wantMax:
|
||||||
acc = -math.inf, None
|
acc = -math.inf, None
|
||||||
for move in board.generate_legal_moves():
|
for move in board.generate_legal_moves():
|
||||||
|
if Goban.Board.flat_to_name(move) == "PASS":
|
||||||
|
continue
|
||||||
|
|
||||||
board.push(move)
|
board.push(move)
|
||||||
value = (
|
value = (
|
||||||
_alphabeta(
|
_alphabeta(
|
||||||
@ -46,13 +50,14 @@ def _alphabeta(
|
|||||||
)
|
)
|
||||||
board.pop()
|
board.pop()
|
||||||
|
|
||||||
if acc[0] >= beta:
|
if shouldStop() or acc[0] >= beta:
|
||||||
break # beta cutoff
|
break # beta cutoff
|
||||||
alpha = max(alpha, value[0])
|
alpha = max(alpha, acc[0])
|
||||||
|
|
||||||
else:
|
else:
|
||||||
acc = math.inf, None
|
acc = math.inf, None
|
||||||
for move in board.generate_legal_moves():
|
for move in board.generate_legal_moves():
|
||||||
|
|
||||||
board.push(move)
|
board.push(move)
|
||||||
value = (
|
value = (
|
||||||
_alphabeta(
|
_alphabeta(
|
||||||
@ -73,9 +78,9 @@ def _alphabeta(
|
|||||||
)
|
)
|
||||||
board.pop()
|
board.pop()
|
||||||
|
|
||||||
if acc[0] <= alpha:
|
if shouldStop() or acc[0] <= alpha:
|
||||||
break # alpha cutoff
|
break # alpha cutoff
|
||||||
beta = min(beta, value[0])
|
beta = min(beta, acc[0])
|
||||||
|
|
||||||
return acc
|
return acc
|
||||||
|
|
||||||
@ -92,15 +97,30 @@ def alphabeta(
|
|||||||
|
|
||||||
def IDDFS(board: Goban.Board, heuristic, color, duration: float, maxdepth=42):
|
def IDDFS(board: Goban.Board, heuristic, color, duration: float, maxdepth=42):
|
||||||
st = time.time()
|
st = time.time()
|
||||||
depth = 1
|
shouldStop = (lambda: time.time() - st > duration)
|
||||||
|
depth = 0
|
||||||
move = -1
|
move = -1
|
||||||
|
score = -1
|
||||||
|
|
||||||
while time.time() - st < duration and depth <= maxdepth:
|
while not shouldStop() and depth <= maxdepth:
|
||||||
print("depth:", depth, time.time() - st, file=stderr)
|
if depth % 2 == 0:
|
||||||
move = _alphabeta(
|
score, move = _alphabeta(
|
||||||
board, heuristic, color, move=-1, alpha=-10, beta=10, depth=depth
|
board, heuristic, color, move=move, alpha=-math.inf, beta=math.inf, depth=depth, shouldStop=shouldStop
|
||||||
)[1]
|
)
|
||||||
|
|
||||||
|
if score == math.inf:
|
||||||
|
return move, score
|
||||||
|
|
||||||
|
else:
|
||||||
|
score, move = _alphabeta(
|
||||||
|
board, heuristic, color, move=move, alpha=-math.inf, beta=math.inf, depth=depth, shouldStop=shouldStop
|
||||||
|
)
|
||||||
|
|
||||||
|
if score == -math.inf:
|
||||||
|
return move, score
|
||||||
|
|
||||||
|
print("depth:", depth, time.time() - st, score, file=stderr)
|
||||||
depth += 1
|
depth += 1
|
||||||
|
|
||||||
print(time.time() - st, duration, depth, file=stderr)
|
print(time.time() - st, duration, depth, file=stderr)
|
||||||
return move
|
return move, score
|
||||||
|
@ -19,11 +19,9 @@ import numpy as np
|
|||||||
from torch.utils.data import Dataset
|
from torch.utils.data import Dataset
|
||||||
|
|
||||||
def setup_device():
|
def setup_device():
|
||||||
torch.set_float32_matmul_precision("medium")
|
|
||||||
# Allows to use the GPU if available
|
# Allows to use the GPU if available
|
||||||
if torch.cuda.is_available():
|
if torch.cuda.is_available():
|
||||||
device = torch.device("cuda")
|
device = torch.device("cuda")
|
||||||
torch.backends.cuda.matmul.allow_tf32 = True
|
|
||||||
elif torch.backends.mps.is_available():
|
elif torch.backends.mps.is_available():
|
||||||
device = torch.device("mps")
|
device = torch.device("mps")
|
||||||
else:
|
else:
|
||||||
@ -167,7 +165,6 @@ class myPlayer(PlayerInterface):
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
self._board = Goban.Board()
|
self._board = Goban.Board()
|
||||||
self._mycolor = None
|
self._mycolor = None
|
||||||
self.moveCount = 0
|
|
||||||
|
|
||||||
self.device = setup_device()
|
self.device = setup_device()
|
||||||
print(self.device)
|
print(self.device)
|
||||||
@ -190,13 +187,16 @@ class myPlayer(PlayerInterface):
|
|||||||
|
|
||||||
def nnheuristic(self, board: Goban.Board, color):
|
def nnheuristic(self, board: Goban.Board, color):
|
||||||
if board.is_game_over():
|
if board.is_game_over():
|
||||||
|
if board.winner() == board._EMPTY:
|
||||||
|
return 0.5
|
||||||
|
|
||||||
return math.inf if board.winner() == color else -math.inf
|
return math.inf if board.winner() == color else -math.inf
|
||||||
|
|
||||||
go_board = torch.from_numpy(np.array([goban2Go(board)])).float().to(self.device)
|
go_board = torch.from_numpy(np.array([goban2Go(board)])).float().to(self.device)
|
||||||
|
|
||||||
self.model.eval()
|
self.model.eval()
|
||||||
with torch.no_grad():
|
with torch.no_grad():
|
||||||
prediction = self.model(go_board)
|
prediction = self.model(go_board).item()
|
||||||
|
|
||||||
if color == Goban.Board._BLACK:
|
if color == Goban.Board._BLACK:
|
||||||
return prediction
|
return prediction
|
||||||
@ -208,33 +208,41 @@ class myPlayer(PlayerInterface):
|
|||||||
print("Referee told me to play but the game is over!")
|
print("Referee told me to play but the game is over!")
|
||||||
return "PASS"
|
return "PASS"
|
||||||
|
|
||||||
if self.moveCount < 40:
|
duration = 1.
|
||||||
|
|
||||||
|
if self._board._nbBLACK + self._board._nbWHITE < 10:
|
||||||
max_depth = 1
|
max_depth = 1
|
||||||
|
|
||||||
|
elif self._board._nbBLACK + self._board._nbWHITE < 20:
|
||||||
|
max_depth = 2
|
||||||
|
|
||||||
|
elif self._board._nbBLACK + self._board._nbWHITE < 40:
|
||||||
|
max_depth = 3
|
||||||
|
|
||||||
else:
|
else:
|
||||||
max_depth = 5
|
duration = 64 - (self._board._nbBLACK + self._board._nbWHITE)
|
||||||
|
max_depth = 24
|
||||||
|
|
||||||
# move = alphabeta(self._board, self.nnheuristic, self._mycolor, 1)
|
# move = alphabeta(self._board, self.nnheuristic, self._mycolor, 1)
|
||||||
move = IDDFS(
|
move, score = IDDFS(
|
||||||
self._board, self.nnheuristic, self._mycolor, duration=1., maxdepth=max_depth
|
self._board, self.nnheuristic, self._mycolor, duration=duration, maxdepth=max_depth
|
||||||
)
|
)
|
||||||
|
|
||||||
self._board.push(move)
|
self._board.push(move)
|
||||||
|
print(move, score, file=stderr)
|
||||||
|
|
||||||
# New here: allows to consider internal representations of moves
|
# New here: allows to consider internal representations of moves
|
||||||
# move is an internal representation. To communicate with the interface I need to change if to a string
|
# move is an internal representation. To communicate with the interface I need to change if to a string
|
||||||
self.moveCount += 1 if Goban.Board.flat_to_name(move) != "PASS" else 0
|
|
||||||
return Goban.Board.flat_to_name(move)
|
return Goban.Board.flat_to_name(move)
|
||||||
|
|
||||||
def playOpponentMove(self, move):
|
def playOpponentMove(self, move):
|
||||||
print("Opponent played ", move) # New here
|
print("Opponent played ", move) # New here
|
||||||
# the board needs an internal represetation to push the move. Not a string
|
# the board needs an internal represetation to push the move. Not a string
|
||||||
self.moveCount += 1 if move != "PASS" else 0
|
|
||||||
self._board.push(Goban.Board.name_to_flat(move))
|
self._board.push(Goban.Board.name_to_flat(move))
|
||||||
|
|
||||||
def newGame(self, color):
|
def newGame(self, color):
|
||||||
self._mycolor = color
|
self._mycolor = color
|
||||||
self._opponent = Goban.Board.flip(color)
|
self._opponent = Goban.Board.flip(color)
|
||||||
self.moveCount = 0
|
|
||||||
|
|
||||||
def endGame(self, winner):
|
def endGame(self, winner):
|
||||||
if self._mycolor == winner:
|
if self._mycolor == winner:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user