From 6e7e587e626918f4ac81d9d36462949c1a14cc0e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 29 Sep 2025 01:32:59 +0000 Subject: [PATCH 1/2] Initial plan From a5e710823a0082358ef8652b69930cb8c85e61a9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 29 Sep 2025 01:46:43 +0000 Subject: [PATCH 2/2] Implement energy system - player starts with 100 energy, fishing consumes 10 per hour, sleep restores full energy Co-authored-by: dmccoystephenson <21204351+dmccoystephenson@users.noreply.github.com> --- schemas/player.json | 8 +++- src/location/docks.py | 18 ++++++- src/location/home.py | 3 +- src/player/player.py | 1 + src/player/playerJsonReaderWriter.py | 2 + src/ui/userInterface.py | 1 + tests/location/test_docks.py | 53 +++++++++++++++++++++ tests/location/test_home.py | 17 ++++++- tests/player/test_player.py | 1 + tests/player/test_playerJsonReaderWriter.py | 23 +++++++++ tests/ui/test_userInterface.py | 2 +- 11 files changed, 123 insertions(+), 6 deletions(-) diff --git a/schemas/player.json b/schemas/player.json index 30e202d..0a151e7 100644 --- a/schemas/player.json +++ b/schemas/player.json @@ -20,6 +20,11 @@ "priceForBait": { "type": "number", "minimum": 0 + }, + "energy": { + "type": "integer", + "minimum": 0, + "maximum": 100 } }, "required": [ @@ -27,6 +32,7 @@ "money", "moneyInBank", "fishMultiplier", - "priceForBait" + "priceForBait", + "energy" ] } \ No newline at end of file diff --git a/src/location/docks.py b/src/location/docks.py index ff2a428..fbc5dbd 100644 --- a/src/location/docks.py +++ b/src/location/docks.py @@ -33,8 +33,12 @@ def run(self): ) if input == "1": - self.fish() - return LocationType.DOCKS + if self.player.energy >= 10: + self.fish() + return LocationType.DOCKS + else: + self.currentPrompt.text = "You're too tired to fish! Go home and sleep." + return LocationType.DOCKS elif input == "2": self.currentPrompt.text = "What would you like to do?" @@ -65,12 +69,22 @@ def fish(self): hours = random.randint(1, 10) + # Check if player has enough energy for all hours + energy_needed = hours * 10 + if self.player.energy < energy_needed: + # Fish for as many hours as energy allows + hours = self.player.energy // 10 + if hours == 0: + self.currentPrompt.text = "You're too tired to fish! Go home and sleep." + return + for i in range(hours): print("><> ") sys.stdout.flush() time.sleep(0.5) self.stats.hoursSpentFishing += 1 self.timeService.increaseTime() + self.player.energy -= 10 # Consume 10 energy per hour fishToAdd = random.randint(1, 10) * self.player.fishMultiplier self.player.fishCount += fishToAdd diff --git a/src/location/home.py b/src/location/home.py index 05ebf26..ebd1a63 100644 --- a/src/location/home.py +++ b/src/location/home.py @@ -43,7 +43,8 @@ def run(self): def sleep(self): self.timeService.increaseDay() - self.currentPrompt.text = "You sleep until the next morning." + self.player.energy = 100 # Restore full energy when sleeping + self.currentPrompt.text = "You sleep until the next morning. You feel refreshed!" def displayStats(self): self.userInterface.lotsOfSpace() diff --git a/src/player/player.py b/src/player/player.py index e30ef13..045af8f 100644 --- a/src/player/player.py +++ b/src/player/player.py @@ -6,3 +6,4 @@ def __init__(self): self.moneyInBank = 0.01 self.fishMultiplier = 1 self.priceForBait = 50 + self.energy = 100 diff --git a/src/player/playerJsonReaderWriter.py b/src/player/playerJsonReaderWriter.py index 89e95f1..254c442 100644 --- a/src/player/playerJsonReaderWriter.py +++ b/src/player/playerJsonReaderWriter.py @@ -10,6 +10,7 @@ def createJsonFromPlayer(self, player): "money": player.money, "moneyInBank": player.moneyInBank, "priceForBait": player.priceForBait, + "energy": player.energy, } def createPlayerFromJson(self, playerJson): @@ -19,6 +20,7 @@ def createPlayerFromJson(self, playerJson): player.money = playerJson["money"] player.moneyInBank = playerJson["moneyInBank"] player.priceForBait = playerJson["priceForBait"] + player.energy = playerJson.get("energy", 100) # Default to 100 for backwards compatibility return player def writePlayerToFile(self, player, jsonFile): diff --git a/src/ui/userInterface.py b/src/ui/userInterface.py index be54a21..0594aa8 100644 --- a/src/ui/userInterface.py +++ b/src/ui/userInterface.py @@ -60,6 +60,7 @@ def showOptions( print(" | " + self.times[self.timeService.time]) print(" | Money: $%d" % self.player.money) print(" | Fish: %d" % self.player.fishCount) + print(" | Energy: %d" % self.player.energy) print("\n " + self.currentPrompt.text) self.divider() self.n = 1 diff --git a/tests/location/test_docks.py b/tests/location/test_docks.py index a295716..d73ab01 100644 --- a/tests/location/test_docks.py +++ b/tests/location/test_docks.py @@ -113,3 +113,56 @@ def test_fish(): assert docks.time.sleep.call_count == 4 assert docksInstance.player.fishCount == 3 assert docksInstance.stats.totalFishCaught == 3 + + +def test_run_fish_action_low_energy(): + # prepare + docksInstance = createDocks() + docksInstance.player.energy = 5 # Too low to fish + docksInstance.userInterface.showOptions = MagicMock(return_value="1") + + # call + nextLocation = docksInstance.run() + + # check + assert nextLocation == LocationType.DOCKS + assert docksInstance.currentPrompt.text == "You're too tired to fish! Go home and sleep." + + +def test_fish_consumes_energy(): + # prepare + docksInstance = createDocks() + docksInstance.player.energy = 100 + docksInstance.userInterface.lotsOfSpace = MagicMock() + docksInstance.userInterface.divider = MagicMock() + docks.print = MagicMock() + docks.sys.stdout.flush = MagicMock() + docks.time.sleep = MagicMock() + docks.random.randint = MagicMock(return_value=3) # Fish for 3 hours, catch 3 fish + docksInstance.timeService.increaseTime = MagicMock() + + # call + docksInstance.fish() + + # check + assert docksInstance.player.energy == 100 - (3 * 10) # Should lose 30 energy (3 hours * 10 per hour) + + +def test_fish_with_limited_energy(): + # prepare + docksInstance = createDocks() + docksInstance.player.energy = 25 # Only enough for 2 hours + docksInstance.userInterface.lotsOfSpace = MagicMock() + docksInstance.userInterface.divider = MagicMock() + docks.print = MagicMock() + docks.sys.stdout.flush = MagicMock() + docks.time.sleep = MagicMock() + docks.random.randint = MagicMock(return_value=5) # Would normally fish for 5 hours, but energy limits to 2 + docksInstance.timeService.increaseTime = MagicMock() + + # call + docksInstance.fish() + + # check + assert docksInstance.player.energy == 5 # Should be 25 - (2 * 10) + assert docksInstance.timeService.increaseTime.call_count == 2 # Only fished for 2 hours due to energy limit diff --git a/tests/location/test_home.py b/tests/location/test_home.py index 4dae402..c57b1ed 100644 --- a/tests/location/test_home.py +++ b/tests/location/test_home.py @@ -85,13 +85,28 @@ def test_sleep(): # prepare homeInstance = createHome() homeInstance.timeService.increaseDay = MagicMock() + homeInstance.player.energy = 50 # Set energy to something less than 100 # call homeInstance.sleep() # check homeInstance.timeService.increaseDay.assert_called_once() - assert homeInstance.currentPrompt.text == "You sleep until the next morning." + assert homeInstance.currentPrompt.text == "You sleep until the next morning. You feel refreshed!" + assert homeInstance.player.energy == 100 # Energy should be restored to full + + +def test_sleep_restores_energy(): + # prepare + homeInstance = createHome() + homeInstance.timeService.increaseDay = MagicMock() + homeInstance.player.energy = 10 # Low energy + + # call + homeInstance.sleep() + + # check + assert homeInstance.player.energy == 100 def test_displayStats(): diff --git a/tests/player/test_player.py b/tests/player/test_player.py index 8fe8efc..e140a8d 100644 --- a/tests/player/test_player.py +++ b/tests/player/test_player.py @@ -14,3 +14,4 @@ def test_initialization(): assert player.money == 20 assert player.moneyInBank == 0.01 assert player.fishMultiplier == 1 + assert player.energy == 100 diff --git a/tests/player/test_playerJsonReaderWriter.py b/tests/player/test_playerJsonReaderWriter.py index 75ccb7f..7b44355 100644 --- a/tests/player/test_playerJsonReaderWriter.py +++ b/tests/player/test_playerJsonReaderWriter.py @@ -40,6 +40,7 @@ def test_createPlayerFromJson(): "money": 0, "moneyInBank": 0, "priceForBait": 50, + "energy": 100, } playerJsonReaderWriter = createPlayerJsonReaderWriter() @@ -49,3 +50,25 @@ def test_createPlayerFromJson(): assert player.fishMultiplier == playerJson["fishMultiplier"] assert player.money == playerJson["money"] assert player.moneyInBank == playerJson["moneyInBank"] + assert player.energy == playerJson["energy"] + + +def test_createPlayerFromJson_backwards_compatibility(): + # Test that old save files without energy still work + playerJson = { + "fishCount": 5, + "fishMultiplier": 2, + "money": 100, + "moneyInBank": 50, + "priceForBait": 75, + # Note: no energy field + } + + playerJsonReaderWriter = createPlayerJsonReaderWriter() + player = playerJsonReaderWriter.createPlayerFromJson(playerJson) + + assert player.fishCount == playerJson["fishCount"] + assert player.fishMultiplier == playerJson["fishMultiplier"] + assert player.money == playerJson["money"] + assert player.moneyInBank == playerJson["moneyInBank"] + assert player.energy == 100 # Should default to 100 diff --git a/tests/ui/test_userInterface.py b/tests/ui/test_userInterface.py index ff58c61..65aaa6b 100644 --- a/tests/ui/test_userInterface.py +++ b/tests/ui/test_userInterface.py @@ -63,7 +63,7 @@ def test_showOptions(): userInterfaceInstance.showOptions("descriptor", ["option1", "option2"]) # check - assert userInterface.print.call_count == 8 + assert userInterface.print.call_count == 9 userInterfaceInstance.lotsOfSpace.assert_called() assert userInterfaceInstance.divider.call_count == 3 userInterface.input.assert_called_with("\n> ")