feat!: implemented multigame support #34

Merged
Janis merged 16 commits from feat/5-create-user-sessions into main 2025-11-01 20:53:23 +01:00
37 changed files with 2255 additions and 110 deletions
Showing only changes of commit f4f886727f - Show all commits

View File

@@ -1,13 +1,12 @@
package components package components
import controllers.WebUI
import de.knockoutwhist.components.DefaultConfiguration import de.knockoutwhist.components.DefaultConfiguration
import de.knockoutwhist.ui.UI import de.knockoutwhist.ui.UI
import de.knockoutwhist.utils.events.EventListener import de.knockoutwhist.utils.events.EventListener
class WebApplicationConfiguration extends DefaultConfiguration { class WebApplicationConfiguration extends DefaultConfiguration {
override def uis: Set[UI] = super.uis + WebUI override def uis: Set[UI] = Set()
override def listener: Set[EventListener] = super.listener + WebUI override def listener: Set[EventListener] = Set()
} }

View File

@@ -7,7 +7,7 @@ import de.knockoutwhist.control.GameState.{InGame, Lobby, SelectTrump, TieBreak}
import de.knockoutwhist.control.controllerBaseImpl.BaseGameLogic import de.knockoutwhist.control.controllerBaseImpl.BaseGameLogic
import di.KnockOutWebConfigurationModule import di.KnockOutWebConfigurationModule
import logic.PodGameManager import logic.PodGameManager
import model.sessions.AdvancedSession import model.sessions.SimpleSession
import play.api.mvc.* import play.api.mvc.*
import play.api.* import play.api.*
import play.twirl.api.Html import play.twirl.api.Html
@@ -61,8 +61,8 @@ class HomeController @Inject()(val controllerComponents: ControllerComponents) e
} }
} else { } else {
val session = PodGameManager.identify(uuid).get val session = PodGameManager.identify(uuid).get
val player = session.asInstanceOf[AdvancedSession].player val player = session.asInstanceOf[SimpleSession].player
val logic = WebUI.logic.get.asInstanceOf[BaseGameLogic] val logic = null
if (logic.getCurrentState == Lobby) { if (logic.getCurrentState == Lobby) {
} else if (logic.getCurrentState == InGame) { } else if (logic.getCurrentState == InGame) {

View File

@@ -8,7 +8,7 @@ import de.knockoutwhist.control.controllerBaseImpl.BaseGameLogic
import di.KnockOutWebConfigurationModule import di.KnockOutWebConfigurationModule
import logic.PodGameManager import logic.PodGameManager
import logic.user.{SessionManager, UserManager} import logic.user.{SessionManager, UserManager}
import model.sessions.AdvancedSession import model.sessions.SimpleSession
import play.api.* import play.api.*
import play.api.mvc.* import play.api.mvc.*
import play.twirl.api.Html import play.twirl.api.Html

View File

@@ -1,50 +0,0 @@
package controllers
import de.knockoutwhist.cards.{Card, CardValue, Hand, Suit}
import de.knockoutwhist.control.GameLogic
import de.knockoutwhist.control.GameState.{InGame, Lobby}
import de.knockoutwhist.control.controllerBaseImpl.BaseGameLogic
import de.knockoutwhist.events.*
import de.knockoutwhist.events.global.GameStateChangeEvent
import de.knockoutwhist.player.AbstractPlayer
import de.knockoutwhist.rounds.Match
import de.knockoutwhist.ui.UI
import de.knockoutwhist.utils.CustomThread
import de.knockoutwhist.utils.events.{EventListener, SimpleEvent}
import logic.PodGameManager
import model.sessions.AdvancedSession
object WebUI extends CustomThread with EventListener with UI {
setName("WebUI")
var init = false
var logic: Option[GameLogic] = None
var latestOutput: String = ""
override def instance: CustomThread = WebUI
override def listen(event: SimpleEvent): Unit = {
event match {
case event: GameStateChangeEvent =>
if (event.oldState == Lobby && event.newState == InGame) {
val match1: Option[Match] = logic.get.asInstanceOf[BaseGameLogic].getCurrentMatch
val players: List[AbstractPlayer] = match1.get.totalplayers
players.map(player => PodGameManager.addSession(AdvancedSession(player.id, player)))
}
case _ =>
}
}
override def initial(gameLogic: GameLogic): Boolean = {
if (init) {
return false
}
init = true
this.logic = Some(gameLogic)
start()
true
}
}

View File

@@ -0,0 +1,14 @@
package model.game
import de.knockoutwhist.control.GameLogic
import de.knockoutwhist.utils.events.{EventListener, SimpleEvent}
class GameLobby(val logic: GameLogic) extends EventListener{
logic.addListener(this)
logic.createSession()
override def listen(event: SimpleEvent): Unit = {
}
}

View File

@@ -1,5 +1,6 @@
package model.sessions package model.sessions
import de.knockoutwhist.player.AbstractPlayer
import de.knockoutwhist.utils.events.SimpleEvent import de.knockoutwhist.utils.events.SimpleEvent
import java.util.UUID import java.util.UUID
@@ -8,6 +9,7 @@ trait PlayerSession {
def id: UUID def id: UUID
def name: String def name: String
def player: AbstractPlayer
def updatePlayer(event: SimpleEvent): Unit def updatePlayer(event: SimpleEvent): Unit
} }

View File

@@ -5,7 +5,7 @@ import de.knockoutwhist.utils.events.SimpleEvent
import java.util.UUID import java.util.UUID
case class AdvancedSession(id: UUID, player: AbstractPlayer) extends PlayerSession { case class SimpleSession(id: UUID, player: AbstractPlayer) extends PlayerSession {
def name: String = player.name def name: String = player.name

View File

@@ -0,0 +1,8 @@
package model.sessions
import de.knockoutwhist.player.AbstractPlayer
import java.util.UUID
class UserSession(id: UUID, player: AbstractPlayer) extends SimpleSession(id, player) {
}

View File

@@ -0,0 +1,29 @@
package util
import scala.util.Random
object GameUtil {
private val CharPool: String = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
private val CodeLength: Int = 6
private val MaxRepetition: Int = 2
private val random = new Random()
def generateCode(): String = {
val freq = Array.fill(CharPool.length)(0)
val code = new StringBuilder(CodeLength)
for (_ <- 0 until CodeLength) {
var index = random.nextInt(CharPool.length)
// Pick a new character if it's already used twice
while (freq(index) >= MaxRepetition) {
index = random.nextInt(CharPool.length)
}
freq(index) += 1
code.append(CharPool.charAt(index))
}
code.toString()
}
}