On Oct 27, 2007, at 12:20 PM, Helder Ribeiro wrote: > Does anyone know if there's a sort of library for the game Checkers in > Ruby? Something that would, at least: > > 1. given a board state and a player, tell me what the legal moves are; > 2. given a board state and a move, tell me if it's legal; > 3. 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 Gray II