diff --git a/src/lx_chess.cr b/src/lx_chess.cr index f43dd7c..36858dd 100644 --- a/src/lx_chess.cr +++ b/src/lx_chess.cr @@ -8,10 +8,6 @@ options = {} of String => String | Nil OptionParser.parse do |parser| parser.banner = "Usage: lx_chess [fen]" - parser.on("--fen=FEN", "use fen string for board") do |fen_string| - options["fen_string"] = fen_string - end - parser.on("-h", "--help", "Show this help") do puts parser exit @@ -22,14 +18,26 @@ OptionParser.parse do |parser| exit end + parser.separator "\nGame options" + + # parser.on("-e", "--eval", "Evaluate a given position") do + # options["evaluate"] = "true" + # end + + parser.on("-f FEN", "--fen=FEN", "use fen string for board") do |fen_string| + options["fen_string"] = fen_string + end + parser.on("--board-theme=COLOR", "Set the board theme") do |color| options["theme"] = color end - parser.on("--open=PGN", "open a pgn file") do |path| + parser.on("-o PGN", "--open=PGN", "open a pgn file") do |path| options["pgn_path"] = path end + parser.separator "\nPlayer options" + parser.on("--player-white=PLAYER", "set the type of player (human|computer)") do |player_type| case player_type when /c(omputer)?/i @@ -44,6 +52,8 @@ OptionParser.parse do |parser| end end + parser.separator "\nDebugging options" + parser.on("--log=FILE", "log to file") do |file_Path| options["log_file"] = file_Path end diff --git a/src/lx_chess/computer.cr b/src/lx_chess/computer.cr index 70cad74..35aeaa0 100644 --- a/src/lx_chess/computer.cr +++ b/src/lx_chess/computer.cr @@ -86,15 +86,15 @@ module LxChess # Generate an array of moves (from => to) which result in an even or best score # TODO: promotion, pruning def best_moves(game : Game, turn : Int8? = nil, depth = 0, root_tree : MoveTree? = nil) # : Array(Array(Int16)) - turn = turn || game.turn + Log.debug { "=================================== Best moves ===================================" } - Log.debug { "Evaluating best moves for turn: #{turn}, depth: #{depth}..." } + turn = turn || game.turn if root_tree.nil? root_tree = MoveTree.new score: board_score(game, turn), turn: turn end - Log.debug { "Current Board score: #{root_tree.score}, turn: #{turn}" } + Log.debug { "Evaluating best moves for turn: #{turn}, depth: #{depth}, current score: #{root_tree.score} ..." } move_sets(game, turn).each do |set| origin = set.piece.index @@ -109,17 +109,27 @@ module LxChess end end - Log.debug { "Considered #{root_tree.branches.size} moves at depth #{depth}" } + Log.debug { "\n" + root_tree.to_s(IO::Memory.new).to_s } + + Log.debug { "Found #{root_tree.branches.size} moves" } + Log.debug do + current_bests = root_tree.best_branches.map { |b| [b[0], b[1]].map { |c| game.board.cord(c) }.join(" => ") }.join(", ") + "current best branches: #{current_bests}" + end if depth < 2 root_tree.branches.each do |branch| from, to, tree = branch - Log.debug { "Considering #{game.board.cord(from)} => #{game.board.cord(to)} ..." } + Log.debug do + "Considering branch: #{game.board.cord(from)} => #{game.board.cord(to)} ..." + end game.tmp_move(from: from, to: to) do best_moves(game, turn, depth + 1, tree) if tree.score > root_tree.score + Log.debug { "Found better branch: #{game.board.cord(from)} => #{game.board.cord(to)} : #{root_tree.score} => #{tree.score}" } + root_tree.score = tree.score root_tree.best_branches.truncate(0, 0) end diff --git a/src/lx_chess/move_tree.cr b/src/lx_chess/move_tree.cr index 16a65cc..c5fa595 100644 --- a/src/lx_chess/move_tree.cr +++ b/src/lx_chess/move_tree.cr @@ -33,5 +33,18 @@ module LxChess @branches << other end + + def to_s(io = STDOUT, depth = 0) + if parent + io << parent.to_s(io) + io << "\n" + depth += 1 + end + io << "Tree: score - " << @score << "\n" + @branches.each do |(from, to, tree)| + io << " " << Board.cord(from) << " => " << Board.cord(to) << " : " << tree.score << "\n" + end + io + end end end