Skip to content

Commit

Permalink
feat: add NearbyArtefactsList (#1581)
Browse files Browse the repository at this point in the history
* feat: add NearbyArtefactsList

* use const

* cover NearbyArtefactsList IndexError

* code review

* comment
  • Loading branch information
razvan-pro committed Oct 11, 2021
1 parent 3002ffa commit bcab6df
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 5 deletions.
10 changes: 10 additions & 0 deletions aimmo-game-worker/simulation/errors.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
class Error(Exception):
"""Base class for other exceptions"""

pass


class NoNearbyArtefactsError(Error):
"""Raised when there are no nearby artefacts"""

pass
23 changes: 23 additions & 0 deletions aimmo-game-worker/simulation/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from typing import TypeVar, List

from .errors import NoNearbyArtefactsError


T = TypeVar("T")


class NearbyArtefactsList(List[T]):
"""
A list-like object that raises NoNearbyArtefactsError when trying to access an element and the list is empty.
"""

def __getitem__(self, i):
try:
return super().__getitem__(i)
except IndexError:
if len(self) == 0:
raise NoNearbyArtefactsError(
"There aren't any nearby artefacts, you need to move closer!"
) from None
else:
raise
9 changes: 6 additions & 3 deletions aimmo-game-worker/simulation/world_map.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
from collections import defaultdict, namedtuple
from enum import Enum
from typing import Dict, List

from .avatar_state import create_avatar_state
from .location import Location
from typing import Dict, List
from .pathfinding import astar
from .utils import NearbyArtefactsList

# how many nearby artefacts to return
SCAN_LIMIT = 3
Expand Down Expand Up @@ -168,7 +169,9 @@ def _scan_artefacts(self, start_location, radius):
artefacts.append(cell)
return artefacts

def scan_nearby(self, avatar_location, radius=SCAN_RADIUS) -> List[dict]:
def scan_nearby(
self, avatar_location, radius=SCAN_RADIUS
) -> NearbyArtefactsList[dict]:
"""
From the given location point search the given radius for artefacts.
Returns list of nearest artefacts (artefact/interactable represented as dict).
Expand Down Expand Up @@ -197,7 +200,7 @@ def scan_nearby(self, avatar_location, radius=SCAN_RADIUS) -> List[dict]:
if len(nearest) > SCAN_LIMIT:
break

return nearest[:SCAN_LIMIT]
return NearbyArtefactsList(nearest[:SCAN_LIMIT])

def __repr__(self):
return repr(self.cells)
14 changes: 13 additions & 1 deletion aimmo-game-worker/tests/tests_simulation/test_world_map.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import pytest

from simulation.errors import NoNearbyArtefactsError
from simulation.location import Location
from simulation.world_map import WorldMap, WorldMapCreator, ARTEFACT_TYPES
from simulation.utils import NearbyArtefactsList
from simulation.world_map import ARTEFACT_TYPES, WorldMapCreator


@pytest.fixture
Expand Down Expand Up @@ -152,4 +154,14 @@ def test_scan_nearby(avatar_state_json):
cells[4]["interactable"] = {"type": ARTEFACT_TYPES[-1]}
map = WorldMapCreator.generate_world_map_from_cells_data(cells)
artefacts = map.scan_nearby(Location(-1, 0))
assert type(artefacts) == NearbyArtefactsList
assert len(artefacts) == 1
with pytest.raises(IndexError):
artefacts[1]

# Test NoNearbyArtefactsError
artefacts = map.scan_nearby(Location(5, 5), radius=1)
assert type(artefacts) == NearbyArtefactsList
assert len(artefacts) == 0
with pytest.raises(NoNearbyArtefactsError):
artefacts[0]
4 changes: 3 additions & 1 deletion game_frontend/src/pyodide/webWorker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,9 @@ export function simplifyErrorMessageInLog(log: string): string {
const regexToFindNextTurnErrors = /.*line (\d+), in next_turn\n((?:.|\n)*)/
const matches = log.match(regexToFindNextTurnErrors)
if (matches?.length >= 2) {
return `Uh oh! Something isn't correct on line ${matches[1]}. Here's the error we got:\n${matches[2]}`
// get only the exception message line, removing potential traceback
const simpleError = matches[2].split('\n').slice(-2).join('')
return `Uh oh! Something isn't correct on line ${matches[1]}. Here's the error we got:\n${simpleError}`
}
// error not in next_turn function
return log
Expand Down

0 comments on commit bcab6df

Please sign in to comment.