예제 #1
0
def generate_moves(board: Board, color: str, dice: Dice, verbose=False):
    root = MoveNode(color + " " + str(dice), board_after=board, deep=0)
    get_moves(color, dice.getDistances(), board.farthestBack(color), root)

    min_die = min(dice.getDice())
    max_die = max(dice.getDice())
    depth = 0
    used_dict = {min_die: set(), max_die: set()}
    moves_dict = {}
    for move in PreOrderIter(root):
        deep = move.deep
        if deep > depth:
            depth = deep

        if deep not in moves_dict:
            moves_dict[deep] = {move}
        else:
            moves_dict[deep].add(move)

        if depth == 1:
            used_dict[move.die].add(move)

    if depth == 1 and used_dict[min_die] and used_dict[max_die]:
        moves = used_dict[max_die]
    else:
        moves = moves_dict[depth]

    if verbose:
        print(board)
        print(dice)
        print(moves)

    return moves
예제 #2
0
 def __init__(self, player1, player2):
     if not {player1.color, player2.color} == {WHITE, BLACK}:
         raise Exception("Must have one player of each color")
     self.players = [player1, player2]
     self.board = Board()
     self.dice = Dice()
     self.on_roll = 0  # starting player 1
예제 #3
0
    def test_4(self):
        b = Board()
        b.pointsContent = [0] * 26
        b.pointsContent[1] = -1
        b.pointsContent[2] = 2
        b.pointsContent[4] = 1
        b.pointsContent[5] = 1
        b.pointsContent[6] = 3
        b.pointsContent[8] = 1
        b.pointsContent[12] = -5
        b.pointsContent[13] = 5
        b.pointsContent[17] = -2
        b.pointsContent[19] = -4
        b.pointsContent[20] = -1
        b.pointsContent[22] = -1
        b.pointsContent[24] = 2
        b.whiteCheckers = {1, 12, 17, 19, 20, 22}
        b.blackCheckers = {24, 13, 8, 6, 5, 4, 2}
        b.whiteCheckersTaken = 1
        b.blackCheckersTaken = 0

        d = Dice(4, 2)
        m = generate_moves(b, "WHITE", d)
        print(b)
        print(m)

        self.assertEqual(len(m), 5)
예제 #4
0
    def test_0(self):
        b = Board()
        b.pointsContent = [0] * 26
        b.pointsContent[1] = -3
        b.pointsContent[2] = 6
        b.pointsContent[3] = 4
        b.pointsContent[6] = 2
        b.pointsContent[4] = 1
        b.pointsContent[13] = -1
        b.pointsContent[19] = -4
        b.pointsContent[20] = 2
        b.pointsContent[22] = -1
        b.pointsContent[23] = -4
        b.pointsContent[24] = -2

        b.whiteCheckers = {1, 13, 19, 22, 23, 24}
        b.blackCheckers = {2, 3, 4, 6, 20}
        b.blackCheckersTaken = 0
        b.whiteCheckersTaken = 0

        d = Dice(4, 1)

        print(b)
        current = MoveNode("start", board_after=b, deep=0)
        ab = alpha_beta(current, 2, "BLACK", dice=d)
        mm = expectiminimax(current, 2, "BLACK", dice=d)
        print(ab)
        print(mm)
예제 #5
0
    def test_12(self):
        b = Board()
        b.pointsContent = [0] * 26
        b.pointsContent[2] = 5
        b.pointsContent[3] = -1
        b.pointsContent[4] = 1
        b.pointsContent[5] = 1
        b.pointsContent[6] = 3
        b.pointsContent[13] = 1
        b.pointsContent[16] = -2
        b.pointsContent[18] = -2
        b.pointsContent[19] = -3
        b.pointsContent[20] = -2
        b.pointsContent[21] = -2
        b.pointsContent[22] = -2
        b.pointsContent[23] = -1
        b.pointsContent[24] = 3
        b.whiteCheckers = {3, 16, 18, 19, 20, 21, 22, 23}
        b.blackCheckers = {24, 13, 6, 5, 4, 2}
        b.whiteCheckersTaken = 0
        b.blackCheckersTaken = 1

        d = Dice(4, 1)
        m = generate_moves(b, "BLACK", d)
        print(b)
        print(m)

        self.assertEqual(len(m), 3)
예제 #6
0
    def test_9(self):
        b = Board()
        b.pointsContent = [0] * 26
        b.pointsContent[1] = -2
        b.pointsContent[6] = 5
        b.pointsContent[7] = 3
        b.pointsContent[8] = 4
        b.pointsContent[12] = -4
        b.pointsContent[13] = -1
        b.pointsContent[18] = 2
        b.pointsContent[19] = -3
        b.pointsContent[21] = -2
        b.pointsContent[23] = -2
        b.pointsContent[24] = -1

        b.whiteCheckers = {1, 12, 13, 19, 21, 23, 24}
        b.blackCheckers = {6, 7, 8, 18}
        b.whiteCheckersTaken = 0
        b.blackCheckersTaken = 1

        d = Dice(4, 1)
        m = generate_moves(b, "BLACK", d)
        print(b)
        print(m)

        self.assertEqual(len(m), 5)
예제 #7
0
    def test_0(self):
        b = Board()
        d = Dice(5, 1)
        m = generate_moves(b, "BLACK", d)

        print(b)
        print(m)
        self.assertEqual(len(m), 8)
예제 #8
0
def get_board_children(board, color, dice=None):
    if not dice:
        children = {}
        for roll in probability:
            moves = generate_moves(board, color, Dice(roll[0], roll[1]))
            children[roll] = moves
        return children
    else:
        return generate_moves(board, color, dice)
예제 #9
0
    def test_1(self):
        b = Board()
        b.pointsContent = [0] * 26
        b.pointsContent[1] = -2
        b.pointsContent[12] = -5
        b.pointsContent[17] = -3
        b.pointsContent[19] = -5
        b.pointsContent[2] = 14
        b.pointsContent[7] = 1
        b.whiteCheckers = {1, 12, 17, 19}
        b.blackCheckers = {2, 7}
        b.blackCheckersTaken = 0
        b.whiteCheckersTaken = 0

        d = Dice(5, 1)
        m = generate_moves(b, "BLACK", d)

        self.assertEqual(len(m), 1)
예제 #10
0
    def test_8(self):
        b = Board()
        b.pointsContent = [0] * 26
        b.pointsContent[7] = -2
        b.pointsContent[12] = -5
        b.pointsContent[17] = -3
        b.pointsContent[19] = -5
        b.pointsContent[8] = 1
        b.pointsContent[3] = 3
        b.pointsContent[1] = 10
        b.pointsContent[0] = 1
        b.whiteCheckers = {7, 12, 17, 19}
        b.blackCheckers = {8, 3, 1}
        b.blackCheckersTaken = 0
        b.whiteCheckersTaken = 0

        d = Dice(2, 2)
        m = generate_moves(b, "BLACK", d)
        print(b)
        print(m)

        self.assertEqual(len(m), 4)
예제 #11
0
    def test_5(self):
        b = Board()
        b.pointsContent = [0] * 26
        b.pointsContent[1] = -2
        b.pointsContent[12] = -5
        b.pointsContent[17] = -3
        b.pointsContent[19] = -5
        b.pointsContent[24] = 2
        b.pointsContent[13] = 5
        b.pointsContent[4] = 3
        b.pointsContent[6] = 5
        b.whiteCheckers = {12, 17, 19}
        b.blackCheckers = {24, 13, 6, 4}
        b.whiteCheckersTaken = 2
        b.blackCheckersTaken = 0

        d = Dice(4, 6)
        m = generate_moves(b, "WHITE", d)
        print(b)
        print(m)

        self.assertEqual(len(m), 1)
예제 #12
0
    def test_10(self):
        b = Board()
        b.pointsContent = [0] * 26
        b.pointsContent[1] = -1
        b.pointsContent[2] = 1
        b.pointsContent[4] = 1
        b.pointsContent[5] = 2
        b.pointsContent[6] = 3
        b.pointsContent[8] = 1
        b.pointsContent[13] = 5
        b.pointsContent[21] = -13
        b.pointsContent[24] = 2
        b.whiteCheckers = {1, 21}
        b.blackCheckers = {24, 13, 8, 6, 5, 4, 2}
        b.whiteCheckersTaken = 1
        b.blackCheckersTaken = 0

        d = Dice(4, 2)
        m = generate_moves(b, "WHITE", d)
        print(b)
        print(m)

        self.assertEqual(len(m), 2)
예제 #13
0
class Backgammon:
    def __init__(self, player1, player2):
        if not {player1.color, player2.color} == {WHITE, BLACK}:
            raise Exception("Must have one player of each color")
        self.players = [player1, player2]
        self.board = Board()
        self.dice = Dice()
        self.on_roll = 0  # starting player 1

    def reset(self):
        self.board = Board()
        self.on_roll = 0

    def do_move(self, move):
        self.board.applyBoard(move.board_after)
        self.dice.roll()
        self.on_roll = (self.on_roll + 1) % 2

    def get_current_player(self):
        return self.players[self.on_roll]

    def start_game(self, verbose=False):
        player1_roll, player2_roll = 0, 0
        while player1_roll == player2_roll:
            player1_roll = random.randint(1, 6)
            player2_roll = random.randint(1, 6)
            if verbose:
                print(self.players[0], "rolls",
                      str(player1_roll) + ",", self.players[1], "rolls",
                      str(player2_roll) + ".")
        self.on_roll = 0 if player1_roll > player2_roll else 1
        self.dice.setRoll((player1_roll, player2_roll))

    def run(self, verbose=False):
        self.start_game(verbose=verbose)
        if verbose:
            print(self.board)
            print(str(self.players[self.on_roll]) + " goes first.")
        while True:
            if verbose:
                print("")
                print(
                    str(self.players[self.on_roll]) + " rolled " +
                    str(self.dice))
            move = self.players[self.on_roll].get_move(self)
            self.do_move(move)
            if verbose:
                print(self.board)
                print(move)
            winner, value = self.board.getWinner(game_value=True)
            if winner != NONE:
                if self.players[0].color == winner:
                    self.players[0].won(self.board, value)
                    self.players[1].lost(self.board, value)
                else:
                    self.players[0].lost(self.board, value)
                    self.players[1].won(self.board, value)
                if verbose:
                    print("Winner, " + winner)
                return winner, value
            ##################################################
            if verbose:
                print("")
                print(
                    str(self.players[self.on_roll]) + " rolled " +
                    str(self.dice))
            move = self.players[self.on_roll].get_move(self)
            self.do_move(move)
            if verbose:
                print(self.board)
                print(move)
            winner, value = self.board.getWinner(game_value=True)
            if winner != NONE:
                if self.players[0].color == winner:
                    self.players[0].won(self.board, value)
                    self.players[1].lost(self.board, value)
                else:
                    self.players[0].lost(self.board, value)
                    self.players[1].won(self.board, value)
                if verbose:
                    print("Winner, " + winner)
                return winner, value

    @staticmethod
    def train(network, iters, start_trial=0, verbose=False):
        p1, p2 = NeuralNetPlayer(BLACK, network,
                                 learning=True), NeuralNetPlayer(WHITE,
                                                                 network,
                                                                 learning=True)
        backgammon = Backgammon(p1, p2)
        for i in range(1, iters + 1):
            winner, _ = backgammon.run()
            backgammon.reset()
            print("\rGame", i + start_trial, "finished", end="")
            if i % 1000 == 0:
                p1.network.save()
                p1.network.save_to_text(str(i + start_trial) + ".txt")
                p1.learning = False
                print("After", i + start_trial, "rounds of training:")
                Backgammon.benchmark(p1, TatePlayer(WHITE), 15)
                p1.learning = True

    @staticmethod
    def benchmark(player1, player2, num_games):
        scores = {BLACK: 0, WHITE: 0}
        wins = {BLACK: 0, WHITE: 0}
        back = Backgammon(player1, player2)
        for i in range(num_games):
            winner, value = back.run(verbose=False)
            print("\rGame",
                  str(i + 1) + ":",
                  winner,
                  "wins a",
                  value,
                  "game",
                  end="")
            scores[winner] += value
            wins[winner] += 1
            back.reset()
        print(scores)
        print(wins)
        return scores