mirror of
https://github.com/SleepingInsomniac/lx_chess_cr
synced 2025-01-31 19:57:54 +01:00
Add more moves to generation
This commit is contained in:
parent
5ebe8a920c
commit
af020fb3c6
6 changed files with 172 additions and 10 deletions
68
spec/lx_chess/game_spec.cr
Normal file
68
spec/lx_chess/game_spec.cr
Normal file
|
@ -0,0 +1,68 @@
|
|||
require "../spec_helper"
|
||||
require "../../src/lx_chess/board"
|
||||
require "../../src/lx_chess/piece"
|
||||
require "../../src/lx_chess/move_set"
|
||||
require "../../src/lx_chess/game"
|
||||
|
||||
describe LxChess::Game do
|
||||
describe "#moves" do
|
||||
it "correctly generates white pawn moves from the initial rank" do
|
||||
game = LxChess::Game.new
|
||||
game.board["e2"] = LxChess::Piece.from_fen('P')
|
||||
moves = game.moves("e2")
|
||||
moves.map { |m| game.board.cord(m) }.should eq(["e3", "e4"])
|
||||
end
|
||||
|
||||
it "correctly generates black pawn moves from the initial rank" do
|
||||
game = LxChess::Game.new
|
||||
game.board["e7"] = LxChess::Piece.from_fen('p')
|
||||
moves = game.moves("e7")
|
||||
moves.map { |m| game.board.cord(m) }.should eq(["e6", "e5"])
|
||||
end
|
||||
|
||||
it "correctly generates single white pawn moves" do
|
||||
game = LxChess::Game.new
|
||||
game.board["e3"] = LxChess::Piece.from_fen('P')
|
||||
moves = game.moves("e3")
|
||||
moves.map { |m| game.board.cord(m) }.should eq(["e4"])
|
||||
end
|
||||
|
||||
it "correctly generates black white pawn moves" do
|
||||
game = LxChess::Game.new
|
||||
game.board["e6"] = LxChess::Piece.from_fen('p')
|
||||
moves = game.moves("e6")
|
||||
moves.map { |m| game.board.cord(m) }.should eq(["e5"])
|
||||
end
|
||||
|
||||
it "correctly generates knight moves" do
|
||||
game = LxChess::Game.new
|
||||
game.board["c3"] = LxChess::Piece.from_fen('N')
|
||||
moves = game.moves("c3")
|
||||
moves.map { |m| game.board.cord(m) }.should eq(["a4", "b5", "d5", "e4", "e2", "d1", "b1", "a2"])
|
||||
end
|
||||
|
||||
it "correctly generates rook moves" do
|
||||
game = LxChess::Game.new
|
||||
game.board["e4"] = LxChess::Piece.from_fen('R')
|
||||
moves = game.moves("e4")
|
||||
moves.map { |m| game.board.cord(m) }.should eq([
|
||||
"d4", "c4", "b4", "a4",
|
||||
"e5", "e6", "e7", "e8",
|
||||
"f4", "g4", "h4",
|
||||
"e3", "e2", "e1",
|
||||
])
|
||||
end
|
||||
|
||||
it "correctly generates bishop moves" do
|
||||
game = LxChess::Game.new
|
||||
game.board["e4"] = LxChess::Piece.from_fen('B')
|
||||
moves = game.moves("e4")
|
||||
moves.map { |m| game.board.cord(m) }.should eq([
|
||||
"d5", "c6", "b7", "a8",
|
||||
"f5", "g6", "h7",
|
||||
"f3", "g2", "h1",
|
||||
"d3", "c2", "b1",
|
||||
])
|
||||
end
|
||||
end
|
||||
end
|
18
spec/lx_chess/move_set_spec.cr
Normal file
18
spec/lx_chess/move_set_spec.cr
Normal file
|
@ -0,0 +1,18 @@
|
|||
require "../spec_helper"
|
||||
require "../../src/lx_chess/board"
|
||||
require "../../src/lx_chess/piece"
|
||||
require "../../src/lx_chess/move_set"
|
||||
|
||||
describe LxChess::MoveSet do
|
||||
describe "#add_vector" do
|
||||
it "generates moves to the right" do
|
||||
game = LxChess::Game.new
|
||||
piece = LxChess::Piece.from_fen('R')
|
||||
game.board["a1"] = piece
|
||||
move_set = LxChess::MoveSet.new(piece, game.board)
|
||||
move_set.add_vector(x: 1, y: 0, limit: 3)
|
||||
move_set.moves.size.should eq(3)
|
||||
move_set.moves.should eq([1, 2, 3])
|
||||
end
|
||||
end
|
||||
end
|
|
@ -43,12 +43,12 @@ loop do
|
|||
input = gets
|
||||
if input
|
||||
notation = LxChess::Notation.new(input)
|
||||
# input = input.to_i16 if input =~ /^\d+$/
|
||||
# puts game.moves(input)
|
||||
from, to = game.parse_san(notation)
|
||||
if from && to
|
||||
puts "#{notation.to_s}: #{game.board.cord(from)} => #{game.board.cord(to)}"
|
||||
end
|
||||
input = input.to_i16 if input =~ /^\d+$/
|
||||
puts game.moves(input).map { |m| game.board.cord(m) }
|
||||
# from, to = game.parse_san(notation)
|
||||
# if from && to
|
||||
# puts "#{notation.to_s}: #{game.board.cord(from)} => #{game.board.cord(to)}"
|
||||
# end
|
||||
end
|
||||
rescue e : LxChess::Notation::InvalidNotation
|
||||
puts e.message
|
||||
|
|
|
@ -51,6 +51,10 @@ module LxChess
|
|||
board
|
||||
end
|
||||
|
||||
def self.standard
|
||||
self.parse "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"
|
||||
end
|
||||
|
||||
property board : Board
|
||||
property turn : String
|
||||
property castling : String
|
||||
|
|
|
@ -7,7 +7,7 @@ module LxChess
|
|||
class Game
|
||||
property turn : Int8, board : Board
|
||||
|
||||
def initialize(@board : Board, @players = [] of Player)
|
||||
def initialize(@board : Board = Board.new, @players = [] of Player)
|
||||
@turn = 0
|
||||
end
|
||||
|
||||
|
@ -38,6 +38,43 @@ module LxChess
|
|||
set.add_vector(x: 0, y: 1, limit: (@board.rank(index) == 1 ? 2 : 1).to_i16)
|
||||
when 'p' # Black pawn
|
||||
set.add_vector(x: 0, y: -1, limit: (@board.rank(index) == @board.height - 2 ? 2 : 1).to_i16)
|
||||
when 'B', 'b' # Bishop
|
||||
set.add_vector(x: -1, y: 1, limit: 8)
|
||||
set.add_vector(x: 1, y: 1, limit: 8)
|
||||
set.add_vector(x: 1, y: -1, limit: 8)
|
||||
set.add_vector(x: -1, y: -1, limit: 8)
|
||||
when 'R', 'r' # Rook
|
||||
set.add_vector(x: -1, y: 0, limit: 8)
|
||||
set.add_vector(x: 0, y: 1, limit: 8)
|
||||
set.add_vector(x: 1, y: 0, limit: 8)
|
||||
set.add_vector(x: 0, y: -1, limit: 8)
|
||||
when 'Q', 'q' # Queen
|
||||
set.add_vector(x: -1, y: 1, limit: 8)
|
||||
set.add_vector(x: 1, y: 1, limit: 8)
|
||||
set.add_vector(x: 1, y: -1, limit: 8)
|
||||
set.add_vector(x: -1, y: -1, limit: 8)
|
||||
set.add_vector(x: -1, y: 0, limit: 8)
|
||||
set.add_vector(x: 0, y: 1, limit: 8)
|
||||
set.add_vector(x: 1, y: 0, limit: 8)
|
||||
set.add_vector(x: 0, y: -1, limit: 8)
|
||||
when 'N', 'n' # Knight
|
||||
set.add_offsets([
|
||||
{x: -2, y: 1}, {x: -1, y: 2}, # up left
|
||||
{x: 1, y: 2}, {x: 2, y: 1}, # up right
|
||||
{x: 2, y: -1}, {x: 1, y: -2}, # down right
|
||||
{x: -1, y: -2}, {x: -2, y: -1}, # down left
|
||||
])
|
||||
when 'K', 'k' # King
|
||||
set.add_offsets([
|
||||
{x: -1, y: 0}, # left
|
||||
{x: -1, y: 1}, # left up
|
||||
{x: 0, y: 1}, # up
|
||||
{x: 1, y: 1}, # up right
|
||||
{x: 1, y: 0}, # right
|
||||
{x: 1, y: -1}, # down right
|
||||
{x: 0, y: -1}, # down
|
||||
{x: -1, y: -1}, # down left
|
||||
])
|
||||
end
|
||||
set.moves
|
||||
else
|
||||
|
|
|
@ -16,17 +16,52 @@ module LxChess
|
|||
end
|
||||
|
||||
def add_vector(offset : Int16, limit : Int16)
|
||||
step = offset
|
||||
location = @piece.index.as(Int16)
|
||||
limit.times do
|
||||
location = location + offset
|
||||
info = add_offset(offset)
|
||||
offset += step
|
||||
break if info[:stop]
|
||||
end
|
||||
end
|
||||
|
||||
def add_offsets(offsets : Array(NamedTuple(x: Int32, y: Int32)))
|
||||
offsets.each do |cord|
|
||||
offset = cord[:y] * @board.width + cord[:x]
|
||||
add_offset(offset.to_i16)
|
||||
end
|
||||
end
|
||||
|
||||
def add_offsets(offsets : Array(Int16))
|
||||
offsets.each do |offset|
|
||||
add_offset(offset)
|
||||
end
|
||||
end
|
||||
|
||||
def add_offset(x : Int16, y : Int16)
|
||||
add_offset(y * @board.width + x)
|
||||
end
|
||||
|
||||
# TODO: Stop at the board edges
|
||||
def add_offset(offset : Int16)
|
||||
added = false; stop = false
|
||||
location = @piece.index.as(Int16) + offset
|
||||
if location < 0 || location >= @board.squares.size
|
||||
# Beyond top or bottom
|
||||
stop = true
|
||||
else
|
||||
if capture = @board[location]
|
||||
unless capture.color == @piece.color
|
||||
@moves.push(location)
|
||||
added = true
|
||||
end
|
||||
break
|
||||
stop = true
|
||||
else
|
||||
@moves.push(location)
|
||||
added = true
|
||||
end
|
||||
@moves.push(location)
|
||||
end
|
||||
{added: added, stop: stop, location: location}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Add table
Reference in a new issue