/** * Spielende feststellen: wenn alle gegebenen Karten im Stich verwendet worden sind. * * @return True, wenn alle gegebenen Karten im Stich verwendet worden sind. */ private boolean areCardsAvailable() { for (PlayCard c : playcards) { if (c.getOwner() != null && c.getStichNr() == 0) { return true; } } log.info("Cards available: NO"); return false; }
private Set<CardInfo> getCardsOnHand(Player p) { final Set<CardInfo> playercards = new HashSet<>(); for (PlayCard pc : playcards) { if (pc.getOwner() != null && pc.getOwner().getId() == p.getId()) { CardInfo hc = new CardInfo(pc.getKarte()); hc.setOffen(!p.isComputer()); playercards.add(hc); } } return playercards; }
private void resetSpiel() { trumpfFarbe = null; geber = null; activePlayer = null; trumpfPlayer = null; original = null; originalSelected = false; stiche.clear(); stichNr.set(1); for (PlayCard c : playcards) { c.setOwner(null); c.setStichNr(0); c.setBidNr(0); } }
private void assignFreeCardToPlayer(final Player p, boolean assignOriginal) { for (; ; ) { long skip = Math.round(Math.random() * (System.nanoTime() & 255)); long s = 0; for (final PlayCard c : playcards) { if (s++ >= skip) { if (c.isFree()) { c.setOwner(p); log.info("card assigned: card=" + c.getKarte() + ", player=" + p.getId()); if (assignOriginal && this.original == null) { this.original = c.getKarte(); log.info("original assigned: card=" + c.getKarte()); } return; } } } } }
private List<CardInfo> buildCardInfo() { final List<CardInfo> info = new ArrayList<>(); final Map<Integer, CardInfo> roundCards = new HashMap<>(); for (final PlayCard card : playcards) { final CardInfo ci = new CardInfo(card.getKarte()); ci.setOffen(card.getOwner() != null && !card.getOwner().isComputer()); ci.setPlayerPosition(card.getOwner() != null ? card.getOwner().getPosition() : 0); CardPlace location = CardPlace.Invisible; // Karte bereits gespielt // 0=bereits gespielt/nicht sichtbar, 1=auf Hand, 2=Original, 3=Stich, 4=Stapel if (card.equals(original)) { if (!originalSelected) { location = CardPlace.Original; // Aufgedeckt vor dem Spieler anzeigen } } if (location == CardPlace.Invisible && isCardInCurrentRound(card)) { location = CardPlace.Bid; // im aktuellen Stich roundCards.put(card.getBidNr(), ci); } if (location == CardPlace.Invisible && card.getOwner() == null) { location = CardPlace.Stock; // im Stapel } if (location == CardPlace.Invisible && card.getOwner() != null && card.getStichNr() == 0) { location = CardPlace.Hand; // Hand, nicht gespielt } ci.setCardPlace(location); info.add(ci); } // Integrate cards from bid in correct order info.removeAll(roundCards.values()); info.addAll(roundCards.values()); return info; }
private PlayCard getCard(Karte k) { for (PlayCard c : playcards) { if (c.equals(k)) return c; } return null; }
private PlayCard getCard(Farbe f, Kartenwert w) { for (PlayCard c : playcards) { if (c.equals(f, w)) return c; } return null; }
/** * - Stichgewinner ermitteln - Mitspieler im gleichen Team ermitteln - Punkte zählen und allen im * Team addieren */ private void calculatePointsInRound(final Stich stich) { final List<PlayCard> stichcards = new ArrayList<>(); for (PlayCard c : playcards) { if (c.getStichNr() == stich.getStichNr()) { stichcards.add(c); } } // Nach Spielreihenfolge sortieren Collections.sort(stichcards, this.stichSorter); // Erste Karte merken final PlayCard karte1 = stichcards.get(0); PlayCard winnerCard = null; Player winner = null; int points = 0; for (PlayCard c : stichcards) { if (winner == null) { winner = karte1.getOwner(); winnerCard = karte1; } else { int r1 = winnerCard.getRank(trumpfFarbe); // Abgeworfen, dann rank 0 int r2 = c.getFarbe() != karte1.getFarbe() && c.getFarbe() != trumpfFarbe ? 0 : c.getRank(trumpfFarbe); if (r2 > r1) { winner = c.getOwner(); winnerCard = c; } } points += c.getPoints(); // Zusatzgewinne // 1) Jass if (c.isJass(trumpfFarbe)) { points += 20; } // 2) Mie if (c.isMie(trumpfFarbe)) { points += 14; } // letzter Stich bekommt 10 Extrapunkte if (this.maxStichNr == c.getStichNr()) { points += 10; } } stich.setWinner(winner); stich.setPoints(points); log.info( "Round " + stich.getStichNr() + ": " + points + " points for player " + winner.getUsername() + ", stich=" + stichcards); }
public void startGame() throws Exception { // PLAYER CHECK // final int playerCount = player.size(); { if (playerCount < 2) { throw new Exception("Zu wenig Spieler für ein Spiel."); } if (playerCount > MAX_PLAYER) { throw new Exception("Zu viele Spieler für ein Spiel."); } if (playerCount < 2 || playerCount > MAX_PLAYER) { throw new Exception("Unpassende Spieleranzahl."); } } // FIRST TIME INITIALIZATION // Thread.currentThread().setName("Game " + this.gameId); this.maxStichNr = 32 / player.size(); gotoGameState(GameState.G0); // LOOP FOR 4 PLAYER !! for (; ; ) { final GameEvent event = getNextEvent(20000); pause(50); if (event == null) { log.info("State=" + gameState + ", waiting for events"); continue; } log.info("State=" + gameState + ", event=" + event); if (event.getEvent() == EventType.gostate) { gameState = event.getState(); } switch (gameState) { // ----------------------------------------------------------- case G0: { resetSpiel(); start = new Date(); selectGeber(); // Reset clients final PlayerCommand pc = new PlayerCommand(); sendCommandToAllPlayer(CommandCode.gameReset); // Initialize clients sendGameInfo(); // 3 Karten für jeden for (int i = 0; i < 3; i++) { for (Player p : player) { assignFreeCardToPlayer(p, false); } } sendPlayerInfo(); gotoGameState(GameState.G1); break; } // ----------------------------------------------------------- case G1: { // 2 Karten für jeden original = null; for (int i = 0; i < 2; i++) { for (Player p : player) { assignFreeCardToPlayer(p, p.getId() == this.geber.getId()); } } sendPlayerInfo(); gotoGameState(GameState.G1a); break; } // ----------------------------------------------------------- case G1a: { // 3 Karten für jeden for (int i = 0; i < 3; i++) { for (Player p : player) { assignFreeCardToPlayer(p, false); } } sendPlayerInfo(); gotoGameState(GameState.G2); break; } // ----------------------------------------------------------- case G2: { Player p = getPlayerLeftFromGeber(+1); sendPlayerCommand( p, CommandCode.frageOriginal, new ResponseCode[] {ResponseCode.ja, ResponseCode.nein}); gameState = GameState.G3; break; } // ----------------------------------------------------------- case G3: { if (event.getEvent() == EventType.player) { final PlayerResponse response = event.getPlayerResponse(); if (response.getResponseCode() == ResponseCode.nein) { sendPlayerMsg(getPlayerById(response.getPlayerId()), "Weg!"); Player p = getPlayerLeftFromGeber(+2); sendPlayerCommand( p, CommandCode.frageOriginal, new ResponseCode[] {ResponseCode.ja, ResponseCode.nein}); gameState = GameState.G4; } else if (response.getResponseCode() == ResponseCode.ja) { trumpfPlayer = getPlayerById(response.getPlayerId()); trumpfFarbe = original.getFarbe(); originalSelected = true; sendPlayerMsg(getPlayerById(response.getPlayerId()), "Ich gehe rein"); gotoGameState(GameState.S0); } else { throw new Exception( "Unexpected response: state=" + gameState + ", response=" + response.getResponseCode()); } } break; } // ----------------------------------------------------------- case G4: { if (event.getEvent() == EventType.player) { final PlayerResponse response = event.getPlayerResponse(); if (response.getResponseCode() == ResponseCode.nein) { sendPlayerMsg(getPlayerById(response.getPlayerId()), "Weg!"); Player p = getPlayerLeftFromGeber(+3); sendPlayerCommand( p, CommandCode.frageOriginal, new ResponseCode[] {ResponseCode.ja, ResponseCode.nein}); gameState = GameState.G5; } else if (response.getResponseCode() == ResponseCode.ja) { trumpfPlayer = getPlayerById(response.getPlayerId()); trumpfFarbe = original.getFarbe(); originalSelected = true; sendPlayerMsg(getPlayerById(response.getPlayerId()), "Ich gehe rein"); gotoGameState(GameState.S0); } else { throw new Exception( "Unexpected response: state=" + gameState + ", response=" + response.getResponseCode()); } } break; } // ----------------------------------------------------------- case G5: { if (event.getEvent() == EventType.player) { final PlayerResponse response = event.getPlayerResponse(); if (response.getResponseCode() == ResponseCode.nein) { sendPlayerMsg(getPlayerById(response.getPlayerId()), "Weg!"); Player p = getPlayerLeftFromGeber(+0); sendPlayerCommand( p, CommandCode.frageOriginal, new ResponseCode[] {ResponseCode.ja, ResponseCode.nein}); gameState = GameState.G6; } else if (response.getResponseCode() == ResponseCode.ja) { trumpfPlayer = getPlayerById(response.getPlayerId()); trumpfFarbe = original.getFarbe(); originalSelected = true; sendPlayerMsg(getPlayerById(response.getPlayerId()), "Ich gehe rein"); gotoGameState(GameState.S0); } else { throw new Exception( "Unexpected response: state=" + gameState + ", response=" + response.getResponseCode()); } } break; } // ----------------------------------------------------------- case G6: { if (event.getEvent() == EventType.player) { final PlayerResponse response = event.getPlayerResponse(); if (response.getResponseCode() == ResponseCode.nein) { sendPlayerMsg(getPlayerById(response.getPlayerId()), "Weg!"); Player p = getPlayerLeftFromGeber(+1); sendPlayerCommand( p, CommandCode.frageKleines, new ResponseCode[] {ResponseCode.ja, ResponseCode.nein}); gameState = GameState.G7; } else if (response.getResponseCode() == ResponseCode.ja) { trumpfPlayer = getPlayerById(response.getPlayerId()); trumpfFarbe = original.getFarbe(); originalSelected = true; sendPlayerMsg(getPlayerById(response.getPlayerId()), "Ich gehe rein"); gotoGameState(GameState.S0); } else { throw new Exception( "Unexpected response: state=" + gameState + ", response=" + response.getResponseCode()); } } break; } // ----------------------------------------------------------- case G7: { if (event.getEvent() == EventType.player) { final PlayerResponse response = event.getPlayerResponse(); if (response.getResponseCode() == ResponseCode.nein) { sendPlayerMsg(getPlayerById(response.getPlayerId()), "Noch weg!"); Player p = getPlayerLeftFromGeber(+2); sendPlayerCommand( p, CommandCode.frageKleines, new ResponseCode[] {ResponseCode.ja, ResponseCode.nein}); gameState = GameState.G8; } else if (response.getResponseCode() == ResponseCode.ja) { Player p = getPlayerLeftFromGeber(+1); sendPlayerCommand( p, CommandCode.frageTrumpffarbe, new ResponseCode[] {ResponseCode.waehleFarbe}); gameState = GameState.G11; } else { throw new Exception( "Unexpected response: state=" + gameState + ", response=" + response.getResponseCode()); } } break; } // ----------------------------------------------------------- case G8: { if (event.getEvent() == EventType.player) { final PlayerResponse response = event.getPlayerResponse(); if (response.getResponseCode() == ResponseCode.nein) { sendPlayerMsg(getPlayerById(response.getPlayerId()), "Noch weg!"); Player p = getPlayerLeftFromGeber(+3); sendPlayerCommand( p, CommandCode.frageKleines, new ResponseCode[] {ResponseCode.ja, ResponseCode.nein}); gameState = GameState.G9; } else if (response.getResponseCode() == ResponseCode.ja) { Player p = getPlayerLeftFromGeber(+2); sendPlayerCommand( p, CommandCode.frageTrumpffarbe, new ResponseCode[] {ResponseCode.waehleFarbe}); gameState = GameState.G12; } else { throw new Exception( "Unexpected response: state=" + gameState + ", response=" + response.getResponseCode()); } } break; } // ----------------------------------------------------------- case G9: { if (event.getEvent() == EventType.player) { final PlayerResponse response = event.getPlayerResponse(); if (response.getResponseCode() == ResponseCode.nein) { sendPlayerMsg(getPlayerById(response.getPlayerId()), "Noch weg!"); Player p = getPlayerLeftFromGeber(+0); sendPlayerCommand( p, CommandCode.frageKleines, new ResponseCode[] {ResponseCode.ja, ResponseCode.nein}); gameState = GameState.G10; } else if (response.getResponseCode() == ResponseCode.ja) { Player p = getPlayerLeftFromGeber(+3); sendPlayerCommand( p, CommandCode.frageTrumpffarbe, new ResponseCode[] {ResponseCode.waehleFarbe}); gameState = GameState.G13; } else { throw new Exception( "Unexpected response: state=" + gameState + ", response=" + response.getResponseCode()); } } break; } // ----------------------------------------------------------- case G10: { if (event.getEvent() == EventType.player) { final PlayerResponse response = event.getPlayerResponse(); if (response.getResponseCode() == ResponseCode.nein) { sendPlayerMsg(getPlayerById(response.getPlayerId()), "Noch weg!"); gotoGameState(GameState.G20); } else if (response.getResponseCode() == ResponseCode.ja) { Player p = getPlayerLeftFromGeber(+0); sendPlayerCommand( p, CommandCode.frageTrumpffarbe, new ResponseCode[] {ResponseCode.waehleFarbe}); gameState = GameState.G14; } else { throw new Exception( "Unexpected response: state=" + gameState + ", response=" + response.getResponseCode()); } } break; } // ----------------------------------------------------------- case G11: case G12: case G13: case G14: { if (event.getEvent() == EventType.player) { final PlayerResponse response = event.getPlayerResponse(); if (response.getResponseCode() == ResponseCode.waehleFarbe) { trumpfPlayer = getPlayerById(response.getPlayerId()); trumpfFarbe = response.getFarbe(); sendPlayerMsg(getPlayerById(response.getPlayerId()), "spiele " + trumpfFarbe); gotoGameState(GameState.S0); } else { throw new Exception( "Unexpected response: state=" + gameState + ", response=" + response.getResponseCode()); } } break; } // ----------------------------------------------------------- case S0: { originalSelected = true; if (playerCount == 2 || playerCount == 3) { /** Spieler, der die Trumpf 7 hält, kann mit 'Original' tauschen */ final PlayCard trumpf7 = getCard(trumpfFarbe, Kartenwert.Sieben); final Player trumpf7_owner = trumpf7.getOwner(); if (trumpf7_owner != null && !original.equals(trumpf7)) { sendPlayerCommand( trumpf7_owner, CommandCode.tauscheSieben, new ResponseCode[] {ResponseCode.ja, ResponseCode.nein}); gameState = GameState.X1; } } else { gotoGameState(GameState.S1); } break; } // ----------------------------------------------------------- case S1: { if (!areCardsAvailable()) { gotoGameState(GameState.S4); } else { // Neue Runde starten final Stich newRound = new Stich(); newRound.setNr(stichNr.getAndIncrement()); newRound.setCount(0); // In der 1. Runde spielt der Nebenmann auf: if (newRound.getStichNr() == 1) { newRound.setStarter(getPlayerLeftFromGeber(+1)); } else { newRound.setStarter(getCurrentStich().getWinner()); } stiche.add(newRound); // Prepare next step and send out game info gotoGameState(GameState.S2); } break; } // ----------------------------------------------------------- case S2: { final Stich r = getCurrentStich(); // Nächster Spieler im Uhrzeigersinn: final Player p = getPlayerLeftFrom(r.getStarter(), r.getCount()); this.activePlayer = p; sendGameInfo(false); sendPlayerInfo(); sendPlayerCommand(p, CommandCode.spieleKarte, new ResponseCode[] {ResponseCode.play}); gotoGameState(GameState.S3); break; } // ----------------------------------------------------------- case S3: { if (event.getEvent() == EventType.player) { final PlayerResponse response = event.getPlayerResponse(); if (response.getResponseCode() == ResponseCode.play) { final PlayCard c = getCard(response.getGespielteKarte()); final Player p = getPlayerById(response.getPlayerId()); final Stich r = getCurrentStich(); if (c == null) throw new Exception("card not found: " + response.getGespielteKarte()); if (p == null) throw new Exception("player not found: " + response.getPlayerId()); c.setBidNr(r.getCount()); c.setStichNr(r.getStichNr()); // TODO: Terz check // TODO: Bella check ... sendPlayerInfo(); if (r.getCount() >= playerCount - 1) { // Runde ist beendet calculatePointsInRound(r); log.info("Stich Ende: " + r.toString()); gotoGameState(GameState.S1); } else { // Weiter auf nächste Karte warten r.setCount(r.getCount() + 1); gotoGameState(GameState.S2); } } } break; } // ----------------------------------------------------------- case S4: { // Spielende: // Gesamtpunkte, Gewinner berechnen. createGameHistoryRecord(); if (this.spielNr.get() == MAX_RUNDEN) { sendGameInfo(); gotoGameState(GameState.GOV); } else { gotoGameState(GameState.S5); } break; } // ----------------------------------------------------------- case S5: { log.info("Game finished."); for (Player p : player) { if ((System.currentTimeMillis() % 5) == p.getPosition()) { sendPlayerMsg(p, "Weiter!"); } } sendPlayerInfo(); sendGameInfo(true); // Prepare next game: spielNr.incrementAndGet(); /** TODO: prüfe neue Runde? TODO: prüfe Holz, ... */ // Restart Game: pause(1000); gotoGameState(GameState.G0); break; } // ----------------------------------------------------------- case G20: { log.info("Alle weg, Karten neu verteilen."); pause(1000); for (Player p : player) { if ((System.currentTimeMillis() % 5) == p.getPosition()) { sendPlayerMsg(p, "Neue Karten"); } else if ((System.currentTimeMillis() % 3) == p.getPosition()) { sendPlayerMsg(p, "Mischen"); } } // Restart Game: pause(1000); gotoGameState(GameState.G0); break; } // ----------------------------------------------------------- case GOV: { end = new Date(); log.info("GAME OVER."); break; } // ----------------------------------------------------------- case X1: { if (event.getEvent() == EventType.player) { final PlayerResponse response = event.getPlayerResponse(); if (response.getResponseCode() == ResponseCode.ja) { sendPlayerMsg(getPlayerById(response.getPlayerId()), "Tausche die 7!"); PlayCard trumpf7 = getCard(trumpfFarbe, Kartenwert.Sieben); PlayCard changeCard = getCard(trumpfFarbe, original.getWert()); changeCard.setOwner(trumpf7.getOwner()); trumpf7.setOwner(null); original = trumpf7.getKarte(); } } gotoGameState(GameState.S1); break; } // ----------------------------------------------------------- case X2: { break; } } } }
private boolean isCardInCurrentRound(PlayCard pc) { final Stich r = getCurrentStich(); return (r != null && r.getStichNr() == pc.getStichNr()); }