Compare commits
9 Commits
b9a7b0a2af
...
10fa4badf0
| Author | SHA1 | Date | |
|---|---|---|---|
| 10fa4badf0 | |||
| f765dd64dd | |||
| ef7397f7f1 | |||
| d833932f16 | |||
| c5dd02a5e8 | |||
| 3048552f4c | |||
| ec94ecd46c | |||
| 20e8bae883 | |||
| a5dcf3ee90 |
@@ -37,13 +37,11 @@ class CardBaseManager extends CardManager {
|
||||
}
|
||||
|
||||
override def nextCard(): Card = {
|
||||
val card = cc(currentIdx)
|
||||
if (currentIdx + 1 > 51) {
|
||||
if (currentIdx > 51)
|
||||
throw new IndexOutOfBoundsException("Trying to access card 53(out of bounds)")
|
||||
} else {
|
||||
currentIdx += 1
|
||||
card
|
||||
}
|
||||
val card = cc(currentIdx)
|
||||
currentIdx += 1
|
||||
card
|
||||
}
|
||||
|
||||
override def removeCards(amount: Int): List[Card] = {
|
||||
|
||||
@@ -16,6 +16,7 @@ trait GameLogic extends EventHandler with SnapshottingGameLogic {
|
||||
def controlPreRound(): Unit
|
||||
def controlRound(): Unit
|
||||
def endRound(winner: AbstractPlayer, roundResult: RoundResult): Match
|
||||
def returnFromTie(winner: AbstractPlayer): Unit
|
||||
def controlTrick(): Unit
|
||||
def endTrick(): Round
|
||||
def controlPlayerPlay(): Unit
|
||||
@@ -27,12 +28,14 @@ trait GameLogic extends EventHandler with SnapshottingGameLogic {
|
||||
def playerTieLogic: PlayerTieLogic
|
||||
def undoManager: UndoManager
|
||||
def persistenceManager: PersistenceManager
|
||||
|
||||
def changeState(gameState: GameState): Unit
|
||||
|
||||
def getCurrentState: GameState
|
||||
def getCurrentMatch: Option[Match]
|
||||
def getCurrentRound: Option[Round]
|
||||
def getCurrentTrick: Option[Trick]
|
||||
def getCurrentPlayer: Option[AbstractPlayer]
|
||||
def getWinner: Option[AbstractPlayer]
|
||||
def getTrumpPlayer: Option[AbstractPlayer]
|
||||
def getPlayerQueue: Option[CustomPlayerQueue[AbstractPlayer]]
|
||||
|
||||
|
||||
@@ -53,8 +53,7 @@ final class BaseGameLogic(val config: Configuration) extends EventHandler with G
|
||||
currentTrick = None
|
||||
currentPlayer = None
|
||||
playerQueue = None
|
||||
invoke(GameStateChangeEvent(state, Lobby))
|
||||
state = Lobby
|
||||
changeState(Lobby)
|
||||
}
|
||||
|
||||
override def createMatch(players: List[AbstractPlayer]): Match = {
|
||||
@@ -72,20 +71,23 @@ final class BaseGameLogic(val config: Configuration) extends EventHandler with G
|
||||
if (matchImpl.isOver) {
|
||||
//Winner is the last person in the playersIn list
|
||||
val winner = matchImpl.playersIn.head
|
||||
|
||||
invoke(GameStateChangeEvent(state, FinishedMatch))
|
||||
state = FinishedMatch
|
||||
|
||||
changeState(FinishedMatch)
|
||||
invoke(MatchEndEvent(winner))
|
||||
} else {
|
||||
|
||||
changeState(InGame)
|
||||
|
||||
if (matchImpl.roundlist.isEmpty) {
|
||||
if (cardManager.isEmpty) throw new IllegalStateException("No card manager set")
|
||||
val cardManagerImpl = cardManager.get
|
||||
cardManagerImpl.shuffleAndReset()
|
||||
val firstCard = cardManagerImpl.nextCard()
|
||||
val newRound = RoundUtil.createRound(firstCard.suit, true)
|
||||
|
||||
providePlayersWithCards()
|
||||
|
||||
val randomPlayer: Int = 1//Random.nextInt(matchImpl.playersIn.size)
|
||||
val randomPlayer: Int = Random.nextInt(matchImpl.playersIn.size)
|
||||
playerQueue = Some(config.createRightQueue(matchImpl.playersIn.toArray, randomPlayer))
|
||||
|
||||
matchImpl.playersIn.foreach(player => {invoke(ReceivedHandEvent(player))})
|
||||
@@ -106,6 +108,18 @@ final class BaseGameLogic(val config: Configuration) extends EventHandler with G
|
||||
controlPreRound()
|
||||
}
|
||||
}
|
||||
|
||||
override def returnFromTie(winner: AbstractPlayer): Unit = {
|
||||
if (currentMatch.isEmpty) throw new IllegalStateException("No current match set")
|
||||
val matchImpl = currentMatch.get
|
||||
if (currentRound.isEmpty) throw new IllegalStateException("No current round set")
|
||||
val roundImpl = currentRound.get
|
||||
|
||||
val roundResult: RoundResult = RoundUtil.finishRound(roundImpl, matchImpl)
|
||||
val newMatch = endRound(winner, roundResult)
|
||||
currentMatch = Some(newMatch)
|
||||
controlMatch()
|
||||
}
|
||||
|
||||
//
|
||||
override def controlPreRound(): Unit = {
|
||||
@@ -122,8 +136,7 @@ final class BaseGameLogic(val config: Configuration) extends EventHandler with G
|
||||
matchImpl.playersIn.indexOf(lastWinner.get)
|
||||
))
|
||||
|
||||
invoke(GameStateChangeEvent(state, SelectTrump))
|
||||
state = SelectTrump
|
||||
changeState(SelectTrump)
|
||||
|
||||
invoke(TrumpSelectEvent(lastWinner.get))
|
||||
|
||||
@@ -131,9 +144,7 @@ final class BaseGameLogic(val config: Configuration) extends EventHandler with G
|
||||
}
|
||||
|
||||
override def controlRound(): Unit = {
|
||||
if (state != InGame)
|
||||
invoke(GameStateChangeEvent(state, InGame))
|
||||
state = InGame
|
||||
changeState(InGame)
|
||||
if (currentMatch.isEmpty) throw new IllegalStateException("No current match set")
|
||||
val matchImpl = currentMatch.get
|
||||
if (currentRound.isEmpty) throw new IllegalStateException("No current round set")
|
||||
@@ -144,8 +155,7 @@ final class BaseGameLogic(val config: Configuration) extends EventHandler with G
|
||||
if (MatchUtil.isRoundOver(matchImpl, roundImpl)) {
|
||||
val roundResult: RoundResult = RoundUtil.finishRound(roundImpl, matchImpl)
|
||||
if (roundResult.isTie) {
|
||||
invoke(GameStateChangeEvent(state, TieBreak))
|
||||
state = TieBreak
|
||||
changeState(TieBreak)
|
||||
|
||||
invoke(TieEvent(roundResult.winners))
|
||||
invoke(DelayEvent(2000))
|
||||
@@ -185,8 +195,11 @@ final class BaseGameLogic(val config: Configuration) extends EventHandler with G
|
||||
).map(rp => rp.amountOfTricks).sum))
|
||||
invoke(DelayEvent(2000))
|
||||
|
||||
if (roundResult.notTricked.nonEmpty && !roundImpl.firstRound) {
|
||||
if (matchImpl.dogLife) {
|
||||
if (roundResult.notTricked.nonEmpty && !resultingRound.firstRound) {
|
||||
// When the number of cards is less than 2, dog life ends automatically
|
||||
val cantDogLife = (matchImpl.numberofcards - 1) < 2
|
||||
|
||||
if (matchImpl.dogLife && !cantDogLife) {
|
||||
invoke(ShowPlayersOutEvent(roundResult.notTricked))
|
||||
invoke(DelayEvent(2000))
|
||||
matchImpl = matchImpl.updatePlayersIn(matchImpl.playersIn.filterNot(roundResult.notTricked.contains(_)))
|
||||
@@ -228,6 +241,7 @@ final class BaseGameLogic(val config: Configuration) extends EventHandler with G
|
||||
queueImpl.resetAndSetStart(winner)
|
||||
controlRound()
|
||||
} else {
|
||||
invoke(DelayEvent(2000))
|
||||
val playerImpl = queueImpl.nextPlayer()
|
||||
currentPlayer = Some(playerImpl)
|
||||
controlPlayerPlay()
|
||||
@@ -295,7 +309,11 @@ final class BaseGameLogic(val config: Configuration) extends EventHandler with G
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
override def changeState(gameState: GameState): Unit = {
|
||||
if(state == gameState) return
|
||||
invoke(GameStateChangeEvent(state, gameState))
|
||||
state = gameState
|
||||
}
|
||||
|
||||
// Getters
|
||||
|
||||
@@ -306,6 +324,14 @@ final class BaseGameLogic(val config: Configuration) extends EventHandler with G
|
||||
override def getCurrentPlayer: Option[AbstractPlayer] = currentPlayer
|
||||
override def getPlayerQueue: Option[CustomPlayerQueue[AbstractPlayer]] = playerQueue
|
||||
|
||||
|
||||
override def getWinner: Option[AbstractPlayer] = {
|
||||
if (currentMatch.isEmpty) throw new IllegalStateException("No current match set")
|
||||
val matchImpl = currentMatch.get
|
||||
if (!matchImpl.isOver) return None
|
||||
Some(matchImpl.playersIn.head)
|
||||
}
|
||||
|
||||
override def getTrumpPlayer: Option[AbstractPlayer] = {
|
||||
if (currentMatch.isEmpty) throw new IllegalStateException("No current match set")
|
||||
val matchImpl = currentMatch.get
|
||||
@@ -328,8 +354,7 @@ final class BaseGameLogic(val config: Configuration) extends EventHandler with G
|
||||
currentPlayer = None
|
||||
playerQueue = None
|
||||
invoke(SessionClosed())
|
||||
invoke(GameStateChangeEvent(state, MainMenu))
|
||||
state = MainMenu
|
||||
changeState(MainMenu)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ final class BasePlayerTieLogic(gameLogic: BaseGameLogic) extends PlayerTieLogic
|
||||
override def handleNextTieBreakerPlayer(): Unit = {
|
||||
tieBreakerIndex += 1
|
||||
if(tieBreakerIndex >= 0 && tieBreakerIndex < tiedPlayers.size) {
|
||||
requestTieChoice(currentTiePlayer())
|
||||
requestTieChoice(currentTiePlayer().get)
|
||||
} else {
|
||||
// All players have selected their tie-breaker cards
|
||||
// Find the highest card among selected cards
|
||||
@@ -70,12 +70,14 @@ final class BasePlayerTieLogic(gameLogic: BaseGameLogic) extends PlayerTieLogic
|
||||
|
||||
val winner = winners.head
|
||||
// Inform game logic about the winner
|
||||
|
||||
gameLogic.returnFromTie(winner)
|
||||
}
|
||||
}
|
||||
|
||||
override def currentTiePlayer(): AbstractPlayer = {
|
||||
tiedPlayers(tieBreakerIndex)
|
||||
override def currentTiePlayer(): Option[AbstractPlayer] = {
|
||||
if (tieBreakerIndex < 0 || tieBreakerIndex >= tiedPlayers.size)
|
||||
return None
|
||||
Some(tiedPlayers(tieBreakerIndex))
|
||||
}
|
||||
|
||||
override def requestTieChoice(player: AbstractPlayer): Unit = {
|
||||
@@ -111,7 +113,7 @@ final class BasePlayerTieLogic(gameLogic: BaseGameLogic) extends PlayerTieLogic
|
||||
|
||||
// The highest allowed number is total cards minus the number of tied players already selected
|
||||
// This ensures that each tied player can select a unique card
|
||||
remainingCards - (tiedPlayers.size - selectedCard.size - 1)
|
||||
remainingCards - (tiedPlayers.size - (selectedCard.size + 1)) - 1
|
||||
}
|
||||
|
||||
override def isWaitingForInput: Boolean = _waitingForInput
|
||||
|
||||
@@ -17,7 +17,7 @@ object MatchUtil {
|
||||
}
|
||||
|
||||
def dogNeedsToPlay(matchImpl: Match, roundImpl: Round): Boolean = {
|
||||
remainingRounds(matchImpl, roundImpl) == 1
|
||||
remainingRounds(matchImpl, roundImpl) <= 1
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ trait PlayerTieLogic extends SnapshottingGameLogic {
|
||||
|
||||
def handleTie(roundResult: RoundResult): Unit
|
||||
def handleNextTieBreakerPlayer(): Unit
|
||||
def currentTiePlayer(): AbstractPlayer
|
||||
def currentTiePlayer(): Option[AbstractPlayer]
|
||||
def requestTieChoice(player: AbstractPlayer): Unit
|
||||
def receivedTieBreakerCard(number: Int): Unit
|
||||
def highestAllowedNumber(): Int
|
||||
|
||||
@@ -4,5 +4,5 @@ import de.knockoutwhist.control.GameState
|
||||
import de.knockoutwhist.utils.events.SimpleEvent
|
||||
|
||||
case class GameStateChangeEvent(oldState: GameState, newState: GameState) extends SimpleEvent {
|
||||
override def id: String = s"GameStateChangeEvent(from=$oldState,to=$newState)"
|
||||
override def id: String = s"GameStateChangeEvent"
|
||||
}
|
||||
|
||||
@@ -4,5 +4,5 @@ import de.knockoutwhist.player.AbstractPlayer
|
||||
import de.knockoutwhist.utils.events.SimpleEvent
|
||||
|
||||
case class RoundEndEvent(winner: AbstractPlayer, amountOfTricks: Int) extends SimpleEvent {
|
||||
override def id: String = s"RoundEndEvent()"
|
||||
override def id: String = s"RoundEndEvent"
|
||||
}
|
||||
|
||||
@@ -3,5 +3,5 @@ package de.knockoutwhist.events.player
|
||||
import de.knockoutwhist.player.AbstractPlayer
|
||||
|
||||
case class RequestCardEvent(player: AbstractPlayer) extends PlayerEvent(player) {
|
||||
override def id: String = "PlayCardEvent"
|
||||
override def id: String = "RequestCardEvent"
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ class TieMenu(gui: GUIMain) {
|
||||
if (gui.logic.isEmpty) throw new IllegalStateException("Logic is not initialized!")
|
||||
val logic = gui.logic.get
|
||||
|
||||
val player = logic.playerTieLogic.currentTiePlayer()
|
||||
val player = logic.playerTieLogic.currentTiePlayer().get
|
||||
updatePlayerLabel(player)
|
||||
|
||||
changeSlider(logic.playerTieLogic.highestAllowedNumber())
|
||||
|
||||
@@ -26,7 +26,7 @@ case class SelectTieNumberCommand[
|
||||
glSnapshot.restore(gameLogic.asInstanceOf[GL])
|
||||
ptlSnapshot.restore(gameLogic.playerTieLogic.asInstanceOf[PT])
|
||||
ControlThread.runLater {
|
||||
gameLogic.playerTieLogic.requestTieChoice(gameLogic.playerTieLogic.currentTiePlayer())
|
||||
gameLogic.playerTieLogic.requestTieChoice(gameLogic.playerTieLogic.currentTiePlayer().get)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,12 +5,15 @@ import de.knockoutwhist.utils.events.{EventListener, SimpleEvent}
|
||||
|
||||
object DelayHandler extends EventListener {
|
||||
|
||||
private[knockoutwhist] var activateDelay: Boolean = false
|
||||
private[knockoutwhist] var activateDelay: Boolean = true
|
||||
|
||||
override def listen(event: SimpleEvent): Unit = {
|
||||
event match {
|
||||
case event: DelayEvent =>
|
||||
if(activateDelay) Thread.sleep(event.delay)
|
||||
if(activateDelay) {
|
||||
println(s"Delaying for ${event.delay}ms")
|
||||
Thread.sleep(event.delay)
|
||||
}
|
||||
case _ =>
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ class BasePlayerTieLogicSpec extends AnyWordSpec with Matchers {
|
||||
tieLogic.getTiedPlayers should contain inOrder (p1, p2)
|
||||
tieLogic.getTieBreakerIndex shouldBe 0
|
||||
tieLogic.isWaitingForInput shouldBe true
|
||||
tieLogic.currentTiePlayer() shouldBe p1
|
||||
tieLogic.currentTiePlayer().get shouldBe p1
|
||||
tieLogic.highestAllowedNumber() shouldBe (logic.cardManager.get.remainingCards - (2 - 0 - 1))
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user