fix import and some error
This commit is contained in:
@@ -6,7 +6,8 @@ from torch.optim import SGD
|
|||||||
|
|
||||||
from tugo.agents.base import Agent
|
from tugo.agents.base import Agent
|
||||||
from tugo.agents.helpers import is_point_an_eye
|
from tugo.agents.helpers import is_point_an_eye
|
||||||
from game_logic import goboard
|
# from tugo.game_logic import goboard
|
||||||
|
from tugo.game_logic import goboard_fast as goboard
|
||||||
|
|
||||||
|
|
||||||
def policy_gradient_loss(y_true, y_pred):
|
def policy_gradient_loss(y_true, y_pred):
|
||||||
@@ -26,7 +27,8 @@ class PolicyAgent(Agent):
|
|||||||
|
|
||||||
def predict(self, game_state):
|
def predict(self, game_state):
|
||||||
encoded_state = self._encoder.encode(game_state)
|
encoded_state = self._encoder.encode(game_state)
|
||||||
input_tensor = torch.tensor([encoded_state], dtype=torch.float32).to('cuda')
|
# input_tensor = torch.tensor([encoded_state], dtype=torch.float32).to('cuda')
|
||||||
|
input_tensor = encoded_state.float().to('cuda')
|
||||||
with torch.no_grad():
|
with torch.no_grad():
|
||||||
output_tensor = self._model(input_tensor)
|
output_tensor = self._model(input_tensor)
|
||||||
return output_tensor.cpu().numpy()[0]
|
return output_tensor.cpu().numpy()[0]
|
||||||
|
|||||||
+4
-2
@@ -1,6 +1,7 @@
|
|||||||
from tugo.agents.base import Agent
|
from tugo.agents.base import Agent
|
||||||
from tugo.agents.helpers import is_point_an_eye
|
from tugo.agents.helpers import is_point_an_eye
|
||||||
from game_logic import goboard
|
# from game_logic import goboard
|
||||||
|
from tugo.game_logic import goboard_fast as goboard
|
||||||
from tugo.models import AlphaGoModel
|
from tugo.models import AlphaGoModel
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
@@ -44,6 +45,7 @@ class DeepLearningAgent(Agent):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def load(cls, file_path, encoder):
|
def load(cls, file_path, encoder):
|
||||||
device = 'cuda' if torch.cuda.is_available() else 'cpu'
|
device = 'cuda' if torch.cuda.is_available() else 'cpu'
|
||||||
model = AlphaGoModel(encoder.get_input_shape(), is_policy_net=True).to(device)
|
# model = AlphaGoModel(encoder.get_input_shape(), is_policy_net=True).to(device)
|
||||||
|
model = AlphaGoModel(encoder.shape(), is_policy_net=True, num_classes=361).to(device)
|
||||||
model.load_state_dict(torch.load(file_path))
|
model.load_state_dict(torch.load(file_path))
|
||||||
return cls(model, encoder)
|
return cls(model, encoder)
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
from game_logic.goboard import Move
|
from tugo.game_logic.goboard_fast import Move
|
||||||
|
|
||||||
|
|
||||||
def is_ladder_capture(game_state, candidate, recursion_depth=50):
|
def is_ladder_capture(game_state, candidate, recursion_depth=50):
|
||||||
|
|||||||
+299
-299
@@ -1,299 +1,299 @@
|
|||||||
import copy
|
# import copy
|
||||||
from game_logic.gotypes import Player, Point
|
# from tugo.game_logic.gotypes import Player, Point
|
||||||
from game_logic.scoring import compute_game_result
|
# from tugo.game_logic.scoring import compute_game_result
|
||||||
from game_logic import zobrist_hash
|
# from tugo.game_logic import zobrist_hash
|
||||||
|
#
|
||||||
|
#
|
||||||
class IllegalMoveError(Exception):
|
# class IllegalMoveError(Exception):
|
||||||
pass
|
# pass
|
||||||
|
#
|
||||||
|
#
|
||||||
# tag::fast_go_strings[]
|
# # tag::fast_go_strings[]
|
||||||
class GoString:
|
# class GoString:
|
||||||
def __init__(self, color, stones, liberties):
|
# def __init__(self, color, stones, liberties):
|
||||||
self.color = color
|
# self.color = color
|
||||||
self.stones = frozenset(stones)
|
# self.stones = frozenset(stones)
|
||||||
self.liberties = frozenset(liberties) # <1>
|
# self.liberties = frozenset(liberties) # <1>
|
||||||
|
#
|
||||||
def without_liberty(self, point): # <2>
|
# def without_liberty(self, point): # <2>
|
||||||
new_liberties = self.liberties - set([point])
|
# new_liberties = self.liberties - set([point])
|
||||||
return GoString(self.color, self.stones, new_liberties)
|
# return GoString(self.color, self.stones, new_liberties)
|
||||||
|
#
|
||||||
def with_liberty(self, point):
|
# def with_liberty(self, point):
|
||||||
new_liberties = self.liberties | set([point])
|
# new_liberties = self.liberties | set([point])
|
||||||
return GoString(self.color, self.stones, new_liberties)
|
# return GoString(self.color, self.stones, new_liberties)
|
||||||
# <1> `stones` and `liberties` are now immutable `frozenset` instances
|
# # <1> `stones` and `liberties` are now immutable `frozenset` instances
|
||||||
# <2> The `without_liberty` methods replaces the previous `remove_liberty` method...
|
# # <2> The `without_liberty` methods replaces the previous `remove_liberty` method...
|
||||||
# <3> ... and `with_liberty` replaces `add_liberty`.
|
# # <3> ... and `with_liberty` replaces `add_liberty`.
|
||||||
# end::fast_go_strings[]
|
# # end::fast_go_strings[]
|
||||||
|
#
|
||||||
def merged_with(self, string):
|
# def merged_with(self, string):
|
||||||
"""Return a new string containing all stones in both strings."""
|
# """Return a new string containing all stones in both strings."""
|
||||||
assert string.color == self.color
|
# assert string.color == self.color
|
||||||
combined_stones = self.stones | string.stones
|
# combined_stones = self.stones | string.stones
|
||||||
return GoString(
|
# return GoString(
|
||||||
self.color,
|
# self.color,
|
||||||
combined_stones,
|
# combined_stones,
|
||||||
(self.liberties | string.liberties) - combined_stones)
|
# (self.liberties | string.liberties) - combined_stones)
|
||||||
|
#
|
||||||
@property
|
# @property
|
||||||
def num_liberties(self):
|
# def num_liberties(self):
|
||||||
return len(self.liberties)
|
# return len(self.liberties)
|
||||||
|
#
|
||||||
def __eq__(self, other):
|
# def __eq__(self, other):
|
||||||
return isinstance(other, GoString) and \
|
# return isinstance(other, GoString) and \
|
||||||
self.color == other.color and \
|
# self.color == other.color and \
|
||||||
self.stones == other.stones and \
|
# self.stones == other.stones and \
|
||||||
self.liberties == other.liberties
|
# self.liberties == other.liberties
|
||||||
|
#
|
||||||
def __deepcopy__(self, memodict={}):
|
# def __deepcopy__(self, memodict={}):
|
||||||
return GoString(self.color, self.stones, copy.deepcopy(self.liberties))
|
# return GoString(self.color, self.stones, copy.deepcopy(self.liberties))
|
||||||
|
#
|
||||||
|
#
|
||||||
# tag::init_zobrist[]
|
# # tag::init_zobrist[]
|
||||||
class Board:
|
# class Board:
|
||||||
def __init__(self, num_rows, num_cols):
|
# def __init__(self, num_rows, num_cols):
|
||||||
self.num_rows = num_rows
|
# self.num_rows = num_rows
|
||||||
self.num_cols = num_cols
|
# self.num_cols = num_cols
|
||||||
self._grid = {}
|
# self._grid = {}
|
||||||
self._hash = zobrist_hash.EMPTY_BOARD
|
# self._hash = zobrist_hash.EMPTY_BOARD
|
||||||
# end::init_zobrist[]
|
# # end::init_zobrist[]
|
||||||
|
#
|
||||||
def place_stone(self, player, point):
|
# def place_stone(self, player, point):
|
||||||
assert self.is_on_grid(point)
|
# assert self.is_on_grid(point)
|
||||||
if self._grid.get(point) is not None:
|
# if self._grid.get(point) is not None:
|
||||||
print('Illegal play on %s' % str(point))
|
# print('Illegal play on %s' % str(point))
|
||||||
assert self._grid.get(point) is None
|
# assert self._grid.get(point) is None
|
||||||
# 0. Examine the adjacent points.
|
# # 0. Examine the adjacent points.
|
||||||
adjacent_same_color = []
|
# adjacent_same_color = []
|
||||||
adjacent_opposite_color = []
|
# adjacent_opposite_color = []
|
||||||
liberties = []
|
# liberties = []
|
||||||
for neighbor in point.neighbors():
|
# for neighbor in point.neighbors():
|
||||||
if not self.is_on_grid(neighbor):
|
# if not self.is_on_grid(neighbor):
|
||||||
continue
|
# continue
|
||||||
neighbor_string = self._grid.get(neighbor)
|
# neighbor_string = self._grid.get(neighbor)
|
||||||
if neighbor_string is None:
|
# if neighbor_string is None:
|
||||||
liberties.append(neighbor)
|
# liberties.append(neighbor)
|
||||||
elif neighbor_string.color == player:
|
# elif neighbor_string.color == player:
|
||||||
if neighbor_string not in adjacent_same_color:
|
# if neighbor_string not in adjacent_same_color:
|
||||||
adjacent_same_color.append(neighbor_string)
|
# adjacent_same_color.append(neighbor_string)
|
||||||
else:
|
# else:
|
||||||
if neighbor_string not in adjacent_opposite_color:
|
# if neighbor_string not in adjacent_opposite_color:
|
||||||
adjacent_opposite_color.append(neighbor_string)
|
# adjacent_opposite_color.append(neighbor_string)
|
||||||
new_string = GoString(player, [point], liberties)
|
# new_string = GoString(player, [point], liberties)
|
||||||
# tag::apply_zobrist[]
|
# # tag::apply_zobrist[]
|
||||||
new_string = GoString(player, [point], liberties) # <1>
|
# new_string = GoString(player, [point], liberties) # <1>
|
||||||
|
#
|
||||||
for same_color_string in adjacent_same_color: # <2>
|
# for same_color_string in adjacent_same_color: # <2>
|
||||||
new_string = new_string.merged_with(same_color_string)
|
# new_string = new_string.merged_with(same_color_string)
|
||||||
for new_string_point in new_string.stones:
|
# for new_string_point in new_string.stones:
|
||||||
self._grid[new_string_point] = new_string
|
# self._grid[new_string_point] = new_string
|
||||||
|
#
|
||||||
self._hash ^= zobrist_hash.HASH_CODE[point, player] # <3>
|
# self._hash ^= zobrist_hash.HASH_CODE[point, player] # <3>
|
||||||
|
#
|
||||||
for other_color_string in adjacent_opposite_color:
|
# for other_color_string in adjacent_opposite_color:
|
||||||
replacement = other_color_string.without_liberty(point) # <4>
|
# replacement = other_color_string.without_liberty(point) # <4>
|
||||||
if replacement.num_liberties:
|
# if replacement.num_liberties:
|
||||||
self._replace_string(other_color_string.without_liberty(point))
|
# self._replace_string(other_color_string.without_liberty(point))
|
||||||
else:
|
# else:
|
||||||
self._remove_string(other_color_string) # <5>
|
# self._remove_string(other_color_string) # <5>
|
||||||
# <1> Until this line `place_stone` remains the same.
|
# # <1> Until this line `place_stone` remains the same.
|
||||||
# <2> You merge any adjacent strings of the same color.
|
# # <2> You merge any adjacent strings of the same color.
|
||||||
# <3> Next, you apply the hash code for this point and player
|
# # <3> Next, you apply the hash code for this point and player
|
||||||
# <4> Then you reduce liberties of any adjacent strings of the opposite color.
|
# # <4> Then you reduce liberties of any adjacent strings of the opposite color.
|
||||||
# <5> If any opposite color strings now have zero liberties, remove them.
|
# # <5> If any opposite color strings now have zero liberties, remove them.
|
||||||
# end::apply_zobrist[]
|
# # end::apply_zobrist[]
|
||||||
|
#
|
||||||
|
#
|
||||||
# tag::unapply_zobrist[]
|
# # tag::unapply_zobrist[]
|
||||||
def _replace_string(self, new_string): # <1>
|
# def _replace_string(self, new_string): # <1>
|
||||||
for point in new_string.stones:
|
# for point in new_string.stones:
|
||||||
self._grid[point] = new_string
|
# self._grid[point] = new_string
|
||||||
|
#
|
||||||
def _remove_string(self, string):
|
# def _remove_string(self, string):
|
||||||
for point in string.stones:
|
# for point in string.stones:
|
||||||
for neighbor in point.neighbors(): # <2>
|
# for neighbor in point.neighbors(): # <2>
|
||||||
neighbor_string = self._grid.get(neighbor)
|
# neighbor_string = self._grid.get(neighbor)
|
||||||
if neighbor_string is None:
|
# if neighbor_string is None:
|
||||||
continue
|
# continue
|
||||||
if neighbor_string is not string:
|
# if neighbor_string is not string:
|
||||||
self._replace_string(neighbor_string.with_liberty(point))
|
# self._replace_string(neighbor_string.with_liberty(point))
|
||||||
self._grid[point] = None
|
# self._grid[point] = None
|
||||||
|
#
|
||||||
self._hash ^= zobrist_hash.HASH_CODE[point, string.color] # <3>
|
# self._hash ^= zobrist_hash.HASH_CODE[point, string.color] # <3>
|
||||||
# <1> This new helper method updates our Go board grid.
|
# # <1> This new helper method updates our Go board grid.
|
||||||
# <2> Removing a string can create liberties for other strings.
|
# # <2> Removing a string can create liberties for other strings.
|
||||||
# <3> With Zobrist hashing, you need to unapply the hash for this move.
|
# # <3> With Zobrist hashing, you need to unapply the hash for this move.
|
||||||
# end::unapply_zobrist[]
|
# # end::unapply_zobrist[]
|
||||||
|
#
|
||||||
def is_on_grid(self, point):
|
# def is_on_grid(self, point):
|
||||||
return 1 <= point.row <= self.num_rows and \
|
# return 1 <= point.row <= self.num_rows and \
|
||||||
1 <= point.col <= self.num_cols
|
# 1 <= point.col <= self.num_cols
|
||||||
|
#
|
||||||
def get(self, point):
|
# def get(self, point):
|
||||||
"""Return the content of a point on the board.
|
# """Return the content of a point on the board.
|
||||||
|
#
|
||||||
Returns None if the point is empty, or a Player if there is a
|
# Returns None if the point is empty, or a Player if there is a
|
||||||
stone on that point.
|
# stone on that point.
|
||||||
"""
|
# """
|
||||||
string = self._grid.get(point)
|
# string = self._grid.get(point)
|
||||||
if string is None:
|
# if string is None:
|
||||||
return None
|
# return None
|
||||||
return string.color
|
# return string.color
|
||||||
|
#
|
||||||
def get_go_string(self, point):
|
# def get_go_string(self, point):
|
||||||
"""Return the entire string of stones at a point.
|
# """Return the entire string of stones at a point.
|
||||||
|
#
|
||||||
Returns None if the point is empty, or a GoString if there is
|
# Returns None if the point is empty, or a GoString if there is
|
||||||
a stone on that point.
|
# a stone on that point.
|
||||||
"""
|
# """
|
||||||
string = self._grid.get(point)
|
# string = self._grid.get(point)
|
||||||
if string is None:
|
# if string is None:
|
||||||
return None
|
# return None
|
||||||
return string
|
# return string
|
||||||
|
#
|
||||||
def __eq__(self, other):
|
# def __eq__(self, other):
|
||||||
return isinstance(other, Board) and \
|
# return isinstance(other, Board) and \
|
||||||
self.num_rows == other.num_rows and \
|
# self.num_rows == other.num_rows and \
|
||||||
self.num_cols == other.num_cols and \
|
# self.num_cols == other.num_cols and \
|
||||||
self._hash() == other._hash()
|
# self._hash() == other._hash()
|
||||||
|
#
|
||||||
def __deepcopy__(self, memodict={}):
|
# def __deepcopy__(self, memodict={}):
|
||||||
copied = Board(self.num_rows, self.num_cols)
|
# copied = Board(self.num_rows, self.num_cols)
|
||||||
# Can do a shallow copy b/c the dictionary maps tuples
|
# # Can do a shallow copy b/c the dictionary maps tuples
|
||||||
# (immutable) to GoStrings (also immutable)
|
# # (immutable) to GoStrings (also immutable)
|
||||||
copied._grid = copy.copy(self._grid)
|
# copied._grid = copy.copy(self._grid)
|
||||||
copied._hash = self._hash
|
# copied._hash = self._hash
|
||||||
return copied
|
# return copied
|
||||||
|
#
|
||||||
# tag::return_zobrist[]
|
# # tag::return_zobrist[]
|
||||||
def zobrist_hash(self):
|
# def zobrist_hash(self):
|
||||||
return self._hash
|
# return self._hash
|
||||||
# end::return_zobrist[]
|
# # end::return_zobrist[]
|
||||||
|
#
|
||||||
|
#
|
||||||
class Move:
|
# class Move:
|
||||||
"""Any action a player can play on a turn.
|
# """Any action a player can play on a turn.
|
||||||
Exactly one of is_play, is_pass, is_resign will be set.
|
# Exactly one of is_play, is_pass, is_resign will be set.
|
||||||
"""
|
# """
|
||||||
def __init__(self, point=None, is_pass=False, is_resign=False):
|
# def __init__(self, point=None, is_pass=False, is_resign=False):
|
||||||
assert (point is not None) ^ is_pass ^ is_resign
|
# assert (point is not None) ^ is_pass ^ is_resign
|
||||||
self.point = point
|
# self.point = point
|
||||||
self.is_play = (self.point is not None)
|
# self.is_play = (self.point is not None)
|
||||||
self.is_pass = is_pass
|
# self.is_pass = is_pass
|
||||||
self.is_resign = is_resign
|
# self.is_resign = is_resign
|
||||||
|
#
|
||||||
@classmethod
|
# @classmethod
|
||||||
def play(cls, point):
|
# def play(cls, point):
|
||||||
"""A move that places a stone on the board."""
|
# """A move that places a stone on the board."""
|
||||||
return Move(point=point)
|
# return Move(point=point)
|
||||||
|
#
|
||||||
@classmethod
|
# @classmethod
|
||||||
def pass_turn(cls):
|
# def pass_turn(cls):
|
||||||
return Move(is_pass=True)
|
# return Move(is_pass=True)
|
||||||
|
#
|
||||||
@classmethod
|
# @classmethod
|
||||||
def resign(cls):
|
# def resign(cls):
|
||||||
return Move(is_resign=True)
|
# return Move(is_resign=True)
|
||||||
|
#
|
||||||
def __str__(self):
|
# def __str__(self):
|
||||||
if self.is_pass:
|
# if self.is_pass:
|
||||||
return 'pass'
|
# return 'pass'
|
||||||
if self.is_resign:
|
# if self.is_resign:
|
||||||
return 'resign'
|
# return 'resign'
|
||||||
return '(r %d, c %d)' % (self.point.row, self.point.col)
|
# return '(r %d, c %d)' % (self.point.row, self.point.col)
|
||||||
|
#
|
||||||
|
#
|
||||||
# tag::init_state_zobrist[]
|
# # tag::init_state_zobrist[]
|
||||||
class GameState:
|
# class GameState:
|
||||||
def __init__(self, board, next_player, previous, move):
|
# def __init__(self, board, next_player, previous, move):
|
||||||
self.board = board
|
# self.board = board
|
||||||
self.next_player = next_player
|
# self.next_player = next_player
|
||||||
self.previous_state = previous
|
# self.previous_state = previous
|
||||||
if self.previous_state is None:
|
# if self.previous_state is None:
|
||||||
self.previous_states = frozenset()
|
# self.previous_states = frozenset()
|
||||||
else:
|
# else:
|
||||||
self.previous_states = frozenset(
|
# self.previous_states = frozenset(
|
||||||
previous.previous_states |
|
# previous.previous_states |
|
||||||
{(previous.next_player, previous.board.zobrist_hash())})
|
# {(previous.next_player, previous.board.zobrist_hash())})
|
||||||
self.last_move = move
|
# self.last_move = move
|
||||||
# end::init_state_zobrist[]
|
# # end::init_state_zobrist[]
|
||||||
|
#
|
||||||
def apply_move(self, move):
|
# def apply_move(self, move):
|
||||||
"""Return the new GameState after applying the move."""
|
# """Return the new GameState after applying the move."""
|
||||||
if move.is_play:
|
# if move.is_play:
|
||||||
next_board = copy.deepcopy(self.board)
|
# next_board = copy.deepcopy(self.board)
|
||||||
next_board.place_stone(self.next_player, move.point)
|
# next_board.place_stone(self.next_player, move.point)
|
||||||
else:
|
# else:
|
||||||
next_board = self.board
|
# next_board = self.board
|
||||||
return GameState(next_board, self.next_player.other, self, move)
|
# return GameState(next_board, self.next_player.other, self, move)
|
||||||
|
#
|
||||||
@classmethod
|
# @classmethod
|
||||||
def new_game(cls, board_size):
|
# def new_game(cls, board_size):
|
||||||
if isinstance(board_size, int):
|
# if isinstance(board_size, int):
|
||||||
board_size = (board_size, board_size)
|
# board_size = (board_size, board_size)
|
||||||
board = Board(*board_size)
|
# board = Board(*board_size)
|
||||||
return GameState(board, Player.black, None, None)
|
# return GameState(board, Player.black, None, None)
|
||||||
|
#
|
||||||
def is_move_self_capture(self, player, move):
|
# def is_move_self_capture(self, player, move):
|
||||||
if not move.is_play:
|
# if not move.is_play:
|
||||||
return False
|
# return False
|
||||||
next_board = copy.deepcopy(self.board)
|
# next_board = copy.deepcopy(self.board)
|
||||||
next_board.place_stone(player, move.point)
|
# next_board.place_stone(player, move.point)
|
||||||
new_string = next_board.get_go_string(move.point)
|
# new_string = next_board.get_go_string(move.point)
|
||||||
return new_string.num_liberties == 0
|
# return new_string.num_liberties == 0
|
||||||
|
#
|
||||||
@property
|
# @property
|
||||||
def situation(self):
|
# def situation(self):
|
||||||
return (self.next_player, self.board)
|
# return (self.next_player, self.board)
|
||||||
|
#
|
||||||
# tag::ko_zobrist[]
|
# # tag::ko_zobrist[]
|
||||||
def does_move_violate_ko(self, player, move):
|
# def does_move_violate_ko(self, player, move):
|
||||||
if not move.is_play:
|
# if not move.is_play:
|
||||||
return False
|
# return False
|
||||||
next_board = copy.deepcopy(self.board)
|
# next_board = copy.deepcopy(self.board)
|
||||||
next_board.place_stone(player, move.point)
|
# next_board.place_stone(player, move.point)
|
||||||
next_situation = (player.other, next_board.zobrist_hash())
|
# next_situation = (player.other, next_board.zobrist_hash())
|
||||||
return next_situation in self.previous_states
|
# return next_situation in self.previous_states
|
||||||
# end::ko_zobrist[]
|
# # end::ko_zobrist[]
|
||||||
|
#
|
||||||
def is_valid_move(self, move):
|
# def is_valid_move(self, move):
|
||||||
if self.is_over():
|
# if self.is_over():
|
||||||
return False
|
# return False
|
||||||
if move.is_pass or move.is_resign:
|
# if move.is_pass or move.is_resign:
|
||||||
return True
|
# return True
|
||||||
return (
|
# return (
|
||||||
self.board.get(move.point) is None and
|
# self.board.get(move.point) is None and
|
||||||
not self.is_move_self_capture(self.next_player, move) and
|
# not self.is_move_self_capture(self.next_player, move) and
|
||||||
not self.does_move_violate_ko(self.next_player, move))
|
# not self.does_move_violate_ko(self.next_player, move))
|
||||||
|
#
|
||||||
def is_over(self):
|
# def is_over(self):
|
||||||
if self.last_move is None:
|
# if self.last_move is None:
|
||||||
return False
|
# return False
|
||||||
if self.last_move.is_resign:
|
# if self.last_move.is_resign:
|
||||||
return True
|
# return True
|
||||||
second_last_move = self.previous_state.last_move
|
# second_last_move = self.previous_state.last_move
|
||||||
if second_last_move is None:
|
# if second_last_move is None:
|
||||||
return False
|
# return False
|
||||||
return self.last_move.is_pass and second_last_move.is_pass
|
# return self.last_move.is_pass and second_last_move.is_pass
|
||||||
|
#
|
||||||
def legal_moves(self):
|
# def legal_moves(self):
|
||||||
moves = []
|
# moves = []
|
||||||
for row in range(1, self.board.num_rows + 1):
|
# for row in range(1, self.board.num_rows + 1):
|
||||||
for col in range(1, self.board.num_cols + 1):
|
# for col in range(1, self.board.num_cols + 1):
|
||||||
move = Move.play(Point(row, col))
|
# move = Move.play(Point(row, col))
|
||||||
if self.is_valid_move(move):
|
# if self.is_valid_move(move):
|
||||||
moves.append(move)
|
# moves.append(move)
|
||||||
# These two moves are always legal.
|
# # These two moves are always legal.
|
||||||
moves.append(Move.pass_turn())
|
# moves.append(Move.pass_turn())
|
||||||
moves.append(Move.resign())
|
# moves.append(Move.resign())
|
||||||
|
#
|
||||||
return moves
|
# return moves
|
||||||
|
#
|
||||||
def winner(self):
|
# def winner(self):
|
||||||
if not self.is_over():
|
# if not self.is_over():
|
||||||
return None
|
# return None
|
||||||
if self.last_move.is_resign:
|
# if self.last_move.is_resign:
|
||||||
return self.next_player
|
# return self.next_player
|
||||||
game_result = compute_game_result(self)
|
# game_result = compute_game_result(self)
|
||||||
return game_result.winner
|
# return game_result.winner
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import copy
|
import copy
|
||||||
from game_logic.gotypes import Player, Point
|
from tugo.game_logic.gotypes import Player, Point
|
||||||
from game_logic.scoring import compute_game_result
|
from tugo.game_logic.scoring import compute_game_result
|
||||||
from game_logic import zobrist_hash
|
from tugo.game_logic import zobrist_hash
|
||||||
from tugo.print_utils import MoveAge
|
from tugo.print_utils import MoveAge
|
||||||
|
|
||||||
neighbor_tables = {}
|
neighbor_tables = {}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
|
||||||
from game_logic.gotypes import Player, Point
|
from tugo.game_logic.gotypes import Player, Point
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
from game_logic.gotypes import Player, Point
|
from tugo.game_logic.gotypes import Player, Point
|
||||||
|
|
||||||
|
|
||||||
HASH_CODE = {
|
HASH_CODE = {
|
||||||
|
|||||||
@@ -3,7 +3,8 @@ import torch
|
|||||||
import torch.optim as optim
|
import torch.optim as optim
|
||||||
|
|
||||||
from tugo import encoders
|
from tugo import encoders
|
||||||
from tugo.game_logic import goboard
|
# from tugo.game_logic import goboard
|
||||||
|
from tugo.game_logic import goboard_fast as goboard
|
||||||
from tugo.agents import Agent
|
from tugo.agents import Agent
|
||||||
from tugo.agents.helpers import is_point_an_eye
|
from tugo.agents.helpers import is_point_an_eye
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -2,7 +2,8 @@ import torch
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
from tugo import encoders
|
from tugo import encoders
|
||||||
from tugo.game_logic import goboard
|
# from tugo.game_logic import goboard
|
||||||
|
from tugo.game_logic import goboard_fast as goboard
|
||||||
from tugo.agents import Agent
|
from tugo.agents import Agent
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,8 @@ import torch.optim as optim
|
|||||||
from torch.distributions import Categorical
|
from torch.distributions import Categorical
|
||||||
|
|
||||||
from tugo import encoders
|
from tugo import encoders
|
||||||
from tugo.game_logic import goboard
|
# from tugo.game_logic import goboard
|
||||||
|
from tugo.game_logic import goboard_fast as goboard
|
||||||
from tugo.agents import Agent
|
from tugo.agents import Agent
|
||||||
from tugo.agents.helpers import is_point_an_eye
|
from tugo.agents.helpers import is_point_an_eye
|
||||||
|
|
||||||
|
|||||||
+7
-4
@@ -1,4 +1,4 @@
|
|||||||
from tugo import rl
|
from tugo.rl import experience
|
||||||
from tugo.game_logic import scoring
|
from tugo.game_logic import scoring
|
||||||
from tugo.game_logic import goboard_fast as goboard
|
from tugo.game_logic import goboard_fast as goboard
|
||||||
from tugo.game_logic.gotypes import Player
|
from tugo.game_logic.gotypes import Player
|
||||||
@@ -32,8 +32,8 @@ def simulate_game(black_player, white_player):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def experience_simulation(num_games, agent1, agent2):
|
def experience_simulation(num_games, agent1, agent2, progress_callback=None):
|
||||||
collectors = [rl.ExperienceCollector() for _ in range(2)]
|
collectors = [experience.ExperienceCollector() for _ in range(2)]
|
||||||
agents = [agent1, agent2]
|
agents = [agent1, agent2]
|
||||||
|
|
||||||
color1 = Player.black
|
color1 = Player.black
|
||||||
@@ -55,4 +55,7 @@ def experience_simulation(num_games, agent1, agent2):
|
|||||||
|
|
||||||
color1 = color1.other
|
color1 = color1.other
|
||||||
|
|
||||||
return rl.combine_experience(collectors)
|
if progress_callback:
|
||||||
|
progress_callback()
|
||||||
|
|
||||||
|
return experience.combine_experience(collectors)
|
||||||
|
|||||||
+2
-1
@@ -4,7 +4,8 @@ import torch.optim as optim
|
|||||||
from torch.distributions import Categorical
|
from torch.distributions import Categorical
|
||||||
|
|
||||||
from tugo import encoders
|
from tugo import encoders
|
||||||
from tugo import goboard
|
# from tugo.game_logic import goboard
|
||||||
|
from tugo.game_logic import goboard_fast as goboard
|
||||||
from tugo.agents import Agent
|
from tugo.agents import Agent
|
||||||
from tugo.agents.helpers import is_point_an_eye
|
from tugo.agents.helpers import is_point_an_eye
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user