Skip to content

Instantly share code, notes, and snippets.

@asterite
Created September 15, 2013 15:17
Show Gist options
  • Select an option

  • Save asterite/6571678 to your computer and use it in GitHub Desktop.

Select an option

Save asterite/6571678 to your computer and use it in GitHub Desktop.
Chinese checkers solver written in Crystal
Directions = [:up, :down, :left, :right]
class Board
getter :cells
def initialize
@cells = [
['x', 'x', ' ', 'o', ' ', 'x', 'x'],
['x', 'x', ' ', 'o', ' ', 'x', 'x'],
[' ', ' ', 'o', 'o', 'o', ' ', ' '],
['o', 'o', 'o', ' ', 'o', 'o', 'o'],
[' ', ' ', 'o', 'o', 'o', ' ', ' '],
['x', 'x', ' ', 'o', ' ', 'x', 'x'],
['x', 'x', ' ', 'o', ' ', 'x', 'x'],
]
end
def initialize(@cells)
end
def can_move?(row, col, direction)
return false unless @cells[row][col] == 'o'
case direction
when :up
row >= 2 && @cells[row - 1][col] == 'o' && @cells[row - 2][col] == ' '
when :down
row <= 4 && @cells[row + 1][col] == 'o' && @cells[row + 2][col] == ' '
when :left
col >= 2 && @cells[row][col - 1] == 'o' && @cells[row][col - 2] == ' '
when :right
col <= 4 && @cells[row][col + 1] == 'o' && @cells[row][col + 2] == ' '
else
raise "Unknown direction: #{direction}"
end
end
def move(row, col, direction)
new_cells = @cells.clone
case direction
when :up
new_cells[row][col] = ' '
new_cells[row - 1][col] = ' '
new_cells[row - 2][col] = 'o'
when :down
new_cells[row][col] = ' '
new_cells[row + 1][col] = ' '
new_cells[row + 2][col] = 'o'
when :left
new_cells[row][col] = ' '
new_cells[row][col - 1] = ' '
new_cells[row][col - 2] = 'o'
when :right
new_cells[row][col] = ' '
new_cells[row][col + 1] = ' '
new_cells[row][col + 2] = 'o'
else
raise "Unknown direction: #{direction}"
end
Board.new(new_cells)
end
def solved?
@cells.each_with_index do |row, row_index|
row.each_with_index do |cell, col_index|
if row_index == 3 && col_index == 3
return false unless cell == 'o'
else
return false if cell == 'o'
end
end
end
true
end
def to_s
to_s(-1, -1)
end
def to_s(highlight_row, highlight_col)
String.build do |str|
str << "---------"
@cells.each_with_index do |row, row_index|
str << "\n|"
row.each_with_index do |cell, col_index|
if row_index == highlight_row && col_index == highlight_col
str << "\033[1;32m#{cell}\033[0m"
else
str << cell
end
end
str << "|"
end
str << "\n---------"
end
end
end
class Solver
getter :board
getter :row
getter :col
getter :direction
getter :next_board
getter :next_solver
def initialize(@board = Board.new)
@row = -1
@col = -1
@direction = :none
end
def solve
7.times do |row|
7.times do |col|
Directions.each do |direction|
if @board.can_move?(row, col, direction)
next_board = @board.move(row, col, direction)
if next_board.solved? || (@next_solver = Solver.new(next_board)).solve
@next_board = next_board
@row = row
@col = col
@direction = direction
return true
end
end
end
end
end
@next_solver = nil
false
end
def to_s
board.to_s row, col
end
end
solver = Solver.new
if solver.solve
puts "The solution is..."
current_solver = solver
while current_solver
puts
if current_solver.next_solver
puts "Move #{current_solver.direction}"
puts current_solver
current_board = current_solver.next_board
else
puts "Finally..."
puts current_board
end
current_solver = current_solver.next_solver
end
else
puts "No solution : -("
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment