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
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 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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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