ChessEngine.cpp 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. /*
  2. * Copyright (c) 2020, the SerenityOS developers.
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include "ChessEngine.h"
  7. #include "MCTSTree.h"
  8. #include <AK/Debug.h>
  9. #include <AK/Random.h>
  10. #include <LibCore/ElapsedTimer.h>
  11. using namespace Chess::UCI;
  12. void ChessEngine::handle_uci()
  13. {
  14. send_command(IdCommand(IdCommand::Type::Name, "ChessEngine"));
  15. send_command(IdCommand(IdCommand::Type::Author, "the SerenityOS developers"));
  16. send_command(UCIOkCommand());
  17. }
  18. void ChessEngine::handle_position(const PositionCommand& command)
  19. {
  20. // FIXME: Implement fen board position.
  21. VERIFY(!command.fen().has_value());
  22. m_board = Chess::Board();
  23. for (auto& move : command.moves()) {
  24. VERIFY(m_board.apply_move(move));
  25. }
  26. }
  27. void ChessEngine::handle_go(const GoCommand& command)
  28. {
  29. // FIXME: A better algorithm than naive mcts.
  30. // FIXME: Add different ways to terminate search.
  31. VERIFY(command.movetime.has_value());
  32. srand(get_random<u32>());
  33. Core::ElapsedTimer elapsed_time;
  34. elapsed_time.start();
  35. MCTSTree mcts(m_board);
  36. // FIXME: optimize simulations enough for use.
  37. mcts.set_eval_method(MCTSTree::EvalMethod::Heuristic);
  38. int rounds = 0;
  39. while (elapsed_time.elapsed() <= command.movetime.value()) {
  40. mcts.do_round();
  41. ++rounds;
  42. }
  43. dbgln("MCTS finished {} rounds.", rounds);
  44. dbgln("MCTS evaluation {}", mcts.expected_value());
  45. auto best_move = mcts.best_move();
  46. dbgln("MCTS best move {}", best_move.to_long_algebraic());
  47. send_command(BestMoveCommand(best_move));
  48. }