diff --git a/SnakeAndLadder/pom.xml b/SnakeAndLadder/pom.xml new file mode 100644 index 00000000..68167b0c --- /dev/null +++ b/SnakeAndLadder/pom.xml @@ -0,0 +1,45 @@ + + + 4.0.0 + + org.main + SnakeAndLadder + 1.0-SNAPSHOT + + + 21 + 21 + UTF-8 + + + + + org.mockito + mockito-core + 5.12.0 + test + + + org.projectlombok + lombok + 1.18.32 + provided + + + org.junit.jupiter + junit-jupiter-engine + 5.8.1 + test + + + + org.junit.jupiter + junit-jupiter-api + 5.8.1 + test + + + + \ No newline at end of file diff --git a/SnakeAndLadder/src/main/java/org/main/Dice.java b/SnakeAndLadder/src/main/java/org/main/Dice.java new file mode 100644 index 00000000..1b404afd --- /dev/null +++ b/SnakeAndLadder/src/main/java/org/main/Dice.java @@ -0,0 +1,39 @@ +package org.main; + +import lombok.Getter; +import lombok.Setter; + +import java.util.Random; + +/** + * + */ +@Getter +@Setter +public class Dice { + private Integer numOfDices; + private Integer minDiceRollValue; + private Integer maxDiceRollValue; + + public Dice(Integer numOfDices) { + this.numOfDices = numOfDices; + updateMinAndMaxDiceRollValues(numOfDices); + } + + public void updateMinAndMaxDiceRollValues(Integer numOfDices) { + minDiceRollValue = numOfDices; + maxDiceRollValue = 6*numOfDices; + } + + public int rollDice() { + return getRandomNumberBetween(minDiceRollValue, maxDiceRollValue); + } + + private int getRandomNumberBetween(int min, int max) throws IllegalArgumentException { + if (max < min) { + throw new IllegalArgumentException("Max value "+max+" should be less than min "+min); + } + Random r = new Random(); + return r.nextInt((max-min)+1)+min; + } +} diff --git a/SnakeAndLadder/src/main/java/org/main/GameBoard.java b/SnakeAndLadder/src/main/java/org/main/GameBoard.java new file mode 100644 index 00000000..3ab50430 --- /dev/null +++ b/SnakeAndLadder/src/main/java/org/main/GameBoard.java @@ -0,0 +1,5 @@ +package org.main; + +public interface GameBoard { + +} diff --git a/SnakeAndLadder/src/main/java/org/main/GameFilePathManager.java b/SnakeAndLadder/src/main/java/org/main/GameFilePathManager.java new file mode 100644 index 00000000..6f1fcbc5 --- /dev/null +++ b/SnakeAndLadder/src/main/java/org/main/GameFilePathManager.java @@ -0,0 +1,40 @@ +package org.main; + +import lombok.AccessLevel; +import lombok.Getter; +import lombok.Setter; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +@Getter +@Setter(AccessLevel.PRIVATE) +public class GameFilePathManager { + private Path filePath; + + public GameFilePathManager() { + filePath = null; + } + + public Boolean fileExists(Path path) { + if (Files.exists(path)) { + return true; + } + return false; + } + + public Boolean validateAndSetFilePath(String path) { + if (path == null || path.isEmpty()) { + System.out.println("The File path provided for the game " +path+ " is not valid"); + } else { + Path tempFilePath = Paths.get(path); + if (fileExists(tempFilePath)) { + filePath = tempFilePath; + return true; + } + } + return false; + } + +} diff --git a/SnakeAndLadder/src/main/java/org/main/GamePlay.java b/SnakeAndLadder/src/main/java/org/main/GamePlay.java new file mode 100644 index 00000000..6713ebe5 --- /dev/null +++ b/SnakeAndLadder/src/main/java/org/main/GamePlay.java @@ -0,0 +1,4 @@ +package org.main; + +public interface GamePlay { +} diff --git a/SnakeAndLadder/src/main/java/org/main/GamePlayers.java b/SnakeAndLadder/src/main/java/org/main/GamePlayers.java new file mode 100644 index 00000000..3e7e955f --- /dev/null +++ b/SnakeAndLadder/src/main/java/org/main/GamePlayers.java @@ -0,0 +1,4 @@ +package org.main; + +public interface GamePlayers { +} diff --git a/SnakeAndLadder/src/main/java/org/main/LoadGameBoard.java b/SnakeAndLadder/src/main/java/org/main/LoadGameBoard.java new file mode 100644 index 00000000..a6eb4b07 --- /dev/null +++ b/SnakeAndLadder/src/main/java/org/main/LoadGameBoard.java @@ -0,0 +1,8 @@ +package org.main; + +import java.io.FileNotFoundException; + +public interface LoadGameBoard { + public void LoadGameboard() throws FileNotFoundException; +} + diff --git a/SnakeAndLadder/src/main/java/org/main/Main.java b/SnakeAndLadder/src/main/java/org/main/Main.java new file mode 100644 index 00000000..264b5756 --- /dev/null +++ b/SnakeAndLadder/src/main/java/org/main/Main.java @@ -0,0 +1,30 @@ +package org.main; + +import java.io.FileNotFoundException; +import java.util.Scanner; + +public class Main { + public static void main(String[] args) throws FileNotFoundException, InterruptedException { + + System.out.println("Hello and welcome to the Snake and Ladder!"); + Scanner scanner = new Scanner(System.in); + String filepath=""; + + GameFilePathManager gameFilePathManager = new GameFilePathManager(); + while (!(gameFilePathManager.validateAndSetFilePath(filepath))) { + System.out.println("Please give the valid game Loader file path"); + filepath = scanner.nextLine(); + } + GameBoard gameBoard = new SnakeAndLadderGameBoard(gameFilePathManager, new Dice(2), 120); + SnakeAndLadderGameBoardLoader snakeAndLadderGameBoardLoader = new SnakeAndLadderGameBoardLoader(gameBoard); + snakeAndLadderGameBoardLoader.LoadGameboard(); + + for(int i =0; i<1; i++) { + SnakeAndLadderGamePlayers snakeAndLadderGamePlayers = new SnakeAndLadderGamePlayers(); + snakeAndLadderGamePlayers.LoadPlayers(snakeAndLadderGameBoardLoader.getSnakeAndLadderGamePlayersNames()); + SnakeAndLadderGameBoardPlay snakeAndLadderGameBoardPlay = new SnakeAndLadderGameBoardPlay((SnakeAndLadderGameBoard)gameBoard, snakeAndLadderGamePlayers); + snakeAndLadderGameBoardPlay.StartGame(); + System.out.println("Thanks for playing the snake and ladder Game!!!!"); + } + } +} \ No newline at end of file diff --git a/SnakeAndLadder/src/main/java/org/main/MovementCause.java b/SnakeAndLadder/src/main/java/org/main/MovementCause.java new file mode 100644 index 00000000..0be1635a --- /dev/null +++ b/SnakeAndLadder/src/main/java/org/main/MovementCause.java @@ -0,0 +1,16 @@ +package org.main; + +import lombok.Getter; + +@Getter +public enum MovementCause { + SNAKE_BITE("Snake bite"), + GOT_LADDER("Got Ladder"), + DICE("Dice"); + + MovementCause(String description) { + this.description = description; + } + + private String description; +} diff --git a/SnakeAndLadder/src/main/java/org/main/Player.java b/SnakeAndLadder/src/main/java/org/main/Player.java new file mode 100644 index 00000000..e2abaf1d --- /dev/null +++ b/SnakeAndLadder/src/main/java/org/main/Player.java @@ -0,0 +1,45 @@ +package org.main; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +import java.util.ArrayList; + +@Getter +@Setter +class PlayerMove { + private Integer initialPosition; + private Integer finalPosition; + private MovementCause cause; + + public PlayerMove(Integer initialPosition, Integer finalPosition, MovementCause cause) { + this.initialPosition = initialPosition; + this.finalPosition = finalPosition; + this.cause = cause; + } +} + +@Getter +@Setter +@ToString +public class Player { + private String name; + private Integer curPosition; + private PlayerStatus playerStatus; + private ArrayList moves; + + public Player(String name) { + this.name = name; + this.curPosition = 0; + this.playerStatus = PlayerStatus.IDLE; + this.moves = new ArrayList<>(); + } + + public boolean won() { + if (this.playerStatus == PlayerStatus.WON) { + return true; + } + return false; + } +} diff --git a/SnakeAndLadder/src/main/java/org/main/PlayerStatus.java b/SnakeAndLadder/src/main/java/org/main/PlayerStatus.java new file mode 100644 index 00000000..82b7d7d2 --- /dev/null +++ b/SnakeAndLadder/src/main/java/org/main/PlayerStatus.java @@ -0,0 +1,7 @@ +package org.main; + +public enum PlayerStatus { + PLAYING, + WON, + IDLE; +} diff --git a/SnakeAndLadder/src/main/java/org/main/SnakeAndLadderGameBoard.java b/SnakeAndLadder/src/main/java/org/main/SnakeAndLadderGameBoard.java new file mode 100644 index 00000000..119b0d50 --- /dev/null +++ b/SnakeAndLadder/src/main/java/org/main/SnakeAndLadderGameBoard.java @@ -0,0 +1,35 @@ +package org.main; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +import java.util.HashMap; + +@Setter +@Getter +@ToString +public class SnakeAndLadderGameBoard implements GameBoard { + private GameFilePathManager gameFilePathManager; + private HashMap SnakesMap; + private HashMap LadderMap; + private Integer boardSize; + private Dice dice; + + public SnakeAndLadderGameBoard(GameFilePathManager gameFilePathManager, Dice dice, Integer size) { + this.gameFilePathManager = gameFilePathManager; + SnakesMap = new HashMap<>(); + LadderMap = new HashMap<>(); + this.dice = dice; + this.boardSize = size; + } + + public Integer caughtBySnake(Integer curPosition) { + return SnakesMap.getOrDefault(curPosition, -1); + } + + public Integer gotLadder(Integer curPosition) { + return LadderMap.getOrDefault(curPosition, -1); + } + +} diff --git a/SnakeAndLadder/src/main/java/org/main/SnakeAndLadderGameBoardLoader.java b/SnakeAndLadder/src/main/java/org/main/SnakeAndLadderGameBoardLoader.java new file mode 100644 index 00000000..8a08ab83 --- /dev/null +++ b/SnakeAndLadder/src/main/java/org/main/SnakeAndLadderGameBoardLoader.java @@ -0,0 +1,91 @@ +package org.main; + +import lombok.Getter; +import lombok.Setter; + +import java.io.File; +import java.io.FileNotFoundException; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Scanner; + +@Getter +@Setter +public class SnakeAndLadderGameBoardLoader implements LoadGameBoard{ + private GameBoard gameBoard; + private Scanner gameBoardFileScanner; + private ArrayList snakeAndLadderGamePlayersNames; + private SnakeAndLadderGameBoard snakeAndLadderGameBoard; + + public SnakeAndLadderGameBoardLoader(GameBoard gameBoard) { + this.gameBoard = gameBoard; + this.snakeAndLadderGamePlayersNames = new ArrayList<>(); + } + + private void readGameBoardFile() throws FileNotFoundException { + snakeAndLadderGameBoard = (SnakeAndLadderGameBoard)(gameBoard); + Path path = snakeAndLadderGameBoard.getGameFilePathManager().getFilePath(); + File file = new File(String.valueOf(path)); + gameBoardFileScanner = new Scanner(file); + } + + private boolean checkIfGameBoardIsOfSnakeAndLadder() { + return (gameBoard instanceof SnakeAndLadderGameBoard); + } + + private void LoadSnakes(int numOfSnakes) { + while (numOfSnakes > 0) { + Integer snakeHead = gameBoardFileScanner.nextInt(); + Integer snakeTail = gameBoardFileScanner.nextInt(); + //System.out.println("Adding the snake with snakeHead "+snakeHead+" and snakeTail "+snakeTail); + snakeAndLadderGameBoard.getSnakesMap().put(snakeHead, snakeTail); + numOfSnakes--; + } + } + + private void LoadLadders(int numOfLadders) { + while (numOfLadders > 0) { + Integer ladderHead = gameBoardFileScanner.nextInt(); + Integer ladderTail = gameBoardFileScanner.nextInt(); + //System.out.println("Adding the snake with ladderHead "+ladderHead+" and ladderTail "+ladderTail); + snakeAndLadderGameBoard.getLadderMap().put(ladderHead, ladderTail); + numOfLadders--; + } + } + + private void LoadUsers(int numOfUsers) { + gameBoardFileScanner.nextLine(); + while (numOfUsers > 0) { + String name = gameBoardFileScanner.nextLine(); + //System.out.println("Adding a user with name "+name); + snakeAndLadderGamePlayersNames.add(name); + numOfUsers--; + } + } + + @Override + public void LoadGameboard() throws FileNotFoundException { + if (checkIfGameBoardIsOfSnakeAndLadder()) { + readGameBoardFile(); + //Load snakes + int numOfSnakes = gameBoardFileScanner.nextInt(); + //System.out.println("Number of Snakes for the game is = "+ numOfSnakes); + LoadSnakes(numOfSnakes); + + //Load Ladders + int numOfLadders = gameBoardFileScanner.nextInt(); + //System.out.println("Number of Ladders for the game is = "+ numOfLadders); + LoadLadders(numOfLadders); + + //Load Users + int numOfUsers = gameBoardFileScanner.nextInt(); + //System.out.println("Number of Users for the game is = "+ numOfUsers); + LoadUsers(numOfUsers); + + gameBoardFileScanner.close(); + } else { + System.out.println("The Object Provided for the class"+ SnakeAndLadderGameBoardLoader.class +" is not of type "+ SnakeAndLadderGameBoard.class); + System.exit(0); + } + } +} diff --git a/SnakeAndLadder/src/main/java/org/main/SnakeAndLadderGameBoardPlay.java b/SnakeAndLadder/src/main/java/org/main/SnakeAndLadderGameBoardPlay.java new file mode 100644 index 00000000..90070617 --- /dev/null +++ b/SnakeAndLadder/src/main/java/org/main/SnakeAndLadderGameBoardPlay.java @@ -0,0 +1,119 @@ +package org.main; + +public class SnakeAndLadderGameBoardPlay implements GamePlay { + private SnakeAndLadderGameBoard snakeAndLadderGameBoard; + private SnakeAndLadderGamePlayers snakeAndLadderGamePlayers; + + public SnakeAndLadderGameBoardPlay(SnakeAndLadderGameBoard snakeAndLadderGameBoard, SnakeAndLadderGamePlayers snakeAndLadderGamePlayers) { + this.snakeAndLadderGameBoard = snakeAndLadderGameBoard; + this.snakeAndLadderGamePlayers = snakeAndLadderGamePlayers; + } + + public void updatePlayersGameStart() { + for (Player player : snakeAndLadderGamePlayers.getPlayers()) { + player.setPlayerStatus(PlayerStatus.PLAYING); + player.setPlayerStatus(PlayerStatus.PLAYING); + } + } + + public boolean stopGame () { + if ((snakeAndLadderGamePlayers.getPlayers().size() - snakeAndLadderGamePlayers.getNumOfPlayersWon()) == 1) { + return true; + } + return false; + } + + public void StartGame() throws InterruptedException { + Integer diceVal; + Integer consecutiveMaxDiceRollCount = 0; + updatePlayersGameStart(); + + while (!(stopGame())) { + for (Player player : snakeAndLadderGamePlayers.getPlayers()) { + consecutiveMaxDiceRollCount = 0; + if (stopGame()) { + break; + } + if (player.getPlayerStatus() == PlayerStatus.WON) { + continue; + } + + //First Roll + diceVal = snakeAndLadderGameBoard.getDice().rollDice(); + + //Consecutive Dice Rolls + if (diceVal == snakeAndLadderGameBoard.getDice().getMaxDiceRollValue()) { + do { + consecutiveMaxDiceRollCount++; + System.out.println(player.getName()+" Rolled a "+snakeAndLadderGameBoard.getDice().getMaxDiceRollValue()+" will get another chance ,Currently Chance num "+ consecutiveMaxDiceRollCount); + movePlayerOnBoard(diceVal, player, MovementCause.DICE); + diceVal = snakeAndLadderGameBoard.getDice().rollDice(); + } while (diceVal == snakeAndLadderGameBoard.getDice().getMaxDiceRollValue() && consecutiveMaxDiceRollCount<3); + } + + if (consecutiveMaxDiceRollCount == 3 && diceVal == snakeAndLadderGameBoard.getDice().getMaxDiceRollValue()) { + revertMovesOfPlayerOnBoard(player); + } else { + movePlayerOnBoard(diceVal, player, MovementCause.DICE); + } + } + } + } + + public void revertMovesOfPlayerOnBoard(Player player) { + System.out.println(player.getName()+ " Rolled more than 4 times consecutively "+ snakeAndLadderGameBoard.getDice().getMaxDiceRollValue()+" So we are cancelling all his moves "); + PlayerMove lastMove; + int i = 3; + + while (i>0) { + lastMove = player.getMoves().removeLast(); + System.out.println(player.getName()+ " movement reverted from "+ lastMove.getFinalPosition() +" to "+lastMove.getInitialPosition()); + player.setCurPosition(lastMove.getInitialPosition()); + i--; + } + + } + + public void printMove(Integer newPos, Player player, MovementCause cause) { + if (newPos > snakeAndLadderGameBoard.getBoardSize()) { + System.out.println(player.getName()+" Is trying to move to "+ newPos +" which is out of boundary of the board of size "+ snakeAndLadderGameBoard.getBoardSize()); + } + + if (cause == MovementCause.DICE) { + int diceVal = newPos - player.getCurPosition(); + System.out.println(player.getName()+ " rolled a "+diceVal+" and Moved From "+player.getCurPosition()+ " to "+newPos); + } else { + System.out.println(player.getName()+" "+cause.getDescription()+" and Moved From "+player.getCurPosition()+ " to "+newPos); + } + } + + public void updatePlayer(Integer newPos, Player player, MovementCause cause) { + printMove(newPos, player, cause); + if (newPos <= snakeAndLadderGameBoard.getBoardSize()) { + player.getMoves().add(new PlayerMove(player.getCurPosition(), newPos, cause)); + if (newPos == snakeAndLadderGameBoard.getBoardSize()) { + player.setPlayerStatus(PlayerStatus.WON); + System.out.println(player.getName()+" Reached "+snakeAndLadderGameBoard.getBoardSize()+" won!! "); + snakeAndLadderGamePlayers.getPlayersWon().add(player); + } + player.setCurPosition(newPos); + } + } + + public void movePlayerOnBoard(Integer diceVal, Player player, MovementCause cause) { + Integer newPos; + if (cause == MovementCause.DICE) { + newPos = player.getCurPosition() + diceVal; + } else { + newPos = diceVal; + } + updatePlayer(newPos, player, cause); + if (snakeAndLadderGameBoard.caughtBySnake(newPos)!=-1) { + newPos = snakeAndLadderGameBoard.caughtBySnake(newPos); + movePlayerOnBoard(newPos, player, MovementCause.SNAKE_BITE); + } else if (snakeAndLadderGameBoard.gotLadder(newPos)!=-1) { + newPos = snakeAndLadderGameBoard.gotLadder(newPos); + movePlayerOnBoard(newPos, player, MovementCause.GOT_LADDER); + } + } +} diff --git a/SnakeAndLadder/src/main/java/org/main/SnakeAndLadderGamePlayers.java b/SnakeAndLadder/src/main/java/org/main/SnakeAndLadderGamePlayers.java new file mode 100644 index 00000000..026c49e6 --- /dev/null +++ b/SnakeAndLadder/src/main/java/org/main/SnakeAndLadderGamePlayers.java @@ -0,0 +1,28 @@ +package org.main; + +import lombok.Getter; +import lombok.Setter; + +import java.util.ArrayList; + +@Getter +@Setter +public class SnakeAndLadderGamePlayers implements GamePlayers{ + private ArrayList players; + private ArrayList playersWon; + + public SnakeAndLadderGamePlayers() { + this.players = new ArrayList<>(); + this.playersWon = new ArrayList<>(); + } + + public void LoadPlayers (ArrayList players) { + for (String name : players) { + this.players.add(new Player(name)); + } + } + + public Integer getNumOfPlayersWon() { + return playersWon.size(); + } +} diff --git a/SnakeAndLadder/src/main/resources/SankeAndLadderGameInput.txt b/SnakeAndLadder/src/main/resources/SankeAndLadderGameInput.txt new file mode 100644 index 00000000..5ee5a87f --- /dev/null +++ b/SnakeAndLadder/src/main/resources/SankeAndLadderGameInput.txt @@ -0,0 +1,24 @@ +9 +62 5 +33 6 +49 9 +88 16 +41 20 +56 53 +98 64 +93 73 +95 75 +8 +2 37 +27 46 +10 32 +51 68 +61 79 +65 84 +71 91 +81 100 +4 +Gaurav +Sagar +Mahesh +Anusha \ No newline at end of file diff --git a/SnakeAndLadder/src/test/java/org/main/DiceTest.java b/SnakeAndLadder/src/test/java/org/main/DiceTest.java new file mode 100644 index 00000000..bfe10785 --- /dev/null +++ b/SnakeAndLadder/src/test/java/org/main/DiceTest.java @@ -0,0 +1,25 @@ +package org.main; + +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class DiceTest { + public boolean isBetween(int min, int max, int val) { + return (val <= max && val >=min); + } + + @Test + public void testRollDice() { + final int numOfDices = 2; + int diceVal; + Dice dice = new Dice(numOfDices); + + //Test the Random generator used in Dice class + for (int i=0; i < 100; i++) { + diceVal = dice.rollDice(); + System.out.println("Dice Val is "+diceVal); + assertTrue(isBetween(dice.getMinDiceRollValue(), dice.getMaxDiceRollValue(), diceVal), "Val Produced "+ dice.getMinDiceRollValue()+" is in range 1 and "+dice.getMaxDiceRollValue()); + } + } + +} \ No newline at end of file diff --git a/SnakeAndLadder/src/test/java/org/main/GameFilePathManagerTest.java b/SnakeAndLadder/src/test/java/org/main/GameFilePathManagerTest.java new file mode 100644 index 00000000..9b939507 --- /dev/null +++ b/SnakeAndLadder/src/test/java/org/main/GameFilePathManagerTest.java @@ -0,0 +1,39 @@ +package org.main; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class TestCase { + String path; + Boolean result; + String description; + + public TestCase(String path, Boolean result, String description) { + this.path = path; + this.result = result; + this.description = description; + } +} + +class GameFilePathManagerTest { + @Test + void validateAndSetFilePath() { + GameFilePathManager gameFilePathManager = new GameFilePathManager(); + + final TestCase[] testCases = new TestCase[] { + new TestCase("src/main/resources/SankeAndLadderGameInput.txt", true, "Correct path for Snake and Ladder Game"), + new TestCase("src/main/resources/SankeAndLadderGameInt.txt", false, "Correct path but wrong file name"), + new TestCase("resources/SankeAndLadderGameInput.txt", false, "Invalid path but correct File name") + }; + + for (TestCase test: testCases) { + try { + assertEquals(test.result, gameFilePathManager.validateAndSetFilePath(test.path)); + System.out.println(test.description+" -- Passed"); + } catch (AssertionError e) { + System.out.println(test.description+" -- Failed due to "+ e); + } + } + } +} \ No newline at end of file diff --git a/SnakeAndLadder/src/test/java/org/main/SnakeAndLadderGameBoardLoaderTest.java b/SnakeAndLadder/src/test/java/org/main/SnakeAndLadderGameBoardLoaderTest.java new file mode 100644 index 00000000..98580118 --- /dev/null +++ b/SnakeAndLadder/src/test/java/org/main/SnakeAndLadderGameBoardLoaderTest.java @@ -0,0 +1,17 @@ +package org.main; + +import org.junit.jupiter.api.Test; + +import java.io.FileNotFoundException; + +class SnakeAndLadderGameBoardLoaderTest { + + @Test + void loadGameboard() throws FileNotFoundException { + GameFilePathManager gameFilePathManager = new GameFilePathManager(); + gameFilePathManager.validateAndSetFilePath("src/main/resources/SankeAndLadderGameInput.txt"); + GameBoard gameBoard = new SnakeAndLadderGameBoard(gameFilePathManager, new Dice(2), 120); + SnakeAndLadderGameBoardLoader snakeAndLadderGameBoardLoader = new SnakeAndLadderGameBoardLoader(gameBoard); + snakeAndLadderGameBoardLoader.LoadGameboard(); + } +} \ No newline at end of file diff --git a/SnakeAndLadder/src/test/java/org/main/SnakeAndLadderGameBoardPlayTest.java b/SnakeAndLadder/src/test/java/org/main/SnakeAndLadderGameBoardPlayTest.java new file mode 100644 index 00000000..c5297377 --- /dev/null +++ b/SnakeAndLadder/src/test/java/org/main/SnakeAndLadderGameBoardPlayTest.java @@ -0,0 +1,30 @@ +package org.main; + +import org.junit.jupiter.api.Test; + +import java.io.FileNotFoundException; + +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; + +class SnakeAndLadderGameBoardPlayTest { + + @Test + void startGame() throws FileNotFoundException, InterruptedException { + String filepath = "C:\\Users\\mahes\\Exercism\\java\\SnakeAndLadder\\src\\main\\resources\\SankeAndLadderGameInput.txt"; + + GameFilePathManager gameFilePathManager = new GameFilePathManager(); + gameFilePathManager.validateAndSetFilePath(filepath); + Dice spyDice = spy(new Dice(2)); + + GameBoard gameBoard = new SnakeAndLadderGameBoard(gameFilePathManager, spyDice, 120); + SnakeAndLadderGameBoardLoader snakeAndLadderGameBoardLoader = new SnakeAndLadderGameBoardLoader(gameBoard); + snakeAndLadderGameBoardLoader.LoadGameboard(); + SnakeAndLadderGamePlayers snakeAndLadderGamePlayers = new SnakeAndLadderGamePlayers(); + snakeAndLadderGamePlayers.LoadPlayers(snakeAndLadderGameBoardLoader.getSnakeAndLadderGamePlayersNames()); + SnakeAndLadderGameBoardPlay snakeAndLadderGameBoardPlay = new SnakeAndLadderGameBoardPlay((SnakeAndLadderGameBoard) gameBoard, snakeAndLadderGamePlayers); + + when(spyDice.rollDice()).thenReturn(12); + snakeAndLadderGameBoardPlay.StartGame(); + } +} \ No newline at end of file diff --git a/SnakeAndLadder/target/classes/SankeAndLadderGameInput.txt b/SnakeAndLadder/target/classes/SankeAndLadderGameInput.txt new file mode 100644 index 00000000..5ee5a87f --- /dev/null +++ b/SnakeAndLadder/target/classes/SankeAndLadderGameInput.txt @@ -0,0 +1,24 @@ +9 +62 5 +33 6 +49 9 +88 16 +41 20 +56 53 +98 64 +93 73 +95 75 +8 +2 37 +27 46 +10 32 +51 68 +61 79 +65 84 +71 91 +81 100 +4 +Gaurav +Sagar +Mahesh +Anusha \ No newline at end of file diff --git a/SplitWise/pom.xml b/SplitWise/pom.xml new file mode 100644 index 00000000..204be5a9 --- /dev/null +++ b/SplitWise/pom.xml @@ -0,0 +1,56 @@ + + + 4.0.0 + + org.main + SplitWise + 1.0-SNAPSHOT + + + 21 + 21 + UTF-8 + + + + org.projectlombok + lombok + 1.18.32 + provided + + + org.junit.jupiter + junit-jupiter-engine + 5.8.1 + test + + + + org.junit.jupiter + junit-jupiter-api + 5.8.1 + test + + + org.mockito + mockito-core + 5.12.0 + test + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 22 + 22 + + + + + + \ No newline at end of file diff --git a/SplitWise/src/main/java/org/main/Balances.java b/SplitWise/src/main/java/org/main/Balances.java new file mode 100644 index 00000000..81c09ba5 --- /dev/null +++ b/SplitWise/src/main/java/org/main/Balances.java @@ -0,0 +1,239 @@ +package org.main; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +import java.util.*; +import java.text.DecimalFormat; +import java.util.concurrent.atomic.AtomicInteger; + +@Getter +@Setter +class StringFloat { + private String userId; + private Float amt; + + public StringFloat(String userId, Float amt) { + this.userId = userId; + this.amt = amt; + } + + +} + +class StringFloatMap extends HashMap { + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("{"); + this.forEach((key, value) -> sb.append(key).append("=").append(value).append(", ")); + if (sb.length() > 1) sb.setLength(sb.length() - 2); // Remove trailing comma and space + sb.append("}"); + return sb.toString(); + } +} + +@ToString +public class Balances { + private Currencies currencies; + private Float totalGroupSpending; + private HashMap usersBalancesMap; + private HashMap userBalancesSimplifiedMap; + public static final DecimalFormat df = new DecimalFormat("#.00"); + + public Balances(Currencies currencies) { + this.currencies = currencies; + this.totalGroupSpending = 0f; + usersBalancesMap = new HashMap<>(); + userBalancesSimplifiedMap = new HashMap<>(); + } + + //Function to debug print of Map + public void printBalancesMap() { + System.out.println("\n -- User balances map -- \n"); + for (Map.Entry usersBalances : usersBalancesMap.entrySet()) { + System.out.println("{ "+ usersBalances.getKey()+" = { "+ usersBalances.getValue()+ " }" +" }"); + } + } + + public void initlizeUsersBalancesMap(GroupUsers users) { + initlizeUsersBalancesMap(users, this.usersBalancesMap); + } + + public void initlizeUsersBalancesMap(GroupUsers users, HashMap usersBalancesMapInit) { + ArrayList userIds = new ArrayList<>(); + StringFloatMap tempMap = new StringFloatMap(); + + //creating the Map for all Users present in the Group + for (Map.Entry user : users.getUsers().entrySet()) { + usersBalancesMapInit.put(user.getKey(), new StringFloatMap()); + userIds.add(user.getKey()); + } + + //Updating every UserId with mappings of other user with default value as 0f + for (Map.Entry user : usersBalancesMapInit.entrySet()) { + for (String userId : userIds) { + //Avoiding BalanceMap of its own in the balances Map + if (user.getKey() != userId) { + user.getValue().put(userId, 0f); + } + } + } + } + + public HashMap getBalanceForUser(String userId) { + return usersBalancesMap.get(userId); + } + + public Float getBalanceForUser (String userId1, String userId2, HashMap usersBalancesMaping) { + StringFloatMap userBalances = usersBalancesMaping.get(userId1); + return userBalances.get(userId2); + } + + //Set of print functions for Single user input + public void getBalanceForUserPrint(String userId1) { + getBalanceForUserPrint(userId1, true); + } + + public void getBalanceForUserPrint(String userId1, Boolean showNoBalance) { + getBalanceForUserPrint(userId1, true, usersBalancesMap); + } + + public int getBalanceForUserPrint(String userId1, Boolean showNoBalance, HashMap usersBalancesMaping) + { + AtomicInteger userWithBalanceSum = new AtomicInteger(0); + + getBalanceForUser(userId1).forEach((userIdBal, balanceMap) -> { + userWithBalanceSum.addAndGet(getBalanceForUserPrint(userId1, userIdBal, false, usersBalancesMaping)); + }); + + if (userWithBalanceSum.get() == 0 && showNoBalance) { + System.out.println("No Balance"); + } + + return userWithBalanceSum.get(); + } + + //Set of print functions for Dual user input + // By default, it shows the No Balance Msg + public void getBalanceForUserPrint(String userId1, String userId2) { + getBalanceForUserPrint(userId1, userId2, true); + } + + public void getBalanceForUserPrint(String userId1, String userId2, Boolean showNoBalance) { + getBalanceForUserPrint(userId1, userId2, showNoBalance, usersBalancesMap); + } + + public int getBalanceForUserPrint(String userId1, String userId2, Boolean showNoBalance, HashMap usersBalancesMaping) { + Float balance = getBalanceForUser(userId1, userId2, usersBalancesMaping); + + if (balance > 0) { + System.out.println(userId2+ " Owes " + userId1 + " an amount of "+ currencies.getCurrencySymbol()+df.format(balance)); + return 1; + } else if (showNoBalance) { + System.out.println("No Balance"); + } + return 0; + } + + public void printGroupBalances() { + System.out.println("\n -- Group balances Summary -- "); + AtomicInteger userWithBalanceSum = new AtomicInteger(0); + + usersBalancesMap.forEach( (userId, userBalancesMap) -> { + userWithBalanceSum.addAndGet(getBalanceForUserPrint(userId, false, usersBalancesMap)); + } ); + + if (userWithBalanceSum.get() == 0) { + System.out.println("No Balance"); + } + } + + public void printSimpliedBalances() { + System.out.println("\n -- Simplified balances Summary -- "); + + AtomicInteger userWithBalanceSum = new AtomicInteger(0); + + userBalancesSimplifiedMap.forEach( (userId, userBalancesMap) -> { + userWithBalanceSum.addAndGet(getBalanceForUserPrint(userId, false, userBalancesSimplifiedMap)); + } ); + + if (userWithBalanceSum.get() == 0) { + System.out.println("No Balance"); + } + } + + public void processSimplifiedBalances(GroupUsers users) { + Comparator byBalance = (p1, p2) -> Float.compare(p2.getAmt(), p1.getAmt()); + PriorityQueue owedSet = new PriorityQueue<>(byBalance); + PriorityQueue owesSet = new PriorityQueue<>(byBalance); + initlizeUsersBalancesMap(users, this.userBalancesSimplifiedMap); + updateOwesAndOwedSet(owedSet, owesSet); + calculateAndUpdateSimplifiedBalances(owedSet, owesSet); + + } + + private void calculateAndUpdateSimplifiedBalances(PriorityQueue owedSet, PriorityQueue owesSet) + { + while (!(owedSet.isEmpty() || owesSet.isEmpty())) { + StringFloat temp1 = owedSet.poll(); + StringFloat temp2 = owesSet.poll(); + + /*Diff is negative which means that owedSet user will be cleared of balance and gets deleted and diff amt will be left in owes Set + Diff is Positive which means that owesSet user will be cleared of balance and gets deleted and diff amt will be left in owed set*/ + + Float balanceAmt = temp1.getAmt() - temp2.getAmt(); + Float paymentAmt = balanceAmt<0? temp1.getAmt():temp2.getAmt(); + + if (balanceAmt < 0) { + owesSet.add(new StringFloat(temp2.getUserId(), Math.abs(balanceAmt))); + } else if (balanceAmt > 0) { + owedSet.add(new StringFloat(temp1.getUserId(), balanceAmt)); + } + userBalancesSimplifiedMap.get(temp1.getUserId()).put(temp2.getUserId(), paymentAmt); + } + } + + private void updateOwesAndOwedSet(PriorityQueue owedSet, PriorityQueue owesSet) { + usersBalancesMap.forEach( (userId, userBalances) -> { + float[] totalBalance = {0f}; + userBalances.forEach( (_, balance) -> { + totalBalance[0] = totalBalance[0] + balance; + }); + if (totalBalance[0] < 0f) { + owesSet.add(new StringFloat(userId, Math.abs(totalBalance[0]))); + } else { + owedSet.add(new StringFloat(userId, totalBalance[0])); + } + }); + } + + public void updateBalances(String transactionUserId, StringFloatMap transactionDetails, Float totalTransactionVal, Group group) + { + totalGroupSpending = totalGroupSpending + totalTransactionVal; + updateTransactionUserBalances(transactionUserId, transactionDetails, totalTransactionVal, group); + } + + public void updateTransactionUserBalances(String transactionUserId, StringFloatMap transactionDetails, Float totalTransactionVal, Group group) { + StringFloatMap transactionUserBalances = usersBalancesMap.get(transactionUserId); + for(Map.Entry transaction : transactionDetails.entrySet()) { + addTransactionSummaryToUser(transactionUserId, transaction.getKey(), transaction.getValue(), totalTransactionVal, group); + if ( !(transactionUserId.equals(transaction.getKey())) ) { + updateTransactionSplitUserBalances(transactionUserId, transaction.getKey(), transaction.getValue()); + Float updatedBalance = transaction.getValue() + transactionUserBalances.get(transaction.getKey()); + transactionUserBalances.put(transaction.getKey(), updatedBalance); + } + } + } + + public void updateTransactionSplitUserBalances(String transactionUserId, String splitUser, Float transAmt) { + StringFloatMap splitUserBalances = usersBalancesMap.get(splitUser); + splitUserBalances.put(transactionUserId, splitUserBalances.get(transactionUserId) - transAmt); + } + + public void addTransactionSummaryToUser(String transactorUser, String transactionUser, Float transactionUserShare, Float totalTransactionVal, Group group) { + TransactionSummary transactionSummary = new TransactionSummary(transactorUser, totalTransactionVal, transactionUserShare); + group.getGroupUsers().getUserByUserId(transactionUser).getTransactions().add(transactionSummary); + } +} diff --git a/SplitWise/src/main/java/org/main/Currencies.java b/SplitWise/src/main/java/org/main/Currencies.java new file mode 100644 index 00000000..87ad2dd7 --- /dev/null +++ b/SplitWise/src/main/java/org/main/Currencies.java @@ -0,0 +1,19 @@ +package org.main; + +import lombok.Getter; + + +@Getter +public enum Currencies { + RUPEE("Rupee", "₹"), + + DOLLAR("Dollar", "$"); + + private String currencyName; + private String currencySymbol; + + Currencies(String currencyName, String currencySymbol) { + this.currencyName = currencyName; + this.currencySymbol = currencySymbol; + } +} diff --git a/SplitWise/src/main/java/org/main/Group.java b/SplitWise/src/main/java/org/main/Group.java new file mode 100644 index 00000000..b3219ef9 --- /dev/null +++ b/SplitWise/src/main/java/org/main/Group.java @@ -0,0 +1,18 @@ +package org.main; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class Group { + private String groupName; + private GroupUsers groupUsers; + private Balances balances; + + public Group(String groupName, GroupUsers groupUsers, Balances balances) { + this.groupName = groupName; + this.groupUsers = groupUsers; + this.balances = balances; + } +} diff --git a/SplitWise/src/main/java/org/main/GroupUsers.java b/SplitWise/src/main/java/org/main/GroupUsers.java new file mode 100644 index 00000000..ade9feab --- /dev/null +++ b/SplitWise/src/main/java/org/main/GroupUsers.java @@ -0,0 +1,35 @@ +package org.main; + +import lombok.Getter; +import lombok.Setter; + +import java.util.ArrayList; +import java.util.*; + +@Getter +@Setter +public class GroupUsers { + private HashMap users; + + public GroupUsers() { + this.users = new HashMap<>(); + } + + public User getUserByUserId(String userId) { + return users.getOrDefault(userId, null); + } + + public void addUserToGroup(User user) { + users.put(user.getUserId(), user); + } + + public void addUsersToGroup(ArrayList userList) { + for (User user : userList) { + users.put(user.generateUserID(), user); + } + } + + public boolean checkIfUserIsPartOfGroup(String transUser) { + return (getUserByUserId(transUser) != null); + } +} diff --git a/SplitWise/src/main/java/org/main/Main.java b/SplitWise/src/main/java/org/main/Main.java new file mode 100644 index 00000000..8391136b --- /dev/null +++ b/SplitWise/src/main/java/org/main/Main.java @@ -0,0 +1,53 @@ +package org.main; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.Scanner; + +public class Main { + public static void main(String[] args) throws IOException { + String line; + String[] input; + String filePath = "C:\\Users\\mahes\\Exercism\\java\\SplitWise\\src\\main\\resources\\transactions.txt"; + Scanner scanner = new Scanner(Path.of(filePath)); + + ArrayList users = new ArrayList<>(); + users.add(new User("M", "1212", "1@")); + users.add(new User("A", "2212", "2@")); + users.add(new User("H", "1254", "3@")); + users.add(new User("E", "5415", "4@")); + GroupUsers groupUsers = new GroupUsers(); + groupUsers.addUsersToGroup(users); + Balances balances = new Balances(Currencies.RUPEE); + balances.initlizeUsersBalancesMap(groupUsers); + Group group = new Group("Trip1", groupUsers, balances); + + while (scanner.hasNextLine()) { + line = scanner.nextLine(); + line = line.strip(); + input = line.split(" "); + ArrayList processLine = new ArrayList<>(List.of(input)); + Transaction transaction = new Transaction(); + + if (processLine.get(0).equals("SHOW")) { + if (input.length != 1) { + group.getBalances().getBalanceForUserPrint(processLine.get(1).strip()); + System.out.println("--- = ---"); + } else { + group.getBalances().printGroupBalances(); + System.out.println("--- = ---"); + } + } else if (processLine.get(0).equals("EXPENSE")) { + processLine.remove(0); + transaction.processTransaction(processLine, group); + group.getGroupUsers().getUserByUserId(processLine.get(0)).printTransactions(); + System.out.println("--- = ---"); + } + } + group.getBalances().printBalancesMap(); + group.getBalances().processSimplifiedBalances(groupUsers); + group.getBalances().printSimpliedBalances(); + } +} \ No newline at end of file diff --git a/SplitWise/src/main/java/org/main/Transaction.java b/SplitWise/src/main/java/org/main/Transaction.java new file mode 100644 index 00000000..106478d8 --- /dev/null +++ b/SplitWise/src/main/java/org/main/Transaction.java @@ -0,0 +1,79 @@ +package org.main; + +import lombok.Getter; +import lombok.Setter; + +import java.util.ArrayList; + +@Getter +@Setter +public class Transaction { + private String transactionUser; + private Float totalTransactionValue; + private StringFloatMap transactionMap; + private TransactionType transactionType; + private static final float EPSILON = 0.000001f; + + public boolean processTransaction(ArrayList transactionDetails, Group group) { + transactionType = getTransType(transactionDetails); + + if (validateTransactionDetails(transactionDetails, group)) { + group.getBalances().updateBalances(transactionUser, transactionMap, totalTransactionValue, group); + return true; + } + return false; + } + + private boolean validateTransactionDetails(ArrayList transactionDetails, Group group) { + if (!basicChecksPassed(transactionDetails, group)) { + return false; + } + if (transactionType != null) { + return transactionType.validateTransactionDetails(transactionDetails, this); + } + return false; + } + + private boolean basicChecksPassed(ArrayList transactionDetails, Group group) { + transactionMap = new StringFloatMap(); + transactionUser = transactionDetails.get(0); + if (!group.getGroupUsers().checkIfUserIsPartOfGroup(transactionUser)) { + return false; + } + totalTransactionValue = Float.parseFloat(transactionDetails.get(1)); + if (totalTransactionValue < EPSILON) { + return false; + } + int numOfUsers = Integer.parseInt(transactionDetails.get(2)); + if (numOfUsers < 0) { + return false; + } + return true; + } + + public boolean checkFloatsAreEqual(Float num1, Float num2) { + return Math.abs(num1 - num2) < EPSILON; + } + + public TransactionType getTransType(ArrayList transactionDetails) { + TransactionType transactionType = null; + for (String input : transactionDetails) { + if (input.equals("EQUAL")) { + transactionDetails.remove("EQUAL"); + transactionType = TransactionType.fromString("EQUAL"); + break; + } + if (input.equals("EXACT")) { + transactionDetails.remove("EXACT"); + transactionType = TransactionType.fromString("EXACT"); + break; + } + if (input.equals("PERCENT")) { + transactionDetails.remove("PERCENT"); + transactionType = TransactionType.fromString("PERCENT"); + break; + } + } + return transactionType; + } +} diff --git a/SplitWise/src/main/java/org/main/TransactionSummary.java b/SplitWise/src/main/java/org/main/TransactionSummary.java new file mode 100644 index 00000000..1c13bd45 --- /dev/null +++ b/SplitWise/src/main/java/org/main/TransactionSummary.java @@ -0,0 +1,17 @@ +package org.main; + +public class TransactionSummary { + private String transactorName; + private Float transactionTotalVal; + private Float userShare; + + public TransactionSummary(String transactorName, Float transactionTotalVal, Float userShare) { + this.transactorName = transactorName; + this.transactionTotalVal = transactionTotalVal; + this.userShare = userShare; + } + + public void printTransactionSummary() { + System.out.println("User " + transactorName + " added Expense of total Val "+ transactionTotalVal+" your share is "+ userShare); + } +} diff --git a/SplitWise/src/main/java/org/main/TransactionType.java b/SplitWise/src/main/java/org/main/TransactionType.java new file mode 100644 index 00000000..bfa7a3e8 --- /dev/null +++ b/SplitWise/src/main/java/org/main/TransactionType.java @@ -0,0 +1,65 @@ +package org.main; + +import lombok.Getter; + +import java.util.ArrayList; + +@Getter +public enum TransactionType { + EXACT("EXACT") { + @Override + public boolean validateTransactionDetails(ArrayList transDetails, Transaction transaction) { + int numOfUsers = Integer.parseInt(transDetails.get(2)); + for (int i = 1; i <= numOfUsers; i++) { + Float transVal = Float.parseFloat(transDetails.get(2 + i + numOfUsers)); + transaction.getTransactionMap().put(transDetails.get(2 + i), transVal); + } + return checkIfTransactionsMatchesTotal(transaction); + } + }, + EQUAL("EQUAL") { + @Override + public boolean validateTransactionDetails(ArrayList transDetails, Transaction transaction) { + int numOfUsers = Integer.parseInt(transDetails.get(2)); + for (int i = 1; i <= numOfUsers; i++) { + transaction.getTransactionMap().put(transDetails.get(2+i), transaction.getTotalTransactionValue() / numOfUsers); + } + return true; + } + }, + PERCENT("PERCENT") { + @Override + public boolean validateTransactionDetails(ArrayList transDetails, Transaction transaction) { + float totalTransPerc = 0f; + int numOfUsers = Integer.parseInt(transDetails.get(2)); + for (int i = 1; i <= numOfUsers; i++) { + Float transPer = Float.parseFloat(transDetails.get(2+i+numOfUsers)); + totalTransPerc += transPer; + transaction.getTransactionMap().put(transDetails.get(2+i), transaction.getTotalTransactionValue() * (transPer / 100)); + } + return transaction.checkFloatsAreEqual(totalTransPerc, 100f); + } + }; + + private final String transactionName; + + TransactionType(String transactionName) { + this.transactionName = transactionName; + } + + public abstract boolean validateTransactionDetails(ArrayList trans, Transaction transaction); + + protected boolean checkIfTransactionsMatchesTotal(Transaction transaction) { + float sum = transaction.getTransactionMap().values().stream().reduce(0f, Float::sum); + return transaction.checkFloatsAreEqual(sum, transaction.getTotalTransactionValue()); + } + + public static TransactionType fromString(String name) { + for (TransactionType transactionType : TransactionType.values()) { + if (transactionType.transactionName.equalsIgnoreCase(name)) { + return transactionType; + } + } + throw new IllegalArgumentException("No constant named "+name); + } +} \ No newline at end of file diff --git a/SplitWise/src/main/java/org/main/User.java b/SplitWise/src/main/java/org/main/User.java new file mode 100644 index 00000000..d984901b --- /dev/null +++ b/SplitWise/src/main/java/org/main/User.java @@ -0,0 +1,42 @@ +package org.main; + +import lombok.AccessLevel; +import lombok.Getter; +import lombok.Setter; + +import java.util.ArrayList; +import java.util.Random; + +@Getter +@Setter +public class User { + private String name; + @Setter(AccessLevel.NONE) + private String userId; + private String phoneNum; + private String emailId; + private ArrayList transactions; + + public User(String name, String phoneNum, String emailId) { + this.name = name; + this.phoneNum = phoneNum; + this.emailId = emailId; + this.userId = generateUserID(); + transactions = new ArrayList<>(); + } + + public String generateUserID() { + return name+Integer.valueOf(phoneNum.trim()); + } + + private long getRandom() { + Random r = new Random(); + return r.nextLong(100-000-000-00) + Integer.valueOf(phoneNum.trim()); + } + + public void printTransactions() { + for (TransactionSummary transactionSummary : transactions) { + transactionSummary.printTransactionSummary(); + } + } +} diff --git a/SplitWise/src/main/resources/transactions.txt b/SplitWise/src/main/resources/transactions.txt new file mode 100644 index 00000000..e37bea65 --- /dev/null +++ b/SplitWise/src/main/resources/transactions.txt @@ -0,0 +1,10 @@ +SHOW +SHOW M1212 +EXPENSE M1212 1000 4 M1212 A2212 H1254 E5415 EQUAL +SHOW E5415 +SHOW M1212 +EXPENSE M1212 1250 3 A2212 H1254 E5415 EXACT 200 880 170 +SHOW +EXPENSE E5415 1200 4 M1212 A2212 H1254 E5415 PERCENT 40 20 20 20 +SHOW M1212 +SHOW \ No newline at end of file diff --git a/SplitWise/src/test/java/org/main/BalancesTest.java b/SplitWise/src/test/java/org/main/BalancesTest.java new file mode 100644 index 00000000..dee70128 --- /dev/null +++ b/SplitWise/src/test/java/org/main/BalancesTest.java @@ -0,0 +1,35 @@ +package org.main; + +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; + +class BalancesTest { + + @Test + void initlizeUsersBalancesMap() { + ArrayList users = new ArrayList<>(); + users.add(new User("M", "1212", "1@")); + users.add(new User("A", "2212", "2@")); + users.add(new User("H", "1254", "3@")); + users.add(new User("E", "5415", "4@")); + GroupUsers groupUsers = new GroupUsers(); + groupUsers.addUsersToGroup(users); + Balances balances = new Balances(Currencies.RUPEE); + balances.initlizeUsersBalancesMap(groupUsers); + Group group = new Group("Test", groupUsers, balances); + + StringFloatMap trans1 = new StringFloatMap(); + trans1.put("A2212", 200f); + trans1.put("H1254", 200f); + trans1.put("E5415", 200f); + balances.printGroupBalances(); +// balances.updateBalances("M1212", trans1, 1000f); + balances.printBalancesMap(); + System.out.println("A2212 and M1212"); + balances.getBalanceForUserPrint("M1212", "A2212"); + System.out.println("M1212"); + balances.getBalanceForUserPrint("M1212"); + balances.printGroupBalances(); + } +} \ No newline at end of file diff --git a/SplitWise/src/test/java/org/main/TransactionTypeTest.java b/SplitWise/src/test/java/org/main/TransactionTypeTest.java new file mode 100644 index 00000000..1abee13b --- /dev/null +++ b/SplitWise/src/test/java/org/main/TransactionTypeTest.java @@ -0,0 +1,41 @@ +package org.main; + +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; + +class TransactionTypeTest { + + @Test + void processTransaction() { + ArrayList users = new ArrayList<>(); + users.add(new User("M", "1212", "1@")); + users.add(new User("A", "2212", "2@")); + users.add(new User("H", "1254", "3@")); + users.add(new User("E", "5415", "4@")); + GroupUsers groupUsers = new GroupUsers(); + groupUsers.addUsersToGroup(users); + Balances balances = new Balances(Currencies.RUPEE); + balances.initlizeUsersBalancesMap(groupUsers); + Group group = new Group("Test", groupUsers, balances); + + StringFloatMap trans1 = new StringFloatMap(); + trans1.put("M1212", 200f); + trans1.put("A2212", 20f); + trans1.put("H1254", 200f); + trans1.put("E5415", 200f); + +// System.out.println(TransactionType.EXACT.processTransaction("M1212 1000 4 M1212 A2212 H1254 E5415 250 350 250 150", group)); +// group.getBalances().printGroupBalances(); +// System.out.println(TransactionType.EQUAL.processTransaction("M1212 1000 3 M1212 A2212 H1254", group)); +// group.getBalances().printGroupBalances(); +// System.out.println(TransactionType.PERCENT.processTransaction("M1212 1000 3 M1212 A2212 H1254 40 20 40", group)); +// group.getBalances().printGroupBalances(); + System.out.println("-- -- - -"); + group.getBalances().getBalanceForUserPrint("M1212"); + System.out.println("-- -- - -"); + group.getBalances().getBalanceForUserPrint("A2212", "M1212"); + System.out.println("-- -- - -"); + group.getBalances().getBalanceForUserPrint("M1212", "A2212"); + } +} \ No newline at end of file diff --git a/SplitWise/src/test/java/org/main/UserTest.java b/SplitWise/src/test/java/org/main/UserTest.java new file mode 100644 index 00000000..ec14a933 --- /dev/null +++ b/SplitWise/src/test/java/org/main/UserTest.java @@ -0,0 +1,14 @@ +package org.main; + +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +class UserTest { + + @Test + void generateUserID() { + User user = spy(new User("Mahesh", "334156413", "mahesh@bidgely.com")); + System.out.println(user.generateUserID()); + } +} \ No newline at end of file diff --git a/SplitWise/target/classes/transactions.txt b/SplitWise/target/classes/transactions.txt new file mode 100644 index 00000000..e37bea65 --- /dev/null +++ b/SplitWise/target/classes/transactions.txt @@ -0,0 +1,10 @@ +SHOW +SHOW M1212 +EXPENSE M1212 1000 4 M1212 A2212 H1254 E5415 EQUAL +SHOW E5415 +SHOW M1212 +EXPENSE M1212 1250 3 A2212 H1254 E5415 EXACT 200 880 170 +SHOW +EXPENSE E5415 1200 4 M1212 A2212 H1254 E5415 PERCENT 40 20 20 20 +SHOW M1212 +SHOW \ No newline at end of file