Example #1
0
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
Example #2
0
 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
Example #3
0
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)
Example #4
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()
Example #5
0
 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
Example #6
0
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
Example #7
0
 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
Example #8
0
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()
Example #9
0
 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
Example #10
0
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()
Example #11
0
 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
Example #12
0
 def __init__(self, fen_str=None):
     self.board = Board(self, fen_str)
     self._uuid = self.board._uuid
     self.data = dict()
     self.history = []
     self.moves = []
Example #13
0
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
Example #14
0
 def __init__(self, fen_str=None):
     self.board = Board(self, fen_str)
     self._uuid = self.board._uuid
     self.data = dict()
     self.history = []
     self.moves = []
Example #15
0
 def boardcopy(self):
     newboard = Board(fen=self.board.fen_str())
     newboard.set_game(self.board.game)
     return newboard
Example #16
0
 def variate(self, *args):
     ret = Board(fen=self.board.fen_str())
     ret.set_game(self.board.game)
     ret.move(*args)
     return ret
Example #17
0
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
Example #18
0
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
Example #19
0
 def boardcopy(self):
     newboard = Board(fen=self.board.fen_str())
     newboard.set_game(self.board.game)
     return newboard
Example #20
0
 def variate(self, *args):
     ret = Board(fen=self.board.fen_str())
     ret.set_game(self.board.game)
     ret.move(*args)
     return ret