fix: BAC-29 Implement Mappers for Common Classes (#101)

Reviewed-on: #101
Co-authored-by: Janis <janis.e.20@gmx.de>
Co-committed-by: Janis <janis.e.20@gmx.de>
This commit is contained in:
2025-12-05 19:24:10 +01:00
committed by Janis
parent 73dbe5826a
commit 270f44cc1f
12 changed files with 202 additions and 6 deletions

View File

@@ -0,0 +1,26 @@
package dto
import de.knockoutwhist.cards.Card
import play.api.libs.json.{Json, OFormat}
import util.WebUIUtils
case class CardDTO(identifier: String, path: String, idx: Int) {
def toCard: Card = {
WebUIUtils.stringToCard(identifier)
}
}
object CardDTO {
implicit val cardFormat: OFormat[CardDTO] = Json.format[CardDTO]
def apply(card: Card, index: Int = 0): CardDTO = {
CardDTO(
identifier = WebUIUtils.cardtoString(card),
path = WebUIUtils.cardToPath(card),
idx = index
)
}
}

View File

@@ -0,0 +1,18 @@
package dto
import de.knockoutwhist.cards.Hand
import play.api.libs.json.{Json, OFormat}
case class HandDTO(card: List[CardDTO])
object HandDTO {
implicit val handFormat: OFormat[HandDTO] = Json.format[HandDTO]
def apply(hand: Hand): HandDTO = {
HandDTO(
card = hand.cards.zipWithIndex.map { case (card, idx) => CardDTO(card, idx) }
)
}
}

View File

@@ -0,0 +1,20 @@
package dto
import de.knockoutwhist.player.AbstractPlayer
import play.api.libs.json.{Json, OFormat}
case class PlayerDTO(id: String, name: String, dogLife: Boolean)
object PlayerDTO {
implicit val playerFormat: OFormat[PlayerDTO] = Json.format[PlayerDTO]
def apply(player: AbstractPlayer): PlayerDTO = {
PlayerDTO(
id = player.id.toString,
name = player.name,
dogLife = player.isInDogLife
)
}
}

View File

@@ -0,0 +1,22 @@
package dto
import de.knockoutwhist.control.GameLogic
import play.api.libs.json.{Json, OFormat}
case class PlayerQueueDTO(currentPlayer: Option[PlayerDTO], queue: Seq[PlayerDTO])
object PlayerQueueDTO {
implicit val queueFormat: OFormat[PlayerQueueDTO] = Json.format[PlayerQueueDTO]
def apply(logic: GameLogic): PlayerQueueDTO = {
val currentPlayerDTO = logic.getCurrentPlayer.map(PlayerDTO(_))
val queueDTO = logic.getPlayerQueue.map(_.duplicate().flatMap(player => Some(PlayerDTO(player))).toSeq)
if (queueDTO.isEmpty) {
PlayerQueueDTO(currentPlayerDTO, Seq.empty)
} else {
PlayerQueueDTO(currentPlayerDTO, queueDTO.get)
}
}
}

View File

@@ -0,0 +1,22 @@
package dto
import de.knockoutwhist.cards.Card
import de.knockoutwhist.cards.CardValue.Ace
import play.api.libs.json.{Json, OFormat}
case class RoundDTO(trumpSuit: CardDTO, firstRound: Boolean, tricklist: List[TrickDTO], winner: Option[PlayerDTO])
object RoundDTO {
implicit val roundFormat: OFormat[RoundDTO] = Json.format[RoundDTO]
def apply(round: de.knockoutwhist.rounds.Round): RoundDTO = {
RoundDTO(
trumpSuit = CardDTO(Card(Ace, round.trumpSuit)),
firstRound = round.firstRound,
tricklist = round.tricklist.map(trick => TrickDTO(trick)),
winner = round.winner.map(player => PlayerDTO(player))
)
}
}

View File

@@ -0,0 +1,20 @@
package dto
import de.knockoutwhist.control.sublogic.PlayerTieLogic
import play.api.libs.json.{Json, OFormat}
case class TieInfoDTO(currentPlayer: Option[PlayerDTO], tiedPlayers: Seq[PlayerDTO], highestAmount: Int)
object TieInfoDTO {
implicit val tieInfoFormat: OFormat[TieInfoDTO] = Json.format[TieInfoDTO]
def apply(tieInput: PlayerTieLogic): Unit = {
TieInfoDTO(
currentPlayer = tieInput.currentTiePlayer().map(PlayerDTO.apply),
tiedPlayers = tieInput.getTiedPlayers.map(PlayerDTO.apply),
highestAmount = tieInput.highestAllowedNumber()
)
}
}

View File

@@ -0,0 +1,20 @@
package dto
import de.knockoutwhist.rounds.Trick
import play.api.libs.json.{Json, OFormat}
case class TrickDTO(cards: Map[PlayerDTO, CardDTO], firstCard: Option[CardDTO], winner: Option[PlayerDTO])
object TrickDTO {
implicit val trickFormat: OFormat[TrickDTO] = Json.format[TrickDTO]
def apply(trick: Trick): TrickDTO = {
TrickDTO(
cards = trick.cards.map { case (card, player) => PlayerDTO(player) -> CardDTO(card) },
firstCard = trick.firstCard.map(card => CardDTO(card)),
winner = trick.winner.map(player => PlayerDTO(player))
)
}
}

View File

@@ -0,0 +1,19 @@
package dto
import model.users.User
import play.api.libs.json.{Json, OFormat}
case class UserDTO(id: String, username: String)
object UserDTO {
implicit val userFormat: OFormat[UserDTO] = Json.format[UserDTO]
def apply(user: User): UserDTO = {
UserDTO(
id = user.id.toString,
username = user.name
)
}
}

View File

@@ -9,10 +9,14 @@ import scalafx.scene.image.Image
object WebUIUtils {
def cardtoImage(card: Card): Html = {
views.html.render.card.apply(f"images/cards/${cardtoString(card)}.png")(card.toString)
views.html.render.card.apply(cardToPath(card))(card.toString)
}
def cardToPath(card: Card): String = {
f"images/cards/${cardtoString(card)}.png"
}
def cardtoString(card: Card) = {
def cardtoString(card: Card): String = {
val s = card.suit match {
case Spades => "S"
case Hearts => "H"
@@ -36,6 +40,31 @@ object WebUIUtils {
}
f"$cv$s"
}
def stringToCard(cardStr: String): Card = {
val cv = cardStr.charAt(0) match {
case 'A' => Ace
case 'K' => King
case 'Q' => Queen
case 'J' => Jack
case 'T' => Ten
case '9' => Nine
case '8' => Eight
case '7' => Seven
case '6' => Six
case '5' => Five
case '4' => Four
case '3' => Three
case '2' => Two
}
val s = cardStr.charAt(1) match {
case 'S' => Spades
case 'H' => Hearts
case 'C' => Clubs
case 'D' => Diamonds
}
Card(cv, s)
}
/**
* Map a Hand to a JsArray of cards

View File

@@ -20,7 +20,7 @@
</p>
</div>
@if(player.equals(gamelobby.logic.playerTieLogic.currentTiePlayer())) {
@if(gamelobby.logic.playerTieLogic.currentTiePlayer().contains(player)) {
@defining(gamelobby.logic.playerTieLogic.highestAllowedNumber()) { maxNum =>
<div class="alert alert-info" role="alert" aria-live="polite">
Pick a number between 1 and @{
@@ -71,7 +71,7 @@
}
} else {
<div class="alert alert-warning" role="alert" aria-live="polite">
<strong>@gamelobby.logic.playerTieLogic.currentTiePlayer()</strong>
<strong>@gamelobby.logic.playerTieLogic.currentTiePlayer().get</strong>
is currently picking a number for the cut.
</div>