Exit Full View

Games Cupboard / gamescupboard-server / src / main / kotlin / uk / co / nickthecoder / gamescupboard / server / commands / DealCommand.kt

package uk.co.nickthecoder.gamescupboard.server.commands

import ChangePrivacy
import ChatMessage
import MoveObject
import ChangeZOrder
import uk.co.nickthecoder.gamescupboard.common.CommandInfo
import uk.co.nickthecoder.gamescupboard.common.SpecialArea
import uk.co.nickthecoder.gamescupboard.common.SpecialPoint
import uk.co.nickthecoder.gamescupboard.server.ConnectedPlayer
import kotlin.math.min

// region ==== DealCommand ====
class DealCommand(
    private val fromPoint: SpecialPoint,
    private val toArea: SpecialArea,
    private val spreadX: Int

) : Command(
    CommandInfo(
        "deal",
        "Deal cards to each player",
        1,
        parameterHelp = listOf("Number of cards to deal to each player")
    )
) {

    override suspend fun run(from: ConnectedPlayer, parameters: List<String>): String? {
        val count = parameters[0].toIntOrNull() ?: return "Expected an integer"
        val game = from.game

        val available = game.playingObjects().count { fromPoint.contains(it.x, it.y) }
        if (available < count * game.connectedPlayers.size) {
            return "Not enough cards. Only $available remaining"
        }

        val actualSpread = min(spreadX.toDouble(), (toArea.width - spreadX) / count.toDouble()).toInt()
        val y = toArea.y + toArea.height / 2
        val left = actualSpread + toArea.x + toArea.width / 2 - (actualSpread * count) / 2

        for (playerId in game.connectedPlayers.keys) {
            val cards = game.playingObjects().filter { fromPoint.contains(it.x, it.y) }.take(count)
            for ((i, card) in cards.withIndex()) {
                game.send(ChangePrivacy(card.id, playerId))
                card.privateToPlayerId = playerId

                val x = left + i * actualSpread
                game.send(MoveObject(card.id, x, y, ChangeZOrder.TOP))
                card.x = x
                card.y = y

                // NOTE, If the card is face down (as is typical when taking a card from the deck),
                // then the card will REMAIN face down on the server, but the owning player's client
                // will turn it face up (for them only) when it receives the MoveObject message.
            }
        }
        game.send(ChatMessage(from.id, "Dealt $count cards", null))

        return null
    }
}