From 1bf9dff43f9578247b989d4ae97f571384a1556e Mon Sep 17 00:00:00 2001 From: Martin Stenhagen Date: Wed, 14 Jan 2026 18:31:47 +0100 Subject: [PATCH 1/2] =?UTF-8?q?addScore=20och=20getScore-metoder=20i=20Tra?= =?UTF-8?q?veler=20f=C3=B6r=20att=20logiken=20ska=20g=C3=A5=20genom=20trav?= =?UTF-8?q?eler.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/org/example/Traveler.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/main/java/org/example/Traveler.java b/src/main/java/org/example/Traveler.java index 8788ffd8..2bcc61c2 100644 --- a/src/main/java/org/example/Traveler.java +++ b/src/main/java/org/example/Traveler.java @@ -92,6 +92,16 @@ public void setPosition() { } } + public void addScore(int delta) { + if (delta < 0) throw new IllegalArgumentException("delta must be >= 0"); + this.score += delta; + } + + public int getScore() { + return score; + } + + /** * (behåll) används för "fri" gui-rörelse när destination kommer från klick på karta * OBS: den här räknar manhattan via destinationPosX/Y From acfae84b1ee9102a4c08285ea3f41bbf957c5098 Mon Sep 17 00:00:00 2001 From: Martin Stenhagen Date: Wed, 14 Jan 2026 19:12:59 +0100 Subject: [PATCH 2/2] =?UTF-8?q?Tidigare=20kod=20fr=C3=A5n=20Player=20och?= =?UTF-8?q?=20playerMovement=20=C3=A4r=20flyttat=20till=20Traveler,=20Jour?= =?UTF-8?q?neyService=20samt=20anpassningar=20i=20TravelGameController.=20?= =?UTF-8?q?App.javas=20mainmetod=20=C3=A4r=20rensad=20p=C3=A5=20gammal=20k?= =?UTF-8?q?od=20fr=C3=A5n=20tidigare=20versioner?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/org/example/App.java | 235 --------------- .../org/example/TravelGameController.java | 79 +++-- src/main/java/org/example/Traveler.java | 196 ++++--------- src/main/java/org/example/player.java | 144 --------- src/main/java/org/example/playerMovement.java | 276 ------------------ .../org/example/service/JourneyService.java | 7 +- 6 files changed, 107 insertions(+), 830 deletions(-) delete mode 100644 src/main/java/org/example/player.java delete mode 100644 src/main/java/org/example/playerMovement.java diff --git a/src/main/java/org/example/App.java b/src/main/java/org/example/App.java index 68356857..834b2648 100644 --- a/src/main/java/org/example/App.java +++ b/src/main/java/org/example/App.java @@ -8,242 +8,7 @@ public class App { public static void main(String[] args) throws IOException { - EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpa-hibernate-mysql"); - EntityManager em = emf.createEntityManager(); - new BootstrapService(em).initialize(); - EntityTransaction tx = em.getTransaction(); - boolean wonGame = false; - Traveler p1; - Traveler p2; - Traveler p3; - Traveler p4; - try { - tx.begin(); - List transportMethods = em.createQuery("select t from Transport t", Transport.class).getResultList(); - int pAmount = 0; - String input = IO.readln("Welcome, how many players??? 2 - 4 "); - try { - pAmount = Integer.parseInt(input); - } catch (NumberFormatException e){ - System.out.println("Not a number"); - } - - switch (pAmount){ - case 2 ->{ - String p1Name = IO.readln("Input name for player 1: "); - Location newDestP1 = randomLocation(em); - p1 = new Traveler(p1Name, randomLocation(em)); - p1.setDestinationPos(newDestP1.getX(), newDestP1.getY()); - p1.startJourney(newDestP1); - String p2Name = IO.readln("Input name for player 2: "); - Location newDestP2 = randomLocation(em); - p2 = new Traveler(p2Name, randomLocation(em)); - p2.setDestinationPos(newDestP2.getX(), newDestP2.getY()); - p2.startJourney(newDestP2); - em.persist(p1); - em.persist(p2); - while(!wonGame){ - p1.playerTurn(transportMethods); - p2.playerTurn(transportMethods); - if (p1.checkIfPlayerIsAtDestination()){ - Location newDest = randomLocation(em); - p1.setDestinationPos(newDest.getX(), newDest.getY()); - }else if(p2.checkIfPlayerIsAtDestination()){ - Location newDest = randomLocation(em); - p2.setDestinationPos(newDest.getX(), newDest.getY()); - } - if(p1.checkScore()){ - System.out.println(p1.getPlayerName() + " wins"); - wonGame = true; - } else if(p2.checkScore()){ - System.out.println(p2.getPlayerName() + " wins"); - wonGame = true; - } - p1.updateJourney(); - p2.updateJourney(); - em.persist(p1); - em.persist(p2); - } - - }case 3 ->{ - String p1Name = IO.readln("Input name for player 1: "); - Location newDestP1 = randomLocation(em); - p1 = new Traveler(p1Name, randomLocation(em)); - p1.setDestinationPos(newDestP1.getX(), newDestP1.getY()); - p1.startJourney(newDestP1); - String p2Name = IO.readln("Input name for player 2: "); - Location newDestP2 = randomLocation(em); - p2 = new Traveler(p2Name, randomLocation(em)); - p2.setDestinationPos(newDestP2.getX(), newDestP2.getY()); - p2.startJourney(newDestP2); - String p3Name = IO.readln("Input name for player 2: "); - Location newDestP3 = randomLocation(em); - p3 = new Traveler(p3Name, randomLocation(em)); - p3.setDestinationPos(newDestP3.getX(), newDestP3.getY()); - p3.startJourney(newDestP3); - em.persist(p1); - em.persist(p2); - em.persist(p3); - - while(!wonGame){ - p1.playerTurn(transportMethods); - p2.playerTurn(transportMethods); - p3.playerTurn(transportMethods); - if (p1.checkIfPlayerIsAtDestination()){ - Location newDest = randomLocation(em); - p1.setDestinationPos(newDest.getX(), newDest.getY()); - }else if(p2.checkIfPlayerIsAtDestination()){ - Location newDest = randomLocation(em); - p2.setDestinationPos(newDest.getX(), newDest.getY()); - }else if(p3.checkIfPlayerIsAtDestination()){ - Location newDest = randomLocation(em); - p3.setDestinationPos(newDest.getX(), newDest.getY()); - } - if(p1.checkScore()){ - System.out.println(p1.getPlayerName() + " wins"); - wonGame = true; - } else if(p2.checkScore()){ - System.out.println(p2.getPlayerName() + " wins"); - wonGame = true; - } else if(p3.checkScore()){ - System.out.println(p3.getPlayerName() + " wins"); - wonGame = true; - } - p1.updateJourney(); - p2.updateJourney(); - p3.updateJourney(); - em.persist(p1); - em.persist(p2); - em.persist(p3); - } - - }case 4 ->{ - String p1Name = IO.readln("Input name for player 1: "); - Location newDestP1 = randomLocation(em); - p1 = new Traveler(p1Name, randomLocation(em)); - p1.setDestinationPos(newDestP1.getX(), newDestP1.getY()); - p1.startJourney(newDestP1); - String p2Name = IO.readln("Input name for player 2: "); - Location newDestP2 = randomLocation(em); - p2 = new Traveler(p2Name, randomLocation(em)); - p2.setDestinationPos(newDestP2.getX(), newDestP2.getY()); - p2.startJourney(newDestP2); - String p3Name = IO.readln("Input name for player 2: "); - Location newDestP3 = randomLocation(em); - p3 = new Traveler(p3Name, randomLocation(em)); - p3.setDestinationPos(newDestP3.getX(), newDestP3.getY()); - p3.startJourney(newDestP3); - String p4Name = IO.readln("Input name for player 4: "); - Location newDestP4 = randomLocation(em); - p4 = new Traveler(p4Name, randomLocation(em)); - p4.setDestinationPos(newDestP4.getX(), newDestP4.getY()); - p4.startJourney(newDestP4); - em.persist(p1); - em.persist(p2); - em.persist(p3); - em.persist(p4); - while(!wonGame){ - p1.playerTurn(transportMethods); - p2.playerTurn(transportMethods); - p3.playerTurn(transportMethods); - p4.playerTurn(transportMethods); - if (p1.checkIfPlayerIsAtDestination()){ - Location newDest = randomLocation(em); - p1.setDestinationPos(newDest.getX(), newDest.getY()); - }else if(p2.checkIfPlayerIsAtDestination()){ - Location newDest = randomLocation(em); - p2.setDestinationPos(newDest.getX(), newDest.getY()); - }else if(p3.checkIfPlayerIsAtDestination()){ - Location newDest = randomLocation(em); - p3.setDestinationPos(newDest.getX(), newDest.getY()); - }else if(p4.checkIfPlayerIsAtDestination()){ - Location newDest = randomLocation(em); - p4.setDestinationPos(newDest.getX(), newDest.getY()); - } - if(p1.checkScore()){ - System.out.println(p1.getPlayerName() + " wins"); - wonGame = true; - } else if(p2.checkScore()){ - System.out.println(p2.getPlayerName() + " wins"); - wonGame = true; - } else if(p3.checkScore()){ - System.out.println(p3.getPlayerName() + " wins"); - wonGame = true; - }else if(p4.checkScore()){ - System.out.println(p4.getPlayerName() + " wins"); - wonGame = true; - } - p1.updateJourney(); - p2.updateJourney(); - p3.updateJourney(); - p4.updateJourney(); - em.persist(p1); - em.persist(p2); - em.persist(p3); - em.persist(p4); - } - } - } - - tx.commit(); - - } catch (Exception e) { - if (tx.isActive()) tx.rollback(); - throw e; - } finally { - em.close(); - } - } - - //Randomize through all points for continent, country and locations to get a random location. If the country has no locations, loop again until it finds a location. - static public Location randomLocation(EntityManager em){ - - Long contCount = em.createQuery("Select count(c) from Continent c", Long.class).getSingleResult(); - - Continent randCont = em.createQuery("select c from Continent c", Continent.class).setFirstResult(randomIndex(contCount)).setMaxResults(1).getSingleResult(); - - while(randCont.getId() == 2){ - randCont = em.createQuery("select c from Continent c", Continent.class).setFirstResult(randomIndex(contCount)).setMaxResults(1).getSingleResult(); - } - - Long countryCount = em.createQuery("Select count(c) from Country c where c.continent = :continent", Long.class) - .setParameter("continent", randCont) - .getSingleResult(); - - Country randCountry = em.createQuery("select c from Country c where continent = :continent", Country.class) - .setParameter("continent", randCont) - .setFirstResult(randomIndex(countryCount)) - .setMaxResults(1).getSingleResult(); - - Long locCount = em.createQuery("select count(o) from Location o where o.country = :country", Long.class) - .setParameter("country", randCountry) - .getSingleResult(); - - while(locCount == 0){ - randCountry = em.createQuery("select c from Country c where continent = :continent", Country.class) - .setParameter("continent", randCont) - .setFirstResult(randomIndex(countryCount)) - .setMaxResults(1).getSingleResult(); - - locCount = em.createQuery("select count(o) from Location o where o.country = :country", Long.class) - .setParameter("country", randCountry) - .getSingleResult(); - } - - Location randLocation = em.createQuery("select l from Location l where l.country = :country", Location.class) - .setParameter("country", randCountry).setFirstResult(randomIndex(locCount)).setMaxResults(1).getSingleResult(); - - System.out.println(randLocation.getName() + " " + randLocation.getX() + " " + randLocation.getY()); - - return randLocation; - } - - static public int randomIndex(long indexes){ - if (indexes <= 0) { - throw new IllegalArgumentException("indexes must be > 0"); - } - return (int) (Math.random() * indexes); } } diff --git a/src/main/java/org/example/TravelGameController.java b/src/main/java/org/example/TravelGameController.java index ce626dd8..f9f52270 100644 --- a/src/main/java/org/example/TravelGameController.java +++ b/src/main/java/org/example/TravelGameController.java @@ -51,6 +51,8 @@ public class TravelGameController { private MapVisualizer visualizer; private JourneyService journeyService; private PlayerEventService eventService; + private static final int WIN_SCORE = 5; + private PossibleMoves selectedMove = null; private boolean awaitingMoveChoice = false; @@ -120,9 +122,6 @@ public void setupGame(String playerName) { Traveler p1 = new Traveler(playerName, stockholm); Traveler p2 = new Traveler("Player 2", berlin); - p1.setDestinationPos(paris.getX(), paris.getY()); - p2.setDestinationPos(stockholm.getX(), stockholm.getY()); - em.persist(p1); em.persist(p2); @@ -370,9 +369,13 @@ private void updateHud() { int lastTurn = lastTurnByTravelerId.getOrDefault(current.getId(), 0); currentTurnLabel.setText(String.valueOf(lastTurn + 1)); - currentPointLabel.setText(String.valueOf(current.getPlayerScore())); + currentPointLabel.setText(String.valueOf(current.getScore())); - currentLocationLabel.setText("[" + clampToGrid(current.getPlayerPosX()) + "," + clampToGrid(current.getPlayerPosY()) + "]"); + + Location loc = current.getCurrentLocation(); + currentLocationLabel.setText(loc != null + ? "[" + clampToGrid(loc.getX()) + "," + clampToGrid(loc.getY()) + "]" + : "-"); if (current.isTravelling() && current.getTargetLocation() != null) { destinationLabel.setText("[" + current.getTargetLocation().getX() + "," + current.getTargetLocation().getY() + "]"); @@ -401,8 +404,8 @@ private void updateGraphics() { } private double[] computePlayerGridPos(Traveler t) { - double baseX = clampToGrid(t.getPlayerPosX()); - double baseY = clampToGrid(t.getPlayerPosY()); + double baseX = clampToGrid(t.getPosX()); + double baseY = clampToGrid(t.getPosY()); if (!t.isTravelling() || t.getId() == null || em == null) { return new double[]{baseX, baseY}; @@ -507,22 +510,6 @@ private int clampToGrid(int v) { return Math.max(0, Math.min(GRID_SIZE - 1, v)); } - public void startMockJourney() { - logList.getItems().add("📜 Demo path!"); - if (players.isEmpty()) return; - - Traveler current = players.get(currentPlayerIndex); - int px = clampToGrid(current.getPlayerPosX()); - int py = clampToGrid(current.getPlayerPosY()); - - List journeyPath = new ArrayList<>(); - journeyPath.add(new int[]{px, py}); - journeyPath.add(new int[]{10, 15}); - journeyPath.add(new int[]{25, 20}); - journeyPath.add(new int[]{40, 45}); - visualizer.animateJourney(journeyPath, drawingPane.getWidth(), drawingPane.getHeight()); - } - private void doMove(Long travelerId, PossibleMoves chosen) { if (wonGame) return; @@ -553,7 +540,6 @@ private void doMove(Long travelerId, PossibleMoves chosen) { + " kom fram till " + targetName + " (rolled=" + journey.getDistanceMoved() + ")" ); - managed.increaseScore(); } tx.commit(); @@ -597,11 +583,21 @@ private void doMove(Long travelerId, PossibleMoves chosen) { } private void doesPlayerWin() { - for (Traveler player : players) { - if (player.checkScore()) { + if (players.isEmpty() || em == null) return; + + for (Traveler ref : players) { + if (ref.getId() == null) continue; + + Traveler t = em.find(Traveler.class, ref.getId()); // läs färskt från db + if (t != null && t.getScore() >= WIN_SCORE) { wonGame = true; - System.out.println(player.getPlayerName() + " Wins the game. Congratulations"); - winConLabel.setContentText(player.getPlayerName() + " Wins the game. Congratulations"); + + String msg = t.getPlayerName() + " wins the game. congratulations!"; + System.out.println(msg); + winConLabel.setContentText(msg); + logList.getItems().add("🏆 " + msg); + + return; } } } @@ -680,8 +676,14 @@ private void doContinueJourney(Long travelerId) { EntityTransaction tx = em.getTransaction(); tx.begin(); + try { Traveler managed = em.find(Traveler.class, travelerId); + if (managed == null) { + logList.getItems().add("⚠️ kunde inte hitta spelare i db"); + if (tx.isActive()) tx.rollback(); + return; + } Location targetBefore = managed.getTargetLocation(); String targetName = (targetBefore != null) ? targetBefore.getName() : "?"; @@ -698,11 +700,11 @@ private void doContinueJourney(Long travelerId) { ); } else { logList.getItems().add("✅ " + safeName(managed) + " kom fram till " + targetName + "!"); - managed.increaseScore(); doesPlayerWin(); } tx.commit(); + players.set(currentPlayerIndex, managed); if (!managed.isTravelling() && !wonGame) { @@ -710,14 +712,31 @@ private void doContinueJourney(Long travelerId) { } syncHudAndMap(); + + } catch (IllegalStateException e) { + if (tx.isActive()) tx.rollback(); + + String msg = e.getMessage() != null ? e.getMessage() : "okänt fel"; + if (msg.toLowerCase().contains("cannot afford")) { + eliminatePlayer(em.find(Traveler.class, travelerId), "har inte råd att fortsätta resan"); + return; + } + + logList.getItems().add("⚠️ kunde inte fortsätta resa: " + msg); + syncHudAndMap(); + } catch (RuntimeException e) { if (tx.isActive()) tx.rollback(); - throw e; + logList.getItems().add("❌ fel vid continue: " + (e.getMessage() != null ? e.getMessage() : e.getClass().getSimpleName())); + e.printStackTrace(); + syncHudAndMap(); + } finally { rollButton.setDisable(false); } } + private String safeName(Traveler t) { if (t == null) return "?"; if (t.getPlayerName() != null) return t.getPlayerName(); diff --git a/src/main/java/org/example/Traveler.java b/src/main/java/org/example/Traveler.java index 2bcc61c2..ead6c67f 100644 --- a/src/main/java/org/example/Traveler.java +++ b/src/main/java/org/example/Traveler.java @@ -5,7 +5,10 @@ import java.math.BigDecimal; @Entity -public class Traveler extends playerMovement { +@Table(name = "Traveler", indexes = { + @Index(name = "idx_traveler_score", columnList = "score") +}) +public class Traveler { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @@ -28,24 +31,30 @@ public class Traveler extends playerMovement { @Column(name = "turn_count", nullable = false) private int turnCount = 0; - @Column(nullable = false) - private BigDecimal money = BigDecimal.valueOf(credits); + @Column(nullable = false, precision = 12, scale = 2) + private BigDecimal money = BigDecimal.valueOf(10000); - @Column + @Column(nullable = false) private int score = 0; + // ✅ gui-position i db (så du slipper legacy-klasser) + @Column(name = "pos_x", nullable = false) + private int posX; + + @Column(name = "pos_y", nullable = false) + private int posY; + protected Traveler() {} public Traveler(String name, Location startLocation) { - this.playerName = name; // ✅ jpa-kolumn + setPlayerName(name); this.currentLocation = startLocation; - - setPosition(); + syncPositionFromCurrentLocation(); } - public String getPlayerName() { - return playerName; - } + // getters/setters + public Long getId() { return id; } + public String getPlayerName() { return playerName; } public void setPlayerName(String playerName) { if (playerName == null || playerName.isBlank()) { @@ -54,95 +63,56 @@ public void setPlayerName(String playerName) { this.playerName = playerName; } - public Long getId() { - return id; - } + public Location getCurrentLocation() { return currentLocation; } + public Location getTargetLocation() { return targetLocation; } + public int getRemainingDistance() { return remainingDistance; } + public int getTurnCount() { return turnCount; } + public BigDecimal getMoney() { return money; } + public int getScore() { return score; } - public Location getCurrentLocation() { - return currentLocation; - } + public int getPosX() { return posX; } + public int getPosY() { return posY; } - public Location getTargetLocation() { - return targetLocation; - } + public boolean isTravelling() { return targetLocation != null; } - public int getTurnCount() { - return turnCount; + public void addScore(int delta) { + if (delta < 0) throw new IllegalArgumentException("delta must be >= 0"); + this.score += delta; } - public BigDecimal getMoney() { - return money; + public void pay(BigDecimal amount) { + if (amount == null) throw new IllegalArgumentException("amount cannot be null"); + if (amount.signum() < 0) throw new IllegalArgumentException("amount must be >= 0"); + if (money.compareTo(amount) < 0) throw new IllegalStateException("not enough money"); + money = money.subtract(amount); } - public int getRemainingDistance() { - return remainingDistance; + public void addMoney(BigDecimal amount) { + if (amount == null) throw new IllegalArgumentException("amount cannot be null"); + if (amount.signum() < 0) throw new IllegalArgumentException("amount must be positive"); + money = money.add(amount); } - public boolean isTravelling() { - return targetLocation != null; + public void deductMoney(BigDecimal amount) { + if (amount.signum() < 0) throw new IllegalArgumentException("amount must be positive"); + BigDecimal next = this.money.subtract(amount); + this.money = next.signum() < 0 ? BigDecimal.ZERO : next; } - /** - * håller playerPosX/Y i sync med currentLocation (för gui) - */ - public void setPosition() { + public void syncPositionFromCurrentLocation() { if (currentLocation != null) { - setPlayerPosX(currentLocation.getX()); - setPlayerPosY(currentLocation.getY()); + this.posX = currentLocation.getX(); + this.posY = currentLocation.getY(); } } - public void addScore(int delta) { - if (delta < 0) throw new IllegalArgumentException("delta must be >= 0"); - this.score += delta; - } - - public int getScore() { - return score; - } - - - /** - * (behåll) används för "fri" gui-rörelse när destination kommer från klick på karta - * OBS: den här räknar manhattan via destinationPosX/Y - */ - public void startJourney(Location target) { - this.targetLocation = target; - - // ✅ viktigt: synca destinationPos så att calculateDistance funkar - setDestinationPos(target.getX(), target.getY()); - - calculateDistanceFromDestinationPos(); - } - - /** - * ✅ NY: används av JourneyService när du reser via LocationLink.distance - * då ska remainingDistance baseras på routeDistance (inte koordinater) - */ public void startJourney(Location target, int routeDistance) { if (routeDistance < 0) throw new IllegalArgumentException("routeDistance must be >= 0"); - this.targetLocation = target; this.remainingDistance = routeDistance; - - // ändå bra för gui att visa destination - setDestinationPos(target.getX(), target.getY()); - } - - /** - * gamla logiken, men tydligare namn - */ - private void calculateDistanceFromDestinationPos() { - // använder destinationPos som sätts via setDestinationPos(...) - int xPos = Math.abs(currentLocation.getX() - getDestinationPosX()); - int yPos = Math.abs(currentLocation.getY() - getDestinationPosY()); - this.remainingDistance = xPos + yPos; } - /** - * när vi avancerar på en länk-baserad resa använder vi remainingDistance direkt - */ - public void advance(int distanceThisTurn) { + public boolean advance(int distanceThisTurn) { remainingDistance -= distanceThisTurn; turnCount++; @@ -151,77 +121,15 @@ public void advance(int distanceThisTurn) { targetLocation = null; remainingDistance = 0; - // ✅ synca gui-position när du "kommer fram" - setPosition(); - } - } - - public void pay(BigDecimal amount) { - if (amount == null) throw new IllegalArgumentException("amount cannot be null"); - if (amount.signum() < 0) throw new IllegalArgumentException("amount must be >= 0"); - - if (money.compareTo(amount) < 0) { - throw new IllegalStateException("not enough money"); - } - - money = money.subtract(amount); - - // ✅ håll gamla credits i sync så gui/cli fortfarande visar rätt - this.credits = money.intValue(); - } - - public void addMoney(BigDecimal amount) { - if (amount == null) throw new IllegalArgumentException("amount cannot be null"); - if (amount.signum() < 0) { - throw new IllegalArgumentException("amount must be positive"); - } - - money = money.add(amount); - - // ✅ sync credits - this.credits = money.intValue(); - } - - /** - * om du fortfarande använder gamla "updateJourney()" i någon kod: - * den bör i princip inte användas i nya link-baserade flödet. - * men om du vill behålla den utan att den sabbar: - */ - public void updateJourney() { - turnCount = getTurns(); - setPosition(); - - // ⚠️ bara meningsfullt om destinationPos är satt (fri gui-rörelse) - if (isTravelling()) { - calculateDistanceFromDestinationPos(); - } - } - public void subtractMoneyClamped(BigDecimal amount) { - if (amount.signum() < 0) { - throw new IllegalArgumentException("amount must be positive"); - } - BigDecimal newValue = this.money.subtract(amount); - if (newValue.signum() < 0) { - this.money = BigDecimal.ZERO; - } else { - this.money = newValue; - } - } - - public void deductMoney(BigDecimal amount) { - if (amount.signum() < 0) { - throw new IllegalArgumentException("amount must be positive"); + syncPositionFromCurrentLocation(); + return true; // ✅ arrived this turn } - BigDecimal next = this.money.subtract(amount); - this.money = next.signum() < 0 ? BigDecimal.ZERO : next; + return false; } public void cancelJourney() { this.targetLocation = null; this.remainingDistance = 0; - // destinationPos kan du låta vara, eller synca till current: - // setDestinationPos(currentLocation.getX(), currentLocation.getY()); } - - } + diff --git a/src/main/java/org/example/player.java b/src/main/java/org/example/player.java deleted file mode 100644 index cef5f154..00000000 --- a/src/main/java/org/example/player.java +++ /dev/null @@ -1,144 +0,0 @@ -package org.example; - -abstract class Player { - String playerName; - private int playerScore = 0; - int credits = 10000; - - //Returns the name of the player. - public String getPlayerName() { - return playerName; - } - - //Use to get the players current credits. - public int getCredits() { - return credits; - } - - //remove credits from a player bank - public void removeCredits(int credits) { - if (this.credits - credits < 0) { - this.credits = 0; - }else { - this.credits = this.credits - credits; - } - } - - //add credits to player bank - public void addCredits(int credits) { - if(credits < 0){ - System.out.println("Invalid, credits cannot be under zero!"); - return; - } - this.credits = this.credits + credits; - } - - public boolean checkIfPlayerHasEnoughCredits(int credits) { - if(this.credits < credits){ - System.out.println("Not enough credits for option"); - return false; - } - return true; - } - - //Make a penalties check for the round. A chance under 5 percent for a player to get a penalty. - void checkIfPlayerHasPenalties(){ - if (Math.random() < 0.05){ - System.out.println("You got the penalty!"); - getPenalty(); - } - } - - /* if a player gets a penalty, get a random number between 0 - 5, choose a penalty from the switch.*/ - public void getPenalty() { - int getPenaltyNumber = (int) (6*Math.random()+1); - switch (getPenaltyNumber) { - case 1 -> { - System.out.println(" "); - System.out.println("You fell and bruised, pay some fees 50 credits"); - removeCredits(50); - } case 2 -> { - System.out.println(" "); - System.out.println("You partied too hard last night, lost 100 credits"); - removeCredits(100); - } case 3 -> { - System.out.println(" "); - System.out.println("You got scammed by a local, what a shame"); - removeCredits(150); - } case 4 -> { - System.out.println(" "); - System.out.println("You're transport broke, need a mechanic"); - removeCredits(200); - } case 5 -> { - System.out.println(" "); - System.out.println("You have a big phone bill, dont call that much"); - removeCredits(250); - } case 6 -> { - System.out.println(" "); - System.out.println("Really.. the Ritz hotel"); - removeCredits(500); - }default -> { - System.out.println(" "); - System.out.println("no penalties"); - } - } - } - - void checkIfPlayerHasBonus(){ - if (Math.random() < 0.10){ - System.out.println("You got the penalty!"); - getBonus(); - } - } - - public void getBonus() { - int getPenaltyNumber = (int) (6*Math.random()+1); - switch (getPenaltyNumber) { - case 1 -> { - System.out.println(" "); - System.out.println("found some spare change"); - addCredits(50); - } case 2 -> { - System.out.println(" "); - System.out.println("helped an old woman across the street"); - addCredits(100); - } case 3 -> { - System.out.println(" "); - System.out.println("got a day job"); - addCredits(250); - } case 4 -> { - System.out.println(" "); - System.out.println("you're parents sent you some money"); - addCredits(400); - } case 5 -> { - System.out.println(" "); - System.out.println("Happy birthday"); - addCredits(500); - } case 6 -> { - System.out.println(" "); - System.out.println("won the lottery"); - addCredits(1000); - }default -> { - System.out.println(" "); - System.out.println("no bonus"); - } - } - } - - /* - * Scoring for a player. Players start with zero and has a win state when the score reaches 5. */ - public void increaseScore() { - playerScore++; - } - - public int getPlayerScore() { - return playerScore; - } - - public boolean checkScore() { - if (playerScore == 5) { - return true; - } - return false; - } -} diff --git a/src/main/java/org/example/playerMovement.java b/src/main/java/org/example/playerMovement.java deleted file mode 100644 index c9b7c05e..00000000 --- a/src/main/java/org/example/playerMovement.java +++ /dev/null @@ -1,276 +0,0 @@ -package org.example; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.List; - -public class playerMovement extends Player{ - private final int dice = 6; - private final int walkingDice = 4; - private int selectedTransportDice; - private int availableMovement; - private int playerPosX; - private int playerPosY; - record destinationPos(int destinationX, int destinationY) {} - private destinationPos destination; - private int playerTurnCount = 0; - - public int getTurns(){ - return playerTurnCount; - } - public void setPlayerPosX(int playerPosX) { - if (playerPosX >= 0) { - this.playerPosX = playerPosX; - } else { - System.out.println("Invalid, playerPosX must be greater than or equal to zero!"); - } - } - - public int getPlayerPosX() { - return playerPosX; - } - - public void setPlayerPosY(int playerPosY) { - if (playerPosY >= 0){ - this.playerPosY = playerPosY; - } else { - System.out.println("Invalid, playerPosY must be greater than or equal to zero!"); - } - } - - public int getPlayerPosY() { - return playerPosY; - } - - public void playerMoveUp(){ - this.playerPosY++; - } - - public void playerMoveDown(){ - if (playerPosY > 0){ - this.playerPosY--; - } else { - System.out.println("Invalid, player cant move less than zero"); - } - } - - public void playerMoveLeft(){ - if(playerPosX > 0 ) { - this.playerPosX--; - } else { - System.out.println("Invalid, player cant move less than zero!"); - } - } - - public void playerMoveRight(){ - this.playerPosX++; - } - public void autoMove(){ - for(int i = 0; i < availableMovement; i++){ - if (playerPosX != getDestinationPosX()){ - if(playerPosX > getDestinationPosX()){ - playerMoveLeft(); - } else { - playerMoveRight(); - } - } else if (playerPosY != getDestinationPosY()) { - if (playerPosY > getDestinationPosY()){ - playerMoveDown(); - } else{ - playerMoveUp(); - } - } - availableMovement--; - } - } - - public void setDestinationPos(int destinationX, int destinationY) { - this.destination = new destinationPos(destinationX, destinationY); - } - - public int getDestinationPosX() { - if(this.destination == null){ - throw new NullPointerException("Destination has not been set"); - } - return this.destination.destinationX(); - } - - public int getDestinationPosY() { - if(this.destination == null){ - throw new NullPointerException("Destination has not been set"); - } - return this.destination.destinationY(); - } - - public boolean checkIfPlayerIsAtDestination(){ - if (this.playerPosX == getDestinationPosX() && this.playerPosY == getDestinationPosY()) { - setAvailableMovement(0); - System.out.println(playerName + " has arrived at destination. +1 score and 500 credits"); - addCredits(1000); - return true; - } - return false; - } - - public void setAvailableMovement(int availableMovement) { - this.availableMovement = availableMovement; - } - - public int getAvailableMovement() { - return availableMovement; - } - - public boolean checkMovementIsZero(){ - if (this.availableMovement == 0) { - return true; - } else if (this.availableMovement < 0) { - System.out.println("Invalid movement cant be less than zero"); - } - return false; - } - - public void playerTurn(List transports) throws IOException { - chooseTransportation(transports); - setAvailableMovement(rollDice(selectedTransportDice)); - System.out.println(playerName + " turn"); - System.out.println("Score: " + getPlayerScore()); - while (!checkMovementIsZero()){ - System.out.println(" "); - System.out.println(playerName + " at position X: " + playerPosX + " Y: " + playerPosY ); - System.out.println("dest x: " + destination.destinationX + " dest y: " + destination.destinationY); - System.out.println("available movement left: " + getAvailableMovement()); - String input = IO.readln("choose movement! Available is up, down, left, right, auto"); - input = input.toLowerCase(); - switch (input) { - case "up" -> { - playerMoveUp(); - availableMovement--; - } - case "down" -> { - playerMoveDown(); - availableMovement--; - } - case "left" -> { - playerMoveLeft(); - availableMovement--; - } - case "right" -> { - playerMoveRight(); - availableMovement--; - }case "auto" -> autoMove(); - default -> System.out.println("Invalid input!"); - } - if (checkIfPlayerIsAtDestination()){ - increaseScore(); - } - - } - System.out.println("End of "+ playerName + " turn"); - System.out.println("- - - - - - - - - -"); - checkIfPlayerHasPenalties(); - checkIfPlayerHasBonus(); - playerTurnCount++; - } - public void playerTurnGui(int diceAmount) { - setAvailableMovement(rollDice(diceAmount)); - System.out.println(playerName + " GUI turn"); - - - autoMove(); - - - if (checkIfPlayerIsAtDestination()) { - increaseScore(); - } - - System.out.println("End of " + playerName + " GUI turn"); - checkIfPlayerHasPenalties(); - } - - public void playerTurnByMode(List transports, int guiDiceAmount) throws IOException { - if (GameConfig.MODE == GameMode.CLI) { - playerTurn(transports); - } else { - playerTurnGui(guiDiceAmount); - } - } - - - public void chooseTransportation(List transport) throws IOException { - BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); - - while (true){ - System.out.println("Player: "+playerName+" has " + getCredits() + " credits"); - for (int i = 0; i < transport.size(); i++){ - System.out.println("Nr " + (i+1) + ": " + transport.get(i).getType() + ". Dice amount: "+ transport.get(i).getDiceCount() + ". Costs: " + transport.get(i).getCostPerMove()); - } - System.out.println("Nr 4: Player walks"); - System.out.println("Choose transportation: "); - String input = br.readLine(); - if (input.isEmpty()) { - System.out.println("Invalid input, needs to be a number"); - continue; - } - int choice = 0; - try{ - choice = Integer.parseInt(input); - } catch (NumberFormatException e) { - System.out.println("Invalid input, needs to be a number"); - continue; - } - switch (choice) { - case 1 -> { - if (checkIfPlayerHasEnoughCredits(transport.getFirst().getCostPerMove().intValue())){ - this.selectedTransportDice = transport.getFirst().getDiceCount(); - removeCredits(transport.getFirst().getCostPerMove().intValue()); - return; - } else { - System.out.println("Not enough credits"); - } - } - case 2 -> { - - if (checkIfPlayerHasEnoughCredits(transport.get(1).getCostPerMove().intValue())){ - this.selectedTransportDice = transport.get(1).getDiceCount(); - removeCredits(transport.get(1).getCostPerMove().intValue()); - return; - } else { - System.out.println("Not enough credits"); - } - } - case 3 -> { - if (checkIfPlayerHasEnoughCredits(transport.get(2).getCostPerMove().intValue())){ - this.selectedTransportDice = transport.get(2).getDiceCount(); - removeCredits(transport.get(2).getCostPerMove().intValue()); - return; - } else { - System.out.println("Not enough credits"); - } - } case 4 -> { - System.out.println("Player walks"); - this.selectedTransportDice = (int) ((walkingDice * Math.random()+1)); - return; - } - default -> System.out.println("Invalid input, needs to be a number"); - } - } - } - - //Dice roll method - public int rollDice(int amount) { - int tempRoll; - int roll = 0; - for (int i = 0; i < amount; i++){ - tempRoll = (int) ((dice * Math.random()+1)); - System.out.println("Rolled a " + tempRoll); - roll += tempRoll; - } - System.out.println("Total amount is " + roll); - return roll; - } -} - - - - diff --git a/src/main/java/org/example/service/JourneyService.java b/src/main/java/org/example/service/JourneyService.java index 8fac9f73..f77608a5 100644 --- a/src/main/java/org/example/service/JourneyService.java +++ b/src/main/java/org/example/service/JourneyService.java @@ -89,7 +89,12 @@ private Journey doTravelStep(Traveler traveler, LocationLink route, Transport tr int rolledDistance = transport.rollDistance(); traveler.pay(cost); - traveler.advance(rolledDistance); + + boolean arrived = traveler.advance(rolledDistance); // gör advance return boolean + if (arrived) { + traveler.addScore(1); + } + Journey journey = new Journey( traveler,