From d475f910e5d38d126db84d706d11b8d200ff8f5c Mon Sep 17 00:00:00 2001 From: Falcon <35808469+FalconsSky@users.noreply.github.com> Date: Tue, 20 Dec 2022 09:54:45 +0100 Subject: [PATCH 1/7] field: add a repr method --- socha/api/plugin/penguins.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/socha/api/plugin/penguins.py b/socha/api/plugin/penguins.py index 9783fa7..ca95ee6 100644 --- a/socha/api/plugin/penguins.py +++ b/socha/api/plugin/penguins.py @@ -449,10 +449,12 @@ def get_team(self) -> Union[Team, None]: def __eq__(self, __o: object) -> bool: return isinstance(__o, Field) and self.field == __o.field - - def __str__(self): - return f"This Field is occupied by {self.field}" + ( - " fish(es)." if isinstance(self.field, int) else ".") + + def __repr__(self): + if isinstance(self.field, int): + return f"Field({self.coordinate}, Fish({self.field}))" + else: + return f"Field({self.coordinate}, {self.field})" class Board: From 8fa6318907a5b9ab52d90ae6c831800e49ea7062 Mon Sep 17 00:00:00 2001 From: Falcon <35808469+FalconsSky@users.noreply.github.com> Date: Tue, 20 Dec 2022 09:57:42 +0100 Subject: [PATCH 2/7] readme: remove shield with error --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 824dde0..84dd486 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,6 @@ # Python Client for the Software-Challenge Germany 2023 -[![GitHub Workflow Status](https://img.shields.io/github/workflow/status/FalconsSky/Software-Challenge-Python-Client/static%20and%20unit%20tests?label=Test)](https://github.com/FalconsSky/Software-Challenge-Python-Client) [![Read the Docs](https://img.shields.io/readthedocs/software-challenge-python-client?label=Docs)](https://software-challenge-python-client.readthedocs.io/en/latest/) [![PyPI](https://img.shields.io/pypi/v/socha?label=PyPi)](https://pypi.org/project/socha/) [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/socha?label=Python)](https://pypi.org/project/socha/) From 5106b27b4612001e4e507cd378f72dfa37725515 Mon Sep 17 00:00:00 2001 From: Falcon <35808469+FalconsSky@users.noreply.github.com> Date: Tue, 20 Dec 2022 15:24:25 +0100 Subject: [PATCH 3/7] cartesiancoordinate: raise a index error now --- socha/api/plugin/penguins.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/socha/api/plugin/penguins.py b/socha/api/plugin/penguins.py index ca95ee6..a128640 100644 --- a/socha/api/plugin/penguins.py +++ b/socha/api/plugin/penguins.py @@ -223,7 +223,7 @@ def from_index(index: int) -> Optional['CartesianCoordinate']: """ if 0 <= index <= 63: return CartesianCoordinate(x=index % 8, y=int(index / 8)) - return None + raise IndexError("Index out of range.") def __repr__(self) -> str: return f"CartesianCoordinate({self.x}, {self.y})" From 4315e71869c95fefbf8303860515131d26530f7e Mon Sep 17 00:00:00 2001 From: Falcon <35808469+FalconsSky@users.noreply.github.com> Date: Tue, 20 Dec 2022 15:24:41 +0100 Subject: [PATCH 4/7] test: add tests for the board class --- tests/test_penguins.py | 91 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/tests/test_penguins.py b/tests/test_penguins.py index 361c85d..338b253 100644 --- a/tests/test_penguins.py +++ b/tests/test_penguins.py @@ -1,8 +1,36 @@ import unittest +import random from socha.api.plugin.penguins import * +def create_random_board() -> Board: + game_field = [] + teams = ["ONE", "TWO"] + one_penguins = 0 + two_penguins = 0 + for y in range(8): + row = [] + for x in range(8): + choice = random.choice([0, 1]) + if choice == 0: + field = Field(CartesianCoordinate(x, y).to_hex(), random.randint(0, 4)) + else: + if one_penguins <= 4 and two_penguins <= 4: + if one_penguins == two_penguins: + team = random.choice(teams) + elif one_penguins > two_penguins: + team = "TWO" + else: + team = "ONE" + field = Field(CartesianCoordinate(x, y).to_hex(), team) + else: + field = Field(CartesianCoordinate(x, y).to_hex(), random.randint(0, 4)) + row.append(field) + game_field.append(row) + return Board(game_field) + + class VectorTest(unittest.TestCase): def testVectorInit(self): v = Vector(5, -5) @@ -84,6 +112,69 @@ def testGetEmptyField(self): self.assertEqual(len(e), 49) +class BoardTest(unittest.TestCase): + b = create_random_board() + + def test_get_empty_fields(self): + empty_fields = self.b.get_empty_fields() + + for field in empty_fields: + self.assertTrue(field.is_empty()) + + def test_is_occupied(self): + for x in range(self.b.width() - 1): + for y in range(self.b.height() - 1): + field = self.b._get_field(x, y) + if field.is_occupied(): + self.assertTrue(self.b.is_occupied(field.coordinate)) + else: + self.assertFalse(self.b.is_occupied(field.coordinate)) + + def test_is_valid(self): + for x in range(self.b.width()): + for y in range(self.b.height()): + self.assertTrue(self.b.is_valid(CartesianCoordinate(x, y).to_hex())) + + self.assertFalse(self.b.is_valid(CartesianCoordinate(-1, 0).to_hex())) + self.assertFalse(self.b.is_valid(CartesianCoordinate(0, -1).to_hex())) + self.assertFalse(self.b.is_valid(CartesianCoordinate(8, 0).to_hex())) + self.assertFalse(self.b.is_valid(CartesianCoordinate(0, 8).to_hex())) + + def test_get_field(self): + valid_coordinates = [] + for y in range(self.b.height() - 1): + for x in range(self.b.width() - 1): + valid_coordinates.append(CartesianCoordinate(x, y).to_hex()) + random_coordinates = random.choice(valid_coordinates) + field = self.b.get_field(random_coordinates) + self.assertEqual(field.coordinate, random_coordinates) + self.assertTrue(isinstance(field.field, int) or isinstance(field.field, Team)) + + invalid_coordinates = [HexCoordinate(-1, 0), HexCoordinate(0, -1), HexCoordinate(self.b.width(), 0), + HexCoordinate(0, self.b.height())] + random_coordinates = random.choice(invalid_coordinates) + with self.assertRaises(IndexError): + self.b.get_field(random_coordinates) + + def test_get_field_by_index(self): + random_indices = random.randint(0, 63) + field = self.b.get_field_by_index(random_indices) + self.assertEqual(field.coordinate, CartesianCoordinate(random_indices % self.b.width(), + int(random_indices / self.b.width())).to_hex()) + self.assertTrue(isinstance(field.field, int) or isinstance(field.field, Team)) + + random_indices = random.randint(-100, -1) + with self.assertRaises(IndexError): + self.b.get_field_by_index(random_indices) + + def test_get_most_fish(self): + most_fish_fields = self.b.get_most_fish() + self.assertTrue(isinstance(most_fish_fields, list)) + self.assertTrue(all(isinstance(field, Field) for field in most_fish_fields)) + self.assertTrue(all(isinstance(field.field, int) for field in most_fish_fields)) + self.assertTrue(all(field.field >= 0 for field in most_fish_fields)) + + class GameStateTest(unittest.TestCase): b = Board(game_field=[[Field(coordinate=CartesianCoordinate(j, i).to_hex(), field=1) for i in range(8)] for j in range(8)]) From 140024c6f9b920c32c45304cb05247ce1a39bb48 Mon Sep 17 00:00:00 2001 From: tms-hl <100803511+tms-hl@users.noreply.github.com> Date: Tue, 20 Dec 2022 15:27:28 +0100 Subject: [PATCH 5/7] fixed bug to prevent type error when calling get_most_fish on board with occupied fields (#19) Co-authored-by: Daniel --- socha/api/plugin/penguins.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/socha/api/plugin/penguins.py b/socha/api/plugin/penguins.py index a128640..44c59dd 100644 --- a/socha/api/plugin/penguins.py +++ b/socha/api/plugin/penguins.py @@ -673,7 +673,8 @@ def get_most_fish(self) -> List[Field]: :return: A list of Fields. """ - fields = self.get_all_fields() + + fields = list(filter(lambda field_x: not field_x.is_occupied(), self.get_all_fields())) fields.sort(key=lambda field_x: field_x.get_fish(), reverse=True) for i, field in enumerate(fields): if field.get_fish() < fields[0].get_fish(): From 92b26c3adc9079bd6aeded16b0c8608e1c3f07fd Mon Sep 17 00:00:00 2001 From: Falcon <35808469+FalconsSky@users.noreply.github.com> Date: Tue, 20 Dec 2022 15:43:06 +0100 Subject: [PATCH 6/7] release v1.0.0 --- pyproject.toml | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 5b732f4..bc163b7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "socha" -version = "0.9.9" +version = "1.0.0" authors = [ { name = "FalconsSky", email = "stu222782@mail.uni-kiel.de" }, ] diff --git a/setup.py b/setup.py index 5e5e803..04a9da9 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ setup( name='socha', - version='0.9.9', + version='1.0.0', packages=['socha', 'socha.api', 'socha.api.plugin', 'socha.api.protocol', 'socha.api.networking'], url='https://github.com/FalconsSky/Software-Challenge-Python-Client', From bb729230606e82026d7bad1ad7c725c63ad6ebf0 Mon Sep 17 00:00:00 2001 From: Falcon <35808469+FalconsSky@users.noreply.github.com> Date: Tue, 20 Dec 2022 15:50:45 +0100 Subject: [PATCH 7/7] test: fix bug in a board test --- tests/test_penguins.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/test_penguins.py b/tests/test_penguins.py index 338b253..500bf7d 100644 --- a/tests/test_penguins.py +++ b/tests/test_penguins.py @@ -150,8 +150,9 @@ def test_get_field(self): self.assertEqual(field.coordinate, random_coordinates) self.assertTrue(isinstance(field.field, int) or isinstance(field.field, Team)) - invalid_coordinates = [HexCoordinate(-1, 0), HexCoordinate(0, -1), HexCoordinate(self.b.width(), 0), - HexCoordinate(0, self.b.height())] + invalid_coordinates = [CartesianCoordinate(-1, 0).to_hex(), CartesianCoordinate(0, -1).to_hex(), + CartesianCoordinate(self.b.width(), 0).to_hex(), + CartesianCoordinate(0, self.b.height()).to_hex()] random_coordinates = random.choice(invalid_coordinates) with self.assertRaises(IndexError): self.b.get_field(random_coordinates)