Skip to content

Commit

Permalink
synce server to master (#90) (#91)
Browse files Browse the repository at this point in the history
* Base file (#80)

Made base file and folder structure.

* Game generation tweak (#89)

* Tweaked game generation

* Tweaked game generation names

* Added type

* moved to actual function

* cleaned up ternary

* Added comments

* documentation updates

---------



---------

Co-authored-by: Ian <[email protected]>
Co-authored-by: KingPhilip14 <[email protected]>
  • Loading branch information
3 people authored Sep 22, 2023
1 parent 89b0c02 commit 173ed61
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 29 deletions.
68 changes: 53 additions & 15 deletions game/common/map/game_board.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import random
from typing import Self
from typing import Self, Callable

from game.common.avatar import Avatar
from game.common.enums import *
Expand Down Expand Up @@ -175,11 +175,11 @@ def locations(self, locations: dict[tuple[Vector]:list[GameObject]] | None) -> N
if locations is not None and not isinstance(locations, dict):
raise ValueError("Locations must be a dict. The key must be a tuple of Vector Objects, and the "
"value a list of GameObject.")
if locations is not None:
for k, v in locations.items():
if len(k) != len(v):
raise ValueError("Cannot set the locations for the game_board. A key has a different "
"length than its key.")
# if locations is not None:
# for k, v in locations.items():
# if len(k) != len(v):
# raise ValueError("Cannot set the locations for the game_board. A key has a different "
# "length than its key.")

self.__locations = locations

Expand Down Expand Up @@ -212,28 +212,66 @@ def generate_map(self) -> None:

def __populate_map(self) -> None:
for k, v in self.locations.items():
if len(k) != len(v) or (len(k) == 0 or len(v) == 0): # Key-Value lengths must be > 0 and equal
raise ValueError("A key-value pair from game_board.locations has mismatching lengths. "
"They must be the same length, regardless of size.")
if len(k) == 0 or len(v) == 0: # Key-Value lengths must be > 0 and equal
raise ValueError("A key-value pair from game_board.locations has a length of 0. ")

# random.sample returns a randomized list which is used in __help_populate()
j = random.sample(k, k=len(k))
self.__help_populate(j, v)

def __help_populate(self, vector_list: list[Vector], v: list[GameObject]) -> None:
for j, i in zip(vector_list, v):
if isinstance(i, Avatar): # If the GameObject is an Avatar, assign it the coordinate position
i.position = j
def __occupied_filter(self, game_object_list: list[GameObject]) -> list[GameObject]:
"""
A helper method that returns a list of game objects that have the 'occupied_by' attribute.
:param game_object_list:
:return: a list of game object
"""
return [game_object for game_object in game_object_list if hasattr(game_object, 'occupied_by')]

temp_tile: GameObject = self.game_map[j.y][j.x]
def __help_populate(self, vector_list: list[Vector], game_object_list: list[GameObject]) -> None:
"""
A helper method that helps populate the game map.
:param vector_list:
:param game_object_list:
:return: None
"""

zipped_list: [tuple[list[Vector], list[GameObject]]] = list(zip(vector_list, game_object_list))
last_vec: Vector = zipped_list[-1][0]

remaining_objects: list[GameObject] | None = self.__occupied_filter(game_object_list[len(zipped_list):]) \
if len(self.__occupied_filter(game_object_list)) > len(zipped_list) \
else None

# Will cap at smallest list when zipping two together
for vector, game_object in zipped_list:
if isinstance(game_object, Avatar): # If the GameObject is an Avatar, assign it the coordinate position
game_object.position = vector

temp_tile: GameObject = self.game_map[vector.y][vector.x]

while hasattr(temp_tile.occupied_by, 'occupied_by'):
temp_tile = temp_tile.occupied_by

if temp_tile is None:
raise ValueError("Last item on the given tile doesn't have the 'occupied_by' attribute.")

temp_tile.occupied_by = i
temp_tile.occupied_by = game_object

if remaining_objects is None:
return

# stack remaining game_objects on last vector
temp_tile: GameObject = self.game_map[last_vec.y][last_vec.x]

while hasattr(temp_tile.occupied_by, 'occupied_by'):
temp_tile = temp_tile.occupied_by

for game_object in remaining_objects:
if temp_tile is None:
raise ValueError("Last item on the given tile doesn't have the 'occupied_by' attribute.")

temp_tile.occupied_by = game_object
temp_tile = temp_tile.occupied_by

def get_objects(self, look_for: ObjectType) -> list[tuple[Vector, list[GameObject]]]:
to_return: list[tuple[Vector, list[GameObject]]] = list()
Expand Down
15 changes: 13 additions & 2 deletions game/test_suite/tests/test_game_board.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ def setUp(self) -> None:
self.locations: dict[tuple[Vector]:list[GameObject]] = {
(Vector(1, 1),): [Station(None)],
(Vector(1, 2), Vector(1, 3)): [OccupiableStation(self.item), Station(None)],
(Vector(2, 2), Vector(2, 3)): [OccupiableStation(self.item), OccupiableStation(self.item), OccupiableStation(self.item), OccupiableStation(self.item)],
(Vector(3, 1), Vector(3, 2), Vector(3, 3)): [OccupiableStation(self.item), Station(None)],
(Vector(5, 5),): [self.avatar],
(Vector(5, 6),): [self.wall]
}
Expand Down Expand Up @@ -69,14 +71,23 @@ def test_walled_fail(self):
def test_get_objects_station(self):
stations: list[tuple[Vector, list[Station]]] = self.game_board.get_objects(ObjectType.STATION)
self.assertTrue(all(map(lambda station: isinstance(station[1][0], Station), stations)))
self.assertEqual(len(stations), 2)
self.assertEqual(len(stations), 3)

# test that get_objects works correctly with occupiable stations
def test_get_objects_occupiable_station(self):
occupiable_stations: list[tuple[Vector, list[OccupiableStation]]] = self.game_board.get_objects(ObjectType.OCCUPIABLE_STATION)
self.assertTrue(
all(map(lambda occupiable_station: isinstance(occupiable_station[1][0], OccupiableStation), occupiable_stations)))
self.assertEqual(len(occupiable_stations), 1)
objects_stacked = [x[1] for x in occupiable_stations]
objects_unstacked = [x for xs in objects_stacked for x in xs]
self.assertEqual(len(objects_unstacked), 6)

def test_get_objects_occupiable_station_2(self):
occupiable_stations: list[tuple[Vector, list[OccupiableStation]]] = self.game_board.get_objects(ObjectType.OCCUPIABLE_STATION)
self.assertTrue(any(map(lambda vec_list: len(vec_list[1]) == 3, occupiable_stations)))
objects_stacked = [x[1] for x in occupiable_stations]
objects_unstacked = [x for xs in objects_stacked for x in xs]
self.assertEqual(len(objects_unstacked), 6)

# test that get_objects works correctly with avatar
def test_get_objects_avatar(self):
Expand Down
12 changes: 0 additions & 12 deletions game/test_suite/tests/test_game_board_no_gen.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,18 +72,6 @@ def test_locations_fail_type(self):
self.assertEqual(str(e.exception), 'Locations must be a dict. The key must be a tuple of Vector Objects, '
'and the value a list of GameObject.')

def test_locations_fail_len(self):
with self.assertRaises(ValueError) as e:
self.locations = {
(Vector(1, 1),): [],
(Vector(1, 2), Vector(1, 3)): [OccupiableStation(self.item), Station(None)],
(Vector(5, 5),): [Station(None)],
(Vector(5, 6),): [self.wall]
}
self.game_board.locations = self.locations
self.assertEqual(str(e.exception), 'Cannot set the locations for the game_board. A key has a different length '
'than its key.')

# test walled
def test_walled(self):
self.game_board.walled = True
Expand Down

0 comments on commit 173ed61

Please sign in to comment.