training_Data #29

Closed
s464933 wants to merge 2 commits from (deleted):master into master
16 changed files with 331 additions and 80 deletions
Showing only changes of commit dff39e4d26 - Show all commits

View File

@ -7,4 +7,4 @@ class AgentState:
def __init__(self, position: Tuple[int, int], orientation: AgentOrientation) -> None:
self.orientation = orientation
self.position = position
self.position = position

172
bfs.py
View File

@ -1,89 +1,165 @@
from agentState import AgentState
from typing import Dict, Tuple
from typing import Dict, Tuple, List
from city import City
from gridCellType import GridCellType
from agentActionType import AgentActionType
from agentOrientation import AgentOrientation
from queue import Queue
from queue import Queue, PriorityQueue
from turnCar import turn_left_orientation, turn_right_orientation
class Succ:
state: AgentState
action: AgentActionType
def __init__(self, state: AgentState, action: AgentActionType) -> None:
class Successor:
def __init__(self, state: AgentState, action: AgentActionType, cost: int, predicted_cost: int) -> None:
self.state = state
self.action = action
self.cost = cost
self.predicted_cost = cost
def find_path_to_nearest_can(startState: AgentState, grid: Dict[Tuple[int, int], GridCellType]) -> list[AgentActionType]:
q: Queue[list[Succ]] = Queue()
visited: list[AgentState] = []
startStates: list[Succ] = [Succ(startState, AgentActionType.UNKNOWN)]
q.put(startStates)
while not q.empty():
currently_checked = q.get()
visited.append(currently_checked[-1].state)
if is_state_success(currently_checked[-1].state, grid):
return extract_actions(currently_checked)
successors = succ(currently_checked[-1].state)
class SuccessorList:
succ_list: list[Successor]
def __init__(self, succ_list: list[Successor]) -> None:
self.succ_list = succ_list
def __gt__(self, other):
return self.succ_list[-1].predicted_cost > other.succ_list[-1].predicted_cost
def __lt__(self, other):
return self.succ_list[-1].predicted_cost < other.succ_list[-1].predicted_cost
def find_path_to_nearest_can(startState: AgentState, grid: Dict[Tuple[int, int], GridCellType], city: City) -> List[
AgentActionType]:
visited: List[AgentState] = []
queue: PriorityQueue[SuccessorList] = PriorityQueue()
queue.put(SuccessorList([Successor(startState, AgentActionType.UNKNOWN, 0, _heuristics(startState.position, city))]))
while not queue.empty():
current = queue.get()
previous = current.succ_list[-1]
visited.append(previous.state)
if is_state_success(previous.state, grid):
return extract_actions(current)
successors = get_successors(previous, grid, city)
for s in successors:
already_visited = False
for v in visited:
if v.position[0] == s.state.position[0] and v.position[1] == s.state.position[1] and s.state.orientation == v.orientation:
if v.position == s.state.position and v.orientation == s.state.orientation:
already_visited = True
break
if already_visited:
continue
if is_state_valid(s.state, grid):
new_list = currently_checked.copy()
new_list = current.succ_list.copy()
new_list.append(s)
q.put(new_list)
queue.put(SuccessorList(new_list))
return []
def extract_actions(successors: list[Succ]) -> list[AgentActionType]:
def extract_actions(successors: SuccessorList) -> list[AgentActionType]:
output: list[AgentActionType] = []
for s in successors:
for s in successors.succ_list:
if s.action != AgentActionType.UNKNOWN:
output.append(s.action)
return output
def succ(state: AgentState) -> list[Succ]:
result: list[Succ] = []
result.append(Succ(AgentState(state.position, turn_left_orientation(state.orientation)), AgentActionType.TURN_LEFT))
result.append(Succ(AgentState(state.position, turn_right_orientation(state.orientation)), AgentActionType.TURN_RIGHT))
state_succ = move_forward_succ(state)
if state_succ != None:
result.append(move_forward_succ(state))
def get_successors(succ: Successor, grid: Dict[Tuple[int, int], GridCellType], city: City) -> List[Successor]:
result: List[Successor] = []
turn_left_cost = 1 + succ.cost
turn_left_state = AgentState(succ.state.position, turn_left_orientation(succ.state.orientation))
turn_left_heuristics = _heuristics(succ.state.position, city)
result.append(
Successor(turn_left_state, AgentActionType.TURN_LEFT, turn_left_cost, turn_left_cost + turn_left_heuristics))
turn_right_cost = 1 + succ.cost
turn_right_state = AgentState(succ.state.position, turn_right_orientation(succ.state.orientation))
turn_right_heuristics = _heuristics(succ.state.position, city)
result.append(
Successor(turn_right_state, AgentActionType.TURN_RIGHT, turn_right_cost,
turn_right_cost + turn_right_heuristics))
state_succ = move_forward_succ(succ, city, grid)
if state_succ is not None:
result.append(state_succ)
return result
def move_forward_succ(state: AgentState) -> Succ:
position = get_next_cell(state)
if position == None:
def move_forward_succ(succ: Successor, city: City, grid: Dict[Tuple[int, int], GridCellType]) -> Successor:
position = get_next_cell(succ.state)
if position is None:
return None
return Succ(AgentState(position, state.orientation), AgentActionType.MOVE_FORWARD)
cost = get_cost_for_action(AgentActionType.MOVE_FORWARD, grid[position]) + succ.cost
predicted_cost = cost + _heuristics(position, city)
new_state = AgentState(position, succ.state.orientation)
return Successor(new_state, AgentActionType.MOVE_FORWARD, cost, predicted_cost)
def get_next_cell(state: AgentState) -> Tuple[int, int]:
if state.orientation == AgentOrientation.UP:
if state.position[1] - 1 < 1:
x, y = state.position
orientation = state.orientation
if orientation == AgentOrientation.UP:
if y - 1 < 1:
return None
return (state.position[0], state.position[1] - 1)
if state.orientation == AgentOrientation.DOWN:
if state.position[1] + 1 > 27:
return x, y - 1
elif orientation == AgentOrientation.DOWN:
if y + 1 > 27:
return None
return (state.position[0], state.position[1] + 1)
if state.orientation == AgentOrientation.LEFT:
if state.position[0] - 1 < 1:
return x, y + 1
elif orientation == AgentOrientation.LEFT:
if x - 1 < 1:
return None
return (state.position[0] - 1, state.position[1])
if state.position[0] + 1 > 27:
return x - 1, y
elif x + 1 > 27:
return None
return (state.position[0] + 1, state.position[1])
else:
return x + 1, y
def is_state_success(state: AgentState, grid: Dict[Tuple[int, int], GridCellType]) -> bool:
next_cell = get_next_cell(state)
return grid[next_cell] == GridCellType.GARBAGE_CAN
try:
return grid[next_cell] == GridCellType.GARBAGE_CAN
except KeyError:
return False
def get_cost_for_action(action: AgentActionType, cell_type: GridCellType) -> int:
if action in [AgentActionType.TURN_LEFT, AgentActionType.TURN_RIGHT]:
return 1
if cell_type == GridCellType.SPEED_BUMP and action == AgentActionType.MOVE_FORWARD:
return 10
if action == AgentActionType.MOVE_FORWARD:
return 3
def is_state_valid(state: AgentState, grid: Dict[Tuple[int, int], GridCellType]) -> bool:
return grid[state.position] == GridCellType.STREET_HORIZONTAL or grid[state.position] == GridCellType.STREET_VERTICAL
try:
return grid[state.position] == GridCellType.STREET_HORIZONTAL or grid[
state.position] == GridCellType.STREET_VERTICAL or grid[state.position] == GridCellType.SPEED_BUMP
except KeyError:
return False
def _heuristics(position: Tuple[int, int], city: City):
min_distance: int = 300
found_nonvisited: bool = False
for can in city.cans:
if can.is_visited:
continue
found_nonvisited = True
distance = 3 * (abs(position[0] - can.position[0]) + abs(position[1] - can.position[1]))
if distance < min_distance:
min_distance = distance
if found_nonvisited:
return min_distance
return -1

38
city.py
View File

@ -1,38 +1,44 @@
from typing import List
from typing import List, Dict, Tuple
from garbageCan import GarbageCan
from speedBump import SpeedBump
from street import Street
from gameContext import GameContext
class Node:
garbageCan: GarbageCan
id: int
def __init__(self, id: int, can: GarbageCan) -> None:
self.id
self.can = can
class City:
nodes: List[GarbageCan]
cans: List[GarbageCan]
bumps: List[SpeedBump]
streets: List[Street]
cans_dict: Dict[Tuple[int, int], GarbageCan] = {}
def __init__(self) -> None:
self.nodes = []
self.cans = []
self.streets = []
self.bumps = []
def add_can(self, can: GarbageCan) -> None:
self.cans.append(can)
self.cans_dict[can.position] = can
def add_node(self, node: GarbageCan) -> None:
self.nodes.append(node)
def add_street(self, street: Street) -> None:
self.streets.append(street)
def add_bump(self, bump: SpeedBump) -> None:
self.streets.append(bump)
def render_city(self, game_context: GameContext) -> None:
self._render_streets(game_context)
self._render_nodes(game_context)
self._render_bumps(game_context)
def _render_streets(self, game_context: GameContext) -> None:
for street in self.streets:
street.render(game_context)
def _render_nodes(self, game_context: GameContext) -> None:
for node in self.nodes:
node.render(game_context)
for node in self.cans:
node.render(game_context)
def _render_bumps(self, game_context: GameContext) -> None:
for bump in self.bumps:
bump.render(game_context)

View File

@ -14,6 +14,9 @@ class GameContext:
city = None
grid: Dict[Tuple[int, int], GridCellType] = {}
dust_car = None
landfill = None
def __init__(self) -> None:
self._init_grid()

View File

@ -6,10 +6,12 @@ from gridCellType import GridCellType
class GarbageCan:
position: Tuple[int, int]
garbage: List[Garbage]
is_visited: bool
def __init__(self, position: Tuple[int, int]) -> None:
self.position = position
self.garbage = []
self.is_visited = False
def add_garbage(self, garbage: Garbage) -> None:
self.garbage.append(garbage)

View File

@ -5,4 +5,7 @@ class GridCellType(Enum):
STREET_VERTICAL = 1
STREET_HORIZONTAL = 2
GARBAGE_CAN = 3
VISITED_GARBAGE_CAN = 4
VISITED_GARBAGE_CAN = 4
LANDFILL = 5
SPEED_BUMP = 6
UNKNOWN = None

BIN
imgs/landfill.png Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 857 B

After

Width:  |  Height:  |  Size: 857 B

BIN
imgs/speed_bump.png Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 293 B

After

Width:  |  Height:  |  Size: 293 B

39
landfill.py Normal file
View File

@ -0,0 +1,39 @@
from typing import Tuple
from gameContext import GameContext
from garbage import RecognizedGarbage
from gridCellType import GridCellType
class Landfill:
position: Tuple[int, int] = []
paper: list[RecognizedGarbage]
plastic_and_metal: list[RecognizedGarbage] = []
glass: list[RecognizedGarbage] = []
bio: list[RecognizedGarbage] = []
mixed: list[RecognizedGarbage] = []
def __init__(self, position: Tuple[int, int]) -> None:
self.position = position
def add_paper(self, paper: list[RecognizedGarbage]) -> None:
for p in paper:
self.paper.append(p)
def add_plastic_and_metal(self, plastic_and_metal: list[RecognizedGarbage]) -> None:
for p in plastic_and_metal:
self.plastic_and_metal.append(p)
def add_glass(self, glass: list[RecognizedGarbage]) -> None:
for g in glass:
self.glass.append(g)
def add_paper(self, bio: list[RecognizedGarbage]) -> None:
for b in bio:
self.bio.append(b)
def add_mixed(self, mixed: list[RecognizedGarbage]) -> None:
for m in mixed:
self.mixed.append(m)
def render(self, game_context: GameContext) -> None:
game_context.render_in_cell(self.position, 'imgs/landfill.png')
game_context.grid[self.position] = GridCellType.LANDFILL

View File

@ -0,0 +1,23 @@
import os
from trainingData import TrainingData
def _read_training_data() -> TrainingData:
attributes: list[list[str]] = []
classes: list[str] = []
__location__ = os.path.realpath(
os.path.join(os.getcwd(), os.path.dirname(__file__)))
file = open(os.path.join(__location__, 'training_data.csv'))
lines = file.readlines()[1:]
file.close()
for line in lines:
actual_row = line.replace('\n', '')
values = actual_row.split(',')
line_attributes = values[:-1]
line_class = values[-1]
attributes.append(line_attributes)
classes.append(line_class)
return TrainingData(attributes, classes)
trainning_data = _read_training_data()

View File

@ -0,0 +1,7 @@
class TrainingData:
attributes: list[list[str]]
classes: list[str]
def __init__(self, attributes: list[list[str]], classes: list[str]) -> None:
self.attributes = attributes
self.classes = classes

View File

@ -0,0 +1,51 @@
Shape,Flexibility,DoesSmell,Weight,Size,Color,Softness,DoesDin,GarbageType
Round,High,No,High,Medium,Light,Low,No,MIXED
Longitiudonal,Medium,No,Medium,High,Light,Medium,Yes,PLASTIC_AND_METAL
Flat,Medium,No,High,Medium,Light,High,Yes,PLASTIC_AND_METAL
Round,Low,No,Medium,Low,Dark,High,Yes,MIXED
Longitiudonal,Medium,No,High,Medium,Light,Medium,No,PLASTIC_AND_METAL
Longitiudonal,Low,No,Medium,Low,Dark,Medium,No,BIO
Irregular,High,Yes,High,Medium,Transparent,Medium,No,PLASTIC_AND_METAL
Round,Low,Yes,Medium,Low,Light,Medium,No,BIO
Flat,Medium,Yes,High,Low,Transparent,Medium,No,PLASTIC_AND_METAL
Irregular,Low,No,Low,Medium,Colorful,High,Yes,MIXED
Flat,Low,Yes,Medium,High,Transparent,Low,No,GLASS
Flat,Low,Yes,Low,Low,Transparent,Low,No,GLASS
Longitiudonal,High,Yes,Low,High,Transparent,High,No,PLASTIC_AND_METAL
Longitiudonal,Low,Yes,Low,Medium,Transparent,Low,Yes,GLASS
Round,Medium,Yes,Medium,Medium,Light,Medium,Yes,BIO
Flat,Medium,Yes,High,High,Transparent,High,Yes,MIXED
Irregular,Medium,Yes,High,Low,Transparent,Medium,No,PLASTIC_AND_METAL
Round,High,No,Low,Medium,Colorful,High,Yes,PAPER
Round,Low,Yes,Medium,High,Colorful,Medium,Yes,MIXED
Longitiudonal,Low,Yes,Medium,Medium,Transparent,Low,No,GLASS
Flat,Medium,Yes,Medium,High,Light,Medium,Yes,MIXED
Irregular,Medium,No,High,High,Colorful,Medium,No,MIXED
Round,Medium,No,Medium,Low,Colorful,Medium,No,MIXED
Longitiudonal,Medium,No,High,Low,Dark,Low,No,MIXED
Flat,High,No,Low,High,Colorful,Medium,No,PAPER
Flat,Medium,No,High,High,Transparent,Medium,Yes,PLASTIC_AND_METAL
Longitiudonal,High,No,Medium,Medium,Light,Low,Yes,PLASTIC_AND_METAL
Longitiudonal,High,Yes,Low,Medium,Transparent,High,No,BIO
Irregular,Low,Yes,Low,High,Colorful,Medium,Yes,BIO
Irregular,Low,Yes,High,High,Light,Medium,No,BIO
Irregular,Low,No,High,Medium,Light,Medium,No,MIXED
Round,Low,No,High,Low,Dark,Low,No,PLASTIC_AND_METAL
Flat,Low,No,Medium,Medium,Colorful,High,Yes,MIXED
Irregular,High,Yes,Medium,Low,Colorful,Medium,No,BIO
Round,Low,Yes,Medium,High,Transparent,Medium,Yes,PLASTIC_AND_METAL
Flat,Medium,Yes,High,Low,Light,High,Yes,PAPER
Irregular,Medium,No,Medium,Medium,Transparent,Medium,No,PLASTIC_AND_METAL
Longitiudonal,Low,Yes,Low,High,Dark,Low,Yes,GLASS
Round,High,Yes,Medium,Low,Colorful,Low,No,MIXED
Round,Low,No,Medium,High,Dark,High,Yes,MIXED
Longitiudonal,Low,No,High,High,Transparent,Low,No,GLASS
Round,Medium,Yes,Low,Low,Light,Medium,Yes,BIO
Flat,Low,Yes,Low,Medium,Transparent,Medium,Yes,MIXED
Flat,Medium,No,High,Medium,Colorful,Medium,Yes,PLASTIC_AND_METAL
Irregular,Medium,Yes,Medium,Low,Light,Low,No,BIO
Irregular,Low,No,Low,Medium,Light,Medium,No,PAPER
Flat,Low,No,High,Low,Dark,Low,No,PLASTIC_AND_METAL
Irregular,Low,Yes,Low,Low,Transparent,Medium,Yes,MIXED
Flat,Low,No,High,High,Light,Low,No,PLASTIC_AND_METAL
Longitiudonal,Medium,No,High,Medium,Dark,Low,Yes,PLASTIC_AND_METAL
1 Shape Flexibility DoesSmell Weight Size Color Softness DoesDin GarbageType
1 Shape Flexibility DoesSmell Weight Size Color Softness DoesDin GarbageType
2 Round High No High Medium Light Low No MIXED
3 Longitiudonal Medium No Medium High Light Medium Yes PLASTIC_AND_METAL
4 Flat Medium No High Medium Light High Yes PLASTIC_AND_METAL
5 Round Low No Medium Low Dark High Yes MIXED
6 Longitiudonal Medium No High Medium Light Medium No PLASTIC_AND_METAL
7 Longitiudonal Low No Medium Low Dark Medium No BIO
8 Irregular High Yes High Medium Transparent Medium No PLASTIC_AND_METAL
9 Round Low Yes Medium Low Light Medium No BIO
10 Flat Medium Yes High Low Transparent Medium No PLASTIC_AND_METAL
11 Irregular Low No Low Medium Colorful High Yes MIXED
12 Flat Low Yes Medium High Transparent Low No GLASS
13 Flat Low Yes Low Low Transparent Low No GLASS
14 Longitiudonal High Yes Low High Transparent High No PLASTIC_AND_METAL
15 Longitiudonal Low Yes Low Medium Transparent Low Yes GLASS
16 Round Medium Yes Medium Medium Light Medium Yes BIO
17 Flat Medium Yes High High Transparent High Yes MIXED
18 Irregular Medium Yes High Low Transparent Medium No PLASTIC_AND_METAL
19 Round High No Low Medium Colorful High Yes PAPER
20 Round Low Yes Medium High Colorful Medium Yes MIXED
21 Longitiudonal Low Yes Medium Medium Transparent Low No GLASS
22 Flat Medium Yes Medium High Light Medium Yes MIXED
23 Irregular Medium No High High Colorful Medium No MIXED
24 Round Medium No Medium Low Colorful Medium No MIXED
25 Longitiudonal Medium No High Low Dark Low No MIXED
26 Flat High No Low High Colorful Medium No PAPER
27 Flat Medium No High High Transparent Medium Yes PLASTIC_AND_METAL
28 Longitiudonal High No Medium Medium Light Low Yes PLASTIC_AND_METAL
29 Longitiudonal High Yes Low Medium Transparent High No BIO
30 Irregular Low Yes Low High Colorful Medium Yes BIO
31 Irregular Low Yes High High Light Medium No BIO
32 Irregular Low No High Medium Light Medium No MIXED
33 Round Low No High Low Dark Low No PLASTIC_AND_METAL
34 Flat Low No Medium Medium Colorful High Yes MIXED
35 Irregular High Yes Medium Low Colorful Medium No BIO
36 Round Low Yes Medium High Transparent Medium Yes PLASTIC_AND_METAL
37 Flat Medium Yes High Low Light High Yes PAPER
38 Irregular Medium No Medium Medium Transparent Medium No PLASTIC_AND_METAL
39 Longitiudonal Low Yes Low High Dark Low Yes GLASS
40 Round High Yes Medium Low Colorful Low No MIXED
41 Round Low No Medium High Dark High Yes MIXED
42 Longitiudonal Low No High High Transparent Low No GLASS
43 Round Medium Yes Low Low Light Medium Yes BIO
44 Flat Low Yes Low Medium Transparent Medium Yes MIXED
45 Flat Medium No High Medium Colorful Medium Yes PLASTIC_AND_METAL
46 Irregular Medium Yes Medium Low Light Low No BIO
47 Irregular Low No Low Medium Light Medium No PAPER
48 Flat Low No High Low Dark Low No PLASTIC_AND_METAL
49 Irregular Low Yes Low Low Transparent Medium Yes MIXED
50 Flat Low No High High Light Low No PLASTIC_AND_METAL
51 Longitiudonal Medium No High Medium Dark Low Yes PLASTIC_AND_METAL

12
main.py
View File

@ -4,7 +4,7 @@ from gameContext import GameContext
from startup import startup
from PIL import Image
from agentActionType import AgentActionType
from movement import move_dust_car
from movement import collect_garbage
pygame.init()
@ -18,15 +18,7 @@ game_context.dust_car_pil = dust_car_pil
game_context.dust_car_pygame = pygame.image.frombuffer(dust_car_pil.tobytes(), dust_car_pil.size, 'RGB')
game_context.canvas = canvas
startup(game_context)
# test = [AgentActionType.MOVE_FORWARD, AgentActionType.MOVE_FORWARD, AgentActionType.MOVE_FORWARD,
# AgentActionType.MOVE_FORWARD, AgentActionType.MOVE_FORWARD, AgentActionType.MOVE_FORWARD,
# AgentActionType.MOVE_FORWARD, AgentActionType.TURN_RIGHT, AgentActionType.MOVE_FORWARD,
# AgentActionType.MOVE_FORWARD, AgentActionType.MOVE_FORWARD, AgentActionType.MOVE_FORWARD,
# AgentActionType.MOVE_FORWARD, AgentActionType.MOVE_FORWARD, AgentActionType.MOVE_FORWARD,
# AgentActionType.TURN_LEFT, AgentActionType.MOVE_FORWARD]
# move_dust_car(test, game_context)
collect_garbage(game_context)
exit = False

View File

@ -7,6 +7,22 @@ from gridCellType import GridCellType
from gameContext import GameContext
from agentOrientation import AgentOrientation
import pygame
from bfs import find_path_to_nearest_can
from agentState import AgentState
def collect_garbage(game_context: GameContext) -> None:
while True:
start_agent_state = AgentState(game_context.dust_car.position, game_context.dust_car.orientation)
path = find_path_to_nearest_can(start_agent_state, game_context.grid, game_context.city)
if path == None or len(path) == 0:
break
move_dust_car(path, game_context)
next_position = calculate_next_position(game_context.dust_car)
game_context.grid[next_position] = GridCellType.VISITED_GARBAGE_CAN
game_context.city.cans_dict[next_position].is_visited = True
pass
def move_dust_car(actions: list[AgentActionType], game_context: GameContext) -> None:
for action in actions:
@ -25,10 +41,11 @@ def move_dust_car(actions: list[AgentActionType], game_context: GameContext) ->
game_context.render_in_cell(street_position, "imgs/street_horizontal.png")
elif game_context.grid[street_position] == GridCellType.STREET_VERTICAL:
game_context.render_in_cell(street_position, "imgs/street_vertical.png")
elif game_context.grid[street_position] == GridCellType.SPEED_BUMP:
game_context.render_in_cell(street_position, "imgs/speed_bump.png")
pygame.display.update()
time.sleep(0.5)
time.sleep(0.15)
def calculate_next_position(car: GarbageTruck) -> Tuple[int, int]:
if car.orientation == AgentOrientation.UP:

13
speedBump.py Normal file
View File

@ -0,0 +1,13 @@
from typing import List, Tuple
from gameContext import GameContext
from gridCellType import GridCellType
class SpeedBump:
position: Tuple[int, int]
def __init__(self, position: Tuple[int, int]) -> None:
self.position = position
def render(self, game_context: GameContext) -> None:
game_context.render_in_cell(self.position, "imgs/speed_bump.png")
game_context.grid[self.position] = GridCellType.SPEED_BUMP

View File

@ -6,6 +6,8 @@ from typing import Tuple, List
from street import Street, StreetType
from garbageTruck import GarbageTruck
from garbageCan import GarbageCan
from speedBump import SpeedBump
from landfill import Landfill
def startup(game_context: GameContext):
@ -15,6 +17,7 @@ def startup(game_context: GameContext):
car = create_dust_car(game_context)
car.render(game_context)
game_context.dust_car = car
_create_landfill(game_context)
def create_dust_car(game_context: GameContext) -> GarbageTruck:
return GarbageTruck((3, 3))
@ -28,10 +31,13 @@ def create_city() -> City:
city: City = City()
streets = create_streets()
trashcans = create_trashcans()
bumps = create_speed_bumps()
for s in streets:
city.add_street(s)
for t in trashcans:
city.add_node(t)
city.add_can(t)
for b in bumps:
city.add_bump(b)
return city
def create_streets() -> List[Street]:
@ -57,4 +63,17 @@ def create_trashcans() -> List[GarbageCan]:
trashcans.append(GarbageCan((17, 9)))
trashcans.append(GarbageCan((24, 17)))
trashcans.append(GarbageCan((26, 4)))
return trashcans
return trashcans
def create_speed_bumps() -> List[SpeedBump]:
bumps = []
bumps.append(SpeedBump((10, 9)))
bumps.append(SpeedBump((12, 16)))
return bumps
def _create_landfill(game_context: GameContext) -> None:
landfil_position = (23,24)
landfill = Landfill(landfil_position)
game_context.landfill = landfill
landfill.render(game_context)