Chess Code Crunch
I called out a challenge, each participant should code not more than somewhat around one hour (max 75 minutes), language of your choice, OOP prefered (best in one file only).
There no right or wrong, just the time to beat. It sure won’t be the best code you had ever written - but that’s fine. It’s all about excercising, having fun and laughing about your final result when the time is over.
Specifications
- build a chess board (a1 to h8)
- add figurines, one black, one white
- both figurines can walk 1 step (up, down, left, right)
- white starts at g1
- black starts at a8
- only white moves and wipes black off the board with exactly 15 steps
optional:
- validate no one steps off the board
- log steps
- track wipes
here is what i came up with
what I like:
- the board as hash
- board has most of the game logic
what I dislike:
- how I solved moving, I would use an abstraction of the board next time
class Board
attr_reader :types, :grid, :alphabet, :draws, :kill_stack
def initialize
@figures = {}
@draws = {}
@types = %i[peasant king queen tower horse bishop1]
@kill_stack = []
@alphabet = ('a'..'h').to_a
@grid =
{
h1: nil, g1: nil, f1: nil, e1: nil, d1: nil, c1: nil, b1: nil, a1: nil,
h2: nil, g2: nil, f2: nil, e2: nil, d2: nil, c2: nil, b2: nil, a2: nil,
h3: nil, g3: nil, f3: nil, e3: nil, d3: nil, c3: nil, b3: nil, a3: nil,
h4: nil, g4: nil, f4: nil, e4: nil, d4: nil, c4: nil, b4: nil, a4: nil,
h5: nil, g5: nil, f5: nil, e5: nil, d5: nil, c5: nil, b5: nil, a5: nil,
h6: nil, g6: nil, f6: nil, e6: nil, d6: nil, c6: nil, b6: nil, a6: nil,
h7: nil, g7: nil, f7: nil, e7: nil, d7: nil, c7: nil, b7: nil, a7: nil,
h8: nil, g8: nil, f8: nil, e8: nil, d8: nil, c8: nil, b8: nil, a8: nil
}
end
def place_figure(figure)
raise ArgumentError unless figure.color == :white || figure.color == :black
@figures[figure.color] ||= {}
@figures[figure.color][figure.type] = figure
@grid[figure.position] = figure
end
def move_figurine(figure, new_position)
puts "moving figure #{figure.type} #{figure.color} from #{figure.position} to #{new_position}"
check_grid?(new_position)
@grid[figure.position] = nil
@draws[figure.color] || @draws[figure.color] = 0
figure.position = new_position
@draws[figure.color] = @draws[figure.color] + 1
@grid[new_position] = figure
end
def check_grid(new_position)
figure = @grid[new_position]
puts 'you captured the king' if figure && figure.type == :king
@kill_stack.push(figure) if figure
figure
end
def check_grid?(new_position)
!!check_grid(new_position)
end
def show_grid
temp_grid = {}
@grid.each do |field_id, figure|
temp_grid[field_id] = (figure.name if figure)
end
puts temp_grid
end
end
class Figurine
attr_reader :board, :color, :type
attr_accessor :position
def initialize(board, starting_position, color, type)
@board = board
@position = starting_position
@color = color
@type = type
validate_initialize
end
def name
"#{color} #{type}"
end
private
def validate_initialize
raise ArgumentError unless @color == :black || @color == :white
raise ArgumentError unless @board.is_a?(Board)
raise ArgumentError unless @position.is_a?(Symbol) && @board.grid.keys.any? { |grid_elem| grid_elem == @position }
raise ArgumentError unless @board.types.include? @type
end
end
class Peasant < Figurine
def move(position)
@position = position
@board.grid[:position]
end
def extract_row_column_from_position
column = @position.to_s.split('').first # :a8
row = @position.to_s.split('').last.to_i # :a8
{ column: column, row: row }
end
def move_forward
row, column = extract_row_column_from_position.values_at(:row, :column)
if @color == :black
raise ArgumentError if row - 1 < 1
@board.move_figurine(self, "#{column}#{row - 1}".to_sym)
elsif @color == :white
raise ArgumentError if row + 1 > 8
@board.move_figurine(self, "#{column}#{row + 1}".to_sym)
end
end
def move_backward
row, column = extract_row_column_from_position.values_at(:row, :column)
if @color == :black
raise ArgumentError if row + 1 > 8
@board.move_figurine(self, "#{column}#{row + 1}").to_sym
elsif @color == :white
raise ArgumentError if row - 1 < 1
@board.move_figurine(self, "#{column}#{row - 1}".to_sym)
end
end
def move_left
row, column = extract_row_column_from_position.values_at(:row, :column)
alphabet = @board.alphabet
if @color == :black
next_step = alphabet.index(column) + 1
raise ArgumentError if next_step > 7
@board.move_figurine(self, "#{alphabet[next_step]}#{row}").to_sym
elsif @color == :white
next_step = alphabet.index(column) - 1
raise ArgumentError if next_step < 0
@board.move_figurine(self, "#{alphabet[next_step]}#{row}".to_sym)
end
end
def move_right
row, column = extract_row_column_from_position.values_at(:row, :column)
alphabet = @board.alphabet
if @color == :black
next_step = alphabet.index(column) - 1
raise ArgumentError if next_step < 0
@board.move_figurine(self, "#{alphabet[next_step]}#{row}").to_sym
elsif @color == :white
next_step = alphabet.index(column) + 1
raise ArgumentError if next_step > 7
@board.move_figurine(self, "#{alphabet[next_step]}#{row}".to_sym)
end
end
end
current_board = Board.new
peasant_white = Peasant.new(current_board, :g1, :white, :peasant)
peasant_black = Peasant.new(current_board, :a8, :black, :peasant)
current_board.place_figure(peasant_white)
current_board.place_figure(peasant_black)
puts current_board.show_grid
puts current_board.grid[:a8].name
puts current_board.grid[:g1].name
peasant_white.move_forward
peasant_white.move_forward
peasant_white.move_forward
peasant_white.move_forward
peasant_white.move_forward
peasant_white.move_forward
peasant_white.move_forward
peasant_white.move_left
peasant_white.move_right
peasant_white.move_left
peasant_white.move_left
peasant_white.move_left
peasant_white.move_left
peasant_white.move_left
peasant_white.move_left
puts current_board.draws
puts current_board.show_grid
puts 'wiped: ' << current_board.kill_stack.map(&:name).join(', ')
``
⬅️ Read previous Read next ➡️