package uk.co.nickthecoder.gamescupboard.server.games
import uk.co.nickthecoder.gamescupboard.common.*
import uk.co.nickthecoder.gamescupboard.server.*
import uk.co.nickthecoder.gamescupboard.server.commands.DealCommand
import uk.co.nickthecoder.gamescupboard.server.commands.PeelCommand
import uk.co.nickthecoder.gamescupboard.server.commands.ShuffleCommand
import uk.co.nickthecoder.gamescupboard.server.commands.TakeCommand
private const val smallTileSize = 24
private const val margin = 10
private const val left = margin
private const val top = margin
/**
* The point where the "bag" of tiles is located.
*/
private val bagPoint = SpecialPoint("bag", 101, playingAreaHeight - 21)
/**
* Avatars are at the top of the screen.
*/
private val avatarPositions = HorizontalAvatarPositions(26)
/**
* The area containing each player's hand of tiles.
* Each player only sees their own tiles (PRIVATE).
*/
private val handArea = SpecialArea("hand", AreaType.PRIVATE, 150, playingAreaHeight - 40, playingAreaWidth - 150, 40)
/**
* The main playing area. Tiles are always face up here.
*/
private val playArea = SpecialArea(
"tileGrid",
AreaType.PUBLIC,
left,
top,
playingAreaWidth,
playingAreaHeight - top - handArea.height,
changeZOrder = ChangeZOrder.TOP,
snap = RectangularSnapToGrid(smallTileSize, smallTileSize),
warnUsingTint = false
)
private val letterTiles =
Grid("pieces", "letterTiles.png", across = 7, down = 4, itemWidth = smallTileSize, itemHeight = smallTileSize)
/**
* Tile frequency (taken from Wikipedia)
*
* * 2: J, K, Q, X, Z
* * 3: B, C, F, H, M, P, V, W, Y
* * 4: G
* * 5: L
* * 6: D, S, U
* * 8: N
* * 9: T, R
* * 11: O
* * 12: I
* * 13: A
* * 18: E
*/
private fun MutableList<GameObject>.banagramsTiles() {
val frequency = mutableMapOf<Char, Int>()
frequency.putAll(listOf('J', 'K', 'Q', 'X', 'Z').map { it to 2 })
frequency.putAll(listOf('B', 'C', 'F', 'H', 'M', 'P', 'V', 'W', 'Y').map { it to 3 })
frequency.putAll(listOf('G').map { it to 4 })
frequency.putAll(listOf('L').map { it to 5 })
frequency.putAll(listOf('D', 'S', 'U').map { it to 6 })
frequency.putAll(listOf('N').map { it to 8 })
frequency.putAll(listOf('T', 'R').map { it to 9 })
frequency.putAll(listOf('O').map { it to 11 })
frequency.putAll(listOf('I').map { it to 12 })
frequency.putAll(listOf('A').map { it to 13 })
frequency.putAll(listOf('E').map { it to 18 })
// Place all pieces on the "bag" SpecialPoint. These are unsorted!
for (y in 0..3) {
for (x in 0..6) {
val letter = 'A' - 1 + x + y * 7
val count = frequency[letter] ?: 0
for (c in 0 until count) {
add(
FlippableImageObject(
size,
bagPoint.x,
bagPoint.y,
grid = letterTiles, gx = x, gy = y,
altX = 0, altY = 0, isFaceUp = false
)
)
}
}
}
}
private val bananagramsRules = """
_Bananagrams_
See the [Wikipedia article for details|https://en.wikipedia.org/wiki/Bananagrams].
All players are dealt anywhere from 11 to 21 tiles (depending on the number of players).
All players simultaneously start building crossword-like structure of intersecting
words. All words must join together (but not to other players' tiles).
If a player is finding it hard to place any letter, they may place one tile back in the bunch,
and call out "Dump", taking 3 tiles from the bunch.
When a player has used up all their tiles, they call out "Peel", and the other players
take a tile from the bunch.
The game ends when a player calls "Peel", and there are insufficient tiles left in the bunch
for all other players to take a tile.
If a player is found to use a misspelled word, or their tiles are not all connected,
the that player looses, and the remaining players continue to play.
""".trimIndent()
private val regularBananagrams = GameVariation(
"bananagrams",
"Bananagrams",
minPlayers = 2,
maxPlayers = 6,
grids = listOf(letterTiles),
specialAreas = listOf(playArea, handArea),
specialPoints = listOf(bagPoint),
playingObjects = mutableListOf<GameObject>().apply { banagramsTiles() },
foregroundObjects = listOf(
PieceAtPointCounter(0, bagPoint.x + 30, bagPoint.y, bagPoint.name)
),
backgroundObjects = listOf(
ImageObject(- 1, 400, 300, path = "backgrounds/bananagrams.jpg", draggable = false)
),
avatarPositions = avatarPositions,
commands = listOf(
ShuffleCommand(bagPoint),
DealCommand(bagPoint, handArea, 50),
TakeCommand(bagPoint, handArea, 50),
PeelCommand(bagPoint, handArea)
),
commandPrototypes = listOf(
CommandPrototype("Deal", "deal", parameters = listOf("21")),
CommandPrototype("Take", "take"),
CommandPrototype("Peel", "peel", isComplete = true),
CommandPrototype("Dump", "take", parameters = listOf("3"), isComplete = true),
CommandPrototype("Shuffle", "shuffle", isComplete = true)
),
rules = bananagramsRules
)
val bananagrams = GameType(
"bananagrams", "Bananagrams", "bananagrams.png",
listOf(regularBananagrams)
)