diff --git a/monopoly.03-May.log.gz b/monopoly.03-May.log.gz new file mode 100644 index 0000000000000000000000000000000000000000..73f4bdc58d3bbc8df50ed5d9a23788724e8be77f Binary files /dev/null and b/monopoly.03-May.log.gz differ diff --git a/monopoly.04-May.log.gz b/monopoly.04-May.log.gz new file mode 100644 index 0000000000000000000000000000000000000000..6bf6557b832381e5df923aa055e225c62f6427ad Binary files /dev/null and b/monopoly.04-May.log.gz differ diff --git a/monopoly.05-May.log.gz b/monopoly.05-May.log.gz new file mode 100644 index 0000000000000000000000000000000000000000..368c5b53be627b49d7c2ed2904712fc4ff5d38e8 Binary files /dev/null and b/monopoly.05-May.log.gz differ diff --git a/src/main/java/com/cm6123/monopoly/app/Application.java b/src/main/java/com/cm6123/monopoly/app/Application.java index d7bc0f725f0aa0b75f9d996af989da97f2abbb62..ff865aff396460ff2fef77e848efcd64e743f613 100644 --- a/src/main/java/com/cm6123/monopoly/app/Application.java +++ b/src/main/java/com/cm6123/monopoly/app/Application.java @@ -51,6 +51,7 @@ public final class Application { List<Player> players = new ArrayList<>(); Banker banker = new Banker(); GameHandler gameHandler = new GameAction(board); + ArrayList<Player> playersArrayList = new ArrayList<>(players); for (int i = 0; i < numberOfPlayers; i++) { @@ -67,7 +68,11 @@ public final class Application { round++; System.out.println("Round " + round); + + for (int turn = 0; turn < numberOfPlayers; turn++) { + + Player currentPlayer = players.get(currentPlayerIndex); System.out.println("It's " + currentPlayer.getName() + "'s turn. Type 'R' to roll the die."); @@ -82,13 +87,26 @@ public final class Application { } } + if (currentPlayer.getMoney() <= 0 && !currentPlayer.getHasAssets()) { + currentPlayer.checkBankruptcy(currentPlayer, board); + players.remove(currentPlayer); + numberOfPlayers--; + currentPlayerIndex--; + } + + if (currentPlayer.getMoney() <= 0 && currentPlayer.getHasAssets()) { + currentPlayer.checkBankruptcy(currentPlayer, board); + } + int newPosition = currentPlayer.getPosition(); String tileName = board.getGameBoard(newPosition); System.out.println(currentPlayer.getName() + " landed on " + tileName); - currentPlayerIndex = (currentPlayerIndex + 1) % numberOfPlayers; + System.out.println("You have £" + currentPlayer.getMoney() + " in your bank account "); + + if (newPosition == 4 || newPosition == 5 || newPosition == 9 || newPosition == 13 || newPosition == 15) { if (board.canBuyProperty(newPosition)) { gameHandler.landedOnProperty(currentPlayer); @@ -105,16 +123,23 @@ public final class Application { currentPlayer.addMoney(200); System.out.println("You now have £" + currentPlayer.getMoney() + " in your bank account "); } + + currentPlayerIndex = (currentPlayerIndex + 1) % numberOfPlayers; + } if (GameEndings.checkRoundsReached(round, numberOfRounds)) { + GameEndings.determineWinner(new ArrayList<>(players)); break; } - } - ArrayList<Player> playersArrayList = new ArrayList<>(players); - GameEndings.determineWinner(playersArrayList); + if (players.size() < 2) { + GameEndings.determineWinner(new ArrayList<>(players)); + break; + } + + } - LOGGER.info("Application closing"); + LOGGER.info("Thank you for playing!"); } } diff --git a/src/main/java/com/cm6123/monopoly/game/Board.java b/src/main/java/com/cm6123/monopoly/game/Board.java index 056c0e1cace3c84be2e9972e4561249e407d249a..f0515bffad5c8af924e8cb2b4ad9cffd4697151f 100644 --- a/src/main/java/com/cm6123/monopoly/game/Board.java +++ b/src/main/java/com/cm6123/monopoly/game/Board.java @@ -15,7 +15,7 @@ public class Board { /** * HashMap with the properties on them so that when a player buys the property it'll be noticed. */ - private static final HashMap<Integer, Boolean> PROPERTY_OWNERSHIP = new HashMap<>(); + public static final HashMap<Integer, Boolean> PROPERTY_OWNERSHIP = new HashMap<>(); /** * Constructor for the board. @@ -90,22 +90,26 @@ public class Board { /** * If a player decides to purchase a property then 200 will be taken away from the players bank account. * The posisiton/property they just bought will become true so now other players cannot purchase the same property. - * + * It also sets the players 'hasAssets' to true so if the player goes bankrupt then player can sell property. * @param position the position of the property to be purchased * @param player the player buying the property */ public void buyProperty(final int position,final Player player) { - if (canBuyProperty(position)) { - String propertyName = getGameBoard(position); - Properties property = new Properties(propertyName); - player.subtractMoney(property.getPrice()); - PROPERTY_OWNERSHIP.put(position, true); - property.setOwner(player); - - Player propertyOwner = property.getOwner(); + try { + if (canBuyProperty(position)) { + String propertyName = getGameBoard(position); + Properties property = new Properties(propertyName); + player.subtractMoney(property.getPrice()); + PROPERTY_OWNERSHIP.put(position, true); + player.setHasAssets(true); + property.setOwner(player); - System.out.println(propertyOwner.getName() + " has bought this property."); - System.out.println("You now have £" + player.getMoney() + " in your bank account."); + Player propertyOwner = property.getOwner(); + System.out.println(propertyOwner.getName() + " has bought this property."); + System.out.println("You now have £" + player.getMoney() + " in your bank account."); + } + } catch (Exception e) { + System.out.println("Error has occurred during purchase" + e.getMessage()); } } } diff --git a/src/main/java/com/cm6123/monopoly/game/GameAction.java b/src/main/java/com/cm6123/monopoly/game/GameAction.java index 63d049657c846775440a30eb4cec252773e6ca73..9fff47590a43dd3c458a6503ca370f3d61c65d2f 100644 --- a/src/main/java/com/cm6123/monopoly/game/GameAction.java +++ b/src/main/java/com/cm6123/monopoly/game/GameAction.java @@ -49,11 +49,10 @@ public class GameAction implements GameHandler { if (input.equals("Y")) { if (player.getMoney() >= 200) { this.board.buyProperty(position, player); - break; } else { System.out.println("You do not have enough money to buy " + propertyName + ". Moving on..."); - break; } + break; // if user types N then user doesn't want to buy the property and then continue the game } else if (input.equals("N")) { System.out.println("You have chosen N, moving on..."); @@ -65,6 +64,7 @@ public class GameAction implements GameHandler { } } + /** * Performs game actions when a player lands on a train station. * Allows the player to roll again to determine a ticket cost until they enter 'R'. @@ -97,17 +97,19 @@ public class GameAction implements GameHandler { int trainTicket = 10; int ticket = trainTicket * diceResult; - // Subtract ticket cost from player's money and display updated balance - System.out.println("You pay £" + ticket + " to the banker"); - player.subtractMoney(ticket); - System.out.println("You now have £" + player.getMoney() + " in your bank account"); + if (player.getMoney() > 0) { + // Subtract ticket cost from player's money and display updated balance + System.out.println("You pay £" + ticket + " to the banker"); + player.subtractMoney(ticket); + System.out.println("You now have £" + player.getMoney() + " in your bank account"); - // Pay the ticket cost to the banker - Banker banker = new Banker(); - banker.getMoneyFromPlayer(ticket); + // Pay the ticket cost to the banker + Banker banker = new Banker(); + banker.getMoneyFromPlayer(ticket); - // Exit the loop since the user has entered 'R' - break; + // Exit the loop since the user has entered 'R' + break; + } } else { // Make the user enter 'R' or game doesn't continue System.out.println("Invalid input. Please enter 'R'"); diff --git a/src/main/java/com/cm6123/monopoly/game/Player.java b/src/main/java/com/cm6123/monopoly/game/Player.java index 6c6ef9aa9734cfabf6b190955acdd419d49a3d73..a64a78e0f8b1e1d6bfe66b2622bf24abeaa37938 100644 --- a/src/main/java/com/cm6123/monopoly/game/Player.java +++ b/src/main/java/com/cm6123/monopoly/game/Player.java @@ -22,6 +22,11 @@ public class Player { */ private int position; + /** + * Checking if the player has bought properties, initially false. + */ + private static boolean hasAssets = false; + /** @@ -108,6 +113,27 @@ public class Player { this.position = playerPosition; } + /** + * Gets the players assets. + * + * @return the players assets. + */ + public boolean getHasAssets() { + return hasAssets; + } + + /** + * Set the players assets. + * + * @param assetsOwned + */ + public void setHasAssets(final boolean assetsOwned) { + this.hasAssets = assetsOwned; + } + + + + /** List of all players in the game. */ public static final ArrayList<Player> PLAYERSINTHEGAME = new ArrayList<>(); @@ -119,4 +145,37 @@ public class Player { public static ArrayList<Player> getPlayers() { return PLAYERSINTHEGAME; } + + /** + * Handles bankruptcy of the player by selling assets if available, or removing the player from the game. + * + * @param player The player who is declaring bankruptcy. + * @param board The game board containing property ownership information. + */ + public void checkBankruptcy(final Player player, final Board board) { + while (true) { + if (player.getMoney() <= 0) { + if (hasAssets) { + for (Integer propertyPosition : board.PROPERTY_OWNERSHIP.keySet()) { + if (board.PROPERTY_OWNERSHIP.get(propertyPosition)) { + board.PROPERTY_OWNERSHIP.put(propertyPosition, false); + player.addMoney(200); + System.out.println("You have sold " + board.getGameBoard(position) + " for £200 to survive bankruptcy"); + System.out.println("You now have £" + player.getMoney() + " in your bank account"); + player.setHasAssets(false); + return; + } + } + } + + System.out.println("You have no assets to sell, therefore you are bankrupt!"); + System.out.println(player.getName() + " has been removed from the game"); + PLAYERSINTHEGAME.remove(player); + break; + + } else { + break; + } + } + } } diff --git a/src/test/java/com/cm6123/monopoly/BankruptcyTest.java b/src/test/java/com/cm6123/monopoly/BankruptcyTest.java new file mode 100644 index 0000000000000000000000000000000000000000..88d6be5e154e3420043e9c6326b0e1674dc04f71 --- /dev/null +++ b/src/test/java/com/cm6123/monopoly/BankruptcyTest.java @@ -0,0 +1,94 @@ +package com.cm6123.monopoly; + +import com.cm6123.monopoly.game.Board; +import com.cm6123.monopoly.game.GameAction; +import com.cm6123.monopoly.game.Player; +import org.junit.jupiter.api.Test; + +import java.io.ByteArrayInputStream; + +import static org.junit.jupiter.api.Assertions.*; + +public class BankruptcyTest { + + @Test + public void testBankruptcyIfNoAsset() { + Board board = new Board(); + Player player1 = new Player("Player1", 10, 0); // Player1 starts with very low money (10) + Player player2 = new Player("Player2", 1000, 0); // Player2 starts with sufficient money (1000) + + Player.getPlayers().add(player1); + Player.getPlayers().add(player2); + GameAction gameAction = new GameAction(board); + + // Land player 1 on tile 7 which is a train station to force player to go below 0 + player1.setPosition(7); + ByteArrayInputStream in = new ByteArrayInputStream("R".getBytes()); + System.setIn(in); + + gameAction.landedOnTrainStation(player1); + + // Make player 1 now land on a property and type "N" to not buy the property + player1.setPosition(9); + in = new ByteArrayInputStream("N".getBytes()); + System.setIn(in); + + gameAction.landedOnProperty(player1); + + // Check bankruptcy and remove player if bankrupt + if (player1.getMoney() <= 0) { + player1.checkBankruptcy(player1, board); + Player.getPlayers().remove(player1); + } + // checking if the player is bankrupt and removing the player + // checking if there is only 1 player remaining since player 1 got removed + assertTrue(player1.getMoney() <= 0); + assertFalse(Player.getPlayers().contains(player1)); + assertEquals(1, Player.getPlayers().size()); + Player.getPlayers().remove(player1); + Player.getPlayers().remove(player2); + } + + + @Test + public void testBankruptcyIfPlayerHasAssets() { + Board board = new Board(); + Player player1 = new Player("Player1", 210, 0); + Player player2 = new Player("Player2", 1000, 0); + + Player.getPlayers().add(player1); + Player.getPlayers().add(player2); + + + GameAction gameAction = new GameAction(board); + + ByteArrayInputStream in = new ByteArrayInputStream("Y".getBytes()); + // Make the player land on a property and purchases the property, the player will have £10 + player1.setPosition(9); + in = new ByteArrayInputStream("Y".getBytes()); + System.setIn(in); + + gameAction.landedOnProperty(player1); + + // Make player 1 land on a train station and pay the ticket so the players balance goes below 0 + player1.setPosition(7); + in = new ByteArrayInputStream("R".getBytes()); + System.setIn(in); + + gameAction.landedOnTrainStation(player1); + + // Now make player 1 land on a property and type "N" + + if (player1.getMoney() <= 0 && player2.getHasAssets() == true) { + // Checking if players money is below 0, if it is remove the player + player1.checkBankruptcy(player1, board); + } + // The game should have forced sold the property the player had bought and added the funds to the players bank account + // checking if the player got removed or not + assertEquals(2, Player.getPlayers().size() ); + Player.getPlayers().remove(player1); + Player.getPlayers().remove(player2); + player1.setHasAssets(false); + } +} + diff --git a/src/test/java/com/cm6123/monopoly/PropertyPurchaseTest.java b/src/test/java/com/cm6123/monopoly/PropertyPurchaseTest.java index d293f2362e9b5c37f6a2d60522e54e9b0c059cf1..e7fc4b8bfe10ee85c6671aa724c40a9448d3c659 100644 --- a/src/test/java/com/cm6123/monopoly/PropertyPurchaseTest.java +++ b/src/test/java/com/cm6123/monopoly/PropertyPurchaseTest.java @@ -1,5 +1,6 @@ package com.cm6123.monopoly; +import com.cm6123.monopoly.game.Banker; import com.cm6123.monopoly.game.Player; import com.cm6123.monopoly.game.GameAction; import com.cm6123.monopoly.game.Board; @@ -17,7 +18,7 @@ public class PropertyPurchaseTest { Board board = new Board(); - Player player = new Player("TestPlayer", 1000, 0); // Example player with £1000 starting money and at position 0 + Player player = new Player("TestPlayer", 1000, 0); player.setPosition(4); ByteArrayInputStream in = new ByteArrayInputStream("Y".getBytes()); @@ -27,7 +28,7 @@ public class PropertyPurchaseTest { GameAction gameAction = new GameAction(board); gameAction.landedOnProperty(player); - assertEquals(4, player.getPosition(), "Player should land on tile 4 (Old Kent Road)"); + assertEquals(4, player.getPosition()); System.setIn(System.in); } @@ -40,7 +41,7 @@ public class PropertyPurchaseTest { Player owner = new Player("TestPlayer1", 1200, 0); board.buyProperty(4, owner); - Player testPlayer2 = new Player("TestPlayer2", 1000, 0); // Example player with £1000 starting money and at position 0 + Player testPlayer2 = new Player("TestPlayer2", 1000, 0); testPlayer2.setPosition(4); GameAction gameAction = new GameAction(board); diff --git a/src/test/java/com/cm6123/monopoly/PropertyTest.java b/src/test/java/com/cm6123/monopoly/PropertyTest.java index fde740f57a81e5d5f92400ed09b8388a826bb0f6..4e7f11f739f4a2054ae813df8a588232b7c9f18b 100644 --- a/src/test/java/com/cm6123/monopoly/PropertyTest.java +++ b/src/test/java/com/cm6123/monopoly/PropertyTest.java @@ -1,22 +1,36 @@ package com.cm6123.monopoly; +import com.cm6123.monopoly.game.Board; +import com.cm6123.monopoly.game.GameAction; +import com.cm6123.monopoly.game.Player; import com.cm6123.monopoly.game.Properties; import org.junit.jupiter.api.Test; +import java.io.ByteArrayInputStream; + import static org.junit.jupiter.api.Assertions.*; public class PropertyTest { @Test public void testSetAndGetPrice() { + // checking if the price of the property changes Properties property = new Properties("Old Kent Road"); property.setPrice(400); int actualPrice = property.getPrice(); assertEquals(400, actualPrice); } -} + @Test + public void testAssets() { + Player player4 = new Player("TestPlayer", 1000, 0); + // Setting and checking if players assets become true + // Used in board file if player buys a property + player4.setHasAssets(true); + assertTrue(player4.getHasAssets()); + } +}