-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathai.py
98 lines (70 loc) · 2.71 KB
/
ai.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
import math
import time
import numpy as np
UP, DOWN, LEFT, RIGHT = range(4)
class AI():
def get_move(self, board):
best_move, _ = self.maximize(board)
return best_move
def eval_board(self, board, n_empty):
grid = board.grid
utility = 0
smoothness = 0
big_t = np.sum(np.power(grid, 2))
s_grid = np.sqrt(grid)
smoothness -= np.sum(np.abs(s_grid[::,0] - s_grid[::,1]))
smoothness -= np.sum(np.abs(s_grid[::,1] - s_grid[::,2]))
smoothness -= np.sum(np.abs(s_grid[::,2] - s_grid[::,3]))
smoothness -= np.sum(np.abs(s_grid[0,::] - s_grid[1,::]))
smoothness -= np.sum(np.abs(s_grid[1,::] - s_grid[2,::]))
smoothness -= np.sum(np.abs(s_grid[2,::] - s_grid[3,::]))
empty_w = 100000
smoothness_w = 3
empty_u = n_empty * empty_w
smooth_u = smoothness ** smoothness_w
big_t_u = big_t
utility += big_t
utility += empty_u
utility += smooth_u
return (utility, empty_u, smooth_u, big_t_u)
def maximize(self, board, depth = 0):
moves = board.get_available_moves()
moves_boards = []
for m in moves:
m_board = board.clone()
m_board.move(m)
moves_boards.append((m, m_board))
max_utility = (float('-inf'),0,0,0)
best_direction = None
for mb in moves_boards:
utility = self.chance(mb[1], depth + 1)
if utility[0] >= max_utility[0]:
max_utility = utility
best_direction = mb[0]
return best_direction, max_utility
def chance(self, board, depth = 0):
empty_cells = board.get_available_cells()
n_empty = len(empty_cells)
#if n_empty >= 7 and depth >= 5:
# return self.eval_board(board, n_empty)
if n_empty >= 6 and depth >= 3:
return self.eval_board(board, n_empty)
if n_empty >= 0 and depth >= 5:
return self.eval_board(board, n_empty)
if n_empty == 0:
_, utility = self.maximize(board, depth + 1)
return utility
possible_tiles = []
chance_2 = (.9 * (1 / n_empty))
chance_4 = (.1 * (1 / n_empty))
for empty_cell in empty_cells:
possible_tiles.append((empty_cell, 2, chance_2))
possible_tiles.append((empty_cell, 4, chance_4))
utility_sum = [0, 0, 0, 0]
for t in possible_tiles:
t_board = board.clone()
t_board.insert_tile(t[0], t[1])
_, utility = self.maximize(t_board, depth + 1)
for i in range(4):
utility_sum[i] += utility[i] * t[2]
return tuple(utility_sum)