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
30 changes: 30 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Python application

on: [push]

jobs:
build:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- name: Set up Python 3.8
uses: actions/setup-python@v1
with:
python-version: 3.8
- name: Install pipenv
uses: dschep/install-pipenv-action@v1
- name: Install dependencies
run: |
pipenv install --dev
#- name: Lint with flake8
# run: |
# pip install flake8
# # stop the build if there are Python syntax errors or undefined names
# flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
# # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
# flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
- name: Test with pytest
run: |
pipenv run pytest
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -126,4 +126,4 @@ venv.bak/
dmypy.json

# Pyre type checker
.pyre/
.pyre/
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"python.pythonPath": "${workspaceFolder}/.venv/bin/python"
}
15 changes: 15 additions & 0 deletions Pipfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true

[dev-packages]
pytest = "*"
pylint = "*"

[packages]
opensimplex = "*"
colorama = "*"

[requires]
python_version = "3.8"
162 changes: 162 additions & 0 deletions Pipfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Running Locally

```
PIPENV_VENV_IN_PROJECT=1
pipenv install --dev
...
```

# Testing

```
pipenv run pytest
```

17 changes: 13 additions & 4 deletions main_package/field.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,34 @@
logging.basicConfig(level=logging.INFO)

class FieldTypeEnum(Enum):
EMPTY = Fore.LIGHTBLACK_EX + "E"
BASE = Fore.RED + "B"
ANT = Fore.BLUE + "A"
FOOD = Fore.GREEN + "F"

GRASS = Fore.LIGHTBLACK_EX + "g"
FOREST = Fore.LIGHTBLACK_EX + "F"
WATER = Fore.LIGHTBLACK_EX + "w"
DEEP_WATER = Fore.LIGHTBLACK_EX + "W"
ROCK = Fore.LIGHTBLACK_EX + "R"
SAND = Fore.LIGHTBLACK_EX + "S"
DRY_GRASS = Fore.LIGHTBLACK_EX + "D"
TALL_GRASS = Fore.LIGHTBLACK_EX + "G"

class Field:
log = logging.getLogger(__name__)

def __init__(self, xpos:int, ypos:int):
def __init__(self, xpos:int, ypos:int, type: FieldTypeEnum):
self.xpos = xpos
self.ypos = ypos
self.type = FieldTypeEnum.EMPTY
self.emptyType = type
self.type = type
self.entity = None

def getPos(self) -> Tuple[int, int]:
return self.xpos, self.ypos

def resetToEmpty(self):
self.type = FieldTypeEnum.EMPTY
self.type = self.emptyType
self.entity = None

def setEntity(self, entity) -> bool:
Expand Down
20 changes: 12 additions & 8 deletions main_package/gameBoard.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from typing import Tuple, List, Set
from main_package.fieldEntities.ant import Ant
from main_package.field import *
from main_package.mapGenerator import *
from main_package.fieldEntities.base import Base
from main_package.fieldEntities.food import Food
from main_package.interfaces.attackable import Attackable
Expand All @@ -9,18 +10,21 @@


class gameBoard:
resolution = 5
log = logging.getLogger(__name__)
validForAttack = [FieldTypeEnum.ANT, FieldTypeEnum.BASE]

def __init__(self, xdim: int = 10, ydim: int = 10):
def __init__(self, xdim: int = 50, ydim: int = 40):
"""
Initializes an empty board of the given dimensions
:param xdim: x dimension (exclusive)
:param ydim: y dimension (exclusive)
"""
self.xdim = xdim
self.ydim = ydim
self.gameBoard = [[Field(xpos=x, ypos=y) for x in range(xdim)] for y in range(ydim)]

mapGen = MapGenerator(xdim, ydim)
self.gameBoard = mapGen.map
self.ants: dict[str, Ant] = {}
self.playerBases = {}
self.players = []
Expand Down Expand Up @@ -49,8 +53,8 @@ def createBase(self, xpos: int, ypos: int, player: str) -> bool:

# field where base is placed must be empty
field = self.getField(xpos, ypos)
if field.type != FieldTypeEnum.EMPTY:
logging.error("Base cannot be placed on field that is not empty. Field is {}".format(field.type))
if field.type != FieldTypeEnum.GRASS:
logging.error("Base cannot be placed on field that is not grass. Field is {}".format(field.type))
return False

if player in self.playerBases.keys():
Expand Down Expand Up @@ -130,8 +134,8 @@ def createAnt(self, xpos: int, ypos: int, antId: str, player: str) -> bool:
if not any(f.type == FieldTypeEnum.BASE for f in neighbouring_fields):
self.log.error("Invalid Placement, no adjacent base")
return False
elif placementDesitnation.type is not FieldTypeEnum.EMPTY:
self.log.error("Invalid Placement, field not empty")
elif placementDesitnation.type is not FieldTypeEnum.GRASS:
self.log.error("Invalid Placement, field not grass")
return False

# check if player owns base near which they want to place ant
Expand All @@ -156,7 +160,7 @@ def moveAnt(self, antId: str, xpos: int, ypos: int) -> bool:
ant = self.ants[antId]
# determine valid fields for movement
fields = self.getNeighbouringFields(ant.fieldPosition)
validFields = filter(lambda x: x.type == FieldTypeEnum.EMPTY, fields)
validFields = filter(lambda x: x.type != FieldTypeEnum.ROCK, fields)

# is movement valid ?
fieldToMoveTo: Field = None
Expand Down Expand Up @@ -231,7 +235,7 @@ def getBase(self, playerName: str) -> Base or None:

def createFood(self, xpos: int, ypos: int, magnitude: int) -> bool:
targetField = self.getField(xpos, ypos)
if targetField is None or targetField.type is not FieldTypeEnum.EMPTY:
if targetField is None or targetField.type is not FieldTypeEnum.GRASS:
self.log.error("Invalid target ({},{}) for placing food.".format(xpos, ypos))
return False
if magnitude <= 0 or magnitude != magnitude: # test for negative or nan
Expand Down
Loading