package uk.co.nickthecoder.gamescupboard.server
import uk.co.nickthecoder.gamescupboard.common.Avatar
import uk.co.nickthecoder.gamescupboard.common.playingAreaHeight
import uk.co.nickthecoder.gamescupboard.common.playingAreaWidth
interface AvatarPositions {
fun position(avatar: Avatar, players: Int)
}
data class Vector2i(val x: Int, val y: Int)
class FixedAvatarPositions(private val positions: List<Vector2i>, val sides: List<Int> = emptyList()) :
AvatarPositions {
override fun position(avatar: Avatar, players: Int) {
val index = (avatar.playerId - 1) % positions.size
val pos = positions[index]
avatar.x = pos.x
avatar.y = pos.y
avatar.side = sides.getOrNull(index) ?: 0
}
}
class CornerAvatarPositions(
private val left: Int,
private val top: Int,
private val bottom: Int,
private val right: Int
) : AvatarPositions {
override fun position(avatar: Avatar, players: Int) {
avatar.x = if ((avatar.playerId - 1) % 2 == 0) {
left
} else {
right
}
avatar.y = if (avatar.playerId / 2 % 2 == 0) {
avatar.side = 0
top
} else {
avatar.side = 2
bottom
}
}
}
/**
* Arranged in a vertical line.
* The top and bottom margins are half the size of the spacing between the Avatars.
*/
class VerticalAvatarPositions(
private val x: Int,
private val side : Int = 1
) : AvatarPositions {
override fun position(avatar: Avatar, players: Int) {
avatar.x = x
avatar.y = ((avatar.playerId - 0.5) * playingAreaHeight / players).toInt()
avatar.side = side
}
}
/**
* Arranged in a vertical line.
* The top and bottom margins are half the size of the spacing between the Avatars.
*/
class SpacedVerticalAvatarPositions(
private val x: Int,
private val y: Int,
private val spacing: Int,
private val side : Int = 1
) : AvatarPositions {
override fun position(avatar: Avatar, players: Int) {
avatar.x = x
avatar.y = y + spacing * avatar.playerId
avatar.side = side
}
}
class HorizontalAvatarPositions(
private val y: Int,
private val side : Int = 0
) : AvatarPositions {
override fun position(avatar: Avatar, players: Int) {
avatar.y = y
avatar.x = ((avatar.playerId - 0.5) * playingAreaWidth / players).toInt()
avatar.side = side
}
}
class TopAndBottomAvatarPositions(
private val top: Int,
private val bottom: Int,
private val margin: Int = 0,
/**
* Make the avatars follow a clockwise order.
* Otherwise, they will be left to right at the top and the bottom.
*/
private val around: Boolean = true
) : AvatarPositions {
override fun position(avatar: Avatar, players: Int) {
val isTop = (avatar.playerId - 1) % 2 == 0
avatar.y = if (isTop) {
avatar.side = 0
top
} else {
avatar.side = 2
bottom
}
val n = (avatar.playerId - 1) / 2
val from = if (players % 2 == 0 || !isTop) players / 2 else players / 2 + 1
// When margin==0, we calculate the margins based on the number of seats on this side of the table.
if (margin == 0) {
// Spread across the whole width, with an automatic margin left and right
avatar.x = ((n + 0.5) * playingAreaWidth / from).toInt()
} else {
if (from == 1) {
// In the middle
avatar.x = playingAreaWidth / 2
} else {
// Spread from margin to playingAreaWidth-margin
avatar.x = margin + n * (playingAreaWidth - margin * 2) / (from - 1)
}
}
if (around && !isTop) {
avatar.x = playingAreaWidth - avatar.x
}
}
}