Skip to content
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.