diff --git a/monopoly.01-May.log.gz b/monopoly.01-May.log.gz new file mode 100644 index 0000000000000000000000000000000000000000..e5c44d80d8fcabd82bd63f6377e1724a903becf2 Binary files /dev/null and b/monopoly.01-May.log.gz differ diff --git a/monopoly.02-May.log.gz b/monopoly.02-May.log.gz new file mode 100644 index 0000000000000000000000000000000000000000..190b87f62c1b87998c2aaa840544bc67b4e2b251 Binary files /dev/null and b/monopoly.02-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 1db2187b8acd26a1e402c86a8cbb932831a042c3..5c9fe6ab56d8154bd4c93719d5ff69249e04fe31 100644 --- a/src/main/java/com/cm6123/monopoly/app/Application.java +++ b/src/main/java/com/cm6123/monopoly/app/Application.java @@ -1,10 +1,12 @@ package com.cm6123.monopoly.app; +import com.cm6123.monopoly.game.Banker; import com.cm6123.monopoly.game.Player; -import com.cm6123.monopoly.game.Board; -import com.cm6123.monopoly.game.Movement; +import com.cm6123.monopoly.game.GameHandler; import com.cm6123.monopoly.game.GameEndings; -import com.cm6123.monopoly.game.Banker; +import com.cm6123.monopoly.game.Movement; +import com.cm6123.monopoly.game.Board; +import com.cm6123.monopoly.game.GameAction; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -33,7 +35,6 @@ public final class Application { */ public static void main(final String[] args) { - LOGGER.info("Application Started with args:{}", String.join(",", args)); System.out.println("Hello. Welcome to Monopoly."); @@ -49,6 +50,7 @@ public final class Application { Movement movement = new Movement(); List<Player> players = new ArrayList<>(); Banker banker = new Banker(); + GameHandler gameHandler = new GameAction(board); for (int i = 0; i < numberOfPlayers; i++) { @@ -70,8 +72,6 @@ public final class Application { System.out.println("It's " + currentPlayer.getName() + "'s turn. Type 'R' to roll the die."); - - while(true) { String input = scanner.next().toUpperCase(); if (input.equals("R")) { @@ -82,7 +82,6 @@ public final class Application { } } - int newPosition = currentPlayer.getPosition(); String tileName = board.getGameBoard(newPosition); @@ -90,13 +89,18 @@ public final class Application { 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); + } + } + if (newPosition == 1) { banker.checkIfPlayerPassHome(currentPlayer); System.out.println("Banker has given " + currentPlayer.getName() + " £200."); currentPlayer.addMoney(200); System.out.println("You now have £" + currentPlayer.getMoney() + " in your bank account "); } - } if (GameEndings.checkRoundsReached(round, numberOfRounds)) { @@ -107,10 +111,6 @@ public final class Application { ArrayList<Player> playersArrayList = new ArrayList<>(players); GameEndings.determineWinner(playersArrayList); - - LOGGER.info("Application closing"); } - - } diff --git a/src/main/java/com/cm6123/monopoly/game/Banker.java b/src/main/java/com/cm6123/monopoly/game/Banker.java index 338aacb56e7e876b6543a7e7c9fb1a2f7f882362..b6cd0baeaf3d00af834bb071d1e8ca73143264ec 100644 --- a/src/main/java/com/cm6123/monopoly/game/Banker.java +++ b/src/main/java/com/cm6123/monopoly/game/Banker.java @@ -2,7 +2,7 @@ package com.cm6123.monopoly.game; /** - * Represents the banker in a Monopoly game, responsible for managing the game's financial transactions. + * Class for the banker as seen in the pro forma, banker gives money to players. */ public class Banker { /** @@ -32,7 +32,7 @@ public class Banker { } /** - * Pays a specified amount of money to a player and deducts this amount from the banker's balance. + * Pays the player and money gets subtracted from the bankers initial balance. * * @param player The player to whom the money is being paid. * @param amount The amount of money to pay to the player. @@ -43,8 +43,7 @@ public class Banker { } /** - * Checks if a player has passed the 'Go' (Home) position and pays them accordingly. - * If the player's position is greater than 1, the banker pays them $0 (as per the Monopoly rules). + * Checks if a player has passed 'Home' or tile 1, this method gets called in the application class. * * @param player The player whose position is being checked. */ @@ -62,5 +61,4 @@ public class Banker { public int getBalance() { return balance; } - } diff --git a/src/main/java/com/cm6123/monopoly/game/Board.java b/src/main/java/com/cm6123/monopoly/game/Board.java index 4fde08d313ea9773af06d8a0232673c9b47071a8..4b268e2d28bd3eae578de659db403c12f7785cff 100644 --- a/src/main/java/com/cm6123/monopoly/game/Board.java +++ b/src/main/java/com/cm6123/monopoly/game/Board.java @@ -3,24 +3,31 @@ package com.cm6123.monopoly.game; import java.util.HashMap; /** - * Represents the game board for the game. + * Class for the board for the game using hashmaps. */ public class Board { // Using a hashmap from w3schools.com/java/java_hashmap.asp /** * Calibrating hashmap with positions and tile names. */ - public static final HashMap<Integer, String> GAME_BOARD = new HashMap<>(); + private static final HashMap<Integer, String> GAME_BOARD = new HashMap<>(); /** - * add a constructor for the board so its creates it and then returns it. + * 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<>(); + /** + * Constructor for the board. + */ public Board() { createGameBoard(); - getGameBoard(); + propertyBoard(); } - // creating the hashmap with the position and name of the tiles + + /** + * Hashmap with all the tile names and theire positions. + */ private void createGameBoard() { GAME_BOARD.put(1, "Home"); GAME_BOARD.put(2, "Road"); @@ -41,28 +48,64 @@ public class Board { } /** - * Returns the gameboard hashmap with all the names and positions. - * @return the GAME_BOARD hashmap + * Properties on the board are initialy false so when a player buys the property itll become true. + */ + private void propertyBoard() { + PROPERTY_OWNERSHIP.put(4, false); + PROPERTY_OWNERSHIP.put(5, false); + PROPERTY_OWNERSHIP.put(9, false); + PROPERTY_OWNERSHIP.put(13, false); + PROPERTY_OWNERSHIP.put(15, false); + } + + /** + * Gets the board hashmap. + * + * @return the hashmap representing the game board */ public static HashMap<Integer, String> getGameBoard() { - return GAME_BOARD; + return GAME_BOARD; } /** - * Returns the name of tiles at the specified positions. - * @param position the position on the gameboard - * @return the name of the tile at the specified position + * Gets the names of the tiles and their positions. + * + * @param position the position of the tile + * @return the name of the tile at the position */ public String getGameBoard(final int position) { - return GAME_BOARD.get(position); + return GAME_BOARD.get(position); } /** - * sets the tile name in the specified position. - * @param position the position on the game board - * @param name the name of the tile set + * Checks if a property can be purchased by the current player if they land on it. + * + * @param position the position of the property + * @return true if the property can be purchased; false otherwise. */ - public void printHashMap(final int position, final String name) { - GAME_BOARD.put(position, name); + public boolean canBuyProperty(final int position) { + return PROPERTY_OWNERSHIP.containsKey(position) && !PROPERTY_OWNERSHIP.get(position); + } + + /** + * 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. + * + * @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(); + + System.out.println(propertyOwner.getName() + " has bought this property."); + System.out.println("You now have £" + player.getMoney() + " in your bank account."); + } } } diff --git a/src/main/java/com/cm6123/monopoly/game/GameAction.java b/src/main/java/com/cm6123/monopoly/game/GameAction.java new file mode 100644 index 0000000000000000000000000000000000000000..8c20464b684360277fdc8e3ff28fca2361c3d933 --- /dev/null +++ b/src/main/java/com/cm6123/monopoly/game/GameAction.java @@ -0,0 +1,56 @@ +package com.cm6123.monopoly.game; + +import java.util.Scanner; + +/** + * class for game actions if a player lands on a tile that is useful. + */ +public class GameAction implements GameHandler { + + /** + * The board. + */ + private final Board board; + + + /** + * Constructor for GameAction with the board. + * + * @param gameboard the board used for game actions + */ + public GameAction(final Board gameboard) { + this.board = gameboard; + } + + /** + * Game action if a player lands on a property. + * + * @param player the player who landed on the property + */ + @Override + public void landedOnProperty(final Player player) { + int position = player.getPosition(); + + // Check if the property at the current position can be bought + if (this.board.canBuyProperty(position)) { + String propertyName = this.board.getGameBoard(position); + System.out.println("Would you like to buy " + propertyName + " for £200? (Y/N)"); + + Scanner scanner = new Scanner(System.in); + String input = scanner.next().toUpperCase(); + + // if Player chooses to buy the property check if the player has enough to buy it + if (input.equals("Y")) { + if (player.getMoney() >= 200) { + this.board.buyProperty(position, player); + } else { + System.out.println("You do not have enough money to buy " + propertyName + ". Moving on..."); + } // if player doesn't want to buy it move on + } else if (input.equals("N")) { + System.out.println("You have chosen N, moving on..."); + } else { // if user enters something else skip the turn + System.out.println("Invalid input. Skipping turn"); + } + } + } +} diff --git a/src/main/java/com/cm6123/monopoly/game/GameEndings.java b/src/main/java/com/cm6123/monopoly/game/GameEndings.java index 00ce35713fd7b0c7091d159d2c26935f59061d24..9bf345c0d65e9398cab0a128060c2cf75975250d 100644 --- a/src/main/java/com/cm6123/monopoly/game/GameEndings.java +++ b/src/main/java/com/cm6123/monopoly/game/GameEndings.java @@ -4,17 +4,17 @@ package com.cm6123.monopoly.game; import java.util.ArrayList; /** - * Represents the ways that the game can end and what would happen after. + * Class for GameEndings if round max reach and declare winner. */ public final class GameEndings { private GameEndings() {} /** - * Checks if the specified round has reached or exceeded the maximum number of rounds. + * Checks if the round inputed by the user has reached the number of rounds. * - * @param round The current round number. - * @param numberOfRounds The maximum number of rounds allowed. + * @param round The current round number, rounds start at 1. + * @param numberOfRounds The number of rounds the user wants. * @return true if the round has reached or exceeded the maximum number of rounds, false otherwise. */ public static boolean checkRoundsReached (final int round, final int numberOfRounds){ @@ -26,7 +26,7 @@ public final class GameEndings { } /** - * Determines the winner among the given list of players based on their money. + * Determines the winner by checking which player has the most money. * Prints out the winner's name and money amount. * * @param players The list of players in the game. diff --git a/src/main/java/com/cm6123/monopoly/game/GameHandler.java b/src/main/java/com/cm6123/monopoly/game/GameHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..4e1da59ad3df9d74e8ff7d38ddd9b2618b616efa --- /dev/null +++ b/src/main/java/com/cm6123/monopoly/game/GameHandler.java @@ -0,0 +1,15 @@ +package com.cm6123.monopoly.game; + +/** + * Interface in connection with game actions for if a player lands on a useful tile. + */ +public interface GameHandler { + + /** + * Triggers when player lands on a property. + * + * @param player the player who landed on the property + */ + void landedOnProperty(Player player); + +} diff --git a/src/main/java/com/cm6123/monopoly/game/Movement.java b/src/main/java/com/cm6123/monopoly/game/Movement.java index 572d451b00d17f03d0d0d192158ba857ccf3faa6..de784a5235afa8357a4554c4be785839e29089da 100644 --- a/src/main/java/com/cm6123/monopoly/game/Movement.java +++ b/src/main/java/com/cm6123/monopoly/game/Movement.java @@ -3,21 +3,20 @@ package com.cm6123.monopoly.game; import com.cm6123.monopoly.dice.Dice; /** - * Represents the movement logic in a Monopoly game. - * This class manages the movement of players on the game board based on dice rolls. + * Class for the movement when dice is rolled. */ public class Movement { - /** The size of the game board. */ + /** The number of tiles on the board. */ private static final int GAME_BOARD_SIZE = 16; - /** A die object used for rolling. */ + /** The die object used for rolling. */ private final Dice dice = new Dice(6); /** - * Simulates rolling two dice for a player and updates their position on the game board based on the dice roll result. + * Player asked to roll die and the result is added up (diceResult) for the sum of both dies rolled. * * @param player The player whose position will be updated. */ @@ -36,9 +35,7 @@ public class Movement { // Calculate new position on the game board based on dice result int newPosition = (currentPosition + diceResult - 1) % GAME_BOARD_SIZE + 1; - // Update player's position + // Update player's new position player.setPosition(newPosition); } - - } diff --git a/src/main/java/com/cm6123/monopoly/game/Player.java b/src/main/java/com/cm6123/monopoly/game/Player.java index bf9c8fb4d5999b2fd28cdb253d291efe874cdfa5..6c6ef9aa9734cfabf6b190955acdd419d49a3d73 100644 --- a/src/main/java/com/cm6123/monopoly/game/Player.java +++ b/src/main/java/com/cm6123/monopoly/game/Player.java @@ -3,8 +3,7 @@ package com.cm6123.monopoly.game; import java.util.ArrayList; /** - * Represents a player in a Monopoly game. - * Players have a name, money, position, and can interact with the banker. + * Class for the player which holds the names, money and position. */ public class Player { @@ -24,11 +23,12 @@ public class Player { private int position; + /** - * Constructs a new player with the specified name, initial money, and starting position. + * Constructor for player with the user inputed name, initial money, and starting position. * - * @param playerName The name of the player. - * @param playerMoney The initial amount of money the player has. + * @param playerName The name of the player. + * @param playerMoney The initial amount of money the player has. * @param playerPosition The starting position of the player on the game board. */ public Player(final String playerName, final int playerMoney, final int playerPosition) { @@ -46,7 +46,15 @@ public class Player { } /** - * Retrieves the name of the player. + * + * @param amount amount of money subtracted from the players balance. + */ + public void subtractMoney(final int amount) { + this.money -= amount; + } + + /** + * Gets the name of the player. * * @return The name of the player. */ @@ -64,7 +72,7 @@ public class Player { } /** - * Retrieves the amount of money the player has. + * Gets the amount of money the player has. * * @return The amount of money the player has. */ @@ -83,7 +91,7 @@ public class Player { /** - * Retrieves the current position of the player on the game board. + * Gets the current position of the player on the game board. * * @return The current position of the player. */ @@ -104,12 +112,11 @@ public class Player { public static final ArrayList<Player> PLAYERSINTHEGAME = new ArrayList<>(); /** - * Retrieves the list of all players in the game. + * Gets the list of all players in the game. * * @return The list of all players. */ public static ArrayList<Player> getPlayers() { return PLAYERSINTHEGAME; } - } diff --git a/src/main/java/com/cm6123/monopoly/game/Properties.java b/src/main/java/com/cm6123/monopoly/game/Properties.java new file mode 100644 index 0000000000000000000000000000000000000000..ba59ae00d4f9bfa4fde1f32a5c041a30b178f022 --- /dev/null +++ b/src/main/java/com/cm6123/monopoly/game/Properties.java @@ -0,0 +1,79 @@ +package com.cm6123.monopoly.game; + + +/** + * Class for properties. + */ +public class Properties { + + /** + * The name of the property. + */ + private final String name; + + /** + * The price of the property. + */ + private int price; + + /** + * The owner of the property. + */ + private Player owner; + + /** + * Constructor for property with the name. + * + * @param propertyname the name of the property + */ + public Properties(final String propertyname) { + this.name = propertyname; + this.price = 200; + this.owner = null; + } + + /** + * Gets the name of the property. + * + * @return the name of the property + */ + public String getName() { + return name; + } + + /** + * Gets the price of the property. + * + * @return the price of the property + */ + public int getPrice() { + return price; + } + + /** + * Sets the price of the property. + * + * @param newPrice the new price to set for the property + */ + public void setPrice(final int newPrice) { + this.price = newPrice; + } + + /** + * Gets the owner of the property. + * + * @return the owner of the property, or null if the property is not owned + */ + public Player getOwner() { + return owner; + } + + /** + * Sets the owner of the property. + * + * @param player the player to set as the owner of the property + */ + public void setOwner(final Player player) { + this.owner = player; + } +} diff --git a/src/test/java/com/cm6123/monopoly/BankerTest.java b/src/test/java/com/cm6123/monopoly/BankerTest.java index 5ad92a9092eac2be8376cece3e3c19356341dd33..88917840317e5b0844218b7981f67f27cb1aebb8 100644 --- a/src/test/java/com/cm6123/monopoly/BankerTest.java +++ b/src/test/java/com/cm6123/monopoly/BankerTest.java @@ -22,7 +22,7 @@ public class BankerTest { // Add money to the banker's balance banker.addMoney(amountToAdd); - // Check if the balance is updated correctly + // Check if the balance is icnreased by 200 assertEquals(5200, banker.getBalance()); } } diff --git a/src/test/java/com/cm6123/monopoly/BoardTest.java b/src/test/java/com/cm6123/monopoly/BoardTest.java index 5a77b8aba8d5b3aa31c6350d50e4e8f89e848fa7..3fffd8ab7db392cc889d96599e6077b03201f880 100644 --- a/src/test/java/com/cm6123/monopoly/BoardTest.java +++ b/src/test/java/com/cm6123/monopoly/BoardTest.java @@ -1,15 +1,14 @@ package com.cm6123.monopoly; - -import com.cm6123.monopoly.game.Board; import com.cm6123.monopoly.game.Player; +import com.cm6123.monopoly.game.Board; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; public class BoardTest { @Test - public void testPlayerPositionChangeAndTileName() { + public void testPlayerPositionAndTileName() { // Create a new player starting at position 1 Player player = new Player("PlayerTest", 1000, 1); @@ -20,14 +19,14 @@ public class BoardTest { // Change player's position to 5 player.setPosition(5); - // Ensure the position has changed to 5 + // check if players new position is 5 int newPosition = player.getPosition(); Assertions.assertEquals(5, newPosition); - // Create an instance of Board + // Create a Board Board board = new Board(); - // Retrieve the tile name at the new position using the Board instance + // Get the tile name at the new position String tileName = board.getGameBoard(newPosition); Assertions.assertEquals("Pall Mall", tileName); } diff --git a/src/test/java/com/cm6123/monopoly/GameEndingsTest.java b/src/test/java/com/cm6123/monopoly/GameEndingsTest.java index 8a63157cd4204d3abb33fda42262886136603160..b5bd727f2ae4057f114bd406dd81d75438d8778c 100644 --- a/src/test/java/com/cm6123/monopoly/GameEndingsTest.java +++ b/src/test/java/com/cm6123/monopoly/GameEndingsTest.java @@ -9,10 +9,6 @@ import java.util.ArrayList; public class GameEndingsTest { - /** - * Tests the checkRoundsReached method of GameEndings. - * Verifies that the roundsReached flag is true when rounds reach the specified number of rounds. - */ @Test public void testRoundsReached() { int rounds = 10; @@ -21,14 +17,14 @@ public class GameEndingsTest { // Check if rounds reached matches the specified number of rounds boolean roundsReached = GameEndings.checkRoundsReached(rounds, numberOfRounds); - // Assert that roundsReached is true + // check that roundsReached is true Assertions.assertTrue(roundsReached); System.out.println("End game"); } @Test public void testDetermineWinner() { - // Create two players with different initial money + // Create two players with different money Player player1 = new Player("Player1", 1000, 0); Player player2 = new Player("Player2", 2000, 0); @@ -40,7 +36,7 @@ public class GameEndingsTest { // Determine the winner GameEndings.determineWinner(players); - // Assert that the player with more money is identified as the winner + // Check that the player with more money is the winner Player winner = players.stream().max((p1, p2) -> Integer.compare(p1.getMoney(), p2.getMoney())).orElse(null); Assertions.assertNotNull(winner); Assertions.assertEquals("Player2", winner.getName()); diff --git a/src/test/java/com/cm6123/monopoly/MovementTest.java b/src/test/java/com/cm6123/monopoly/MovementTest.java index adc0a919ac5ccca928791eeb0b4bd861dab2015d..10fffc043109ed5a539c08d95f0a0af756d1db75 100644 --- a/src/test/java/com/cm6123/monopoly/MovementTest.java +++ b/src/test/java/com/cm6123/monopoly/MovementTest.java @@ -10,20 +10,16 @@ import static org.junit.jupiter.api.Assertions.assertNotEquals; public class MovementTest { @Test - public void testPlayerMovement() { + public void testMovement() { // Create a player with initial position - Player player = new Player("Alice", 1500, 1); - - // Initialize movement logic + Player player = new Player("PlayerInitial", 1000, 1); Movement movement = new Movement(); // Get initial position int initialPosition = player.getPosition(); - // Test moving the player movement.diceResult(player); - // Ensure player's position has changed assertNotEquals(initialPosition, player.getPosition()); } } diff --git a/src/test/java/com/cm6123/monopoly/PropertyPurchaseTest.java b/src/test/java/com/cm6123/monopoly/PropertyPurchaseTest.java new file mode 100644 index 0000000000000000000000000000000000000000..d293f2362e9b5c37f6a2d60522e54e9b0c059cf1 --- /dev/null +++ b/src/test/java/com/cm6123/monopoly/PropertyPurchaseTest.java @@ -0,0 +1,52 @@ +package com.cm6123.monopoly; + +import com.cm6123.monopoly.game.Player; +import com.cm6123.monopoly.game.GameAction; +import com.cm6123.monopoly.game.Board; + +import org.junit.jupiter.api.Test; + +import java.io.ByteArrayInputStream; + +import static org.junit.jupiter.api.Assertions.*; + +public class PropertyPurchaseTest { + + @Test + public void testPlayerLandsOnUnownedProperty() { + + Board board = new Board(); + + Player player = new Player("TestPlayer", 1000, 0); // Example player with £1000 starting money and at position 0 + player.setPosition(4); + + ByteArrayInputStream in = new ByteArrayInputStream("Y".getBytes()); + System.setIn(in); + + + GameAction gameAction = new GameAction(board); + gameAction.landedOnProperty(player); + + assertEquals(4, player.getPosition(), "Player should land on tile 4 (Old Kent Road)"); + + System.setIn(System.in); + } + + @Test + public void testIfPlayerCanRePurchaseProperty() { + + Board board = new Board(); + + 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 + testPlayer2.setPosition(4); + + GameAction gameAction = new GameAction(board); + gameAction.landedOnProperty(testPlayer2); + + assertEquals(4, testPlayer2.getPosition()); + + } +} diff --git a/src/test/java/com/cm6123/monopoly/PropertyTest.java b/src/test/java/com/cm6123/monopoly/PropertyTest.java new file mode 100644 index 0000000000000000000000000000000000000000..fde740f57a81e5d5f92400ed09b8388a826bb0f6 --- /dev/null +++ b/src/test/java/com/cm6123/monopoly/PropertyTest.java @@ -0,0 +1,22 @@ +package com.cm6123.monopoly; + +import com.cm6123.monopoly.game.Properties; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +public class PropertyTest { + + @Test + public void testSetAndGetPrice() { + Properties property = new Properties("Old Kent Road"); + property.setPrice(400); + int actualPrice = property.getPrice(); + + assertEquals(400, actualPrice); + } +} + + + +