diff --git a/src/main/kotlin/World.kt b/src/main/kotlin/World.kt index b5cb5a4..241293a 100644 --- a/src/main/kotlin/World.kt +++ b/src/main/kotlin/World.kt @@ -19,6 +19,8 @@ import java.util.* object World { //Default size should be 20 val tiles = WorldData(ArrayList>()) + var sizeX = 10 + var sizeY = 10 fun update(tile: Tile, to: TileProperties) { tiles.value[tile.x()][tile.y()] = to @@ -26,10 +28,12 @@ object World { //Returns a coordinate pair fun getRandomLocation(): Tile { - return Tile((0..tiles.value.size-1).random(), (0..tiles.value.get(0).size-1).random()) + return Tile((0.. NONE } } - fun getModifier(dir: Directions): Long { + fun getModifier(dir: Directions): ULong { return when(dir) { UP -> NORTH DOWN -> SOUTH LEFT -> WEST RIGHT -> EAST - else -> 0L + else -> NONEMOD } } - fun convertModifier(mod: Long): Directions { + fun convertModifier(mod: ULong): Directions { return when(mod) { NORTH -> UP SOUTH -> DOWN @@ -37,12 +37,12 @@ enum class Directions(val dir: Int) { } } - const val SOUTH: Long = 0x1L - const val NORTH: Long = -0x1L - const val WEST: Long = -0x100000000L - const val EAST: Long = 0x100000000L + const val SOUTH: ULong = 1UL + const val NORTH: ULong = 4294967295UL + const val WEST: ULong = 18446744069414584320UL + const val EAST: ULong = 4294967296UL val ALL = arrayOf(UP, DOWN, LEFT, RIGHT) - const val NONEMOD = 0L + const val NONEMOD = 0UL } fun inv(): Int { diff --git a/src/main/kotlin/data/Tile.kt b/src/main/kotlin/data/Tile.kt index 6f343c5..f692ba9 100644 --- a/src/main/kotlin/data/Tile.kt +++ b/src/main/kotlin/data/Tile.kt @@ -2,16 +2,20 @@ package technology.zim.data import technology.zim.World + + @JvmInline -value class Tile(val value: Long) { +value class Tile(private val value: ULong) { constructor(x: Int, y: Int): this(pack(x, y)) { + } fun connect(candidateTile: Tile) { - val dir = Directions.convertModifier(candidateTile.value - this.value) + val dir = toward(candidateTile) connect(dir) } + //Connect two tiles together. //Calls utility function on the connected cell fun connect(dir: Directions) { @@ -20,12 +24,12 @@ value class Tile(val value: Long) { //Ensure that the tile is within bounds if(candidateTile.isInBounds() && this.isInBounds()) { - World.tiles.value[x()][y()] = getProperties().add(dir) - World.tiles.value[candidateTile.x()][candidateTile.y()] = candidateTile.getProperties().add(Directions.opposite(dir)) - + if(this.y() == World.sizeY - 1 && dir == Directions.DOWN) + println("wat") + World.update(this, getProperties().add(dir)) + World.update(candidateTile, candidateTile.getProperties().add(candidateTile.toward(this))) } else { - //Shouldn't matter whether we skip connecting an out-of-bounds item //Should also never get to the point where the attempt is made println("Attempted to connect to outside bounds: <" + candidateTile.x() + ", " + candidateTile.y() @@ -35,20 +39,25 @@ value class Tile(val value: Long) { } } - //Duplicating code from getAdjacent shaved off 100ms - //I'm keeping it + fun toward(otherTile: Tile): Directions { + return Directions.convertModifier(otherTile.value - this.value) + } fun getAdjacentTiles(explored:Boolean): Set { val adj = mutableSetOf() val dirs = Directions.ALL dirs.forEach { dir -> val candidateTile = this + dir + //Ensure that the tile is within bounds if(candidateTile.isInBounds() && candidateTile.getProperties().visited() == explored) { + println("$this+$dir --> $candidateTile") adj.add(candidateTile) } } + if(adj.isEmpty() && explored) + println("no explored found") return adj } @@ -77,41 +86,33 @@ value class Tile(val value: Long) { return this + Directions.getModifier(dir) } - operator fun plus(mod: Long): Tile { - return Tile(this.value + mod) + operator fun plus(mod: ULong): Tile { + return Tile(this.x() + x(mod), this.y() + y(mod)) } - operator fun plus(tile: Tile): Tile { - return Tile(x() + tile.x(), y() + tile.y()) - } + fun getCoordinates(): Pair { + return Pair(x(), y()) + } fun x(): Int { - return (value shr 32).toInt() + return x(value) } - //Gets the x value of the given coordinate form - fun x(coord: Tile):Int { - return coord.x() + //Gets the x value of the Long as though it were in coordinate form + fun x(coords: ULong): Int { + return (coords shr 32).toLong().toInt() } - //Gets the x value of the coordinate form of the given direction - fun x(dir: Directions):Int { - return (this + dir).x() - } + //Bitwise and to ensure the left-hand half of the Long is zero'd, then convert toInt() fun y():Int { - return value.toInt() - } - - //Gets the y value of the given coordinate form - fun y(coord: Tile):Int { - return coord.y() + return y(value) } - //Gets the y value of the coordinate form of the given direction - fun y(dir: Directions):Int { - return (this + dir).y() + //Get the y value from a Long as though it were a Tile + fun y(coords: ULong): Int { + return coords.toLong().toInt() } override fun toString():String { @@ -119,8 +120,8 @@ value class Tile(val value: Long) { } companion object { - fun pack(x: Int, y: Int):Long { - return (x.toLong() shl 32) + y.toLong() + fun pack(mostSignificantBits: Int, leastSignificantBits: Int): ULong { + return (mostSignificantBits.toUInt().toULong() shl 32) or leastSignificantBits.toUInt().toULong() } } diff --git a/src/test/kotlin/CoordPackTest.kt b/src/test/kotlin/CoordPackTest.kt new file mode 100644 index 0000000..d40ddc7 --- /dev/null +++ b/src/test/kotlin/CoordPackTest.kt @@ -0,0 +1,35 @@ +import org.junit.jupiter.api.Test + +class CoordPackTest { + + @Test + fun packUnpack() { + val xOrig = -0x1 + val yOrig = 0x1 + + val coords = pack(xOrig, yOrig) + + val xNew = x(coords) + val yNew = y(coords) + + println("done") + + assert(xOrig == xNew) + assert(yOrig == yNew) + + + } + + fun pack(mostSignificantBits: Int, leastSignificantBits: Int): ULong { + return (mostSignificantBits.toUInt().toULong() shl 32) or leastSignificantBits.toUInt().toULong() + } + + fun x(coords: ULong): Int { + return (coords shr 32).toLong().toInt() + } + fun y(coords: ULong): Int { + return coords.toLong().toInt() + } + + +} \ No newline at end of file diff --git a/src/test/kotlin/TileTest.kt b/src/test/kotlin/TileTest.kt index 4b1ef8d..0e6383a 100644 --- a/src/test/kotlin/TileTest.kt +++ b/src/test/kotlin/TileTest.kt @@ -14,8 +14,37 @@ class TileTest { MazeFinder.cleanUp() } + //Confirm that an empty map acts like it is empty + @Test + fun emptyTest() { + val tile = Tile(3, 3) + var adjacent = tile.getAdjacentTiles(false) + assert(adjacent.size == 4) + + var explored = tile.getAdjacentTiles(true) + assert(explored.isEmpty()) + + + } + + @Test + fun squareTest() { + val startTile = Tile(1, 1) + var endTile = startTile + + endTile = endTile + LEFT + endTile = endTile + UP + endTile = endTile + RIGHT + endTile = endTile + DOWN + assert(startTile == endTile) + } + + + @Test fun connectOutOfBoundsInvalid() { + println("Following out of bounds log entries are expected") + println("-------------------------------------------------------------") val bottom = Tile(1, 9) bottom.connect(DOWN) assertFalse(bottom.getProperties().isSouth()) @@ -23,6 +52,7 @@ class TileTest { @Test fun outOfBoundsTest() { + val tooNorth = Tile(1, -1) val tooWest = Tile(-1, 1) val tooEast = Tile(10, 1) @@ -31,6 +61,7 @@ class TileTest { val northIn = Tile(0, 0) val southIn = Tile(9, 9) + println("-------------------------------------------------------------") assert(northIn.isInBounds()) assert(southIn.isInBounds())