forked from nneonneo/threes-ai
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdeck_reconstruct.py
70 lines (60 loc) · 2.2 KB
/
deck_reconstruct.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
# Reconstruct the deck state as the game plays out.
# This enables strong AI play from arbitrary starting positions.
from __future__ import print_function
from itertools import product
class DeckReconstructor:
def __init__(self, board):
''' Initialize the deck reconstruction using the given board. '''
self.candidates = []
vals = list(board.flatten())
ones = vals.count(1)
twos = vals.count(2)
for deck in product(range(5), repeat=3):
if deck[0] == deck[1] == deck[2] == 0:
continue
if deck[0]+ones == deck[1]+twos:
self.candidates.append(list(deck))
def update(self, tile):
''' Update candidates using the tile that just spawned '''
if tile > 3:
return
tile -= 1
newcands = []
for d in self.candidates:
d[tile] -= 1
if d[tile] < 0:
continue
if d[0] == d[1] == d[2] == 0:
d = [4,4,4]
newcands.append(d)
self.candidates = newcands
def __getitem__(self, i):
if not (1 <= i <= 3):
raise KeyError(i)
if len(self.candidates) < 1:
raise Exception("Deck state is invalid.")
elif len(self.candidates) == 1:
return self.candidates[0][i-1]
# Assume all current candidates are equally likely
s = sum(c[i-1] for c in self.candidates)
n = len(self.candidates)
return int(round(float(s)/n))
def __self__(self):
return "<DeckReconstructor, n=%d, avgdeck={1:%d, 2:%d, 3:%d}>" % (len(self.candidates), self[1], self[2], self[3])
def __repr__(self):
return "<DeckReconstructor, candidates=%s>" % self.candidates
if __name__ == '__main__':
# simple test sequence
import sys, os
dirname, startfn = sys.argv[1:]
deck = None
from ocr import OCR
ocr = OCR("LGE Nexus 5")
imglist = sorted([fn for fn in os.listdir(dirname) if fn >= startfn])
for fn in imglist:
print(fn)
board, tileset = ocr.ocr(os.path.join(dirname, fn))
if deck is None:
deck = DeckReconstructor(board)
deck.update(tileset[0])
print(deck)