Skip to content

Commit

Permalink
Simplify up BiMap/CharacterMap
Browse files Browse the repository at this point in the history
  • Loading branch information
haukesomm committed May 31, 2024
1 parent abad2ac commit 3941431
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 103 deletions.
26 changes: 16 additions & 10 deletions core/src/commonMain/kotlin/de/haukesomm/sokoban/core/BiMap.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,31 @@ interface BiMap<K, V> : Map<K, V> {

/**
* The inverse of the [map].
*
* @throws IllegalStateException if the [map] is not bijective.
*/
val inverse: BiMap<V, K>
}

/**
* This class implements a [BiMap].
*
* The provided [map] _must be bijective_, meaning that every key must be mapped to exactly one value and vice versa.
* Otherwise, an [IllegalStateException] will be thrown when trying to access the [inverse] map.
* The provided [map] _should not_ contain duplicate keys as they will get lost when the map's inverse is computed.
* In case a key is provided multiple times, the last one will be kept.
*/
class BiMapImpl<K, V>(val map: Map<K, V>) : Map<K, V> by map, BiMap<K, V> {
internal class BiMapImpl<K, V>(val map: Map<K, V>) : Map<K, V> by map, BiMap<K, V> {

override val inverse: BiMap<V, K>
get() = map.entries
.associate { (k, v) -> v to k }
.let { inverse ->
if (inverse.size == map.size) BiMapImpl(inverse)
else throw IllegalStateException("Map is not bijective!")
}
}
.let(::BiMapImpl)
}

/**
* Creates an _immutable_ [BiMap] from the given [entries].
*
* The provided [map] _should not_ contain duplicate keys as they will get lost when the map's inverse is computed.
* In case a key is provided multiple times, the last one will be kept.
*/
fun biMapOf(vararg entries: Pair<Char, TileProperties>): BiMap<Char, TileProperties> =
BiMapImpl(
mapOf(*entries)
)
Original file line number Diff line number Diff line change
@@ -1,43 +1,25 @@
package de.haukesomm.sokoban.core

import de.haukesomm.sokoban.core.CharacterMap.Companion.default
import kotlin.jvm.JvmInline
import kotlin.jvm.JvmStatic

/**
* This class represents a character map.
* Convenience Type alias for Character maps
*
* A character map is a map that maps [Char]s to [TileProperties], which in turn contain the [TileType] and the
* [EntityType] of the resulting [TileType] on the game board.
*
* All [CharacterMap]s should orient themselves on the default character map, which is defined in the companion object's
* [default] property.
* All [CharacterMap]s should orient themselves on the default character map, which is defined in the globally
* available [DefaultCharacterMap].
*/
class CharacterMap(map: BiMap<Char, TileProperties>) : BiMap<Char, TileProperties> by map {

companion object {

/**
* Default character map based on the original Sokoban game.
*/
val default: CharacterMap = characterMapOf(
'_' to TileProperties(TileType.Empty),
'.' to TileProperties(TileType.Target),
'#' to TileProperties(TileType.Wall),
'$' to TileProperties(TileType.Empty, EntityType.Box),
'@' to TileProperties(TileType.Empty, EntityType.Player),
'*' to TileProperties(TileType.Target, EntityType.Box),
'+' to TileProperties(TileType.Target, EntityType.Player)
)
}
}
typealias CharacterMap = BiMap<Char, TileProperties>

/**
* Creates a [CharacterMap] from the given [entries].
* Default [CharacterMap] as used in the original Sokoban game.
*/
fun characterMapOf(vararg entries: Pair<Char, TileProperties>): CharacterMap =
CharacterMap(
BiMapImpl(
mapOf(*entries)
)
)
val DefaultCharacterMap: CharacterMap = biMapOf(
'_' to TileProperties(TileType.Empty),
'.' to TileProperties(TileType.Target),
'#' to TileProperties(TileType.Wall),
'$' to TileProperties(TileType.Empty, EntityType.Box),
'@' to TileProperties(TileType.Empty, EntityType.Player),
'*' to TileProperties(TileType.Target, EntityType.Box),
'+' to TileProperties(TileType.Target, EntityType.Player)
)
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ data class Level(
val id: String,
val name: String,
val layoutString: String,
val characterMap: CharacterMap = CharacterMap.default
val characterMap: CharacterMap = DefaultCharacterMap
) {
private val lines by lazy {
layoutString.lines()
Expand Down
Loading

0 comments on commit 3941431

Please sign in to comment.