Created
September 15, 2013 15:17
-
-
Save asterite/6571678 to your computer and use it in GitHub Desktop.
Chinese checkers solver written in Crystal
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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