示例#1
0
def run_one_game(nn, randomness, depth, reg, result_counts, count, thread_num,
                 result_list, lr):
    chess = Chess()
    states = []
    while chess.is_in_progress:
        val = None
        if chess.turn_num < 3 or random.random() < randomness:
            move = random.choice(chess.legal_moves)
        else:
            move, val = chess_ai.choose_move_ab(
                chess,
                depth=depth,
                eval_fun=chess_ai.nn_eval,
                nn=nn,
                randomize=False
            )  # Consider saving val for later update (avoid redoing forward pass)
        chess.move(move)
        states.append(chess._efficient_copy())
    val = nn.predict(chess_ai.chess_to_nn_input(chess))[0]

    result = 0 if chess.winner is None else chess.winner
    # result_counts[result + 1] += 1

    total = sum(result_counts)
    # TODO reconsider this entire lr_factor approach
    # lr_factor = (total - result_counts[result + 1]) / total
    total_cost = 0
    last_cost = None
    result_ = result
    avg_dw = []
    avg_db = []
    for i, state in enumerate(reversed(states)):
        # if i > 0:
        # result_ = result_ * .95  # TODO reconsider this
        nn_input = chess_ai.chess_to_nn_input(state)
        cost, grad = nn.cost_grad(
            nn_input, result_, reg=reg
        )  # TODO reconsider weight decay (and check if it even works (it does not right now. Disabled in neural_net.py))
        if last_cost is None:
            last_cost = cost
        # lr2 = lr_factor * lr/(i+1) # TODO do this properly.
        total_cost += cost

        if not avg_dw:
            avg_dw = grad["dw"]
            avg_db = grad["db"]
        else:
            for j in range(len(avg_db)):
                avg_dw[j] += grad["dw"][j] / ((i + 1) * (i + 1))
                avg_db[j] += grad["db"][j] / ((i + 1) * (i + 1))

        if count < 200:
            break

    sum_val = np.sum(chess.board)
    avg_cost = total_cost / chess.turn_num if count >= 200 else total_cost
    print_string = ("Game " + str(count) + ", Avg Cost: " +
                    str("{:.3f}".format(avg_cost[0])) + ", Last cost: " +
                    str("{:.3f}".format(last_cost[0])) + ", Turns: " +
                    ((3 - len(str(chess.turn_num))) * " ") +
                    str(chess.turn_num) + ", Randomness: " +
                    str("{:.2f}".format(randomness)) + ", lr: " +
                    str("{:.3f}".format(lr * 1e5)) + "e5" + ", Win: " +
                    (str(result) if result < 0 else (" " + str(result))) +
                    ", Sum: " + ((2 - len(str(abs(sum_val)))) * " ") +
                    (str(sum_val) if sum_val < 0 else (" " + str(sum_val))) +
                    ", Val: " + (str("{:.4f}".format(val)) if val < 0 else
                                 (" " + str("{:.4f}".format(val)))))

    # print(print_string)
    # with open("logs/detailed_log.txt", "a") as log_file:
    #     log_file.write(print_string + "\n")

    # if result == 1:
    #     cost_file_name = "logs/win_costs.csv"
    # elif result == 0:
    #     cost_file_name = "logs/draw_costs.csv"
    # else:
    #     cost_file_name = "logs/loss_costs.csv"

    # with open(cost_file_name, "a") as cost_file:
    cost_string = (str(count) + "," + str(chess.turn_num) + "," +
                   str(total_cost[0]) + "," + str(avg_cost[0]) + "," +
                   str(last_cost[0]) + "\n")
    # cost_file.write(cost_string)

    result_list[thread_num] = (avg_db, avg_dw, result, print_string,
                               cost_string)
示例#2
0
def test_and_backup(new_nn, best_nn, count, repetitions=4, save_to_files=True):
    print("test and backup started")
    t = time.time()
    string = str(t)
    save_nn("latest", new_nn)
    save_nn(string, new_nn)
    new_wins = 0
    best_wins = 0
    draws = 0

    for i in range(repetitions):
        chess = Chess()

        newest_starting = True if i % 2 == 0 else False
        newest_in_turn = True if newest_starting else False

        while chess.is_in_progress:
            nn = new_nn if newest_in_turn else best_nn  # Set the nn used in this round
            newest_in_turn = not newest_in_turn  # change bool value of if newest nn is in turn
            if chess.turn_num < 5:  # random opening
                move = random.choice(chess.legal_moves)
            else:
                move, val = chess_ai.choose_move_ab(chess,
                                                    depth=1,
                                                    eval_fun=chess_ai.nn_eval,
                                                    nn=nn,
                                                    randomize=True)

            chess.move(move)

        if (newest_starting and chess.winner == 1) or (not newest_starting
                                                       and chess.winner == -1):
            new_wins += 1
            win_string = "New"
        elif (newest_starting
              and chess.winner == -1) or (not newest_starting
                                          and chess.winner == 1):
            best_wins += 1
            win_string = "Best"
        else:
            draws += 1
            win_string = "None"

        print("Winner: ", win_string, ", Last value: ", val)

    print("New wins:", new_wins, ", Best wins:", best_wins, ", Draws:", draws)

    new_wins_sum = 0
    sum_wins = 0
    draws = 0

    for i in range(repetitions):
        chess = Chess()
        newest_starting = True if i % 2 == 0 else False
        newest_in_turn = True if newest_starting else False

        while chess.is_in_progress:
            if chess.turn_num < 5:  #Random opening
                move = random.choice(chess.legal_moves)
            else:
                if newest_in_turn:
                    move, val = chess_ai.choose_move_ab(
                        chess,
                        depth=1,
                        eval_fun=chess_ai.nn_eval,
                        nn=nn,
                        randomize=True)  # TODO increase depth?
                else:
                    move, val = chess_ai.choose_move_ab(chess,
                                                        depth=1,
                                                        randomize=True)

            newest_in_turn = not newest_in_turn
            chess.move(move)

        if (newest_starting and chess.winner == 1) or (not newest_starting
                                                       and chess.winner == -1):
            new_wins_sum += 1
            win_string = "New"
        elif (newest_starting
              and chess.winner == -1) or (not newest_starting
                                          and chess.winner == 1):
            sum_wins += 1
            win_string = "Sum"
        else:
            draws += 1
            win_string = "None"

        print("Winner: ", win_string, ", Last value: ", val)

    print("New wins:", new_wins_sum, ", Sum wins:", sum_wins, ", Draws:",
          draws)

    if save_to_files:
        with open("logs/log.txt", "a") as log_file:
            log_file.write("\n")
            log_file.write("Time: " + str(time.time()) + ", Count: " +
                           str(count) + ", Repetitions: " + str(repetitions))
            log_file.write("\nNew Wins: " + str(new_wins) + ", Best Wins: " +
                           str(best_wins))
            log_file.write("\nNew Wins: " + str(new_wins_sum) +
                           ", Sum Wins: " + str(sum_wins))
            log_file.write("\n")

    # print("new wins: ", new_wins, ", best wins: ", best_wins)
    # print("new wins: ", new_wins_sum, ", sum wins: ", sum_wins)
    if new_wins > best_wins:
        save_nn("best", new_nn)
        return new_nn
    else:
        return copy.deepcopy(best_nn)
示例#3
0
文件: gui.py 项目: willGuimont/chess
class Game(pyglet.window.Window):
    WHITE_PIECE_COLOR = (255, 255, 255, 255)
    BLACK_PIECE_COLOR = (0, 0, 0, 255)
    WHITE_TILE_COLOR = (0, 1, 0, 1)
    BLACK_TILE_COLOR = (1, 0, 0, 1)

    TILE_SIZE = 52
    PIECE_SIZE = 40

    def __init__(self):
        super().__init__(width=640, height=600, caption='Chess')
        self.__chess = Chess()
        self.__ui = UIBoard((self.__chess.BOARD_SIZE, self.__chess.BOARD_SIZE),
                            self.WHITE_PIECE_COLOR, self.BLACK_PIECE_COLOR,
                            self.WHITE_TILE_COLOR, self.BLACK_TILE_COLOR,
                            self.TILE_SIZE, self.PIECE_SIZE, self.width,
                            self.height)

        self.__selected_piece = Maybe.nothing()
        self.__winner = None

    def on_draw(self):
        self.clear()
        self.__ui.draw_board(self.__chess)
        if self.__selected_piece.is_just():
            try:
                p = self.__selected_piece.get()
                possible_captures = self.__chess.get_possible_captures_for(p)
                possible_moves = self.__chess.get_possible_moves_for(p)
                self.__ui.draw_captures(p, possible_captures)
                self.__ui.draw_moves(p, possible_moves)
                self.__ui.draw_selected_piece(p)
            except Exception as e:
                print(e)
                print(traceback.print_exc())
        if self.__winner is not None:
            winner = 'White' if self.__winner == Piece.Color.WHITE else 'Black'
            label = pyglet.text.Label(f'Winner: {winner}',
                                      font_size=32,
                                      color=(255, 255, 255, 255),
                                      x=self.width / 2,
                                      y=50,
                                      anchor_x='center',
                                      anchor_y='center')
            label.draw()

    def on_mouse_press(self, x: int, y: int, button: int, modifiers: int):
        if self.__winner is not None:
            return
        i, j = self.__ui.get_cell_index_from_mouse_position(x, y)
        if 0 <= i < self.__chess.BOARD_SIZE and 0 <= j < self.__chess.BOARD_SIZE:
            if self.__selected_piece.is_nothing():
                maybe_piece = self.__chess.get_maybe_piece_at((i, j))
                if maybe_piece.is_just():
                    p = maybe_piece.get()
                    if p.get_color() == self.__chess.get_player_color():
                        self.__selected_piece = maybe_piece
            else:
                pos = (i, j)
                if pos == self.__selected_piece.get().get_position():
                    self.__selected_piece = Maybe.nothing()
                else:
                    p = self.__selected_piece.get()
                    possible_captures = self.__chess.get_possible_captures_for(
                        p)
                    possible_moves = self.__chess.get_possible_moves_for(p)
                    if pos in possible_captures:
                        self.__chess.capture(p, pos)
                        self.__selected_piece = Maybe.nothing()
                    elif pos in possible_moves:
                        self.__chess.move(p, pos)
                        self.__selected_piece = Maybe.nothing()
        self.__winner = self.__chess.get_winner()