def __init__(self, weights, horizon, weights_bis=None,verbose=False):
     '''
     Constructor
         
     ARGS:
         @param weights: Weights for board Static-Evaluation-Function.
         @param horizon: Max level for the search algorithm. 
         @param weights_bis: Weights for the dark-side AI. 
     '''
     self.weights = weights
     self.horizon = horizon
     
     self.move = 0
     self.board = DBoard()
     self.turn = 'LIGHT'
     
     self.gameover = False
     self.winner = None
     self.nocapturecounter = 0 # Move without a capture.
     
     self.verbose = verbose
     
     if weights_bis == None :
         self.weights_bis = self.weights
     else :
         self.weights_bis = weights_bis            
 def reset(self):
     '''
     Reset this brain.
     
     @deprecated: This method can be deleted in future releases.
     '''
     self.move = 0
     self.board = DBoard()
     self.turn = 'LIGHT'
     self.gameover = False
     self.nocapturecounter = 0
Example #3
0
class TestDPiece(unittest.TestCase):
    
    def setUp(self):
        self.board = DBoard()
        self.piece = self.board.get_piece(0, 1)
        
    def tearDown(self):
        del self.piece
        del self.board

    def testPromotion(self):
        '''Check for piece promotion.'''
        self.piece.promote()
        self.assert_(self.piece.is_king, "Piece DO NOT PROMOTE!")
        
    def testDemotion(self):
        '''Check for piece demotion.'''
        self.piece.promote()
        self.piece.demote()
        self.assert_(not self.piece.is_king, "Piece DO NOT DEMOTE!")
        
    def testGetFeatures(self):
        '''Check for piece features.'''
        self.assert_(not self.piece.is_king, "Piece Must Not Be King.")
        flist = self.piece.get_features()
        print(flist)
        self.assert_('BACK' in  flist, "BACK is not in list!")
        self.assert_('PIECE' in  flist, "PIECE is not in list!")
        self.piece.promote()
        flist = self.piece.get_features()
        self.assert_(self.piece.is_king, "Piece Must Be King.")
        self.assert_('KBACK' in  flist, "KBACK is not in list!")
        self.assert_('KING' in  flist, "KING is not in list!")
    
    def testMove(self):
        '''Test Move. It's not a legal move but don't matter.'''
        target_pos = (5, 6)
        self.piece.move(5, 6)
        self.assertEqual(self.piece.position, target_pos)
        self.assert_(self.board.is_free(0, 1))
        self.assertEqual(self.piece, self.board.get_piece(5, 6))
    
    def testCaptured(self):
        '''Check the piece capture.'''
        self.piece.captured()
        self.assert_(self.board.is_free(0, 1))
        
    def testActionPromotion(self):
        '''Check promotion action.'''
        action = DAction('MOVE', (0, 1), (9, 1), promote=True)
        self.board.apply_action(action)
        self.assert_(self.piece.is_king)
        
    def testPossibleAction(self):
        '''Check if possible_action find all possible actions.'''
        action = self.piece.possible_action()
        self.assertEqual(len(action), 0, "Action list should be empty.")
Example #4
0
class TestDPiece(unittest.TestCase):
    def setUp(self):
        self.board = DBoard()
        self.piece = self.board.get_piece(0, 1)

    def tearDown(self):
        del self.piece
        del self.board

    def testPromotion(self):
        '''Check for piece promotion.'''
        self.piece.promote()
        self.assert_(self.piece.is_king, "Piece DO NOT PROMOTE!")

    def testDemotion(self):
        '''Check for piece demotion.'''
        self.piece.promote()
        self.piece.demote()
        self.assert_(not self.piece.is_king, "Piece DO NOT DEMOTE!")

    def testGetFeatures(self):
        '''Check for piece features.'''
        self.assert_(not self.piece.is_king, "Piece Must Not Be King.")
        flist = self.piece.get_features()
        print(flist)
        self.assert_('BACK' in flist, "BACK is not in list!")
        self.assert_('PIECE' in flist, "PIECE is not in list!")
        self.piece.promote()
        flist = self.piece.get_features()
        self.assert_(self.piece.is_king, "Piece Must Be King.")
        self.assert_('KBACK' in flist, "KBACK is not in list!")
        self.assert_('KING' in flist, "KING is not in list!")

    def testMove(self):
        '''Test Move. It's not a legal move but don't matter.'''
        target_pos = (5, 6)
        self.piece.move(5, 6)
        self.assertEqual(self.piece.position, target_pos)
        self.assert_(self.board.is_free(0, 1))
        self.assertEqual(self.piece, self.board.get_piece(5, 6))

    def testCaptured(self):
        '''Check the piece capture.'''
        self.piece.captured()
        self.assert_(self.board.is_free(0, 1))

    def testActionPromotion(self):
        '''Check promotion action.'''
        action = DAction('MOVE', (0, 1), (9, 1), promote=True)
        self.board.apply_action(action)
        self.assert_(self.piece.is_king)

    def testPossibleAction(self):
        '''Check if possible_action find all possible actions.'''
        action = self.piece.possible_action()
        self.assertEqual(len(action), 0, "Action list should be empty.")
Example #5
0
 def setUp(self):
     self.board = DBoard()
     self.piece = self.board.get_piece(0, 1)
class DraughtsBrain(object):
    '''
    Class AI for Draughts.
    
    Use Min-Max with Alpha-Beta Prune.
    '''

    def __init__(self, weights, horizon, weights_bis=None,verbose=False):
        '''
        Constructor
            
        ARGS:
            @param weights: Weights for board Static-Evaluation-Function.
            @param horizon: Max level for the search algorithm. 
            @param weights_bis: Weights for the dark-side AI. 
        '''
        self.weights = weights
        self.horizon = horizon
        
        self.move = 0
        self.board = DBoard()
        self.turn = 'LIGHT'
        
        self.gameover = False
        self.winner = None
        self.nocapturecounter = 0 # Move without a capture.
        
        self.verbose = verbose
        
        if weights_bis == None :
            self.weights_bis = self.weights
        else :
            self.weights_bis = weights_bis            
    
    def reset(self):
        '''
        Reset this brain.
        
        @deprecated: This method can be deleted in future releases.
        '''
        self.move = 0
        self.board = DBoard()
        self.turn = 'LIGHT'
        self.gameover = False
        self.nocapturecounter = 0
    
    def switch_turn(self):
        '''
        Switch current in-game player.
        '''
        if self.turn == 'LIGHT' :
            self.turn = 'DARK'
        else :
            self.turn = 'LIGHT'
    
    def _switch_player(self, player):
        '''
        Switch player tag.
        
        ARGS:
            @param player: Current player.
        
        RETURN:
            @return: Next Player.
        '''
        if player == 'LIGHT' :
            return 'DARK'
        else :
            return 'LIGHT'
               
    def run_self(self):
        '''
        Execute "selfish" AI vs. AI match.
        '''
        self.gameover = False
        while not self.gameover and self.nocapturecounter < 50 :
            bestmove = self.best_move()
            if not bestmove :
                self.winner = self._switch_player(self.turn) # No valid move!
                break
            self.apply_action(bestmove)
            if self.verbose : 
                print(self.board)
                print(self.board.board_score(self.weights))
        if not self.gameover : # So, too-much noncapture.
            self.winner = 'DRAW'
        return self.winner
                
    def apply_action(self, action):
        '''
        Apply an action to board.
        
        ARGS:
            @param action: Action that it's going to be executed.
        '''
        self.board.apply_action(action)
        self.move += 1
        if len(self.board.light_pieces) == 0 :
            self.gameover = True
            self.winner = 'DARK'
        elif len(self.board.dark_pieces) == 0 :
            self.gameover = True
            self.winner = 'LIGHT'
        else :
            self.switch_turn()
            if action.type != 'CAPTURE' :
                self.nocapturecounter += 1
            else :
                self.nocapturecounter = 0        
                
    ########
    ## AI ##
    ########
    
    def best_move(self):
        '''
        Find the next best move according current player state.
        
        This method use the Min-Max algorithm wit Alpha-Beta pruning system
        to minimize the number of explored nodes.
        
        RETURN:
            @return: One of the best move.
        '''
        if len(self.board.all_move(self.turn)) == 0 :
            self.gameover = True
            self.winner = self._switch_player(self.turn)
            return None
            
        self.path = []
        if self.turn == 'LIGHT' :
            value = self.alphabeta(-float('inf'), float('inf'), self.horizon, self.turn, self.weights)
        else :
            value = self.alphabeta(-float('inf'), float('inf'), self.horizon, self.turn, self.weights_bis)
        
        bestmoves = []
        
        for element in self.path :
            if element[1] == value : # Find path with value equal to best-value.
                bestmoves.append(element[0])
        else :
            if len(bestmoves) == 0 and len(self.path) != 0 : # If path is not empty return first value.
                print("Woops!")
                return self.path[0][0] # WARNING: This code should never be executed.
        
        selected_move = random.choice(bestmoves) # Select randomly a move among the best ones.
        return selected_move
                
    def alphabeta(self, alpha, beta, level, player, weights):
        '''
        THE GLORIOUS ALPHA-BETA ALGORITHM. GLORIFY HIM.
        
        ARGS:
            @param aplha: Current Alpha Value.
            @param beta: Current Beta Value.
            @param level: Current Level.
            @param player: Current Player.
            @param weights: Set of weights to use. TODO: Can remove this?
        
        RETURN    
        '''
        if level == 0 :
            value = self.board.board_score(weights)
            self.path.append((self.board.movelist[self.move], value))
            return value
        if player == 'LIGHT' :
            moves = self.board.all_move(player)
            v = -float('inf')
            for mov in moves :
                self.board.apply_action(mov)
                v = max(v, self.alphabeta(alpha, beta, level - 1, self._switch_player(player), weights))
                self.board.undo_last()
                if beta <= v :
                    return v
                alpha = max(alpha, v)
            if len(moves) == 0 :
                self.path.append((self.board.movelist[self.move], v))
            return v
        else :
            moves = self.board.all_move(player);
            v = float('inf')
            for mov in moves :
                self.board.apply_action(mov)
                v = min(v, self.alphabeta(alpha, beta, level - 1, self._switch_player(player), weights))
                self.board.undo_last()
                if v <= alpha :
                    return v
                beta = min(beta, v)
            if len(moves) == 0 :
                self.path.append((self.board.movelist[self.move], v))
            return v
Example #7
0
 def setUp(self):
     self.board = DBoard()
Example #8
0
class TestDBoard(unittest.TestCase):


    def setUp(self):
        self.board = DBoard()

    def tearDown(self):
        del self.board

    def testSetBitMap(self):
        '''Check correct behavior of set_bitmap method.'''
        self.board.set_bitmap(0, 1, 'DUMMY')
        self.assertEqual(self.board.get_piece(0, 1), 'DUMMY', "DUMMY Isn't where it should...")

    def testIsFree(self):
        '''Check if is_free recognizes free squares as free squares.'''
        self.assert_(self.board.is_free(4, 1))
        self.assert_(not self.board.is_free(0, 1))
        
    def testGetPiece(self):
        '''Check if get_piece returns right piece.'''
        self.board.set_bitmap(0, 1, 'DUMMY')
        self.board.set_bitmap(4, 3, 'DUMMY')
        self.assertEqual(self.board.get_piece(0, 1), 'DUMMY', "DUMMY Isn't where it should...")
        self.assertEqual(self.board.get_piece(4, 3), 'DUMMY', "DUMMY Isn't where it should...")
        
    def testApply(self):
        '''Check if apply_action applies action in a correct way.'''
        piece = self.board.get_piece(0, 1)
        action = DAction('MOVE', (0, 1), (4, 1))
        self.board.apply_action(action)
        self.assertEqual(self.board.get_piece(4, 1), piece, "Wrong Move Effect.")
Example #9
0
 def setUp(self):
     self.board = DBoard()
     self.piece = self.board.get_piece(0, 1)