-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathalgorithm.py
131 lines (116 loc) · 4.79 KB
/
algorithm.py
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
import random
import numpy as np
def take_turn(direc, board):
score = 0
merged = [[False for _ in range(4)] for _ in range(4)]
if direc == 'UP':
for i in range(4):
for j in range(4):
shift = 0
if i > 0:
for q in range(i):
if board[q][j] == 0:
shift += 1
if shift > 0:
board[i - shift][j] = board[i][j]
board[i][j] = 0
if board[i - shift - 1][j] == board[i - shift][j] and not merged[i - shift][j] \
and not merged[i - shift - 1][j]:
board[i - shift - 1][j] *= 2
score += board[i - shift - 1][j]
board[i - shift][j] = 0
merged[i - shift - 1][j] = True
elif direc == 'DOWN':
for i in range(3):
for j in range(4):
shift = 0
for q in range(i + 1):
if board[3 - q][j] == 0:
shift += 1
if shift > 0:
board[2 - i + shift][j] = board[2 - i][j]
board[2 - i][j] = 0
if 3 - i + shift <= 3:
if board[2 - i + shift][j] == board[3 - i + shift][j] and not merged[3 - i + shift][j] \
and not merged[2 - i + shift][j]:
board[3 - i + shift][j] *= 2
score += board[3 - i + shift][j]
board[2 - i + shift][j] = 0
merged[3 - i + shift][j] = True
elif direc == 'LEFT':
for i in range(4):
for j in range(4):
shift = 0
for q in range(j):
if board[i][q] == 0:
shift += 1
if shift > 0:
board[i][j - shift] = board[i][j]
board[i][j] = 0
if board[i][j - shift] == board[i][j - shift - 1] and not merged[i][j - shift - 1] \
and not merged[i][j - shift]:
board[i][j - shift - 1] *= 2
score += board[i][j - shift - 1]
board[i][j - shift] = 0
merged[i][j - shift - 1] = True
elif direc == 'RIGHT':
for i in range(4):
for j in range(4):
shift = 0
for q in range(j):
if board[i][3 - q] == 0:
shift += 1
if shift > 0:
board[i][3 - j + shift] = board[i][3 - j]
board[i][3 - j] = 0
if 4 - j + shift <= 3:
if board[i][4 - j + shift] == board[i][3 - j + shift] and not merged[i][4 - j + shift] \
and not merged[i][3 - j + shift]:
board[i][4 - j + shift] *= 2
score += board[i][4 - j + shift]
board[i][3 - j + shift] = 0
merged[i][4 - j + shift] = True
return board, score
def new_pieces(board):
count = 0
full = False
while any(0 in row for row in board) and count < 1:
row = random.randint(0, 3)
col = random.randint(0, 3)
if board[row][col] == 0:
count += 1
if random.randint(1, 10) == 10:
board[row][col] = 4
else:
board[row][col] = 2
if count < 1:
full = True
return board, not full
def search_move_tree(board, searches_per_move, search_length):
moves = ["LEFT", "RIGHT", "DOWN", "UP"]
scores = np.zeros(4)
score_gain = np.zeros(4)
for idx in range(4):
direction = moves[idx]
current_board, delta_score = take_turn(direction, np.copy(board))
valid = not (np.matrix(current_board) == np.matrix(board)).all()
if valid:
scores[idx] += delta_score
score_gain[idx] = delta_score
current_board, valid = new_pieces(current_board)
else:
continue
for next_move in range(searches_per_move):
move_count = 1
search_board = np.copy(current_board)
valid = True
while valid and move_count < search_length:
next_board, delta_score = take_turn(moves[random.randint(0, 5) % 4], np.copy(search_board))
valid = not (np.matrix(search_board) == np.matrix(next_board)).all()
if valid:
search_board, valid = new_pieces(next_board)
scores[idx] += delta_score
move_count += 1
best_move = moves[np.argmax(scores)]
delta_score = score_gain[np.argmax(scores)]
return best_move, int(delta_score)