Subversion Repositories programming

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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