Skip to content

Commit

Permalink
Initial implementation of Hearts and Arrows puzzles.
Browse files Browse the repository at this point in the history
Built atop Rows Garden logic as these formats are quite similar in
nature. Also fixes a bug with Rows Garden where row clues are labeled in
the grid with letters but in the clue list with numbers.
  • Loading branch information
jpd236 committed Feb 15, 2024
1 parent c2dc23b commit 6236529
Show file tree
Hide file tree
Showing 11 changed files with 451 additions and 138 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package com.jeffpdavidson.kotwords.model

import com.jeffpdavidson.kotwords.formats.Puzzleable
import kotlinx.serialization.Serializable
import kotlin.math.floor
import kotlin.math.roundToInt

@Serializable
data class HeartsAndArrows(
val title: String,
val creator: String,
val copyright: String,
val description: String,
val solutionGrid: List<List<Char>>,
val arrows: List<List<RowsGarden.Entry>>,
val light: List<RowsGarden.Entry>,
val medium: List<RowsGarden.Entry>,
val dark: List<RowsGarden.Entry>,
val lightHeartColor: String = "#FFFFFF",
val mediumHeartColor: String = "#F4BABA",
val darkHeartColor: String = "#E06666",
val addWordCount: Boolean = true,
val addHyphenated: Boolean = true,
val hasHtmlClues: Boolean = false,
) : Puzzleable() {
override suspend fun createPuzzle(): Puzzle {
val originX = solutionGrid[0].indexOfFirst { it != '.' }

return RowsGarden.createPuzzle(
title = title,
creator = creator,
copyright = copyright,
description = description,
solutionGrid = solutionGrid,
rows = arrows,
light = light,
medium = medium,
dark = dark,
lightColor = lightHeartColor,
mediumColor = mediumHeartColor,
darkColor = darkHeartColor,
addWordCount = addWordCount,
addHyphenated = addHyphenated,
hasHtmlClues = hasHtmlClues,
rowsListTitle = "Arrows",
bloomsListTitle = "Hearts",
emptyCellType = Puzzle.CellType.VOID,
bloomTypeForCoordinate = { x, y ->
val heartTopLeft = when ((3 * y - x + originX).mod(8)) {
0 -> x to y
1 -> x - 2 to y - 1
2 -> x - 1 to y - 1
3 -> x to y - 1
4 -> x - 2 to y - 2
5 -> x - 1 to y - 2
6 -> x to y - 2
else -> x - 1 to y
}
val heartX = (heartTopLeft.first + heartTopLeft.second - originX) / 4
val heartY = (3 * heartTopLeft.second - heartTopLeft.first + originX) / 8
when ((heartX + heartY).mod(3)) {
0 -> RowsGarden.BloomType.DARK
1 -> RowsGarden.BloomType.LIGHT
else -> RowsGarden.BloomType.MEDIUM
}
},
isStartOfBloom = { x, y -> (3 * y - x + originX).mod(8) == 7 },
getBloomCoordinates = { x, y ->
listOf(
Puzzle.Coordinate(x = x - 1, y = y),
Puzzle.Coordinate(x = x, y = y),
Puzzle.Coordinate(x = x, y = y + 1),
Puzzle.Coordinate(x = x + 1, y = y + 1),
Puzzle.Coordinate(x = x + 1, y = y + 2),
Puzzle.Coordinate(x = x, y = y + 2),
Puzzle.Coordinate(x = x - 1, y = y + 2),
Puzzle.Coordinate(x = x - 1, y = y + 1),
)
},
)
}
}
Loading

0 comments on commit 6236529

Please sign in to comment.