Subversion Repositories programming

Rev

Details | Last modification | View Log | RSS feed

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