On Oct 27, 2007, at 12:20 PM, Helder R. wrote:
Does anyone know if there’s a sort of library for the game Checkers in
Ruby? Something that would, at least:
- given a board state and a player, tell me what the legal moves are;
- given a board state and a move, tell me if it’s legal;
- given a board state, tell me if it’s a draw or a win (and who won).
Also, if there isn’t a library (very likely), a complete game that’s
open source, from which I could extract that, would be good enough.
I decided to see what I could put together for you request quickly.
Unfortunately, I’m now out of time as I’m about to walk out the door
for a concert.
This doesn’t yet handle jumps and it doesn’t determine win, lose, or
draw conditions. Hopefully it’s enough to get you started though:
#!/usr/bin/env ruby -wKU
require “enumerator”
module Checkers
class Piece
def initialize(color, king = false)
@color = color
@king = king
end
attr_reader :color
def king_me!
@king = true
end
def king?
@king
end
def to_s
str = @color.to_s[0, 1]
@king ? str.upcase : str
end
end
class Board
MOVES = {
1 => [ 5, 6], 2 => [ 6, 7], 3 => [ 7, 8],
4 => [ 8], 5 => [ 1, 9], 6 => [ 1,
2, 9, 10],
7 => [ 2, 3, 10, 11], 8 => [ 3, 4, 11, 12], 9 => [ 5, 6,
13, 14],
10 => [ 6, 7, 14, 15], 11 => [ 7, 8, 15, 16], 12 => [ 8, 16],
13 => [ 9, 17], 14 => [ 9, 10, 17, 18], 15 => [10, 11,
18, 19],
16 => [11, 12, 19, 20], 17 => [13, 14, 21, 22], 18 => [14, 15,
22, 23],
19 => [15, 16, 23, 24], 20 => [16, 24], 21 => [17, 25],
22 => [17, 18, 25, 26], 23 => [18, 19, 26, 27], 24 => [19, 20,
27, 28],
25 => [21, 22, 29, 30], 26 => [22, 23, 30, 31], 27 => [23, 24,
31, 32],
28 => [24, 32], 29 => [25], 30 => [25, 26],
31 => [26, 27], 32 => [27, 28]
}
def initialize
@squares = Array.new(12) { Piece.new(:black) } +
Array.new(8) +
Array.new(12) { Piece.new(:red) }
@turn = :black
end
def [](square_number)
@squares[square_number - 1]
end
def moves(color = @turn)
@squares.enum_with_index.inject([]) do |moves, (piece, i)|
next moves unless piece and piece.color == color
possible = MOVES[i + 1]
unless piece.king?
illegal = piece.color == :black ? :< : :>
possible.reject! { |n| n.send(illegal, i + 1) }
end
moves +
possible.select { |to| self[to].nil? }.map { |m| “#{i + 1}-#
{m}” }
end
end
def legal?(move, color = @turn)
moves(color).include? move
end
def to_s
leading_black = false
border = "+---+---" * 4 + "+\n"
@squares.enum_with_index.enum_slice(4).inject("") do |str, row|
leading_black = !leading_black
pattern = (leading_black ? "|###|%-3s" : "|%-3s|###")
- 4 + “|\n”
str +
border +
pattern % [*row.map { |square| square.first }] +
pattern.delete("-") % [*row.map { |square| square.last + 1 }]
end + border
end
end
end
END
James Edward G. II