def load_epd(string): """Load an EPD from a string and return a board with namespace variables set accordingly.""" halfmove = str(default_halfmove) fullmove = str(default_fullmove) fields = string.split() layout, moving, castling_rights, en_passant_rights = fields[:4] operations = ' '.join(fields[4:]) op_fields = operations.split(';')[:-1] # remove last '' element fen = ' '.join([layout, moving, castling_rights, en_passant_rights, halfmove, fullmove]) b = Board(fen=fen) b.data.raw_operations = operations b.data.op_fields = op_fields op_data = {} for operation in op_fields: fields = operation.strip().split() opcode = fields[0] operand = fields[1:] name = opcodes[opcode] value = operand op_data.update({opcode: (name, value)}) b.data.op_data = op_data if 'fmvn' in op_data: b.fullmove_clock = int(op_data['fvmn']) if 'hmvc' in op_data: b.halfmove_clock = int(op_data['hmvc']) return b
def rollback(self): fen = self.history[-1] data = self.board.data cfg = self.board.cfg #self.player1 = self.board.player1 #self.player2 = self.board.player2 #self.board = Board(self.player1, self.player2, fen) self.board = Board(self.players, fen) self.board.data = data self.board.cfg = cfg
def main(clear=True): if clear: clear_log() log_msg('Testing Phantom.core.board.Board.move() method', 0) b = Board() # white to move, opening layout try: b.move('e2e4') b.move('g8f6') b.move('g2g3') except Exception as e: log_msg('Phantom.core.board.Board.move() method test failed:\n{}'.format(e), 0, err=True) finally: log_msg('Test complete', 0)
def __init__(self, *args, **kwargs): self.board = Board() self.player1 = self.board.player1 self.player2 = self.board.player2 if len(args) > 0: if isinstance(args[0], str): # assume name of a game and load it self.board = _loadboard(args[0]) for arg in args: if isinstance(arg, Board): self.board = arg if isinstance(arg, Player): self.player1 = arg self.player2 = args[args.index(arg)+1] del args[args.index(arg)+1] self.board.player1 = self.player1 self.board.player2 = self.player2 self.player1.board = self.board self.player2.board = self.board self.board.set_game(self) self.history = [] self.moves = [] self._uuid = self.board._uuid self.data = Namespace()
def __init__(self, depth, terminal, board, parent=None): self.depth = depth self.is_terminal = terminal or (self.depth >= maxdepth) self.board = Board(None, fen_str=board.fen_str) # deepcopy the board self.board.set_game(board.game) self.score = pos_eval_advanced(self.board) self.nid = self.cnum + 1 if self.nid >= window: self.spawndepth += 1 self.cnum = self.nid self._uuid = uuid.uuid4() self.parent = parent if self.parent: self.parent.set_child(self) self.children = [] self.numchildren = window**self.depth if self.depth > 1 else window self.tree = None
def load_epd(string): """Load an EPD from a string and return a board with namespace variables set accordingly.""" halfmove = str(default_halfmove) fullmove = str(default_fullmove) fields = string.split() layout, moving, castling_rights, en_passant_rights = fields[:4] operations = ' '.join(fields[4:]) op_fields = operations.split(';')[:-1] # remove last '' element fen = ' '.join([ layout, moving, castling_rights, en_passant_rights, halfmove, fullmove ]) b = Board(None, fen) b.data['raw_operations'] = operations b.data['op_fields'] = op_fields op_data = {} for operation in op_fields: fields = operation.strip().split() opcode = fields[0] operand = fields[1:] name = opcodes[opcode] value = ''.join([ o for o in operand ]) # operand will be a list, make into a single object op_data.update({opcode: (name, value)}) b.data['op_data'] = op_data if 'fmvn' in op_data: b.fullmove_clock = int(op_data['fmvn'][1]) if 'hmvc' in op_data: b.halfmove_clock = int(op_data['hmvc'][1]) return b
def rollback(self): fen = self.history[-1] data = self.board.data cfg = self.board.cfg self.player1 = self.board.player1 self.player2 = self.board.player2 self.board = Board(self.player1, self.player2, fen) self.board.data = data self.board.cfg = cfg
class Node(object): cnum = 0 spawndepth = 0 used_layouts = {} def __init__(self, depth, terminal, board, parent=None): self.depth = depth self.is_terminal = terminal or (self.depth >= maxdepth) self.board = Board(None, fen_str=board.fen_str) # deepcopy the board self.board.set_game(board.game) self.score = pos_eval_advanced(self.board) self.nid = self.cnum + 1 if self.nid >= window: self.spawndepth += 1 self.cnum = self.nid self._uuid = uuid.uuid4() self.parent = parent if self.parent: self.parent.set_child(self) self.children = [] self.numchildren = window**self.depth if self.depth > 1 else window self.tree = None def __hash__(self): return self.depth * self.board.__hash__() def __repr__(self): return '<Phantom search node with depth {} at {}>'.format( self.depth, hex(id(self))) def set_tree(self, t): self.tree = t self.tree.used_layouts.add(self.board.fen_str()) def set_parent(self, p): self.parent = p self.parent.set_child(self) def set_child(self, c): self.children.append(c) def variate(self, *args): ret = Board(fen=self.board.fen_str()) ret.set_game(self.board.game) ret.move(*args) return ret def boardcopy(self): newboard = Board(fen=self.board.fen_str()) newboard.set_game(self.board.game) return newboard def children_gen(self): for k in window: b = self.boardcopy()
def clone(self): fen = self.board.as_fen_str() history = self.history cfg = self.board.cfg data = self.board.data sdata = self.data moves = self.moves #clone = ChessGame(self.player1, self.player2, Board(self.player1, self.player2, fen)) clone = ChessGame(Board(self.board.players, fen)) clone.history = history clone.board.cfg = cfg clone.board.data = data clone.data = sdata clone.moves = moves return clone
class Node (object): cnum = 0 spawndepth = 0 used_layouts = {} def __init__(self, depth, terminal, board, parent=None): self.depth = depth self.is_terminal = terminal or (self.depth >= maxdepth) self.board = Board(None, fen_str=board.fen_str) # deepcopy the board self.board.set_game(board.game) self.score = pos_eval_advanced(self.board) self.nid = self.cnum + 1 if self.nid >= window: self.spawndepth += 1 self.cnum = self.nid self._uuid = uuid.uuid4() self.parent = parent if self.parent: self.parent.set_child(self) self.children = [] self.numchildren = window**self.depth if self.depth > 1 else window self.tree = None def __hash__(self): return self.depth * self.board.__hash__() def __repr__(self): return '<Phantom search node with depth {} at {}>'.format(self.depth, hex(id(self))) def set_tree(self, t): self.tree = t self.tree.used_layouts.add(self.board.fen_str()) def set_parent(self, p): self.parent = p self.parent.set_child(self) def set_child(self, c): self.children.append(c) def variate(self, *args): ret = Board(fen=self.board.fen_str()) ret.set_game(self.board.game) ret.move(*args) return ret def boardcopy(self): newboard = Board(fen=self.board.fen_str()) newboard.set_game(self.board.game) return newboard def children_gen(self): for k in window: b = self.boardcopy()
def __init__(self, fen_str=None): self.board = Board(self, fen_str) self._uuid = self.board._uuid self.data = dict() self.history = [] self.moves = []
class ChessGame(PhantomObj): def __init__(self, fen_str=None): self.board = Board(self, fen_str) self._uuid = self.board._uuid self.data = dict() self.history = [] self.moves = [] #try: # autostart the gui? # import sk # self.sk_gui() #except ImportError: # pass def __repr__(self): return self.board._pprnt() def __hash__(self): return int(self._uuid) % (self.board.__hash__() + 1) @property def ai_rateing(self): from Phantom.ai.pos_eval.advanced import pos_eval_advanced return pos_eval_advanced(self.board) def ai_easy(self): from Phantom.ai.movers.basic import make_random_move return make_random_move(self.board) def ai_hard(self): from Phantom.ai.movers.advanced import make_smart_move return make_smart_move(self.board) def move(self, *args): save_fen_str = self.board.as_fen_str() ret = self.board.move(*args) if ret: self.history.append(save_fen_str) self.moves.append(self.board.lastmove) return ret def castle(self, *args): self.history.append(self.board.as_fen_str()) self.board.castle(*args) def promote(self, *args): self.history.append(self.board.as_fen_str()) self.board.promote(*args) def clone(self): fen = self.board.as_fen_str() history = self.history cfg = self.board.cfg data = self.board.data sdata = self.data moves = self.moves #clone = ChessGame(self.player1, self.player2, Board(self.player1, self.player2, fen)) clone = ChessGame(Board(self.board.players, fen)) clone.history = history clone.board.cfg = cfg clone.board.data = data clone.data = sdata clone.moves = moves return clone def rollback(self): fen = self.history[-1] data = self.board.data cfg = self.board.cfg #self.player1 = self.board.player1 #self.player2 = self.board.player2 #self.board = Board(self.player1, self.player2, fen) self.board = Board(self.players, fen) self.board.data = data self.board.cfg = cfg def scene_gui(self): """Spawn a scene-based GUI for the game. **Only works in Pythonista, on other platforms prints an error message.""" try: import scene from Phantom.gui_pythonista.game_view import GameView self.gui = GameView(self) except ImportError as e: print(e) #sys.exit('Pythonista scene module not found!') def sk_gui(self): """Spawn a sk-based GUI for the game. **Only works in Pythonista v1.6+, on other platforms prints an error message.""" try: import sk # only available in Pythonista from Phantom.sk_gui.SkChessView import SkChessView self.gui = SkChessView(self) except ImportError as e: print(e) #sys.exit('Pythonista sk module not found!') @call_trace(3) def is_won(self): """Tell if the game is won. Returns one of [False, 'white', 'black'].""" kings = self.board.get_piece_list(ptype='king') if len(kings) == 1: return kings[0].color # the last king left standing wins for king in kings: if not king.all_valid_moves and king.threatened_by: return C.opposite_color(king.color) # checkmate! return False
def boardcopy(self): newboard = Board(fen=self.board.fen_str()) newboard.set_game(self.board.game) return newboard
def variate(self, *args): ret = Board(fen=self.board.fen_str()) ret.set_game(self.board.game) ret.move(*args) return ret
class ChessGame (PhantomObj): def __init__(self, *args, **kwargs): self.board = Board() self.player1 = self.board.player1 self.player2 = self.board.player2 if len(args) > 0: if isinstance(args[0], str): # assume name of a game and load it self.board = _loadboard(args[0]) for arg in args: if isinstance(arg, Board): self.board = arg if isinstance(arg, Player): self.player1 = arg self.player2 = args[args.index(arg)+1] del args[args.index(arg)+1] self.board.player1 = self.player1 self.board.player2 = self.player2 self.player1.board = self.board self.player2.board = self.board self.board.set_game(self) self.history = [] self.moves = [] self._uuid = self.board._uuid self.data = Namespace() def __repr__(self): return self.board._pprnt() def __hash__(self): return int(self._uuid) % (self.board.__hash__() + 1) def move(self, *args): self.history.append(self.board.fen_str()) ret = self.board.move(*args) self.moves.append(self.board.lastmove) return ret def castle(self, *args): self.history.append(self.board.fen_str()) self.board.castle(*args) def promote(self, *args): self.history.append(self.board.fen_str()) self.board.promote(*args) def clone(self): fen = self.board.fen_str() history = self.history cfg = self.board.cfg data = self.board.data sdata = self.data moves = self.moves clone = ChessGame(self.player1, self.player2, Board(self.player1, self.player2, fen)) clone.history = history clone.board.cfg = cfg clone.board.data = data clone.data = sdata clone.moves = moves return clone def rollback(self): fen = self.history[-1] data = self.board.data cfg = self.board.cfg self.player1 = self.board.player1 self.player2 = self.board.player2 self.board = Board(self.player1, self.player2, fen) self.board.data = data self.board.cfg = cfg def ai_easy(self): from Phantom.ai.movers.basic import make_random_move return make_random_move(self.board) def ai_hard(self): from Phantom.ai.movers.advanced import make_smart_move return make_smart_move(self.board) def gui(self): """Spawn a GUI for the game. **Only works in Pythonista, on other platforms does nothing.""" from Phantom.constants import in_pythonista if in_pythonista: from Phantom.gui_pythonista.main_scene import MultiScene from Phantom.gui_pythonista.screen_main import ChessMainScreen from Phantom.gui_pythonista.screen_loading import ChessLoadingScreen from Phantom.gui_pythonista.screen_options import ChessOptionsScreen from Phantom.gui_pythonista.screen_promote import ChessPromoteScreen self.data['screen_main'] = ChessMainScreen(self) self.data['screen_load'] = ChessLoadingScreen() self.data['screen_options'] = ChessOptionsScreen(self) self.data['screen_promote'] = ChessPromoteScreen(self) self.data['main_scene'] = MultiScene(self.data['screen_load']) self.data['screen_main'].set_parent(self.data['main_scene']) self.data['screen_load'].set_parent(self.data['main_scene']) self.data['screen_options'].set_parent(self.data['main_scene']) self.data['screen_promote'].set_parent(self.data['main_scene']) self.data['main_scene'].switch_scene(self.data['screen_load']) import scene scene.run(self.data['main_scene']) @call_trace(3) def is_won(self): """Tell if the game is won. Returns one of [False, 'white', 'black'].""" if self.board.player1.kings <= 0: ret = 'black' elif self.board.player2.kings <= 0: ret = 'white' else: ret = False kings = [p for p in self.board.pieces if p.ptype == 'king'] if len(kings) == 1: # at this point we don't need to do checkmate/stalemate tests, because # one side has already lost a king so the game is over return ret else: white_king = [k for k in kings if k.color == 'white'][0] black_king = [k for k in kings if k.color == 'black'][0] if self.board.turn == 'white': if len(white_king.valid()) == 0 and white_king.threatened_by(): ret = 'black' elif self.board.turn == 'black': if len(black_king.valid()) == 0 and black_king.threatened_by(): ret = 'white' return ret
class ChessGame (PhantomObj): def __init__(self, fen_str=None): self.board = Board(self, fen_str) self._uuid = self.board._uuid self.data = dict() self.history = [] self.moves = [] #try: # autostart the gui? # import sk # self.sk_gui() #except ImportError: # pass def __repr__(self): return self.board._pprnt() def __hash__(self): return int(self._uuid) % (self.board.__hash__() + 1) @property def ai_rateing(self): from Phantom.ai.pos_eval.advanced import pos_eval_advanced return pos_eval_advanced(self.board) def ai_easy(self): from Phantom.ai.movers.basic import make_random_move return make_random_move(self.board) def ai_hard(self): from Phantom.ai.movers.advanced import make_smart_move return make_smart_move(self.board) def move(self, *args): save_fen_str = self.board.as_fen_str() ret = self.board.move(*args) if ret: self.history.append(save_fen_str) self.moves.append(self.board.lastmove) return ret def castle(self, *args): self.history.append(self.board.as_fen_str()) self.board.castle(*args) def promote(self, *args): self.history.append(self.board.as_fen_str()) self.board.promote(*args) def clone(self): fen = self.board.as_fen_str() history = self.history cfg = self.board.cfg data = self.board.data sdata = self.data moves = self.moves #clone = ChessGame(self.player1, self.player2, Board(self.player1, self.player2, fen)) clone = ChessGame(Board(self.board.players, fen)) clone.history = history clone.board.cfg = cfg clone.board.data = data clone.data = sdata clone.moves = moves return clone def rollback(self): fen = self.history[-1] data = self.board.data cfg = self.board.cfg #self.player1 = self.board.player1 #self.player2 = self.board.player2 #self.board = Board(self.player1, self.player2, fen) self.board = Board(self.players, fen) self.board.data = data self.board.cfg = cfg def scene_gui(self): """Spawn a scene-based GUI for the game. **Only works in Pythonista, on other platforms prints an error message.""" try: import scene from Phantom.gui_pythonista.game_view import GameView self.gui = GameView(self) except ImportError as e: print(e) #sys.exit('Pythonista scene module not found!') def sk_gui(self): """Spawn a sk-based GUI for the game. **Only works in Pythonista v1.6+, on other platforms prints an error message.""" try: import sk # only available in Pythonista from Phantom.sk_gui.SkChessView import SkChessView self.gui = SkChessView(self) except ImportError as e: print(e) #sys.exit('Pythonista sk module not found!') @call_trace(3) def is_won(self): """Tell if the game is won. Returns one of [False, 'white', 'black'].""" kings = self.board.get_piece_list(ptype='king') if len(kings) == 1: return kings[0].color # the last king left standing wins for king in kings: if not king.all_valid_moves and king.threatened_by: return C.opposite_color(king.color) # checkmate! return False