-
Notifications
You must be signed in to change notification settings - Fork 1
/
game.rb
116 lines (87 loc) · 2.38 KB
/
game.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
113
114
115
116
class Game
attr_reader :board
def initialize(board)
@board = board
end
def play
raise GameFinishedException.new if @board.full?
@board.put_at_random_location(2)
end
def play_right
already_added = []
(@board.size-2).times { add_and_move_right(already_added) }
end
def play_left
already_added = []
(@board.size-2).times { add_and_move_left(already_added) }
end
def add_and_move_right(added)
move_right_to_empty
merge_neighbours_right(added)
end
def add_and_move_left(added)
move_left_to_empty
merge_neighbours_left(added)
end
def merge_neighbours_right(added)
@board.each_vertical_pair_from_top_right do |current, left|
sum!(current, left, added) if possible_to_sum?(current, left, added)
end
end
def merge_neighbours_left(added)
@board.each_verticail_pair_from_top_left do |current, right|
sum!(current, right, added) if possible_to_sum?(current, right, added)
end
end
def move_right_to_empty
@board.each_verticail_pair_from_top_left do |current, right|
move(current, right) if can_move?(current, right)
end
end
def move_left_to_empty
@board.each_vertical_pair_from_top_right do |current, left|
move(current, left) if can_move?(current, left)
end
end
def sum!(location, other_location, added)
double_number!(location)
added << [location]
make_empty(other_location)
end
def possible_to_sum?(current, other, added)
same?(current, other) && !empty?(current) && not_yet_added?(added, current, other)
end
def not_yet_added?(added, location, other_location)
!added.include?([location]) && !added.include?([other_location])
end
def double_number!(location)
put_number(number_at(location) * 2, location)
end
def same?(location, other_location)
number_at(location) == number_at(other_location)
end
def put_number(sum, location)
@board.put_number(sum, location)
end
def number_at(location)
@board.get_number(location)
end
def move(from, to)
copy_this_to(from, to)
make_empty(from)
end
def can_move?(from, to)
! empty?(from) && empty?(to)
end
def copy_this_to(current, right)
put_number(number_at(current), right)
end
def empty?(location)
@board.empty?(location)
end
def make_empty(location)
put_number(0, location)
end
end
class GameFinishedException < StandardError
end