Subversion Repositories programming

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
394 ira 1
#!/usr/bin/env python
2
 
395 ira 3
# Fix for the lame version of python on the school's computers (v2.1)
4
try:
5
	(True, False)
6
except NameError:
7
	(True, False) = (1, 0)
8
 
394 ira 9
from Menu import Menu
10
from PuzzlePiece import PuzzlePiece
11
import PuzzleSearch
12
import sys
13
 
14
################################################################################
15
### Search Algorithms
16
################################################################################
17
 
18
DEFAULT_MAX_ITERATIONS=1000
19
 
20
def m_search_generic (name, start, goals, add_algorithm, MAX_ITERATIONS=DEFAULT_MAX_ITERATIONS):
21
	s = PuzzleSearch.PuzzleSearch (start, goals)
22
 
23
	# Run the search
24
	result = s.search (add_algorithm, MAX_ITERATIONS)
25
	result.set_search_name (name)
26
	print result
27
	print
28
 
29
	return result
30
 
31
def m_bfs (start_node, goal_node):
32
	return m_search_generic ('Breadth First Search', start_node,
33
			(goal_node, ), PuzzleSearch.add_bfs)
34
 
35
def m_dfs (start_node, goal_node):
36
	return m_search_generic ('Depth First Search', start_node,
37
			(goal_node, ), PuzzleSearch.add_dfs)
38
 
39
def m_bfs_h1 (start_node, goal_node):
40
	return m_search_generic ('Best First Search: Heuristic 1', start_node,
41
			(goal_node, ), PuzzleSearch.bfs_oop)
42
 
43
def m_bfs_h2 (start_node, goal_node):
44
	return m_search_generic ('Best First Search: Heuristic 2', start_node,
45
			(goal_node, ), PuzzleSearch.bfs_dfc)
46
 
47
def m_asearch_h1 (start_node, goal_node):
48
	return m_search_generic ('A*-Search: Heuristic 1', start_node,
49
			(goal_node, ), PuzzleSearch.astar_oop)
50
 
51
def m_asearch_h2 (start_node, goal_node):
52
	return m_search_generic ('A*-Search: Heuristic 2', start_node,
53
			(goal_node, ), PuzzleSearch.astar_dfc)
54
 
55
################################################################################
56
 
57
def m_render_graph (result):
58
	try:
395 ira 59
		no_graphviz = False
394 ira 60
		import yapgvb
395 ira 61
	except ImportError:
62
		no_graphviz = True
394 ira 63
 
395 ira 64
	from DrawGraph import DrawGraph
394 ira 65
 
395 ira 66
	if no_graphviz:
67
		dg = DrawGraph (result.search_name, result.result_graph)
68
		dg.render_stupid ('generated_by')
69
 
394 ira 70
	# Try to render the graph, nicely
395 ira 71
	elif result.result_graph != None:
394 ira 72
		fname = raw_input('Enter filename (press ENTER for \'res.svg\'): ')
73
		print
74
 
75
		if fname == '':
76
			fname = 'res.svg'
77
 
78
		# Actually draw the graph
79
		dg = DrawGraph (result.search_name, result.result_graph)
395 ira 80
		dg.render_graphviz (fname, yapgvb.engines.dot)
394 ira 81
	else:
82
		print 'The search failed, therefore I cannot render the graph!'
83
 
84
def gen_start_state (goal_node):
85
	DEPTH=12
86
	result = PuzzleSearch.get_nth_child (goal_node, DEPTH)
87
 
88
	# "Fix" the node given back to us
89
	result.depth = 0
90
	result.goal = goal_node
91
	return result
92
 
93
def getstr (prompt):
94
	return raw_input (prompt + ': ')
95
 
96
def input_start_state ():
97
	state = []
98
	valid_inputs = ('1', '2', '3', '4', '5', '6', '7', '8', 'E')
99
 
100
	print 'Input start state, one row at a time, space seperated:'
101
	state += getstr ('Row 1').split()
102
	state += getstr ('Row 2').split()
103
	state += getstr ('Row 3').split()
104
 
105
	# Check and make sure its ok
106
	if len(state) != 9:
107
		print 'Too many states, try again!\n'
108
		return input_start_state ()
109
 
110
	for el in state:
111
		if el not in valid_inputs:
112
			print '"%s" is not valid, try again!' % el
113
			return input_start_state ()
114
 
115
	return state
116
 
117
 
118
def main ():
119
 
120
	# Very important start state information
121
	goal_config = ['1', '2', '3', '8', 'E', '4', '7', '6', '5']
122
	goal_node = PuzzlePiece (goal_config)
123
 
124
	m = Menu ()
125
	m.add_entry ('1', 'Enter start state', input_start_state)
126
	m.add_entry ('2', 'Generate Reachable Start State', gen_start_state)
127
	m.add_entry ('3', 'Quit', sys.exit)
128
	(entry, callback) = m.run_menu ()
129
 
130
	# Must be from #1
131
	if entry == '1':
132
		start_node = PuzzlePiece (callback(), 0, goal_node)
133
	elif entry == '2':
134
		start_node = callback(goal_node)
135
 
136
	# Get set up for the next menu
137
	search_result = None
138
 
139
	# Set up the final menu
140
	m = Menu ()
141
	m.add_entry ('1', 'Breadth First Search', m_bfs)
142
	m.add_entry ('2', 'Depth First Search', m_dfs)
143
	m.add_entry ('3', 'Best First Search: Heuristic 1', m_bfs_h1)
144
	m.add_entry ('4', 'Best First Search: Heuristic 2', m_bfs_h2)
145
	m.add_entry ('5', 'A*-Search: Heuristic 1', m_asearch_h1)
146
	m.add_entry ('6', 'A*-Search: Heuristic 2', m_asearch_h2)
147
	m.add_entry ('7', 'Change Start State', input_start_state)
148
	m.add_entry ('8', 'Generate Reachable Start State', gen_start_state)
149
	m.add_entry ('9', 'Render Graph of last result', m_render_graph)
150
	m.add_entry ('q', 'Quit', sys.exit)
151
	m.hide_entry ('9')
152
 
153
	while True:
154
		# Add support for graph rendering
155
		m.hide_entry ('9')
156
		if search_result:
157
			if search_result.completed:
158
				m.unhide_entry ('9')
159
 
160
		(entry, callback) = m.run_menu ()
161
 
162
		# Check if we need to change the start node
163
		if entry == '7':
164
			start_node = PuzzlePiece (callback(), 0, goal_node)
165
		elif entry == '8':
166
			search_result = False
167
			start_node = callback (goal_node)
168
		elif entry == '9':
169
			callback (search_result)
170
		# Check if we need to quit
171
		elif entry == 'q':
172
			callback ()
173
		else:
174
			# Must be one of the search functions, so call them!
175
			search_result = callback (start_node, goal_node)
176
 
177
if __name__ == '__main__':
178
	main ()
179