Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 32 additions & 5 deletions ai-readme.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,41 @@
To use this astar GUI/toy, hit the 'l' key to switch to the 'add lava tiles' mode. Then you can click on any cell to add or remove a lava tile from that cell. Hit the spacebar at any time to have Paul plan (or replan) his path, and highlight that path. To see the f,g, and h values that astar calculates, take a look at the instructions in question 1. Feel free to reach out at any time about problems.

0. Read up on astar [here](http://web.mit.edu/eranki/www/tutorials/search/) and [here](http://www.raywenderlich.com/4946/introduction-to-a-pathfinding). Do your best to understand what the pseudocode in the links mean. What are the advantages that A star has over breadth-first search? What advantages does A star have over depth-first search?
0. Read up on astar [here](http://web.mit.edu/eranki/www/tutorials/search/) and [here](http://www.raywenderlich.com/4946/introduction-to-a-pathfinding). Do your best to understand what the pseudocode in the links mean. What are the advantages that A star has over breadth-first search? What advantages does A star have over depth-first search?

Breadth-first is already better than depth-first because it searches its surroundings in a rudimentary way instead of visiting every node randomly, but Astar is better because of the way it utilizes the g and h values over just checking surrounding tiles blindly. This means Astar will be faster than either breath or depth first.



1. Take a look at lines 124-127 of the code. Try commenting and uncommenting lines and running python astar.py to see what values are printed in each cell. Take a screenshot of each example with some lava tiles placed down, and in your own words, explain what f_score, g_score, and h_score are, and why you see those specific values in the screenshot.

g_score is the distance or cost it took to get to the node. For the tile example, the cost for travelling between tiles is one. Between two tiles, it is 2 and so on.
h_score is the estimated cost to the node.
f_score is the combination of g and h. This combination is what makes Astar work better than other searches because it shows the cost relative to how much it should approximately cost and looks for a combination of the lowest h and g values.
The screenshots are located in the f_g_h file.


1. Take a look at lines 124-127 of the code. Try commenting and uncommenting lines and running python astar.py to see what values are printed in each cell. Take a screenshot of each example with some lava tiles placed down, and in your own words, explain what f_score, g_score, and h_score are, and why you see those specific values in the screenshot.

For questions 2, 3, and 4, you should implement the code to get the specified behavior, but also place tiles and set up a scenario/path where that newly implemented behavior is demonstrated (ex. Paul moving diagonally or moving through a swamp.) Then include a screenshot and explanation. Quoting Paul, "Once you make a change, you should include a screenshot of the pygame window that shows the generated path for a given set of obstacles. You should be ready to explain why the shown path is actually the shortest (for instance… “the diagonal move while costly, is necessary in order to reach the goal, paths consisting of just up, down, left, or right would not be able to reach the goal”)."

2. Read the get_open_adj_coords() function and lines 204 to 210 to get an idea of how valid adjacent cells are found. In the current code, valid adjacent cells only include the surrounding cells in the 4 cardinal directions, and moving to any of these cells costs 1 movement point. Add code changing the get_open_adj_coords() function so that surrounding diagonal cells are considered valid adjacent cells and moving to any of these cells costs 3 movement points. This will allow Paul to
move diagonally.

3. Change the program so that pressing 's' allows you to add swamp tiles. Paul should be able to move through swamp tiles, but they will slow him down! Moving into a swamp tile will cost 3 movement points, so Paul should really avoid moving through swamp tiles unless he has to. A swamp.jpg file has been provided for you in the /images folder. You will probably have to make some changes to the costs in get_open_adj_coords and write your own _add_swamp() function to get swamp tiles to behave correctly.


2. Read the get_open_adj_coords() function and lines 204 to 210 to get an idea of how valid adjacent cells are found. In the current code, valid adjacent cells only include the surrounding cells in the 4 cardinal directions, and moving to any of these cells costs 1 movement point. Add code changing the get_open_adj_coords() function so that surrounding diagonal cells are considered valid adjacent cells and moving to any of these cells costs 3 movement points. This will allow Paul to move diagonally.

Screenshot is in the modImg folder.
This screenshot shows that diagonal movement is possible. However, whenever Paul can avoid
moving diagonally he does (as shown by the top left and bottom right of the window) because moving diagonally is more costly.



3. Change the program so that pressing 's' allows you to add swamp tiles. Paul should be able to move through swamp tiles, but they will slow him down! Moving into a swamp tile will cost 3 movement points, so Paul should really avoid moving through swamp tiles unless he has to. A swamp.jpg file has been provided for you in the /images folder. You will probably have to make some changes to the costs in get_open_adj_coords and write your own _add_swamp()_ function to get swamp tiles to behave correctly.

Screenshot is in the modImg folder.
This screenshot shows that hopping is now possible. Paul will avoid this when possible because the cost is so high.



4. Evolve Paul and allow him to jump over lava! Add the ability for Paul to jump one square. This should cost 8 movement points, however. This will involve changing get_open_adj_coords().

Screenshot is in the modImg folder.
The image shows that Paul can cross swamps and the cost is increased (looking at the f value).
37 changes: 29 additions & 8 deletions astar.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import pygame
import math
# http://www.raywenderlich.com/4946/introduction-to-a-pathfinding


Expand Down Expand Up @@ -73,8 +74,14 @@ def _is_occupied(self, cell_coord):

def _add_swamp(self, mouse_pos):
""" Adds a swamp tile in the cell that mouse_pos indicates """
# insert swamp code here.
pass
swamp_coord = (mouse_pos[0]//50, mouse_pos[1]//50)
if self._is_occupied(swamp_coord):
if self.actors[swamp_coord].removable:
self.actors.pop(swamp_coord, None)
elif swamp_coord != self.cake.cell_coordinates:
swamp = ObstacleTile(swamp_coord, self, './images/swamp.jpg',
is_unpassable=False, terrain_cost=3)
self.actors[swamp_coord] = swamp

def _add_lava(self, mouse_pos):
""" Adds a lava tile in the cell that mouse_pos indicates """
Expand Down Expand Up @@ -108,11 +115,15 @@ def main_loop(self):
elif event.type is pygame.MOUSEBUTTONDOWN:
if self.add_tile_type == 'lava':
self._add_lava(event.pos)
if self.add_tile_type == 'swamp':
self._add_swamp(event.pos)
# insert swamp code here
elif event.type is pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
self.paul.run_astar(self.cake.cell_coordinates, self)
self.paul.get_path()
elif event.key == pygame.K_s:
self.add_tile_type = 'swamp'
elif event.key == pygame.K_l:
self.add_tile_type = 'lava'
# insert swamp code here
Expand Down Expand Up @@ -168,9 +179,9 @@ def f_cost(self):

def draw(self):
COST_TO_DRAW = ''
# COST_TO_DRAW = self.g_cost
# COST_TO_DRAW = self.h_cost
# COST_TO_DRAW = self.f_cost
#COST_TO_DRAW = self.g_cost
#COST_TO_DRAW = self.h_cost
COST_TO_DRAW = self.f_cost
line_width = 2
rect = pygame.Rect(self.coordinates, self.dimensions)
pygame.draw.rect(self.draw_screen, self.color, rect, line_width)
Expand All @@ -196,15 +207,25 @@ def get_open_adj_coords(self, coords):
""" returns list of valid coords that are adjacent to the argument,
open, and not in the closed list. """
# modify directions and costs as needed
directions = [(1, 0), (0, 1), (-1, 0), (0, -1)]
directions = [(1, 0), (0, 1), (-1, 0), (0, -1), (1, 1), (1, -1), (-1, -1), (-1, 1), (2, 0), (-2, 0), (0, 2), (0, -2)]
all_adj = [self.world._add_coords(coords, d) for d in directions]
in_bounds = [self.is_valid(c) for c in all_adj]
costs = []
open_adj = []
for i, coord in enumerate(all_adj):
if(in_bounds[i]):
costs.append(1 + self.world.get_terrain_cost(coord))
open_adj.append(coord)
if (math.sqrt(2)) == math.sqrt((coord[0]-coords[0])**2 + (coord[1]-coords[1])**2):
#for diagonal, cost is 3
costs.append(3 + self.world.get_terrain_cost(coord))
open_adj.append(coord)
elif abs(coord[0]-coords[0]) == 2 or abs(coord[1]-coords[1]) == 2:
#for mad hops, cost is 8
costs.append(8 + self.world.get_terrain_cost(coord))
open_adj.append(coord)
else:
#boring Paul goes straight for cost 1
costs.append(1 + self.world.get_terrain_cost(coord))
open_adj.append(coord)
return open_adj, costs

def is_valid(self, coord):
Expand Down
Binary file added f_g_h/f_score.JPG
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added f_g_h/g_score.JPG
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added f_g_h/h_score.JPG
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added modImg/diagonal.PNG
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added modImg/hops.PNG
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added modImg/swamp.PNG
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.