feat(ui): UI now shows player names instead of their id (#11)

Reviewed-on: #11
This commit is contained in:
2025-10-23 08:17:11 +02:00
parent ccf44ede41
commit c168ae7dc0
6 changed files with 10 additions and 264 deletions

View File

@@ -44,7 +44,7 @@ class HomeController @Inject()(val controllerComponents: ControllerComponents) e
def sessions(): Action[AnyContent] = {
Action { implicit request =>
Ok(views.html.sessions.apply(PodGameManager.listSessions().map(f => f.toString)))
Ok(views.html.sessions.apply(PodGameManager.listSessions()))
}
}

View File

@@ -30,8 +30,8 @@ object PodGameManager {
sessions.foreach(session => session._2.updatePlayer(event))
}
def listSessions(): List[UUID] = {
sessions.keys.toList
def listSessions(): List[PlayerSession] = {
sessions.values.toList
}
}

View File

@@ -6,6 +6,9 @@ import de.knockoutwhist.utils.events.SimpleEvent
import java.util.UUID
case class AdvancedSession(id: UUID, player: AbstractPlayer) extends PlayerSession {
def name: String = player.name
override def updatePlayer(event: SimpleEvent): Unit = {
}
}

View File

@@ -7,6 +7,7 @@ import java.util.UUID
trait PlayerSession {
def id: UUID
def name: String
def updatePlayer(event: SimpleEvent): Unit
}

View File

@@ -1,258 +0,0 @@
package controllers.sessions
import de.knockoutwhist.cards.{Card, CardValue, Hand}
import de.knockoutwhist.player.AbstractPlayer
import de.knockoutwhist.utils.events.SimpleEvent
import play.twirl.api.Html
import scalafx.scene.image.Image
import util.WebUIUtils
import java.util.UUID
case class SimpleSession(id: UUID, private var output: List[Html]) extends PlayerSession {
override def updatePlayer(event: SimpleEvent): Unit = {
}
/*
def get(): List[Html] = {
output
}
override def updatePlayer(event: SimpleEvent): Unit = {
event match {
case event: RenderHandEvent =>
renderHand(event)
case event: ShowTieCardsEvent =>
showtiecardseventmethod(event)
case event: ShowGlobalStatus =>
showglobalstatusmethod(event)
case event: ShowPlayerStatus =>
showplayerstatusmethod(event)
case event: ShowRoundStatus =>
showroundstatusmethod(event)
case event: ShowErrorStatus =>
showerrstatmet(event)
case event: ShowCurrentTrickEvent =>
showcurtrevmet(event)
}
}
private def clear(): Unit = {
output = List()
}
private def renderHand(event: RenderHandEvent): Unit = {
output = output :++ WebUICards.renderHandEvent(event.hand)
output = output :+ Html("<br>")
}
private def showtiecardseventmethod(event: ShowTieCardsEvent): Option[Boolean] = {
var l = List[Html]()
for ((player, card) <- event.card) {
l = l :+ Html(s"<p>${player.name}:</p>")
l = l :+ WebUIUtils.cardtoImage(card)
l = l :+ Html("<br>")
}
output = output :++ l
output = output :+ Html("<br>")
Some(true)
}
private def showglobalstatusmethod(event: ShowGlobalStatus): Option[Boolean] = {
event.status match {
case SHOW_TIE =>
println("It's a tie! Let's cut to determine the winner.")
Some(true)
case SHOW_TIE_WINNER =>
if (event.objects.length != 1 || !event.objects.head.isInstanceOf[AbstractPlayer]) {
None
} else {
println(s"${event.objects.head.asInstanceOf[AbstractPlayer].name} wins the cut!")
Some(true)
}
case SHOW_TIE_TIE =>
println("It's a tie again! Let's cut again.")
Some(true)
case SHOW_START_MATCH =>
clear()
println("Starting a new match...")
output = output :+ Html("<br><br>")
Some(true)
case SHOW_TYPE_PLAYERS =>
println("Please enter the names of the players, separated by a comma.")
Some(true)
case SHOW_FINISHED_MATCH =>
if (event.objects.length != 1 || !event.objects.head.isInstanceOf[AbstractPlayer]) {
None
} else {
clear()
println(s"The match is over. The winner is ${event.objects.head.asInstanceOf[AbstractPlayer]}")
Some(true)
}
}
}
private def showplayerstatusmethod(event: ShowPlayerStatus): Option[Boolean] = {
val player = event.player
event.status match {
case SHOW_PLAY_CARD =>
println("Which card do you want to play?")
Some(true)
case SHOW_DOG_PLAY_CARD =>
if (event.objects.length != 1 || !event.objects.head.isInstanceOf[Boolean]) {
None
} else {
println("You are using your dog life. Do you want to play your final card now?")
if (event.objects.head.asInstanceOf[Boolean]) {
println("You have to play your final card this round!")
println("Please enter y to play your final card.")
Some(true)
} else {
println("Please enter y/n to play your final card.")
Some(true)
}
}
case SHOW_TIE_NUMBERS =>
if (event.objects.length != 1 || !event.objects.head.isInstanceOf[Int]) {
None
} else {
println(s"${player.name} enter a number between 1 and ${event.objects.head.asInstanceOf[Int]}.")
Some(true)
}
case SHOW_TRUMPSUIT_OPTIONS =>
println("Which suit do you want to pick as the next trump suit?")
println("1: Hearts")
println("2: Diamonds")
println("3: Clubs")
println("4: Spades")
println()
Some(true)
case SHOW_NOT_PLAYED =>
println(s"Player ${event.player} decided to not play his card")
Some(true)
case SHOW_WON_PLAYER_TRICK =>
println(s"${event.player.name} won the trick.")
output = output :+ Html("<br><br>")
Some(true)
}
}
private def showroundstatusmethod(event: ShowRoundStatus): Option[Boolean] = {
event.status match {
case SHOW_TURN =>
if (event.objects.length != 1 || !event.objects.head.isInstanceOf[AbstractPlayer]) {
None
} else {
println(s"It's ${event.objects.head.asInstanceOf[AbstractPlayer].name} turn.")
Some(true)
}
case SHOW_START_ROUND =>
clear()
println(s"Starting a new round. The trump suit is ${event.currentRound.trumpSuit}.")
output = output :+ Html("<br><br>")
Some(true)
case WON_ROUND =>
if (event.objects.length != 1 || !event.objects.head.isInstanceOf[AbstractPlayer]) {
None
} else {
println(s"${event.objects.head.asInstanceOf[AbstractPlayer].name} won the round.")
Some(true)
}
case PLAYERS_OUT =>
println("The following players are out of the game:")
event.currentRound.playersout.foreach(p => {
println(p.name)
})
Some(true)
}
}
private def showerrstatmet(event: ShowErrorStatus): Option[Boolean] = {
event.status match {
case INVALID_NUMBER =>
println("Please enter a valid number.")
Some(true)
case NOT_A_NUMBER =>
println("Please enter a number.")
Some(true)
case INVALID_INPUT =>
println("Please enter a valid input")
Some(true)
case INVALID_NUMBER_OF_PLAYERS =>
println("Please enter at least two names.")
Some(true)
case IDENTICAL_NAMES =>
println("Please enter unique names.")
Some(true)
case INVALID_NAME_FORMAT =>
println("Please enter valid names. Those can not be empty, shorter than 2 or longer then 10 characters.")
Some(true)
case WRONG_CARD =>
if (event.objects.length != 1 || !event.objects.head.isInstanceOf[Card]) {
None
} else {
println(f"You have to play a card of suit: ${event.objects.head.asInstanceOf[Card].suit}\n")
Some(true)
}
}
}
private def showcurtrevmet(event: ShowCurrentTrickEvent): Option[Boolean] = {
clear()
val sb = new StringBuilder()
sb.append("Current Trick:\n")
sb.append("Trump-Suit: " + event.round.trumpSuit + "\n")
if (event.trick.firstCard.isDefined) {
sb.append(s"Suit to play: ${event.trick.firstCard.get.suit}\n")
}
for ((card, player) <- event.trick.cards) {
sb.append(s"${player.name} played ${card.toString}\n")
}
println(sb.toString())
Some(true)
}
private def println(s: String): Unit = {
var html = List[Html]()
for (line <- s.split("\n")) {
html = html :+ Html(line)
html = html :+ Html("<br>")
}
output = output :++ html
}
private def println(): Unit = {
output = output :+ Html("<br>")
}
object WebUICards {
def renderCardAsString(card: Card): Vector[String] = {
val lines = "│ │"
if (card.cardValue == CardValue.Ten) {
return Vector(
s"┌─────────┐",
s"│${card.cardValue.cardType()} │",
lines,
s"│ ${card.suit.cardType()} │",
lines,
s"│ ${card.cardValue.cardType()}│",
s"└─────────┘"
)
}
Vector(
s"┌─────────┐",
s"│${card.cardValue.cardType()} │",
lines,
s"│ ${card.suit.cardType()} │",
lines,
s"│ ${card.cardValue.cardType()}│",
s"└─────────┘"
)
}
def renderHandEvent(hand: Hand): List[Html] = {
hand.cards.map(WebUIUtils.cardtoImage)
}
}
*/
}

View File

@@ -1,11 +1,11 @@
@(toRender: List[String])
@(sessions: List[controllers.sessions.PlayerSession])
@main("Sessions") {
<div id="sessions">
<h1>Knockout Whist sessions</h1>
<p>Please select your session to jump inside the game!</p>
@for(line <- toRender) {
<a href="@routes.HomeController.ingame(line)">@line</a><br>
@for(session <- sessions) {
<a href="@routes.HomeController.ingame(session.id.toString)">@session.name</a><br>
}
</div>
}