Add board scoring and basic suggestion

This commit is contained in:
Alex Clink 2021-09-27 21:01:04 -04:00
parent ede109d49d
commit d8c2a79733
4 changed files with 59 additions and 0 deletions

View file

@ -9,6 +9,15 @@ require "../../src/lx_chess/player"
include LxChess include LxChess
describe Game do describe Game do
describe "#score" do
it "scores the board" do
game = Game.new
game.board["e4"] = Piece.from_fen('P')
debug_board(game)
game.score.should eq(100)
end
end
describe "#remove_illegal_moves" do describe "#remove_illegal_moves" do
it "removes illegal moves" do it "removes illegal moves" do
game = Game.new players: [Player.new, Player.new] game = Game.new players: [Player.new, Player.new]

View file

@ -481,6 +481,46 @@ module LxChess
@move_clock -= 1 @move_clock -= 1
end end
# evaluate a position
def score(board = @board)
@board.reduce(0) do |score, piece|
next score unless piece
val =
case piece.id
when Piece::PAWN then 100
when Piece::KING then 10000
when Piece::QUEEN then 900
when Piece::ROOK then 500
when Piece::BISHOP then 310
when Piece::KNIGHT then 300
else
0
end
piece.black? ? score - val : score + val
end
end
def suggest
best_score = 0
selected_piece = nil
best_move = nil
pieces_for.each do |piece|
next unless move_set = moves(piece.index)
move_set.moves.reduce(best_score) do |best, move_index|
move_score = tmp_move(from: piece.index, to: move_index) { score }
if move_score > best_score
selected_piece = piece
best_move = move_index
move_score
else
best
end
end
end
return nil unless selected_piece && best_move
[selected_piece.index, best_move]
end
# Return the pieces for a specified player # Return the pieces for a specified player
def pieces_for(turn = @turn) def pieces_for(turn = @turn)
color = turn == 0 ? :black : :white color = turn == 0 ? :black : :white

View file

@ -22,6 +22,10 @@ module LxChess
def initialize(@id : Int8 = 0) def initialize(@id : Int8 = 0)
end end
def id
@id & 0b0111
end
def white? def white?
@id & 0b1000 == 0 @id & 0b1000 == 0
end end

View file

@ -49,6 +49,12 @@ module LxChess
msg.lines.reverse.each { |l| @log.unshift(l) } msg.lines.reverse.each { |l| @log.unshift(l) }
when /flip/i when /flip/i
@gb.flip! @gb.flip!
when /score/i
@log.unshift "score: #{@game.score}"
when /suggest/i
if suggestion = @game.suggest
@log.unshift "suggestion: #{suggestion.map { |s| @game.board.cord(s) }.join(" => ")}"
end
when /(undo|back)/i when /(undo|back)/i
if last_change = @changes.pop? if last_change = @changes.pop?
@game.undo(last_change) @game.undo(last_change)