forked from bloominstituteoftechnology/Graphs
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
226 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
__pycache__ | ||
*.pyc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
## Description | ||
|
||
You are provided with a pre-generated graph consisting of 500 rooms. You are responsible for filling `traversalPath` with directions that, when walked in order, will visit every room on the map at least once. | ||
|
||
Open `adv.py`. There are four parts to the provided code: | ||
|
||
* World generation code. Do not modify this! | ||
* An incomplete list of directions. Your task is to fill this with valid traversal directions. | ||
* Test code. Run the tests by typing `python3 adv.py` in your terminal. | ||
* REPL code. You can uncomment this and run `python3 adv.py` to walk around the map. | ||
|
||
|
||
You may find the commands `player.currentRoom.id`, `player.currentRoom.getExits()` and `player.travel(direction)` useful. | ||
|
||
To solve this path, you'll want to construct your own traversal graph. You start in room `0`, which contains exits `['n', 's', 'w', 'e']`. Your starting graph should look something like this: | ||
|
||
``` | ||
{ | ||
0: {'n': '?', 's': '?', 'w': '?', 'e': '?'} | ||
} | ||
``` | ||
|
||
Try moving south and you will find yourself in room `5` which contains exits `['n', 's', 'e']`. You can now fill in some entries in your graph: | ||
|
||
``` | ||
{ | ||
0: {'n': '?', 's': 5, 'w': '?', 'e': '?'}, | ||
5: {'n': 0, 's': '?', 'e': '?'} | ||
} | ||
``` | ||
|
||
You know you are done when you have exactly 500 entries (0-499) in your graph and no `'?'` in the adjacency dictionaries. To do this, you will need to write a traversal algorithm that logs the path into `traversalPath` as it walks. | ||
|
||
## Hints | ||
|
||
There are a few smaller graphs in the file which you can test your traversal method on before committing to the large graph. You may find these easier to debug. | ||
|
||
Start by writing an algorithm that picks a random unexplored direction from the player's current room, travels and logs that direction, then loops. This should cause your player to walk a depth-first traversal. When you reach a dead-end (i.e. a room with no unexplored paths), walk back to the nearest room that does contain an unexplored path. | ||
|
||
You can find the path to the shortest unexplored room by using a breadth-first search for a room with a `'?'` for an exit. If you use the `bfs` code from the homework, you will need to make a few modifications. | ||
|
||
1. Instead of searching for a target vertex, you are searching for an exit with a `'?'` as the value. If an exit has been explored, you can put it in your BFS queue like normal. | ||
|
||
2. BFS will return the path as a list of room IDs. You will need to convert this to a list of n/s/e/w directions before you can add it to your traversal path. | ||
|
||
If all paths have been explored, you're done! | ||
|
||
## Minimum Viable Product | ||
|
||
* __1__: Tests do not pass | ||
* __2__: Tests pass with `len(traversalPath) < 2000` | ||
* __3__: Tests pass with `len(traversalPath) < 1000` | ||
|
||
## Stretch Problems | ||
|
||
It is very difficult to calculate the shortest possible path that traverses the entire graph. Why? | ||
|
||
My best path is 990 moves. Can you find a shorter path? |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
class Player: | ||
def __init__(self, name, startingRoom): | ||
self.name = name | ||
self.currentRoom = startingRoom | ||
def travel(self, direction, showRooms = False): | ||
nextRoom = self.currentRoom.getRoomInDirection(direction) | ||
if nextRoom is not None: | ||
self.currentRoom = nextRoom | ||
if (showRooms): | ||
nextRoom.printRoomDescription(self) | ||
else: | ||
print("You cannot move in that direction.") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
# Implement a class to hold room information. This should have name and | ||
# description attributes. | ||
class Room: | ||
def __init__(self, name, description, id=0, x=None, y=None): | ||
self.id = id | ||
self.name = name | ||
self.description = description | ||
self.n_to = None | ||
self.s_to = None | ||
self.e_to = None | ||
self.w_to = None | ||
self.x = x | ||
self.y = y | ||
def __str__(self): | ||
return f"\n-------------------\n\n{self.name}\n\n {self.description}\n\n{self.getExitsString()}\n" | ||
def printRoomDescription(self, player): | ||
print(str(self)) | ||
def getExits(self): | ||
exits = [] | ||
if self.n_to is not None: | ||
exits.append("n") | ||
if self.s_to is not None: | ||
exits.append("s") | ||
if self.w_to is not None: | ||
exits.append("w") | ||
if self.e_to is not None: | ||
exits.append("e") | ||
return exits | ||
def getExitsString(self): | ||
return f"Exits: [{', '.join(self.getExits())}]" | ||
def connectRooms(self, direction, connectingRoom): | ||
if direction == "n": | ||
self.n_to = connectingRoom | ||
connectingRoom.s_to = self | ||
elif direction == "s": | ||
self.s_to = connectingRoom | ||
connectingRoom.n_to = self | ||
elif direction == "e": | ||
self.e_to = connectingRoom | ||
connectingRoom.w_to = self | ||
elif direction == "w": | ||
self.w_to = connectingRoom | ||
connectingRoom.e_to = self | ||
else: | ||
print("INVALID ROOM CONNECTION") | ||
return None | ||
def getRoomInDirection(self, direction): | ||
if direction == "n": | ||
return self.n_to | ||
elif direction == "s": | ||
return self.s_to | ||
elif direction == "e": | ||
return self.e_to | ||
elif direction == "w": | ||
return self.w_to | ||
else: | ||
return None | ||
def getCoords(self): | ||
return [self.x, self.y] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
from room import Room | ||
import random | ||
import math | ||
|
||
class World: | ||
def __init__(self): | ||
self.startingRoom = None | ||
self.rooms = {} | ||
self.roomGrid = [] | ||
self.gridSize = 0 | ||
def loadGraph(self, roomGraph): | ||
numRooms = len(roomGraph) | ||
rooms = [None] * numRooms | ||
gridSize = 1 | ||
for i in range(0, numRooms): | ||
x = roomGraph[i][0][0] | ||
gridSize = max(gridSize, roomGraph[i][0][0], roomGraph[i][0][1]) | ||
self.rooms[i] = Room(f"Room {i}", f"({roomGraph[i][0][0]},{roomGraph[i][0][1]})",i, roomGraph[i][0][0], roomGraph[i][0][1]) | ||
self.roomGrid = [] | ||
gridSize += 1 | ||
self.gridSize = gridSize | ||
for i in range(0, gridSize): | ||
self.roomGrid.append([None] * gridSize) | ||
for roomID in roomGraph: | ||
room = self.rooms[roomID] | ||
self.roomGrid[room.x][room.y] = room | ||
if 'n' in roomGraph[roomID][1]: | ||
self.rooms[roomID].connectRooms('n', self.rooms[roomGraph[roomID][1]['n']]) | ||
if 's' in roomGraph[roomID][1]: | ||
self.rooms[roomID].connectRooms('s', self.rooms[roomGraph[roomID][1]['s']]) | ||
if 'e' in roomGraph[roomID][1]: | ||
self.rooms[roomID].connectRooms('e', self.rooms[roomGraph[roomID][1]['e']]) | ||
if 'w' in roomGraph[roomID][1]: | ||
self.rooms[roomID].connectRooms('w', self.rooms[roomGraph[roomID][1]['w']]) | ||
self.startingRoom = self.rooms[0] | ||
|
||
|
||
|