|
1
|
|
|
def mirror(state): |
|
2
|
|
|
return [[j for j in i[::-1]] for i in state] |
|
3
|
|
|
|
|
4
|
|
|
|
|
5
|
|
|
def clockwise_rotate(state): |
|
6
|
|
|
return [list(i) for i in zip(*state[::-1])] |
|
7
|
|
|
|
|
8
|
|
|
|
|
9
|
|
|
def counterclockwise_rotate(state): |
|
10
|
|
|
return mirror(clockwise_rotate(mirror(state))) |
|
11
|
|
|
|
|
12
|
|
|
|
|
13
|
|
|
def remove_zeros(line): |
|
14
|
|
|
return [i for i in line if i != 0] |
|
15
|
|
|
|
|
16
|
|
|
|
|
17
|
|
|
def adding(line): |
|
18
|
|
|
first_element = line[0:1] |
|
19
|
|
|
second_element = line[1:2] |
|
20
|
|
|
rest_line = line[2:] |
|
21
|
|
|
if first_element and first_element == second_element: |
|
22
|
|
|
return [first_element[0] * 2], rest_line |
|
23
|
|
|
else: |
|
24
|
|
|
return first_element, second_element + rest_line |
|
25
|
|
|
|
|
26
|
|
|
|
|
27
|
|
|
def recursive_adding(line): |
|
28
|
|
|
new_line, rest_line = adding(line) |
|
29
|
|
|
if rest_line: |
|
30
|
|
|
return new_line + recursive_adding(rest_line) |
|
31
|
|
|
return new_line |
|
32
|
|
|
|
|
33
|
|
|
|
|
34
|
|
|
def padding_zeros(line): |
|
35
|
|
|
return line + [0] * (4 - len(line)) |
|
36
|
|
|
|
|
37
|
|
|
|
|
38
|
|
|
def move_left(state): |
|
39
|
|
|
non_zero_state = map(remove_zeros, state) |
|
40
|
|
|
added_state = map(recursive_adding, non_zero_state) |
|
41
|
|
|
return list(map(padding_zeros, added_state)) |
|
42
|
|
|
|
|
43
|
|
|
|
|
44
|
|
|
def flatten_list(state): |
|
45
|
|
|
return [item for sublist in state for item in sublist] |
|
46
|
|
|
|
|
47
|
|
|
|
|
48
|
|
|
def add_new_element(state): |
|
49
|
|
|
flat_list = flatten_list(state) |
|
50
|
|
|
try: |
|
51
|
|
|
reversed_flat_list = list(reversed(flat_list)) |
|
52
|
|
|
first_zero = reversed_flat_list.index(0) |
|
53
|
|
|
reversed_flat_list[first_zero] = 2 |
|
54
|
|
|
new_flat_list = list(reversed(reversed_flat_list)) |
|
55
|
|
|
return [new_flat_list[i : i + 4] for i in range(0, len(new_flat_list), 4)] |
|
56
|
|
|
except ValueError: |
|
57
|
|
|
return state |
|
58
|
|
|
|
|
59
|
|
|
|
|
60
|
|
|
def move2048(state, move): |
|
61
|
|
|
if move == 'left': |
|
62
|
|
|
new_state = move_left(state) |
|
63
|
|
|
elif move == 'right': |
|
64
|
|
|
new_state = mirror(move_left(mirror(state))) |
|
65
|
|
|
elif move == 'up': |
|
66
|
|
|
new_state = clockwise_rotate(move_left(counterclockwise_rotate(state))) |
|
67
|
|
|
else: |
|
68
|
|
|
new_state = counterclockwise_rotate(move_left(clockwise_rotate(state))) |
|
69
|
|
|
if new_state == state: |
|
70
|
|
|
return [ |
|
71
|
|
|
['G', 'A', 'M', 'E'], |
|
72
|
|
|
['O', 'V', 'E', 'R'], |
|
73
|
|
|
['G', 'A', 'M', 'E'], |
|
74
|
|
|
['O', 'V', 'E', 'R'], |
|
75
|
|
|
] |
|
76
|
|
|
elif 2048 in flatten_list(new_state): |
|
77
|
|
|
return [ |
|
78
|
|
|
['U', 'W', 'I', 'N'], |
|
79
|
|
|
['U', 'W', 'I', 'N'], |
|
80
|
|
|
['U', 'W', 'I', 'N'], |
|
81
|
|
|
['U', 'W', 'I', 'N'], |
|
82
|
|
|
] |
|
83
|
|
|
return add_new_element(new_state) |
|
84
|
|
|
|
|
85
|
|
|
|
|
86
|
|
|
if __name__ == '__main__': |
|
87
|
|
|
# These "asserts" using only for self-checking and not necessary for |
|
88
|
|
|
# auto-testing |
|
89
|
|
|
assert move2048([[0, 2, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 2, 0, 0]], 'up') == [ |
|
90
|
|
|
[0, 4, 0, 0], |
|
91
|
|
|
[0, 0, 0, 0], |
|
92
|
|
|
[0, 0, 0, 0], |
|
93
|
|
|
[0, 0, 0, 2], |
|
94
|
|
|
], "Start. Move Up!" |
|
95
|
|
|
assert move2048( |
|
96
|
|
|
[[4, 0, 0, 0], [0, 4, 0, 0], [0, 0, 0, 0], [0, 0, 8, 8]], 'right' |
|
97
|
|
|
) == [[0, 0, 0, 4], [0, 0, 0, 4], [0, 0, 0, 0], [0, 0, 2, 16]], "Simple right" |
|
98
|
|
|
assert move2048( |
|
99
|
|
|
[[2, 0, 2, 2], [0, 4, 4, 4], [8, 8, 8, 16], [0, 0, 0, 0]], 'right' |
|
100
|
|
|
) == [[0, 0, 2, 4], [0, 0, 4, 8], [0, 8, 16, 16], [0, 0, 0, 2]], "Three merging" |
|
101
|
|
|
assert move2048( |
|
102
|
|
|
[[256, 0, 256, 4], [16, 8, 8, 0], [32, 32, 32, 32], [4, 4, 2, 2]], 'right' |
|
103
|
|
|
) == [[0, 0, 512, 4], [0, 0, 16, 16], [0, 0, 64, 64], [0, 2, 8, 4]], "All right" |
|
104
|
|
|
assert move2048( |
|
105
|
|
|
[[4, 4, 0, 0], [0, 4, 1024, 0], [0, 256, 0, 256], [0, 1024, 1024, 8]], 'down' |
|
106
|
|
|
) == [ |
|
107
|
|
|
['U', 'W', 'I', 'N'], |
|
108
|
|
|
['U', 'W', 'I', 'N'], |
|
109
|
|
|
['U', 'W', 'I', 'N'], |
|
110
|
|
|
['U', 'W', 'I', 'N'], |
|
111
|
|
|
], "We are the champions!" |
|
112
|
|
|
assert move2048( |
|
113
|
|
|
[[2, 4, 8, 16], [32, 64, 128, 256], [512, 1024, 2, 4], [8, 16, 32, 64]], 'left' |
|
114
|
|
|
) == [ |
|
115
|
|
|
['G', 'A', 'M', 'E'], |
|
116
|
|
|
['O', 'V', 'E', 'R'], |
|
117
|
|
|
['G', 'A', 'M', 'E'], |
|
118
|
|
|
['O', 'V', 'E', 'R'], |
|
119
|
|
|
], "Nobody moves!" |
|
120
|
|
|
|