Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding Tkinter GUI (2) and Visualization in notebook #670

Merged
merged 14 commits into from
Dec 29, 2017
97 changes: 76 additions & 21 deletions gui/romania_problem.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
import math
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
from search import *
from search import breadth_first_tree_search as bfts, depth_first_tree_search as dfts,depth_first_graph_search as dfgs
from search import breadth_first_tree_search as bfts, depth_first_tree_search as dfts, \
depth_first_graph_search as dfgs, breadth_first_search as bfs
from utils import Stack, FIFOQueue, PriorityQueue
from copy import deepcopy

root = None
city_coord = {}
romania_problem = None
Expand All @@ -19,7 +21,8 @@
front = None
node = None
next_button = None
explored=None
explored = None


def create_map(root):
'''
Expand Down Expand Up @@ -97,7 +100,7 @@ def create_map(root):
romania_locations['Mehadia'][0],
height -
romania_locations['Mehadia'][1],
romania_map.get('Lugoj', 'Mehandia'))
romania_map.get('Lugoj', 'Mehadia'))
make_line(
city_map,
romania_locations['Drobeta'][0],
Expand All @@ -106,7 +109,7 @@ def create_map(root):
romania_locations['Mehadia'][0],
height -
romania_locations['Mehadia'][1],
romania_map.get('Drobeta', 'Mehandia'))
romania_map.get('Drobeta', 'Mehadia'))
make_line(
city_map,
romania_locations['Drobeta'][0],
Expand Down Expand Up @@ -274,11 +277,19 @@ def make_rectangle(map, x0, y0, margin, city_name):
x0 + margin,
y0 + margin,
fill="white")
map.create_text(
x0 - 2 * margin,
y0 - 2 * margin,
text=city_name,
anchor=SE)
if "Bucharest" in city_name or "Pitesti" in city_name or "Lugoj" in city_name \
or "Mehadia" in city_name or "Drobeta" in city_name:
map.create_text(
x0 - 2 * margin,
y0 - 2 * margin,
text=city_name,
anchor=E)
else:
map.create_text(
x0 - 2 * margin,
y0 - 2 * margin,
text=city_name,
anchor=SE)
city_coord.update({city_name: rect})


Expand All @@ -302,7 +313,7 @@ def make_legend(map):

def tree_search(problem):
'''
earch through the successors of a problem to find a goal.
Search through the successors of a problem to find a goal.
The argument frontier should be an empty queue.
Don't worry about repeated paths to a state. [Figure 3.7]
This function has been changed to make it suitable for the Tkinter GUI.
Expand All @@ -329,20 +340,23 @@ def tree_search(problem):
display_explored(node)
return None


def graph_search(problem):
'''
Search through the successors of a problem to find a goal.
The argument frontier should be an empty queue.
If two paths reach a state, only use the first one. [Figure 3.7]
This function has been changed to make it suitable for the Tkinter GUI.
'''
global counter,frontier,node,explored
global counter, frontier, node, explored
if counter == -1:
frontier.append(Node(problem.initial))
explored=set()
explored = set()
# print("Frontier: "+str(frontier))
display_frontier(frontier)
if counter % 3 ==0 and counter >=0:
if counter % 3 == 0 and counter >= 0:
node = frontier.pop()
# print("Current node: "+str(node))
display_current(node)
if counter % 3 == 1 and counter >= 0:
if problem.goal_test(node.state):
Expand All @@ -351,13 +365,14 @@ def graph_search(problem):
frontier.extend(child for child in node.expand(problem)
if child.state not in explored and
child not in frontier)
# print("Frontier: " + str(frontier))
display_frontier(frontier)
if counter % 3 == 2 and counter >= 0:
# print("Explored node: "+str(node))
display_explored(node)
return None



def display_frontier(queue):
'''
This function marks the frontier nodes (orange) on the map.
Expand All @@ -370,6 +385,7 @@ def display_frontier(queue):
if node.state == city:
city_map.itemconfig(city_coord[city], fill="orange")


def display_current(node):
'''
This function marks the currently exploring node (red) on the map.
Expand All @@ -378,6 +394,7 @@ def display_current(node):
city = node.state
city_map.itemconfig(city_coord[city], fill="red")


def display_explored(node):
'''
This function marks the already explored node (gray) on the map.
Expand All @@ -386,6 +403,7 @@ def display_explored(node):
city = node.state
city_map.itemconfig(city_coord[city], fill="gray")


def display_final(cities):
'''
This function marks the final solution nodes (green) on the map.
Expand All @@ -394,6 +412,7 @@ def display_final(cities):
for city in cities:
city_map.itemconfig(city_coord[city], fill="green")


def breadth_first_tree_search(problem):
"""Search the shallowest nodes in the search tree first."""
global frontier, counter
Expand All @@ -405,19 +424,48 @@ def breadth_first_tree_search(problem):
def depth_first_tree_search(problem):
"""Search the deepest nodes in the search tree first."""
# This search algorithm might not work in case of repeated paths.
global frontier,counter
global frontier, counter
if counter == -1:
frontier=Stack()
frontier = Stack()
return tree_search(problem)

# TODO: Check if the solution given by this function is consistent with the original function.

def breadth_first_search(problem):
"""[Figure 3.11]"""
global frontier, node, explored, counter
if counter == -1:
node = Node(problem.initial)
display_current(node)
if problem.goal_test(node.state):
return node
frontier = FIFOQueue()
frontier.append(node)
display_frontier(frontier)
explored = set()
if counter % 3 == 0 and counter >= 0:
node = frontier.pop()
display_current(node)
explored.add(node.state)
if counter % 3 == 1 and counter >= 0:
for child in node.expand(problem):
if child.state not in explored and child not in frontier:
if problem.goal_test(child.state):
return child
frontier.append(child)
display_frontier(frontier)
if counter % 3 == 2 and counter >= 0:
display_explored(node)
return None


def depth_first_graph_search(problem):
"""Search the deepest nodes in the search tree first."""
global frontier, counter
if counter == -1:
frontier = Stack()
return graph_search(problem)


# TODO:
# Remove redundant code.
# Make the interchangbility work between various algorithms at each step.
Expand All @@ -443,19 +491,24 @@ def on_click():
display_final(final_path)
next_button.config(state="disabled")
counter += 1
elif "Breadth-First Search" == algo.get():
node = breadth_first_search(romania_problem)
if node is not None:
final_path = bfs(romania_problem).solution()
final_path.append(start.get())
display_final(final_path)
next_button.config(state="disabled")
counter += 1
elif "Depth-First Graph Search" == algo.get():
node = depth_first_graph_search(romania_problem)
if node is not None:
print(node)
final_path = dfgs(romania_problem).solution()
print(final_path)
final_path.append(start.get())
display_final(final_path)
next_button.config(state="disabled")
counter += 1



def reset_map():
global counter, city_coord, city_map, next_button
counter = -1
Expand All @@ -479,7 +532,9 @@ def main():
goal.set('Bucharest')
cities = sorted(romania_map.locations.keys())
algorithm_menu = OptionMenu(
root, algo, "Breadth-First Tree Search", "Depth-First Tree Search","Depth-First Graph Search")
root,
algo, "Breadth-First Tree Search", "Depth-First Tree Search",
"Breadth-First Search", "Depth-First Graph Search")
Label(root, text="\n Search Algorithm").pack()
algorithm_menu.pack()
Label(root, text="\n Start City").pack()
Expand Down
6 changes: 3 additions & 3 deletions gui/tic-tac-toe.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,8 @@ def check_victory(button):
return True

# check if previous move was on the secondary diagonal and caused a win
if x + \
y == 2 and buttons[0][2]['text'] == buttons[1][1]['text'] == buttons[2][0]['text'] != " ":
if x + y \
== 2 and buttons[0][2]['text'] == buttons[1][1]['text'] == buttons[2][0]['text'] != " ":
buttons[0][2].config(text="/" + tt + "/")
buttons[1][1].config(text="/" + tt + "/")
buttons[2][0].config(text="/" + tt + "/")
Expand Down Expand Up @@ -218,6 +218,7 @@ def main():

root = Tk()
root.title("TicTacToe")
root.geometry("150x200") # Improved the window geometry
root.resizable(0, 0) # To remove the maximize window option
result = StringVar()
result.set("Your Turn!")
Expand All @@ -233,4 +234,3 @@ def main():

if __name__ == "__main__":
main()

349 changes: 311 additions & 38 deletions search.ipynb

Large diffs are not rendered by default.