4 Commits

Author SHA1 Message Date
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
44 changed files with 292 additions and 183 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

@@ -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,6 +13,7 @@ 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 controlTrick(): Unit
@@ -32,6 +33,7 @@ trait GameLogic extends EventHandler with SnapshottingGameLogic {
def getCurrentRound: Option[Round]
def getCurrentTrick: Option[Trick]
def getCurrentPlayer: Option[AbstractPlayer]
def getTrumpPlayer: Option[AbstractPlayer]
def getPlayerQueue: Option[CustomPlayerQueue[AbstractPlayer]]
}

View File

@@ -103,28 +103,33 @@ 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 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)
))
invoke(GameStateChangeEvent(state, SelectTrump))
state = SelectTrump
invoke(TrumpSelectEvent(lastWinner.get))
playerInputLogic.requestTrumpSuit(lastWinner.get)
}
override def controlRound(): Unit = {
if (state != InGame)
invoke(GameStateChangeEvent(state, InGame))
@@ -301,7 +306,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 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 +321,15 @@ 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())
invoke(GameStateChangeEvent(state, MainMenu))
state = 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

@@ -89,6 +89,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 +99,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)

View File

@@ -5,12 +5,14 @@ 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
}

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

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

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

@@ -30,6 +30,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
textAlignment = TextAlignment.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,10 +20,21 @@ 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()
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 SelectTrumpSuitCommand[
glSnapshot.restore(gameLogic.asInstanceOf[GL])
ptlSnapshot.restore(gameLogic.playerTieLogic.asInstanceOf[PT])
ControlThread.runLater {
gameLogic.controlMatch()
gameLogic.controlPreRound()
}
}
}

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 {

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 {