diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml new file mode 100644 index 0000000..0c8ff52 --- /dev/null +++ b/.github/workflows/python-app.yml @@ -0,0 +1,32 @@ +# This workflow will install Python dependencies, run tests and lint with a single version of Python +# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python + +name: Python application + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +permissions: + contents: read + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - name: Set up Python 3.10 + uses: actions/setup-python@v3 + with: + python-version: "3.10" + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install mypy + - name: Test and checks + run: | + make diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0c4323f --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.mypy_cache +__pycache__ diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..3ea9ae1 --- /dev/null +++ b/Makefile @@ -0,0 +1,6 @@ +test: FORCE + mypy azul --strict + mypy test --strict + python3 -m unittest + +FORCE: ; diff --git a/azul/Floor.py b/azul/Floor.py new file mode 100644 index 0000000..fdbacea --- /dev/null +++ b/azul/Floor.py @@ -0,0 +1,32 @@ +from __future__ import annotations +from azul.UsedTilesGiveInterface import UsedTilesGiveInterface +from azul.Tile import Tile, compressTileList +from azul.Points import Points +from typing import List +from itertools import chain, repeat, islice + + +class Floor: + _pointPattern: List[Points] + _usedTiles: UsedTilesGiveInterface + _tiles: List[Tile] + + def __init__(self, pointPattern: List[Points], _usedTiles: UsedTilesGiveInterface): + self._pointPattern = pointPattern.copy() + self._usedTiles = _usedTiles + self._tiles = [] + + def put(self, tiles: List[Tile]) -> None: + self._tiles.extend(tiles) + + def finishRound(self) -> Points: + extendedPattern = chain( + self._pointPattern, repeat(self._pointPattern[-1])) + points: Points = Points.sum( + list(islice(extendedPattern, 0, len(self._tiles)))) + self._usedTiles.give(self._tiles.copy()) + self._tiles = [] + return points + + def state(self) -> str: + return compressTileList(self._tiles) diff --git a/azul/Points.py b/azul/Points.py new file mode 100644 index 0000000..1ff562f --- /dev/null +++ b/azul/Points.py @@ -0,0 +1,16 @@ +from __future__ import annotations +from typing import List + + +class Points: + _value: int + + def __init__(self, value: int): + self._value = value + + @staticmethod + def sum(pointsList: List[Points]) -> Points: + return Points(sum([x._value for x in pointsList])) + + def __str__(self) -> str: + return str(self._value) diff --git a/azul/Tile.py b/azul/Tile.py new file mode 100644 index 0000000..5ca771b --- /dev/null +++ b/azul/Tile.py @@ -0,0 +1,25 @@ +from __future__ import annotations +from enum import Enum +from typing import List + + +class Tile: + _representation: str + + def __init__(self, representation: str): + self._representation = representation + + def __str__(self) -> str: + return self._representation + + +STARTING_PLAYER: Tile = Tile("S") +RED: Tile = Tile("R") +BLUE: Tile = Tile("B") +YELLOW: Tile = Tile("Y") +GREEN: Tile = Tile("G") +BLACK: Tile = Tile("L") + + +def compressTileList(tiles: List[Tile]) -> str: + return "".join([str(x) for x in tiles]) diff --git a/azul/UsedTilesGiveInterface.py b/azul/UsedTilesGiveInterface.py new file mode 100644 index 0000000..3dc12bc --- /dev/null +++ b/azul/UsedTilesGiveInterface.py @@ -0,0 +1,8 @@ +from __future__ import annotations +from azul.Tile import Tile +from typing import List + + +class UsedTilesGiveInterface: + def give(self, tiles: List[Tile]) -> None: + pass diff --git a/azul/__init__.py b/azul/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/test/__init__.py b/test/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/test/test_floor.py b/test/test_floor.py new file mode 100644 index 0000000..d5eca64 --- /dev/null +++ b/test/test_floor.py @@ -0,0 +1,35 @@ +from __future__ import annotations +import unittest +from azul.UsedTilesGiveInterface import UsedTilesGiveInterface +from azul.Tile import Tile, STARTING_PLAYER, RED, GREEN +from azul.Floor import Floor +from azul.Points import Points +from typing import List + + +class FakeUsedTiles(UsedTilesGiveInterface): + tilesGiven: List[Tile] + + def __init__(self) -> None: + self.tilesGiven = [] + + def give(self, tiles: List[Tile]) -> None: + self.tilesGiven.extend(tiles) + + +class TestFloor(unittest.TestCase): + def setUp(self) -> None: + self.usedTiles: FakeUsedTiles = FakeUsedTiles() + self.floor: Floor = Floor( + [Points(1), Points(2), Points(2)], self.usedTiles) + + def test_many_tiles(self) -> None: + tiles = [STARTING_PLAYER, RED, GREEN, RED] + self.floor.put(tiles) + points: Points = self.floor.finishRound() + self.assertEquals(str(points), "7") + self.assertCountEqual(tiles, self.usedTiles.tilesGiven) + + +if __name__ == '__main__': + unittest.main()