13 Commits

Author SHA1 Message Date
10fa4badf0 fix: BAC-29 Implement Mappers for Common Classes (#60)
Reviewed-on: #60
Co-authored-by: Janis <janis.e.20@gmx.de>
Co-committed-by: Janis <janis.e.20@gmx.de>
2025-12-05 19:24:07 +01:00
f765dd64dd fix: CORE-5 GameStateChange Event can be fired without an actual change (#59)
Reviewed-on: #59
Reviewed-by: lq64 <lq@blackhole.local>
Co-authored-by: Janis <janis.e.20@gmx.de>
Co-committed-by: Janis <janis.e.20@gmx.de>
2025-12-03 12:14:36 +01:00
ef7397f7f1 fix(api): fixes (#58)
Reviewed-on: #58
2025-11-27 09:53:14 +01:00
d833932f16 feat(ui): Websocket (#57)
Started implementing functionality to the Websocket

Co-authored-by: LQ63 <lkhermann@web.de>
Reviewed-on: #57
2025-11-27 09:17:17 +01:00
c5dd02a5e8 fix(base)!: Fixed gamelogic, but it breaks current UI - required more attention (CORE-2). (#56)
Reviewed-on: #56
Co-authored-by: Janis <janis.e.20@gmx.de>
Co-committed-by: Janis <janis.e.20@gmx.de>
2025-11-26 11:27:58 +01:00
3048552f4c fix(base): COR-1 No Dog after vorletzte Runde (#55)
Reviewed-on: #55
Co-authored-by: Janis <janis.e.20@gmx.de>
Co-committed-by: Janis <janis.e.20@gmx.de>
2025-11-24 12:17:56 +01:00
ec94ecd46c fix(polling): Improve polling mechanism and delay handling (#54)
Reviewed-on: #54
2025-11-20 10:51:14 +01:00
20e8bae883 feat(game)!: Fixed polling, SPA, Gameplayloop etc. (#53)
Reviewed-on: #53
Co-authored-by: Janis <janis.e.20@gmx.de>
Co-committed-by: Janis <janis.e.20@gmx.de>
2025-11-19 22:53:48 +01:00
a5dcf3ee90 feat(game): implement tie resolution and enhance player interaction (#52)
43 [Subtask] UI looks better and improved

Reviewed-on: #52
Co-authored-by: Janis <janis.e.20@gmx.de>
Co-committed-by: Janis <janis.e.20@gmx.de>
2025-11-12 11:47:05 +01:00
b9a7b0a2af feat(user-sessions): enhance game lobby management with user session handling and game full exception (#51)
Reviewed-on: #51
Co-authored-by: Janis <janis.e.20@gmx.de>
Co-committed-by: Janis <janis.e.20@gmx.de>
2025-11-01 20:53:41 +01:00
fbc0ea2277 fix(ui): add light mode styles, update font families and fixed ui (#50)
Reviewed-on: #50
Co-authored-by: Janis <janis.e.20@gmx.de>
Co-committed-by: Janis <janis.e.20@gmx.de>
2025-10-28 19:06:52 +01:00
f998d5f6f0 fix(imports): reorganized import statements for clarity and consistency (#49)
Reviewed-on: #49
Co-authored-by: Janis <janis.e.20@gmx.de>
Co-committed-by: Janis <janis.e.20@gmx.de>
2025-10-26 18:09:45 +01:00
c5895f094b fix(base): fixed persistence logic (#48)
Fixed persistence logic for Trump Selection and Save File Loading

Reviewed-on: #48
Co-authored-by: Janis <janis.e.20@gmx.de>
Co-committed-by: Janis <janis.e.20@gmx.de>
2025-10-26 18:03:20 +01:00
51 changed files with 356 additions and 216 deletions

View File

@@ -33,7 +33,6 @@ object KnockOutWhist {
_config = Some(configuration)
val baseLogic = BaseGameLogic(configuration)
for (handler <- configuration.listener) baseLogic.addListener(handler)
ControlThread.start()
for (ui <- configuration.uis) {
if (!ui.initial(baseLogic)) throw new IllegalStateException(s"${ui.getClass.getName} could not be started.")
ui match {

View File

@@ -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] = {

View File

@@ -1,13 +1,9 @@
package de.knockoutwhist.control
import de.knockoutwhist.utils.CustomThread
object ControlThread {
object ControlThread extends CustomThread {
setName("ControlThread")
def isControlThread: Boolean = Thread.currentThread().equals(ControlThread)
override def instance: CustomThread = ControlThread
def runLater[R](op: => R): Unit = {
op
}
}

View File

@@ -13,8 +13,10 @@ trait GameLogic extends EventHandler with SnapshottingGameLogic {
def endSession(): Unit
def createMatch(players: List[AbstractPlayer]): Match
def controlMatch(): Unit
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
@@ -26,12 +28,15 @@ 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]]
}

View File

@@ -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))})
@@ -103,32 +105,46 @@ final class BaseGameLogic(val config: Configuration) extends EventHandler with G
matchImpl.playersIn.foreach(player => {invoke(ReceivedHandEvent(player))})
//Check if the last round had a winner
val lastRound = matchImpl.roundlist.last
if (lastRound.winner.isEmpty)
throw new IllegalStateException("Last round had no winner")
val lastWinner = lastRound.winner.get
//Create new player queue starting with last round winner
playerQueue = Some(config.createRightQueue(
matchImpl.playersIn.toArray,
matchImpl.playersIn.indexOf(lastWinner)
))
invoke(GameStateChangeEvent(state, SelectTrump))
state = SelectTrump
invoke(TrumpSelectEvent(lastWinner))
playerInputLogic.requestTrumpSuit(lastWinner)
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 = {
if (currentMatch.isEmpty) throw new IllegalStateException("No current match set")
val matchImpl = currentMatch.get
//Check if the last round had a winner
val lastWinner = getTrumpPlayer
if (lastWinner.isEmpty) throw new IllegalStateException("No last round winner found")
//Create new player queue starting with last round winner
playerQueue = Some(config.createRightQueue(
matchImpl.playersIn.toArray,
matchImpl.playersIn.indexOf(lastWinner.get)
))
changeState(SelectTrump)
invoke(TrumpSelectEvent(lastWinner.get))
playerInputLogic.requestTrumpSuit(lastWinner.get)
}
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")
@@ -139,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))
@@ -180,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(_)))
@@ -223,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()
@@ -290,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
@@ -300,8 +323,23 @@ final class BaseGameLogic(val config: Configuration) extends EventHandler with G
override def getCurrentTrick: Option[Trick] = currentTrick
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
if (matchImpl.roundlist.isEmpty) return None
val roundImpl = matchImpl.roundlist.last
if (roundImpl.winner.isEmpty) return None
Some(roundImpl.winner.get)
}
//Snapshotting
override def createSnapshot(): LogicSnapshot[BaseGameLogic.this.type] = {
@@ -309,8 +347,14 @@ final class BaseGameLogic(val config: Configuration) extends EventHandler with G
}
override def endSession(): Unit = {
//TODO Return to main menu
System.exit(0)
cardManager = None
currentMatch = None
currentRound = None
currentTrick = None
currentPlayer = None
playerQueue = None
invoke(SessionClosed())
changeState(MainMenu)
}
}

View File

@@ -2,12 +2,10 @@ package de.knockoutwhist.control.controllerBaseImpl.sublogic
import de.knockoutwhist.KnockOutWhist
import de.knockoutwhist.control.controllerBaseImpl.BaseGameLogic
import de.knockoutwhist.control.controllerBaseImpl.sublogic.BasePlayerTieLogic
import de.knockoutwhist.control.sublogic.{PersistenceManager, PlayerTieLogic}
import de.knockoutwhist.control.sublogic.PersistenceManager
import de.knockoutwhist.control.{GameLogic, LogicSnapshot}
import de.knockoutwhist.persistence.formats.JSONFormatter
import de.knockoutwhist.events.util.ReloadAllEvent
import de.knockoutwhist.persistence.{MatchSnapshot, MethodEntryPoint}
import de.knockoutwhist.rounds.{Match, Round, Trick}
class BasePersistenceManager(val gameLogic: BaseGameLogic) extends PersistenceManager {
@@ -29,6 +27,7 @@ class BasePersistenceManager(val gameLogic: BaseGameLogic) extends PersistenceMa
if currentSnapshot.entryPoint.isEmpty then
throw new IllegalStateException("Loaded snapshot does not contain an entry point!")
currentSnapshot.gameLogicSnapShot.foreach(_.restore(gameLogic))
gameLogic.invoke(ReloadAllEvent())
currentSnapshot.entryPoint.get match {
case MethodEntryPoint.ControlMatch =>
gameLogic.controlMatch()

View File

@@ -10,16 +10,20 @@ import de.knockoutwhist.player.AbstractPlayer
final class BasePlayerInputLogic(gameLogic: BaseGameLogic) extends PlayerInputLogic {
val TIME_TO_RESPOND: Int = 30 // seconds
private var _waitingForInput: Boolean = false
override def requestTrumpSuit(player: AbstractPlayer): Unit = {
_waitingForInput = true
gameLogic.invoke(RequestTrumpSuitEvent(player))
}
override def receivedTrumpSuit(suit: Suit): Unit = {
val newRound = RoundUtil.createRound(suit)
if (!_waitingForInput) throw new IllegalStateException("Not waiting for input")
_waitingForInput = false
val newRound = RoundUtil.createRound(suit)
gameLogic.currentRound = Some(newRound)
gameLogic.invoke(TrumpSelectedEvent(suit))
gameLogic.controlRound()
@@ -31,12 +35,14 @@ final class BasePlayerInputLogic(gameLogic: BaseGameLogic) extends PlayerInputLo
}
override def receivedCard(card: Card): Unit = {
if (!_waitingForInput) throw new IllegalStateException("Not waiting for input")
_waitingForInput = false
if (gameLogic.currentTrick.isEmpty) throw new IllegalStateException("No current trick set")
val trickImpl = gameLogic.currentTrick.get
if (gameLogic.currentPlayer.isEmpty) throw new IllegalStateException("No current player set")
val player = gameLogic.currentPlayer.get
_waitingForInput = false
val newTrick = if (trickImpl.firstCard.isEmpty) {
trickImpl
@@ -56,13 +62,14 @@ final class BasePlayerInputLogic(gameLogic: BaseGameLogic) extends PlayerInputLo
}
override def receivedDog(dog: Option[Card]): Unit = {
if (!_waitingForInput) throw new IllegalStateException("Not waiting for input")
_waitingForInput = false
if (gameLogic.currentTrick.isEmpty) throw new IllegalStateException("No current trick set")
val trickImpl = gameLogic.currentTrick.get
if (gameLogic.currentPlayer.isEmpty) throw new IllegalStateException("No current player set")
val player = gameLogic.currentPlayer.get
_waitingForInput = false
if (dog.isDefined) {
val newTrick = if (trickImpl.firstCard.isEmpty) {
trickImpl

View File

@@ -18,7 +18,7 @@ final class BasePlayerTieLogic(gameLogic: BaseGameLogic) extends PlayerTieLogic
private[control] var lastNumber = -1
private[control] var selectedCard: Map[AbstractPlayer, Card] = Map.empty
private var _waitingForInput: Boolean = false
override def handleTie(roundResult: RoundResult): Unit = {
this.roundResult = Some(roundResult)
tiedPlayers = roundResult.winners
@@ -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 = {
@@ -89,6 +91,9 @@ final class BasePlayerTieLogic(gameLogic: BaseGameLogic) extends PlayerTieLogic
* @param number the index of the selected card
*/
override def receivedTieBreakerCard(number: Int): Unit = {
if (!_waitingForInput) throw new IllegalStateException("Not waiting for input")
_waitingForInput = false
val player = tiedPlayers(tieBreakerIndex)
val highestNumber = highestAllowedNumber()
if (number < 0 || number > highestNumber)
@@ -96,8 +101,6 @@ final class BasePlayerTieLogic(gameLogic: BaseGameLogic) extends PlayerTieLogic
if (gameLogic.cardManager.isEmpty) throw new IllegalStateException("No card manager set")
_waitingForInput = false
val cardManager = gameLogic.cardManager.get
val card = cardManager.removeCards(number).last
selectedCard += (player -> card)
@@ -110,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

View File

@@ -5,17 +5,19 @@ import de.knockoutwhist.rounds.{Match, Round}
object MatchUtil {
private def remainingRounds(matchImpl: Match, roundImpl: Round): Int = {
//Find player with the most cards
// If no player has any cards left, there are no rounds remaining
if !matchImpl.playersIn
.map(player => player.currentHand()).exists(hand => hand.isDefined && hand.get.cards.nonEmpty) then return 0
// Otherwise, calculate remaining rounds based on number of cards and tricks played
matchImpl.numberofcards - roundImpl.tricklist.size
}
def isRoundOver(matchImpl: Match, roundImpl: Round): Boolean = {
//Find player with the most cards
remainingRounds(matchImpl, roundImpl) == 0
}
def dogNeedsToPlay(matchImpl: Match, roundImpl: Round): Boolean = {
remainingRounds(matchImpl, roundImpl) == 1
remainingRounds(matchImpl, roundImpl) <= 1
}
}

View File

@@ -34,4 +34,19 @@ object PlayerUtil {
Nil
}
def playableCards(round: Round, trick: Trick, player: AbstractPlayer): List[Card] = {
val handOption = player.currentHand()
if (handOption.isEmpty) {
throw new IllegalStateException("You have no cards!")
}
val hand = handOption.get
if (trick.firstCard.isEmpty) {
return hand.cards
}
val playableCards: List[Card] = for cardInHand <- hand.cards
if canPlayCard(cardInHand, round, trick, player)
yield cardInHand
playableCards
}
}

View File

@@ -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

View File

@@ -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"
}

View File

@@ -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"
}

View File

@@ -0,0 +1,7 @@
package de.knockoutwhist.events.global
import de.knockoutwhist.utils.events.SimpleEvent
case class SessionClosed() extends SimpleEvent {
override def id: String = s"SessionClosed"
}

View File

@@ -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"
}

View File

@@ -0,0 +1,7 @@
package de.knockoutwhist.events.util
import de.knockoutwhist.utils.events.SimpleEvent
case class ReloadAllEvent() extends SimpleEvent {
override def id: String = "ReloadAllEvent"
}

View File

@@ -2,22 +2,20 @@ package de.knockoutwhist.ui.gui
import atlantafx.base.theme.PrimerDark
import de.knockoutwhist.control.GameLogic
import de.knockoutwhist.control.GameState.{InGame, Lobby, MainMenu, TieBreak}
import de.knockoutwhist.events.global.tie.{TieShowPlayerCardsEvent, TieTieEvent, TieTurnEvent, TieWinningPlayersEvent}
import de.knockoutwhist.control.GameState.*
import de.knockoutwhist.events.global.*
import de.knockoutwhist.events.global.tie.{TieShowPlayerCardsEvent, TieTieEvent, TieTurnEvent, TieWinningPlayersEvent}
import de.knockoutwhist.events.player.{RequestCardEvent, RequestTieChoiceEvent, RequestTrumpSuitEvent}
import de.knockoutwhist.player.AbstractPlayer
import de.knockoutwhist.events.util.ReloadAllEvent
import de.knockoutwhist.ui.UI
import de.knockoutwhist.utils.CustomThread
import de.knockoutwhist.utils.events.{EventListener, SimpleEvent}
import javafx.application as jfxa
import scalafx.application.JFXApp3.PrimaryStage
import scalafx.application.{JFXApp3, Platform}
import scalafx.beans.property.ObjectProperty
import scalafx.scene.{Parent, Scene}
import scala.compiletime.uninitialized
import scala.util.Try
class GUIMain extends JFXApp3 with EventListener with UI {
@@ -66,11 +64,13 @@ class GUIMain extends JFXApp3 with EventListener with UI {
_tieMenu.changeSlider(logic.get.playerTieLogic.highestAllowedNumber())
case event: NewRoundEvent =>
_game.updateTrumpSuit(logic.get.getCurrentRound.get.trumpSuit)
case event: NewTrickEvent =>
_game.resetFirstCard()
case event: RoundEndEvent =>
_game.showWon(event.winner, event.amountOfTricks)
case event: TurnEvent =>
_game.updateStatus(event.player)
_game.updateNextPlayer(_logic.get.getPlayerQueue.get, _logic.get.getPlayerQueue.get.currentIndex)
case event: TieShowPlayerCardsEvent =>
val cards = logic.get.playerTieLogic.getSelectedCard
_tieMenu.addCutCards(cards.map((p, c) => (p, c)).toList)
@@ -81,18 +81,24 @@ class GUIMain extends JFXApp3 with EventListener with UI {
case event: TrumpSelectedEvent =>
_game.updateTrumpSuit(event.suit)
case event: RequestCardEvent =>
_game.updateNextPlayer(_logic.get.getPlayerQueue.get, _logic.get.getPlayerQueue.get.currentIndex)
_game.updateTrumpSuit(_logic.get.getCurrentRound.get.trumpSuit)
_game.updatePlayerCards(event.player)
_game.updatePlayedCards()
if (_logic.get.getCurrentTrick.get.firstCard.isDefined)
_game.updateFirstCard(_logic.get.getCurrentTrick.get.firstCard.get)
else
_game.resetFirstCard()
case event: RequestTieChoiceEvent =>
_tieMenu.showNeccessary()
case event: RequestTrumpSuitEvent =>
_pickTrumpsuit.showPickTrumpsuit(event.player)
case event: ReloadAllEvent =>
if (_logic.isEmpty) throw new Exception("Logic is not initialized!")
val logicImpl = _logic.get
if (logicImpl.getCurrentState == MainMenu)
_mainMenu.createMainMenu
else if (logicImpl.getCurrentState == Lobby)
_mainMenu.createPlayeramountmenu()
else if (logicImpl.getCurrentState == InGame)
_game.reloadAll()
else if (logicImpl.getCurrentState == TieBreak)
_tieMenu.reloadAll()
else if (logicImpl.getCurrentState == SelectTrump)
_pickTrumpsuit.reloadAll()
case _ => None
}
}

View File

@@ -29,6 +29,29 @@ import scala.collection.mutable.ListBuffer
class Game(gui: GUIMain) {
private[ui] def reloadAll(): Unit = {
if (gui.logic.isEmpty) throw new IllegalStateException("Logic is not initialized!")
val logic = gui.logic.get
if (logic.getCurrentRound.isEmpty) throw new IllegalStateException("No current round available!")
val currentRound = logic.getCurrentRound.get
if (logic.getCurrentTrick.isEmpty) throw new IllegalStateException("No current trick available!")
val currentTrick = logic.getCurrentTrick.get
if (logic.getCurrentPlayer.isEmpty) throw new IllegalStateException("No current player available!")
val currentPlayer = logic.getCurrentPlayer.get
updateStatus(currentPlayer)
updateNextPlayer(logic.getPlayerQueue.get, logic.getPlayerQueue.get.currentIndex)
updatePlayedCards()
if (currentTrick.firstCard.isDefined) {
updateFirstCard(currentTrick.firstCard.get)
} else {
resetFirstCard()
}
updateTrumpSuit(currentRound.trumpSuit)
updatePlayerCards(currentPlayer)
createGame()
}
private val statusLabel: Label = new Label {
alignment = Center

View File

@@ -1,6 +1,5 @@
package de.knockoutwhist.ui.gui
import de.knockoutwhist.KnockOutWhist
import de.knockoutwhist.cards.Suit
import de.knockoutwhist.control.ControlThread
import de.knockoutwhist.player.AbstractPlayer
@@ -15,10 +14,21 @@ import scalafx.scene.layout.{HBox, StackPane, VBox}
import scalafx.scene.text.Font
import scalafx.util.Duration
import scala.util.Try
class PickTrumsuit(gui: GUIMain) {
private[ui] def reloadAll(): Unit = {
if (gui.logic.isEmpty) throw new IllegalStateException("Logic is not initialized!")
val logic = gui.logic.get
if (logic.getCurrentMatch.isEmpty) throw new IllegalStateException("No current match set")
val matchImpl = logic.getCurrentMatch.get
//Check if the last round had a winner
val lastRound = matchImpl.roundlist.last
if (lastRound.winner.isEmpty)
throw new IllegalStateException("Last round had no winner")
val lastWinner = lastRound.winner.get
showPickTrumpsuit(lastWinner)
}
def showPickTrumpsuit(player: AbstractPlayer): Unit = {
if (gui.logic.isEmpty) throw new IllegalStateException("Game logic is not initialized in GUI")
val logicImpl = gui.logic.get

View File

@@ -1,22 +1,18 @@
package de.knockoutwhist.ui.gui
import atlantafx.base.theme.Styles
import de.knockoutwhist.KnockOutWhist
import de.knockoutwhist.cards.Card
import de.knockoutwhist.control.{ControlThread, GameLogic}
import de.knockoutwhist.events.global.tie.{TieTieEvent, TieWinningPlayersEvent}
import de.knockoutwhist.player.AbstractPlayer
import de.knockoutwhist.rounds.{Match, Round}
import de.knockoutwhist.undo.commands.SelectTieNumberCommand
import de.knockoutwhist.utils.gui.Animations
import javafx.scene.layout.{BackgroundImage, BackgroundPosition, BackgroundRepeat, BackgroundSize}
import scalafx.animation.Timeline
import scalafx.geometry.Insets
import scalafx.geometry.Pos.{BottomCenter, Center, TopCenter}
import scalafx.geometry.Pos.{BottomCenter, TopCenter}
import scalafx.scene.control.{Button, Label, Slider}
import scalafx.scene.image.{Image, ImageView}
import scalafx.scene.image.ImageView
import scalafx.scene.layout.*
import scalafx.scene.layout.Priority.Always
import scalafx.scene.text.Font
import scalafx.scene.{Node, Parent, layout}
import scalafx.util.Duration
@@ -24,9 +20,20 @@ import scalafx.util.Duration
import scala.collection.immutable
import scala.collection.mutable.ListBuffer
import scala.compiletime.uninitialized
import scala.util.Try
class TieMenu(gui: GUIMain) {
private[ui] def reloadAll(): Unit = {
if (gui.logic.isEmpty) throw new IllegalStateException("Logic is not initialized!")
val logic = gui.logic.get
val player = logic.playerTieLogic.currentTiePlayer().get
updatePlayerLabel(player)
changeSlider(logic.playerTieLogic.highestAllowedNumber())
showNeccessary()
spawnTieMain()
}
private def logic: GameLogic = {
gui.logic.get

View File

@@ -412,6 +412,20 @@ class TUIMain extends CustomThread with EventListener with UI {
}
private def reqpicktevmet(event: RequestTrumpSuitEvent): Option[Boolean] = {
println(s"${event.player.name}, please select a trump suit:")
println("1. Hearts")
println("2. Diamonds")
println("3. Clubs")
println("4. Spades")
println()
println("Your cards are:")
if (event.player.currentHand().isEmpty) {
println("You have no cards! This should not happen.")
return Some(true)
}
val hand = event.player.currentHand().get
TUICards.renderHandEvent(hand, false).foreach(println(_))
println()
val trySuit = Try {
val suit = input().toInt
suit match {

View File

@@ -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)
}
}
}

View File

@@ -26,7 +26,7 @@ case class SelectTrumpSuitCommand[
glSnapshot.restore(gameLogic.asInstanceOf[GL])
ptlSnapshot.restore(gameLogic.playerTieLogic.asInstanceOf[PT])
ControlThread.runLater {
gameLogic.controlMatch()
gameLogic.controlPreRound()
}
}
}

View File

@@ -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 _ =>
}
}

View File

@@ -1,7 +1,7 @@
package de.knockoutwhist.cards
import org.scalatest.wordspec.AnyWordSpec
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec
class HandSpec extends AnyWordSpec with Matchers {

View File

@@ -1,8 +1,8 @@
package de.knockoutwhist.cards.base
import org.scalatest.wordspec.AnyWordSpec
import de.knockoutwhist.cards.*
import org.scalatest.matchers.should.Matchers
import de.knockoutwhist.cards._
import org.scalatest.wordspec.AnyWordSpec
class CardBaseManagerSpec extends AnyWordSpec with Matchers {

View File

@@ -1,14 +1,14 @@
package de.knockoutwhist.control.controllerBaseImpl
import org.scalatest.wordspec.AnyWordSpec
import org.scalatest.matchers.should.Matchers
import de.knockoutwhist.components.Configuration
import de.knockoutwhist.cards.base.CardBaseManager
import de.knockoutwhist.cards.{Card, CardValue, Suit}
import de.knockoutwhist.components.Configuration
import de.knockoutwhist.persistence.formats.FileFormatter
import de.knockoutwhist.player.{AbstractPlayer, PlayerFactory, Playertype}
import de.knockoutwhist.utils.baseQueue.CustomPlayerBaseQueue
import de.knockoutwhist.cards.{Card, CardValue, Suit}
import de.knockoutwhist.rounds.{Round, Trick}
import de.knockoutwhist.utils.baseQueue.CustomPlayerBaseQueue
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec
class BaseGameLogicControlPlayerPlaySpec extends AnyWordSpec with Matchers {

View File

@@ -1,14 +1,14 @@
package de.knockoutwhist.control.controllerBaseImpl
import org.scalatest.wordspec.AnyWordSpec
import org.scalatest.matchers.should.Matchers
import de.knockoutwhist.components.Configuration
import de.knockoutwhist.cards.base.CardBaseManager
import de.knockoutwhist.cards.{Card, CardValue, Suit}
import de.knockoutwhist.components.Configuration
import de.knockoutwhist.persistence.formats.FileFormatter
import de.knockoutwhist.player.{AbstractPlayer, PlayerFactory, Playertype}
import de.knockoutwhist.utils.baseQueue.CustomPlayerBaseQueue
import de.knockoutwhist.cards.{Card, CardValue, Suit}
import de.knockoutwhist.rounds.{Round, Trick}
import de.knockoutwhist.utils.baseQueue.CustomPlayerBaseQueue
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec
class BaseGameLogicEndRoundSpec extends AnyWordSpec with Matchers {

View File

@@ -1,14 +1,14 @@
package de.knockoutwhist.control.controllerBaseImpl
import org.scalatest.wordspec.AnyWordSpec
import org.scalatest.matchers.should.Matchers
import de.knockoutwhist.components.Configuration
import de.knockoutwhist.cards.base.CardBaseManager
import de.knockoutwhist.cards.{Card, CardValue, Suit}
import de.knockoutwhist.components.Configuration
import de.knockoutwhist.persistence.formats.FileFormatter
import de.knockoutwhist.player.{AbstractPlayer, PlayerFactory, Playertype}
import de.knockoutwhist.utils.baseQueue.CustomPlayerBaseQueue
import de.knockoutwhist.cards.{Card, CardValue, Suit}
import de.knockoutwhist.rounds.{Round, Trick}
import de.knockoutwhist.utils.baseQueue.CustomPlayerBaseQueue
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec
class BaseGameLogicMoreSpec extends AnyWordSpec with Matchers {

View File

@@ -1,16 +1,17 @@
package de.knockoutwhist.control.controllerBaseImpl
import org.scalatest.wordspec.AnyWordSpec
import org.scalatest.matchers.should.Matchers
import de.knockoutwhist.components.Configuration
import de.knockoutwhist.persistence.formats.FileFormatter
import de.knockoutwhist.cards.base.CardBaseManager
import de.knockoutwhist.player.{StubPlayer, AbstractPlayer}
import de.knockoutwhist.utils.baseQueue.CustomPlayerBaseQueue
import de.knockoutwhist.rounds.Trick
import de.knockoutwhist.cards.{Card, CardValue, Suit}
import scala.collection.immutable.HashMap
import de.knockoutwhist.components.Configuration
import de.knockoutwhist.control.controllerBaseImpl.sublogic.util.{ResultPlayer, RoundResult}
import de.knockoutwhist.persistence.formats.FileFormatter
import de.knockoutwhist.player.{AbstractPlayer, StubPlayer}
import de.knockoutwhist.rounds.Trick
import de.knockoutwhist.utils.baseQueue.CustomPlayerBaseQueue
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec
import scala.collection.immutable.HashMap
class BaseGameLogicRoundTrickSpec extends AnyWordSpec with Matchers {

View File

@@ -1,14 +1,13 @@
package de.knockoutwhist.control.controllerBaseImpl
import org.scalatest.wordspec.AnyWordSpec
import org.scalatest.matchers.should.Matchers
import de.knockoutwhist.components.Configuration
import de.knockoutwhist.cards.base.CardBaseManager
import de.knockoutwhist.persistence.formats.FileFormatter
import de.knockoutwhist.player.{PlayerFactory, Playertype}
import de.knockoutwhist.player.AbstractPlayer
import de.knockoutwhist.utils.baseQueue.CustomPlayerBaseQueue
import de.knockoutwhist.components.Configuration
import de.knockoutwhist.control.GameState
import de.knockoutwhist.persistence.formats.FileFormatter
import de.knockoutwhist.player.{AbstractPlayer, PlayerFactory, Playertype}
import de.knockoutwhist.utils.baseQueue.CustomPlayerBaseQueue
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec
class BaseGameLogicSpec extends AnyWordSpec with Matchers {

View File

@@ -1,13 +1,13 @@
package de.knockoutwhist.control.controllerBaseImpl
import org.scalatest.wordspec.AnyWordSpec
import org.scalatest.matchers.should.Matchers
import de.knockoutwhist.components.Configuration
import de.knockoutwhist.cards.base.CardBaseManager
import de.knockoutwhist.components.Configuration
import de.knockoutwhist.control.GameState
import de.knockoutwhist.persistence.formats.FileFormatter
import de.knockoutwhist.player.AbstractPlayer
import de.knockoutwhist.utils.baseQueue.CustomPlayerBaseQueue
import de.knockoutwhist.control.GameState
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec
class BaseGameLogicStateSpec extends AnyWordSpec with Matchers {

View File

@@ -1,14 +1,14 @@
package de.knockoutwhist.control.controllerBaseImpl.sublogic
import org.scalatest.wordspec.AnyWordSpec
import org.scalatest.matchers.should.Matchers
import de.knockoutwhist.cards.base.CardBaseManager
import de.knockoutwhist.components.Configuration
import de.knockoutwhist.control.controllerBaseImpl.BaseGameLogic
import de.knockoutwhist.persistence.MethodEntryPoint
import de.knockoutwhist.persistence.formats.FileFormatter
import de.knockoutwhist.cards.base.CardBaseManager
import de.knockoutwhist.player.AbstractPlayer
import de.knockoutwhist.utils.baseQueue.CustomPlayerBaseQueue
import de.knockoutwhist.control.controllerBaseImpl.BaseGameLogic
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec
class BasePersistenceManagerSpec extends AnyWordSpec with Matchers {

View File

@@ -1,17 +1,16 @@
package de.knockoutwhist.control.controllerBaseImpl.sublogic
import de.knockoutwhist.cards.Suit.Spades
import org.scalatest.wordspec.AnyWordSpec
import org.scalatest.matchers.should.Matchers
import de.knockoutwhist.components.Configuration
import de.knockoutwhist.persistence.formats.FileFormatter
import de.knockoutwhist.cards.base.CardBaseManager
import de.knockoutwhist.control.controllerBaseImpl.BaseGameLogic
import de.knockoutwhist.player.StubPlayer
import de.knockoutwhist.player.AbstractPlayer
import de.knockoutwhist.utils.baseQueue.CustomPlayerBaseQueue
import de.knockoutwhist.rounds.{Round, Trick}
import de.knockoutwhist.cards.{Card, CardValue, Suit}
import de.knockoutwhist.components.Configuration
import de.knockoutwhist.control.controllerBaseImpl.BaseGameLogic
import de.knockoutwhist.persistence.formats.FileFormatter
import de.knockoutwhist.player.{AbstractPlayer, StubPlayer}
import de.knockoutwhist.rounds.{Round, Trick}
import de.knockoutwhist.utils.baseQueue.CustomPlayerBaseQueue
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec
import scala.collection.immutable.HashMap

View File

@@ -1,14 +1,13 @@
package de.knockoutwhist.control.controllerBaseImpl.sublogic
import org.scalatest.wordspec.AnyWordSpec
import org.scalatest.matchers.should.Matchers
import de.knockoutwhist.components.Configuration
import de.knockoutwhist.persistence.formats.FileFormatter
import de.knockoutwhist.cards.base.CardBaseManager
import de.knockoutwhist.components.Configuration
import de.knockoutwhist.control.controllerBaseImpl.BaseGameLogic
import de.knockoutwhist.player.StubPlayer
import de.knockoutwhist.player.AbstractPlayer
import de.knockoutwhist.persistence.formats.FileFormatter
import de.knockoutwhist.player.{AbstractPlayer, StubPlayer}
import de.knockoutwhist.utils.baseQueue.CustomPlayerBaseQueue
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec
class BasePlayerInputLogicSpec extends AnyWordSpec with Matchers {

View File

@@ -1,16 +1,15 @@
package de.knockoutwhist.control.controllerBaseImpl.sublogic
import org.scalatest.wordspec.AnyWordSpec
import org.scalatest.matchers.should.Matchers
import de.knockoutwhist.control.controllerBaseImpl.BaseGameLogic
import de.knockoutwhist.components.Configuration
import de.knockoutwhist.cards.base.CardBaseManager
import de.knockoutwhist.persistence.formats.FileFormatter
import de.knockoutwhist.player.StubPlayer
import de.knockoutwhist.control.controllerBaseImpl.sublogic.util.RoundResult
import de.knockoutwhist.player.AbstractPlayer
import de.knockoutwhist.utils.baseQueue.CustomPlayerBaseQueue
import de.knockoutwhist.cards.{Card, CardValue, Suit}
import de.knockoutwhist.components.Configuration
import de.knockoutwhist.control.controllerBaseImpl.BaseGameLogic
import de.knockoutwhist.control.controllerBaseImpl.sublogic.util.RoundResult
import de.knockoutwhist.persistence.formats.FileFormatter
import de.knockoutwhist.player.{AbstractPlayer, StubPlayer}
import de.knockoutwhist.utils.baseQueue.CustomPlayerBaseQueue
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec
class BasePlayerTieLogicSpec extends AnyWordSpec with Matchers {
@@ -53,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))
}

View File

@@ -1,15 +1,16 @@
package de.knockoutwhist.control.controllerBaseImpl.sublogic
import org.scalatest.wordspec.AnyWordSpec
import org.scalatest.matchers.should.Matchers
import de.knockoutwhist.control.controllerBaseImpl.BaseGameLogic
import de.knockoutwhist.components.Configuration
import de.knockoutwhist.persistence.formats.FileFormatter
import de.knockoutwhist.cards.base.CardBaseManager
import de.knockoutwhist.components.Configuration
import de.knockoutwhist.control.controllerBaseImpl.BaseGameLogic
import de.knockoutwhist.persistence.formats.FileFormatter
import de.knockoutwhist.player.AbstractPlayer
import de.knockoutwhist.utils.baseQueue.CustomPlayerBaseQueue
import java.util.concurrent.atomic.AtomicInteger
import de.knockoutwhist.undo.Command
import de.knockoutwhist.utils.baseQueue.CustomPlayerBaseQueue
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec
import java.util.concurrent.atomic.AtomicInteger
class BaseUndoManagerSpec extends AnyWordSpec with Matchers {

View File

@@ -1,10 +1,10 @@
package de.knockoutwhist.control.controllerBaseImpl.sublogic.util
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec
import de.knockoutwhist.cards.Suit
import de.knockoutwhist.player.{PlayerFactory, Playertype}
import de.knockoutwhist.rounds.{Match, Round, Trick}
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec
class MatchUtilSpec extends AnyWordSpec with Matchers {

View File

@@ -1,10 +1,10 @@
package de.knockoutwhist.control.controllerBaseImpl.sublogic.util
import org.scalatest.wordspec.AnyWordSpec
import org.scalatest.matchers.should.Matchers
import de.knockoutwhist.cards.{Card, CardValue, Hand, Suit}
import de.knockoutwhist.rounds.{Round, Trick}
import de.knockoutwhist.player.StubPlayer
import de.knockoutwhist.rounds.{Round, Trick}
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec
class PlayerUtilSpec extends AnyWordSpec with Matchers {

View File

@@ -1,10 +1,10 @@
package de.knockoutwhist.control.controllerBaseImpl.sublogic.util
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec
import de.knockoutwhist.cards.{Card, CardValue, Suit}
import de.knockoutwhist.player.{PlayerFactory, Playertype}
import de.knockoutwhist.rounds.{Match, Round, Trick}
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec
class RoundUtilSpec extends AnyWordSpec with Matchers {

View File

@@ -1,14 +1,14 @@
package de.knockoutwhist.control.controllerBaseImpl.sublogic.util
import org.scalatest.wordspec.AnyWordSpec
import org.scalatest.matchers.should.Matchers
import de.knockoutwhist.components.Configuration
import de.knockoutwhist.cards.base.CardBaseManager
import de.knockoutwhist.persistence.formats.FileFormatter
import de.knockoutwhist.components.Configuration
import de.knockoutwhist.control.controllerBaseImpl.{BaseGameLogic, BaseGameLogicSnapshot}
import de.knockoutwhist.player.{AbstractPlayer, PlayerFactory, Playertype}
import de.knockoutwhist.control.{GameLogic, GameState, SnapshottingGameLogic}
import de.knockoutwhist.persistence.formats.FileFormatter
import de.knockoutwhist.player.{AbstractPlayer, PlayerFactory, Playertype}
import de.knockoutwhist.utils.baseQueue.CustomPlayerBaseQueue
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec
class SnapshotUtilSpec extends AnyWordSpec with Matchers {

View File

@@ -1,11 +1,11 @@
package de.knockoutwhist.control.controllerBaseImpl.sublogic.util
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec
import de.knockoutwhist.cards.{Card, CardValue, Suit}
import de.knockoutwhist.player.{PlayerFactory, Playertype}
import de.knockoutwhist.rounds.{Match, Round, Trick}
import de.knockoutwhist.utils.baseQueue.CustomPlayerBaseQueue
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec
class TrickUtilSpec extends AnyWordSpec with Matchers {

View File

@@ -1,9 +1,9 @@
package de.knockoutwhist.persistence.formats
import org.scalatest.wordspec.AnyWordSpec
import org.scalatest.matchers.should.Matchers
import de.knockoutwhist.cards.{Card, CardValue, Hand, Suit}
import de.knockoutwhist.player.Playertype
import de.knockoutwhist.cards.{Card, CardValue, Suit, Hand}
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec
import java.util.UUID

View File

@@ -1,11 +1,11 @@
package de.knockoutwhist.persistence.formats
import org.scalatest.wordspec.AnyWordSpec
import org.scalatest.matchers.should.Matchers
import play.api.libs.json._
import de.knockoutwhist.persistence._
import de.knockoutwhist.control.GameState
import de.knockoutwhist.cards.{CardValue, Suit}
import de.knockoutwhist.control.GameState
import de.knockoutwhist.persistence.*
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec
import play.api.libs.json.*
import java.util.UUID

View File

@@ -1,15 +1,12 @@
package de.knockoutwhist.persistence.formats
import org.scalatest.wordspec.AnyWordSpec
import org.scalatest.matchers.should.Matchers
import de.knockoutwhist.components.Configuration
import de.knockoutwhist.persistence.MatchSnapshot
import de.knockoutwhist.persistence.MethodEntryPoint
import de.knockoutwhist.cards.base.CardBaseManager
import de.knockoutwhist.player.PlayerFactory
import de.knockoutwhist.player.Playertype
import de.knockoutwhist.components.Configuration
import de.knockoutwhist.control.controllerBaseImpl.BaseGameLogic
import de.knockoutwhist.player.AbstractPlayer
import de.knockoutwhist.persistence.{MatchSnapshot, MethodEntryPoint}
import de.knockoutwhist.player.{AbstractPlayer, PlayerFactory, Playertype}
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec
class JSONFormatterRoundtripSpec extends AnyWordSpec with Matchers {

View File

@@ -1,8 +1,8 @@
package de.knockoutwhist.persistence.formats
import org.scalatest.wordspec.AnyWordSpec
import org.scalatest.matchers.should.Matchers
import de.knockoutwhist.persistence.*
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec
class JSONFormatterSpec extends AnyWordSpec with Matchers {

View File

@@ -1,8 +1,8 @@
package de.knockoutwhist.player
import org.scalatest.wordspec.AnyWordSpec
import de.knockoutwhist.cards.{Card, CardValue, Hand, Suit}
import org.scalatest.matchers.should.Matchers
import de.knockoutwhist.cards.{Card, CardValue, Suit, Hand}
import org.scalatest.wordspec.AnyWordSpec
import java.util.UUID

View File

@@ -1,9 +1,9 @@
package de.knockoutwhist.player
import org.scalatest.wordspec.AnyWordSpec
import org.scalatest.matchers.should.Matchers
import de.knockoutwhist.cards.{Card, CardValue, Hand, Suit}
import de.knockoutwhist.player.baseImpl.HumanPlayer
import de.knockoutwhist.cards.{Card, CardValue, Suit, Hand}
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec
class HumanPlayerSpec extends AnyWordSpec with Matchers {

View File

@@ -1,7 +1,7 @@
package de.knockoutwhist.player
import org.scalatest.wordspec.AnyWordSpec
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec
import java.util.UUID

View File

@@ -1,9 +1,9 @@
package de.knockoutwhist.rounds
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec
import de.knockoutwhist.cards.{Card, CardValue, Suit}
import de.knockoutwhist.player.{PlayerFactory, Playertype}
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec
class RoundsDataSpec extends AnyWordSpec with Matchers {

View File

@@ -1,8 +1,8 @@
package de.knockoutwhist.utils.baseQueue
import org.scalatest.wordspec.AnyWordSpec
import org.scalatest.matchers.should.Matchers
import de.knockoutwhist.player.StubPlayer
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec
class CustomPlayerBaseQueueSpec extends AnyWordSpec with Matchers {