Exit Full View

Games Cupboard / gamescupboard-common / src / commonMain / kotlin / uk / co / nickthecoder / gamescupboard / common / SpecialArea.kt

package uk.co.nickthecoder.gamescupboard.common

import ChangeZOrder
import kotlinx.serialization.Serializable

@Serializable
enum class AreaType {
    PRIVATE, PUBLIC
}

/**
 * Areas of the playing area, which behave differently.
 *
 * [areaType].[AreaType.PRIVATE] : Hides game objects from other players.
 * e.g. For cards held in a player's hand.
 *
 * [areaType].[AreaType.PUBLIC] : Turns cards face up.
 *
 * Later we will have areas with a snap-to-grid.
 * e.g. a chess board will snap pieces to the 8x8 grid.
 * Outside this grid, the pieces can be moved without snapping.
 */
@Serializable
data class SpecialArea(
    val name: String,
    val areaType: AreaType,
    val x: Int,
    val y: Int,
    val width: Int,
    val height: Int,
    val snap: SnapToGrid? = null,

    /**
     * Game objects placed in this area may be moved to the top or bottom of the Z-Order,
     * or remain unchanged.
     *
     * First used for chess, so that taken pieces are above the piece moved.
     * Other games, such as Scrabble should use value 1 (top), so that when you drag a tile/card over an existing
     * one by mistake, the dragged tile is on top. This makes it easier to correct the mistake.
     */
    val changeZOrder: ChangeZOrder = ChangeZOrder.NO_CHANGE,
    /**
     * Should FlippableImageViews be tinted to warn that they will be turned face up
     * if the user drags and drops to this area?
     *
     * Only applicable to [AreaType.PRIVATE].
     *
     * Primarily for card games. RummyCross sets this to false, because the tint would change the color of the shape.
     */
    val warnUsingTint: Boolean = true
) {

    /**
     * Each client keeps track of the number of objects in this area.
     * This field is unused on the server.
     *
     * Used to display the number of cards in an area.
     */
    var pieceCount: Int = 0

    /**
     * Each client keeps track of the number of objects owned by a player in this area.
     * This field is unused on the server.
     *
     * Used to display the number of cards in a private area.
     */
    var pieceCountByOwner = mutableMapOf<Int, Int>()

    fun increment(byPlayerId: Int) {
        pieceCount--
        pieceCountByOwner[byPlayerId] = (pieceCountByOwner[byPlayerId] ?: 0) - 1
    }

    fun decrement(byPlayerId: Int) {
        pieceCount++
        pieceCountByOwner[byPlayerId] = (pieceCountByOwner[byPlayerId] ?: 0) + 1
    }

    fun contains(x: Int, y: Int) = x >= this.x && y >= this.y && x < this.x + width && y < this.y + height

}

fun SpecialArea?.isPublicOrNull() = this == null || this.areaType == AreaType.PUBLIC
fun SpecialArea?.isPublic() = this?.areaType == AreaType.PUBLIC
fun SpecialArea?.isPrivate() = this?.areaType == AreaType.PRIVATE