/
main.py
121 lines (96 loc) · 3.58 KB
/
main.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
from map_loader import load_map
from sys import exit
import argparse
import time
from searches import breadth_first_search as bfs
from searches import depth_first_search as dfs
from searches import uniform_cost_search as ucs
from searches import greedy_best_first_search as gbfs
from searches import a_star_search as ass
# uninformed searches
u_searches = [
(bfs, 'breadth first search'),
(dfs, 'depth first search'),
(ucs, 'uniform cost search'),
]
# informed searches
i_searches = [
(gbfs, 'greedy best first search'),
(ass, 'A* search')
]
test_maps = [
'easy_3',
'moderate_1',
'moderate_2',
]
def reportit(f):
def report(*args, **kw):
t_start = time.time()
report, board = f(*args, **kw)
runtime = (time.time()-t_start)
print """Data for {search_name}\n{moves}
a)\t{generated}\tNodes generated
b)\t{repeated}\tNodes repeated
c)\t{fringe}\tNodes at the fringe of the search
d)\t{explored}\tnodes explored
e)\t{runtime} seconds
""".format( search_name = kw['search_name'],
moves = ','.join(board.moves),
generated = report['node'],
repeated = report['repeat'],
fringe = report['fringe'],
explored = len(report['explored']),
runtime = runtime
)
return report
@reportit
def run_search(cli_args=None, puzzle_path=None, search=None, search_name=None):
board = load_map(get_map_str(puzzle_path))
results, board = search(board, print_steps=args.steps)
return results, board
def get_map_str(path):
map_str = ''
with open(path, 'r') as f:
map_str = f.read()
return map_str
def get_args():
parser = argparse.ArgumentParser(
description='Get input for the sokoban program.')
parser.add_argument('puzzle', metavar='P', nargs='?',
help='Puzzle to be solved by sokoban')
parser.add_argument('--test', '--tests', dest='test', action='store_const',
const=True, default=False,
help='Run the suite of tests')
parser.add_argument('--steps', dest='steps', action='store_const',
const=True, default=False)
parser.add_argument('--informed', dest='searches', action='store_const',
const=i_searches, default=(i_searches+u_searches))
parser.add_argument('--uninformed', dest='searches', action='store_const',
const=u_searches, default=(i_searches+u_searches))
args = parser.parse_args()
if not args.test and not args.puzzle:
print 'Please use a parameter with this program.'
print "\tRerun the program with the '--help' flag for more details."
exit(1)
return args
def test(args):
for map_path in test_maps:
print '{0}\n\tTesting on map {1}\n{0}'.format('-'*64, map_path)
for search, search_name in args.searches:
run_search( cli_args=args,
puzzle_path='sokoban_boards/{}.txt'.format(map_path),
search=search,
search_name=search_name)
def puzzle(args):
print '{0}\n\tTesting on map {1}\n{0}'.format('-'*64, args.puzzle)
for search, search_name in args.searches:
run_search(cli_args=args,
puzzle_path=args.puzzle,
search=search,
search_name=search_name)
if __name__ == '__main__':
args = get_args()
if args.puzzle:
puzzle(args)
elif args.test:
test(args)