Skip to content

Commit

Permalink
Fix new generated ids conflict with restored grid
Browse files Browse the repository at this point in the history
  • Loading branch information
joaomanaia committed Jul 8, 2024
1 parent 49fad20 commit a0c7f83
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -55,26 +55,24 @@ fun checkIsGameOver(grid: Grid): Boolean {
if (grid.isGridEmpty()) return false

// The game is over if no tiles can be moved in any of the 4 directions.
return Direction.entries.none { hasGridChanged(makeMove(grid, it).second) }
return Direction.entries.none { hasGridChanged(grid.makeMove(it).second) }
}

fun makeMove(grid: Grid, direction: Direction): Pair<Grid, List<GridTileMovement>> {
fun Grid.makeMove(direction: Direction): Pair<Grid, List<GridTileMovement>> {
val numRotations = when (direction) {
Direction.LEFT -> 0
Direction.DOWN -> 1
Direction.RIGHT -> 2
Direction.UP -> 3
}

val gridSize = grid.size

// Rotate the grid so that we can process it as if the user has swiped their
// finger from right to left.
var updatedGrid = grid.rotate(numRotations = numRotations)
var updatedGrid = rotate(numRotations = numRotations)

val gridTileMovements = mutableListOf<GridTileMovement>()

updatedGrid = List(gridSize) { currentRowIndex ->
updatedGrid = List(size) { currentRowIndex ->
val tiles = updatedGrid[currentRowIndex].toMutableList()
var lastSeenTileIndex: Int? = null
var lastSeenEmptyIndex: Int? = null
Expand All @@ -96,7 +94,7 @@ fun makeMove(grid: Grid, direction: Direction): Pair<Grid, List<GridTileMovement
row = currentRowIndex,
col = currentColIndex,
numRotations = numRotations,
gridSize = gridSize
gridSize = size
),
currentTile
)
Expand All @@ -113,7 +111,7 @@ fun makeMove(grid: Grid, direction: Direction): Pair<Grid, List<GridTileMovement
row = currentRowIndex,
col = lastSeenEmptyIndex,
numRotations = numRotations,
gridSize = gridSize
gridSize = size
)
val targetGridTile =
GridTile(targetCell, currentTile)
Expand All @@ -132,7 +130,7 @@ fun makeMove(grid: Grid, direction: Direction): Pair<Grid, List<GridTileMovement
row = currentRowIndex,
col = lastSeenTileIndex,
numRotations = numRotations,
gridSize = gridSize
gridSize = size
)
gridTileMovements.add(
GridTileMovement.shift(
Expand Down Expand Up @@ -168,7 +166,7 @@ fun makeMove(grid: Grid, direction: Direction): Pair<Grid, List<GridTileMovement
row = currentRowIndex,
col = lastSeenEmptyIndex,
numRotations = numRotations,
gridSize = gridSize
gridSize = size
)
val targetGridTile =
GridTile(targetCell, currentTile)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import com.joaomanaia.game2048.core.common.preferences.GameDataPreferencesCommon
import com.joaomanaia.game2048.core.datastore.manager.DataStoreManager
import com.joaomanaia.game2048.domain.repository.SaveGameRepository
import com.joaomanaia.game2048.model.Cell
import com.joaomanaia.game2048.model.Grid
import com.joaomanaia.game2048.model.GridTile
import com.joaomanaia.game2048.model.GridTileMovement
import com.joaomanaia.game2048.model.Tile
Expand All @@ -16,24 +17,24 @@ class SaveGameRepositoryImpl(
) : SaveGameRepository {
override suspend fun checkSaveGameExists() = getSavedGrid().isNotEmpty()

override suspend fun getSavedGrid(): List<List<Tile?>> {
override suspend fun getSavedGrid(): Grid {
val savedGridStr = gameDataStoreManager.getPreference(GameDataPreferencesCommon.Grid)
return Json.decodeFromString(savedGridStr)
}

override suspend fun getSavedGridTileMovements(): List<GridTileMovement> {
return getSavedGrid().flatMapIndexed { row, tiles ->
tiles.mapIndexed { col, tile ->
if (tile == null) null else GridTileMovement.noop(
GridTile(
Cell(
row,
col
), tile
return getSavedGrid()
.flatMapIndexed { row, tiles ->
tiles.mapIndexed { col, tile ->
if (tile == null) null else GridTileMovement.add(
gridTile = GridTile(cell = Cell(row, col), tile = tile)
)
)
}
}.filterNotNull()
.also { movements ->
// Reset the tile id counter
Tile.tileIdCounter = movements.maxOf { it.toGridTile.tile.id }
}
}.filterNotNull()
}

override suspend fun getSavedCurrentScore(): Int =
Expand All @@ -55,7 +56,7 @@ class SaveGameRepositoryImpl(
)
}

override suspend fun saveGame(grid: List<List<Tile?>>, currentScore: Int) {
override suspend fun saveGame(grid: Grid, currentScore: Int) {
val gridStr = Json.encodeToString(grid)

gameDataStoreManager.editPreferences(
Expand All @@ -65,7 +66,7 @@ class SaveGameRepositoryImpl(
}

override suspend fun saveGame(
grid: List<List<Tile?>>,
grid: Grid,
currentScore: Int,
bestScore: Int
) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package com.joaomanaia.game2048.domain.repository

import com.joaomanaia.game2048.model.Grid
import com.joaomanaia.game2048.model.GridTileMovement
import com.joaomanaia.game2048.model.Tile
import kotlinx.coroutines.flow.Flow

interface SaveGameRepository {
suspend fun checkSaveGameExists(): Boolean

suspend fun getSavedGrid(): List<List<Tile?>>
suspend fun getSavedGrid(): Grid

suspend fun getSavedGridTileMovements(): List<GridTileMovement>

Expand All @@ -22,12 +22,12 @@ interface SaveGameRepository {
suspend fun updateGridSize(newSize: Int)

suspend fun saveGame(
grid: List<List<Tile?>>,
grid: Grid,
currentScore: Int
)

suspend fun saveGame(
grid: List<List<Tile?>>,
grid: Grid,
currentScore: Int,
bestScore: Int
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,10 +113,7 @@ class GameViewModel(

private fun move(direction: Direction) {
_homeScreenUiState.update { state ->
var (updatedGrid, updatedGridTileMovements) = makeMove(
grid = state.grid,
direction = direction,
)
var (updatedGrid, updatedGridTileMovements) = state.grid.makeMove(direction = direction)

if (!hasGridChanged(updatedGridTileMovements)) return // No tiles were moved.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ internal class GridMovementTest {
val grid = emptyGrid(3)

for (direction in Direction.entries) {
val (newGrid, movements) = makeMove(grid, direction)
val (newGrid, movements) = grid.makeMove(direction)

assertThat(newGrid.isGridEmpty()).isTrue()
assertThat(movements).isEmpty()
Expand All @@ -46,7 +46,7 @@ internal class GridMovementTest {

@Test
fun testDownTileMovement() {
makeMove(initialGrid, Direction.DOWN).also { (newGridDown, movementsDown) ->
initialGrid.makeMove(Direction.DOWN).also { (newGridDown, movementsDown) ->
assertThat(newGridDown).isEqualTo(initialGrid)
with(initialGrid) {
assertThat(movementsDown).containsExactlyInAnyOrder(
Expand All @@ -62,7 +62,7 @@ internal class GridMovementTest {

@Test
fun testUpTileMovement() {
makeMove(initialGrid, Direction.UP).also { (newGridUp, movementsUp) ->
initialGrid.makeMove(Direction.UP).also { (newGridUp, movementsUp) ->
assertThat(newGridUp).isEqualTo(
listOf(
listOf(Tile(16, 0), Tile(2, 2), null),
Expand All @@ -84,7 +84,7 @@ internal class GridMovementTest {

@Test
fun testLeftTileMovement() {
makeMove(initialGrid, Direction.LEFT).also { (newGridLeft, movementsLeft) ->
initialGrid.makeMove(Direction.LEFT).also { (newGridLeft, movementsLeft) ->
assertThat(newGridLeft).isEqualTo(
listOf(
listOf(Tile(16, 0), null, null),
Expand All @@ -107,7 +107,7 @@ internal class GridMovementTest {

@Test
fun testRightTileMovement() {
makeMove(initialGrid, Direction.RIGHT).also { (newGridRight, movementsRight) ->
initialGrid.makeMove(Direction.RIGHT).also { (newGridRight, movementsRight) ->
assertThat(newGridRight).isEqualTo(
listOf(
listOf(null, null, Tile(16, 0)),
Expand Down

0 comments on commit a0c7f83

Please sign in to comment.