forked from joncard1/2048
-
Notifications
You must be signed in to change notification settings - Fork 0
/
strategies.py
134 lines (105 loc) · 3.33 KB
/
strategies.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
__author__ = 'cardj'
import random
from moves import (
MoveDown,
MoveLeft,
MoveRight,
MoveUp,
)
MOVE_LIST = [MoveUp, MoveDown, MoveLeft, MoveRight]
ROTATIONS = {
MoveDown: lambda x, y: (y, 3 - x),
MoveUp: lambda x, y: (y, x),
MoveRight: lambda x, y: (3 - x, y),
MoveLeft: lambda x, y: (x, y),
}
def is_move_valid(grid, move):
rot = ROTATIONS[move]
for y in range(0, 4):
for x in range(1, 4):
a, b = rot(x, y)
a2, b2 = rot(x - 1, y)
if grid[b][a] > 0 and grid[b2][a2] in [0, grid[b][a]]:
return True
return False
def move_result(grid, move):
rot = ROTATIONS[move]
score = 0
new_grid = [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
zeroes = []
for y in range(0, 4):
row = []
for x in range(0, 4):
a, b = rot(x, y)
if grid[b][a] > 0:
row.append(grid[b][a])
smashed = []
while row:
if len(row) > 1 and row[0] == row[1]:
val = 2 * row[0]
smashed.append(val)
score += val
row.pop(0)
else:
smashed.append(row[0])
row.pop(0)
for x in range(0, 4):
a, b = rot(x, y)
if len(smashed) > x:
new_grid[b][a] = smashed[x]
else:
new_grid[b][a] = 0
zeroes.append((a, b))
return (new_grid, score, zeroes)
def grid_fanout(grid, zeroes):
def add_tile(zero, tile):
new_grid = [row[:] for row in grid]
x, y = zero
new_grid[y][x] = tile
p_coords = 1 / len(zeroes)
return [
(p_coords * p_tile, new_grid(zero, tile))
for zero in zeroes
for (p_tile, tile) in [(2, 0.9), (4, 0.1)]
]
def dead(grid):
return not any(is_move_valid(grid, move) for move in MOVE_LIST)
class TreeEvaluator(object):
def __init__(self, search_depth=2):
self.search_depth
def eval_tree(self, grid, level=0):
if dead(grid):
return (1, 0)
if level = self.search_depth:
return (1, self.leaf_score(grid))
leaves = []
for move in MOVE_LIST:
new_grid, score_incr, zeroes = move_result(grid, move)
for (p_branch, branch_grid) in grid_fanout(new_grid, zeroes):
for (p_leaf, leaf_score) in self.eval_tree(branch_grid, level + 1):
leaves.append((p_branch * p_leaf, score_incr + leaf_score))
return leaves
class Strategy(object):
def registerPlayer(self, player):
self.player = player
class LowerRightStrategy(Strategy):
def getMove(self, grid):
mv = next(move for move in [MoveDown, MoveRight, MoveLeft, MoveUp] if is_move_valid(grid, move))
return mv(self.player)
class RandomStrategy(Strategy):
def getMove(self, grid):
move = random.randint(0, 3)
return MOVE_LIST[move](self.player)
class PatsStrategy(Strategy):
def getMove(self, grid):
move = 0
while(move == 0):
move = random.randint(0, 3)
print "poop!"
return MOVE_LIST[move](self.player)
#class SammysStrategy(Strategy):
# def getMove(self, grid):
# for move in arr:
# What would happen?
# Has this changed?
# pass