-
Notifications
You must be signed in to change notification settings - Fork 279
/
Copy path2048.py
executable file
·131 lines (106 loc) · 4.16 KB
/
2048.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
#!/usr/bin/python
# -*- coding: utf-8 -*-
''' Help the user achieve a high score in a real game of 2048 by using a move searcher. '''
from __future__ import print_function
import time
from ailib import ailib, to_c_board, from_c_index
# Enable multithreading?
MULTITHREAD = True
def print_board(m):
for row in m:
for c in row:
print('%8d' % c, end=' ')
print()
def to_val(m):
return [[from_c_index(c) for c in row] for row in m]
def _to_score(c):
if c <= 1:
return 0
return (c-1) * (2**c)
def to_score(m):
return [[_to_score(c) for c in row] for row in m]
if MULTITHREAD:
from multiprocessing.pool import ThreadPool
pool = ThreadPool(4)
def score_toplevel_move(args):
return ailib.score_toplevel_move(*args)
def find_best_move(m):
board = to_c_board(m)
print_board(to_val(m))
scores = pool.map(score_toplevel_move, [(board, move) for move in range(4)])
bestmove, bestscore = max(enumerate(scores), key=lambda x:x[1])
if bestscore == 0:
return -1
return bestmove
else:
def find_best_move(m):
board = to_c_board(m)
return ailib.find_best_move(board)
def movename(move):
return ['up', 'down', 'left', 'right'][move]
def play_game(gamectrl):
moveno = 0
start = time.time()
while 1:
state = gamectrl.get_status()
if state == 'ended':
break
elif state == 'won':
time.sleep(0.75)
gamectrl.continue_game()
moveno += 1
board = gamectrl.get_board()
move = find_best_move(board)
if move < 0:
break
print("%010.6f: Score %d, Move %d: %s" % (time.time() - start, gamectrl.get_score(), moveno, movename(move)))
gamectrl.execute_move(move)
score = gamectrl.get_score()
board = gamectrl.get_board()
maxval = max(max(row) for row in to_val(board))
print("Game over. Final score %d; highest tile %d." % (score, maxval))
def parse_args(argv):
import argparse
parser = argparse.ArgumentParser(description="Use the AI to play 2048 via browser control")
parser.add_argument('-p', '--port', help="Port number to control on (default: 32000 for Firefox, 9222 for Chrome)", type=int)
parser.add_argument('-b', '--browser', help="Browser you're using. Only Firefox with remote debugging, Firefox with the Remote Control extension (deprecated), and Chrome with remote debugging, are supported right now.", default='firefox', choices=('firefox', 'firefox-rc', 'chrome', 'manual'))
parser.add_argument('-k', '--ctrlmode', help="Control mode to use. If the browser control doesn't seem to work, try changing this.", default='hybrid', choices=('keyboard', 'fast', 'hybrid', 'play2048co'))
return parser.parse_args(argv)
def main(argv):
args = parse_args(argv)
if args.browser == 'firefox':
from ffctrl import FirefoxDebuggerControl
if args.port is None:
args.port = 32000
ctrl = FirefoxDebuggerControl(args.port)
elif args.browser == 'firefox-rc':
from ffctrl import FirefoxRemoteControl
if args.port is None:
args.port = 32000
ctrl = FirefoxRemoteControl(args.port)
elif args.browser == 'chrome':
from chromectrl import ChromeDebuggerControl
if args.port is None:
args.port = 9222
ctrl = ChromeDebuggerControl(args.port)
if args.browser == 'manual':
from manualctrl import ManualControl
gamectrl = ManualControl()
elif args.ctrlmode == 'keyboard':
from gamectrl import Keyboard2048Control
gamectrl = Keyboard2048Control(ctrl)
elif args.ctrlmode == 'fast':
from gamectrl import Fast2048Control
gamectrl = Fast2048Control(ctrl)
elif args.ctrlmode == 'hybrid':
from gamectrl import Hybrid2048Control
gamectrl = Hybrid2048Control(ctrl)
elif args.ctrlmode == 'play2048co':
from gamectrl import Play2048CoControl
gamectrl = Play2048CoControl(ctrl)
if gamectrl.get_status() == 'ended':
gamectrl.restart_game()
play_game(gamectrl)
if __name__ == '__main__':
import sys
exit(main(sys.argv[1:]))