-
Notifications
You must be signed in to change notification settings - Fork 0
/
sudoku.rb
119 lines (91 loc) · 2.69 KB
/
sudoku.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
require 'sinatra'
require 'sinatra/partial'
require 'rack-flash'
configure :production do
require 'newrelic_rpm'
end
require_relative './lib/sudoku'
require_relative './lib/cell'
enable :sessions
set :partial_template_engine, :erb
use Rack::Flash
set :session_secret, "I'm the secret key to sign the cookie"
def random_sudoku
seed = (1..9).to_a.shuffle + Array.new(81-9, 0)
sudoku = Sudoku.new(seed.join)
sudoku.solve!
sudoku.to_s.chars
end
# this method removes some digits from the solution to create a puzzle
def puzzle(sudoku)
sudoku.map {|x| rand < 0.75 ? 0 : x }
end
get '/' do
prepare_to_check_solution
generate_new_puzzle_if_necessary
@current_solution = session[:current_solution] || session[:puzzle]
@solution = session[:solution]
@puzzle = session[:puzzle]
erb :index
end
def generate_new_puzzle_if_necessary
return if session[:current_solution]
sudoku = random_sudoku
session[:solution] = sudoku
session[:puzzle] = puzzle(sudoku)
session[:current_solution] = session[:puzzle]
end
def prepare_to_check_solution
@check_solution = session[:check_solution]
if @check_solution
flash[:notice] = "Incorrect values are highlighted in yellow"
end
session[:check_solution] = nil
end
get '/solution' do
@current_solution = session[:solution]
@puzzle = session[:puzzle]
@solution = session[:solution]
erb :index
end
post '/' do
cells = box_order_to_row_order(params["cell"])
session[:current_solution] = cells.map{|value|value.to_i}.join
session[:check_solution] = true
redirect to ("/")
end
def box_order_to_row_order(cells)
# first, we break down 81 cells into 9 arrays of 9 cells,
# each representing one box
boxes = cells.each_slice(9).to_a
(0..8).to_a.inject([]) do |memo, i|
first_box_index = i / 3 * 3
three_boxes = boxes[first_box_index, 3]
three_rows_of_three = three_boxes.map do |box|
row_number_in_a_box = i % 3
first_cell_in_the_row_index = row_number_in_a_box * 3
box[first_cell_in_the_row_index, 3]
end
memo += three_rows_of_three.flatten
end
end
helpers do
def colour_class(solution_to_check, puzzle_value, current_solution_value, solution_value)
must_be_guessed = puzzle_value.to_i == 0
tried_to_guess = current_solution_value.to_i != 0
guessed_incorrectly = current_solution_value != solution_value
if solution_to_check &&
must_be_guessed &&
tried_to_guess &&
guessed_incorrectly
'incorrect'
elsif !must_be_guessed
'value-provided'
end
end
end
helpers do
def cell_value(value)
value.to_i == 0 ? '' : value
end
end