Skip to content

Commit 0ef13cd

Browse files
committed
♻️ dijkstra refactor
1 parent bf9ee99 commit 0ef13cd

File tree

9 files changed

+43
-57
lines changed

9 files changed

+43
-57
lines changed

app/src/main/java/com/waleska404/algorithms/di/DataModule.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package com.waleska404.algorithms.di
22

33
import com.waleska404.algorithms.domain.bubblesort.BubbleSort
44
import com.waleska404.algorithms.domain.bubblesort.BubbleSortImpl
5+
import com.waleska404.algorithms.domain.dijkstra.Dijkstra
56
import com.waleska404.algorithms.domain.dijkstra.DijkstraImpl
67
import com.waleska404.algorithms.domain.quicksort.QuickSort
78
import com.waleska404.algorithms.domain.quicksort.QuickSortImpl
@@ -25,6 +26,6 @@ class DataModule {
2526

2627
@Singleton
2728
@Provides
28-
fun providesDijkstra(): DijkstraImpl = DijkstraImpl()
29+
fun providesDijkstra(): Dijkstra = DijkstraImpl()
2930

3031
}
Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
package com.waleska404.algorithms.domain.dijkstra
22

3-
interface Dijkstra {
4-
}
3+
import kotlinx.coroutines.flow.Flow
54

5+
interface Dijkstra {
6+
suspend fun animatedDijkstra(
7+
gridSize: Int,
8+
row: Int,
9+
col: Int,
10+
start: Position,
11+
finish: Position,
12+
walls: List<Position>
13+
): Flow<DijkstraDomainModel>
14+
}

app/src/main/java/com/waleska404/algorithms/domain/dijkstra/DijkstraDomianModel.kt renamed to app/src/main/java/com/waleska404/algorithms/domain/dijkstra/DijkstraDomainModel.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ data class CellDomainData(
1717
var type: CellType,
1818
val position: Position,
1919
val isVisited: Boolean = false,
20-
val isShortestPath: Boolean = false,
2120
var distance: Int = Int.MAX_VALUE,
2221
var previousShortestCell: CellDomainData? = null,
2322
)

app/src/main/java/com/waleska404/algorithms/domain/dijkstra/DijkstraImpl.kt

Lines changed: 18 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package com.waleska404.algorithms.domain.dijkstra
22

3-
import android.util.Log
43
import com.waleska404.algorithms.domain.utils.findIndexByCell
54
import com.waleska404.algorithms.domain.utils.isAtPosition
65
import com.waleska404.algorithms.domain.utils.shift
@@ -10,23 +9,21 @@ import kotlinx.coroutines.flow.Flow
109
import kotlinx.coroutines.flow.flow
1110
import kotlin.math.floor
1211

13-
class DijkstraImpl {
12+
class DijkstraImpl: Dijkstra {
1413

15-
suspend fun animatedDijkstra(
14+
override suspend fun animatedDijkstra(
1615
gridSize: Int,
1716
row: Int,
1817
col: Int,
1918
start: Position,
2019
finish: Position,
2120
walls: List<Position>
2221
): Flow<DijkstraDomainModel> {
23-
Log.i("MYTAG", "gridSize: $gridSize, row: $row, col: $col, start: $start, finish: $finish")
2422
return flow {
23+
// set up initial variables
2524
val visitedNodesInOrder = mutableListOf<CellDomainData>()
26-
2725
val startIndex = getIndexFromPosition(start, col)
2826
val finishIndex = getIndexFromPosition(finish, col)
29-
3027
val unvisitedNodes = MutableList(gridSize) {
3128
CellDomainData(
3229
id = it,
@@ -42,7 +39,6 @@ class DijkstraImpl {
4239
unvisitedNodes[finishIndex] = unvisitedNodes[finishIndex].copy(
4340
type = CellType.FINISH
4441
)
45-
Log.i("MYTAG", "FINISH POSITION: $finish, FINISH INDEX: $finishIndex")
4642
walls.forEach {
4743
val index = getIndexFromPosition(it, col)
4844
unvisitedNodes[index] = unvisitedNodes[index].copy(
@@ -51,27 +47,26 @@ class DijkstraImpl {
5147
}
5248
val allNodes = unvisitedNodes.toMutableList()
5349

54-
50+
// main loop
5551
while (unvisitedNodes.isNotEmpty()) {
5652
sortNodesByDistance(unvisitedNodes)
57-
5853
val closestCell = unvisitedNodes.shift()
59-
if (closestCell.type == CellType.WALL) {
60-
continue
61-
}
54+
55+
// wall case
56+
if (closestCell.type == CellType.WALL) continue
57+
58+
// target not reachable case
6259
if (closestCell.distance == Int.MAX_VALUE) {
63-
//TODO: emit return shortest path
6460
emit(
6561
DijkstraDomainModel(
6662
finished = true,
6763
shortestPath = null,
6864
unreachable = true
6965
)
7066
)
71-
Log.i("MYTAG", "closestCell.distance == Int.MAX_VALUE, position: ${closestCell.position}")
7267
}
7368

74-
//TODO: emit set cell visited at position closestCell.position
69+
// background case
7570
if(closestCell.type != CellType.WALL) {
7671
emit(
7772
DijkstraDomainModel(
@@ -82,39 +77,40 @@ class DijkstraImpl {
8277
)
8378
)
8479
}
85-
//gridState.setCellVisitedAtPosition(closestCell.position)
80+
81+
// update allNodes list
8682
allNodes[closestCell.id] = closestCell.copy(isVisited = true)
83+
// update visitedNodes list
8784
visitedNodesInOrder.add(allNodes[closestCell.id])
8885

89-
86+
// target reached case
9087
if (closestCell.isAtPosition(finish)) {
91-
//TODO: emit return shortest path
9288
emit(
9389
DijkstraDomainModel(
9490
finished = true,
9591
shortestPath = getShortestPathOrder(allNodes[finishIndex])
9692
)
9793
)
98-
//return visitedNodesInOrder
9994
}
95+
96+
// update neighbors
10097
updateUnvisitedNeighbors(
10198
cell = closestCell,
10299
allNodes = allNodes,
103100
unvisitedNodes = unvisitedNodes,
104101
row = row,
105102
col = col
106103
)
107-
104+
// TODO: poner esta variable en un sitio más core, un config comun a todas las capas o algo
105+
// o del domain puede venir al ui????? igual si
108106
delay(GAME_DELAY_IN_MS)
109107
}
110-
//TODO: emit return shortest path
111108
emit(
112109
DijkstraDomainModel(
113110
finished = true,
114111
shortestPath = getShortestPathOrder(allNodes[finishIndex])
115112
)
116113
)
117-
//return visitedNodesInOrder
118114
}
119115
}
120116

@@ -151,12 +147,9 @@ class DijkstraImpl {
151147
col: Int
152148
) {
153149
val unvisitedNeighbors = getUnvisitedNeighbors(cell, allNodes, row, col)
154-
155150
for (neighbor in unvisitedNeighbors) {
156151
val index = unvisitedNodes.findIndexByCell(neighbor)
157-
158152
if (index != -1) {
159-
//PETA
160153
unvisitedNodes[index].distance = cell.distance + 1
161154
unvisitedNodes[index].previousShortestCell = cell
162155
}

app/src/main/java/com/waleska404/algorithms/ui/core/theme/Color.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,5 @@ val DisabledColorLight = Color(0xFF8A93A7)
2222
// shared
2323
val AccentGreen = Color(0xFF00FF00)
2424
val AccentRed = Color(0xFFFF0000)
25+
val AccentYellow = Color(0xFFFFFF00)
2526

app/src/main/java/com/waleska404/algorithms/ui/core/theme/Theme.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ private val DarkColorScheme = darkColorScheme(
2020
background = MainColorDark,
2121
surface = DisabledColorDark,
2222
outline = AccentGreen,
23-
outlineVariant = AccentRed
23+
outlineVariant = AccentRed,
24+
inverseSurface = AccentYellow
2425
)
2526

2627
private val LightColorScheme = lightColorScheme(
@@ -32,7 +33,8 @@ private val LightColorScheme = lightColorScheme(
3233
background = MainColorLight,
3334
surface = DisabledColorLight,
3435
outline = AccentGreen,
35-
outlineVariant = AccentRed
36+
outlineVariant = AccentRed,
37+
inverseSurface = AccentYellow
3638

3739
/* Other default colors to override
3840
surface = Color(0xFFFFFBFE),

app/src/main/java/com/waleska404/algorithms/ui/dijkstra/Cell.kt

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ fun Cell(cellData: CellData, onClick: (Position) -> Unit) {
6161

6262
@Composable
6363
private fun getBackgroundByType(cellData: CellData): Color {
64-
if (cellData.isShortestPath && cellData.type != CellType.START && cellData.type != CellType.FINISH) return CELL_PATH
64+
if (cellData.isShortestPath && cellData.type != CellType.START && cellData.type != CellType.FINISH) return MaterialTheme.colorScheme.inverseSurface
6565
if (cellData.isVisited && cellData.type != CellType.START && cellData.type != CellType.FINISH) return MaterialTheme.colorScheme.onSecondary
6666

6767
return when (cellData.type) {
@@ -77,8 +77,4 @@ enum class CellType {
7777
FINISH,
7878
WALL,
7979
BACKGROUND,
80-
}
81-
82-
//val CELL_START = Color.Red
83-
//val CELL_FINISH = Color.Green
84-
val CELL_PATH = Color.Yellow
80+
}

app/src/main/java/com/waleska404/algorithms/ui/dijkstra/DijkstraModel.kt

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,4 @@ data class CellData(
1414
val position: Position,
1515
val isVisited: Boolean = false,
1616
val isShortestPath: Boolean = false,
17-
var distance: Int = Int.MAX_VALUE,
18-
var previousShortestCell: CellData? = null,
19-
var id: Int = (0..Int.MAX_VALUE).random()
2017
)

app/src/main/java/com/waleska404/algorithms/ui/dijkstra/DijkstraViewModel.kt

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
package com.waleska404.algorithms.ui.dijkstra
22

3-
import android.util.Log
43
import androidx.lifecycle.ViewModel
54
import androidx.lifecycle.viewModelScope
6-
import com.waleska404.algorithms.domain.dijkstra.DijkstraImpl
5+
import com.waleska404.algorithms.domain.dijkstra.Dijkstra
76
import com.waleska404.algorithms.domain.dijkstra.Position
87
import dagger.hilt.android.lifecycle.HiltViewModel
98
import kotlinx.coroutines.cancel
@@ -13,20 +12,19 @@ import kotlinx.coroutines.flow.StateFlow
1312
import kotlinx.coroutines.launch
1413
import javax.inject.Inject
1514

15+
//TODO: check best practice to do this
1616
const val NUMBER_OF_ROWS = 16
1717
const val NUMBER_OF_COLUMNS = 9
1818

1919
const val GAME_DELAY_IN_MS = 10.toLong()
2020

2121
@HiltViewModel
2222
class DijkstraViewModel @Inject constructor(
23-
val dijkstra: DijkstraImpl
23+
val dijkstra: Dijkstra
2424
) : ViewModel() {
2525

26-
//private val startPosition = Position((NUMBER_OF_ROWS / 2), (NUMBER_OF_COLUMNS / 4))
26+
//TODO: check best practice to do this
2727
private val startPosition = Position(1, 4)
28-
29-
//private val finishPosition = Position((NUMBER_OF_ROWS / 2), (NUMBER_OF_COLUMNS / 4) * 3)
3028
private val finishPosition = Position(14, 4)
3129

3230
private var walls: MutableList<Position> = mutableListOf()
@@ -114,7 +112,7 @@ class DijkstraViewModel @Inject constructor(
114112
fun animatedShortestPath() {
115113
viewModelScope.launch {
116114
_isVisualizing.value = true
117-
val shortestPath = dijkstra.animatedDijkstra(
115+
dijkstra.animatedDijkstra(
118116
gridSize = NUMBER_OF_ROWS * NUMBER_OF_COLUMNS,
119117
row = NUMBER_OF_ROWS,
120118
col = NUMBER_OF_COLUMNS,
@@ -125,7 +123,6 @@ class DijkstraViewModel @Inject constructor(
125123
if (dijkstraInfo.unreachable) this.cancel(null)
126124
if (dijkstraInfo.finished && !dijkstraInfo.shortestPath.isNullOrEmpty()) {
127125
dijkstraInfo.shortestPath.forEach {
128-
Log.i("MYTAG", "shortestPath: ${it.position.row}, ${it.position.column}")
129126
val p = it.position
130127
updateCellIsShortestPathAtPosition(p, true)
131128
delay(GAME_DELAY_IN_MS)
@@ -134,19 +131,12 @@ class DijkstraViewModel @Inject constructor(
134131
updateCellIsVisitedAtPosition(dijkstraInfo.position, true)
135132
}
136133
}
137-
/*
138-
shortestPath.forEach {
139-
val p = it.position
140-
gridState[p.row][p.column] = getCellAtPosition(p).copy(isShortestPath = true)
141-
delay(GAME_DELAY_IN_MS)
142-
}*/
143134
}
144135
}
145136

146137
private fun getCellAtPosition(p: Position) = _gridState.value.grid[p.row][p.column]
147138

148139
private fun getInitialGrid(): DijkstraGrid {
149-
Log.i("MYTAG", "getInitialGRID: startPosition: $startPosition, finishPosition: $finishPosition")
150140
val mutableGrid = List(NUMBER_OF_ROWS) {
151141
MutableList(NUMBER_OF_COLUMNS) {
152142
CellData(CellType.BACKGROUND, Position(0, 0))
@@ -155,10 +145,8 @@ class DijkstraViewModel @Inject constructor(
155145
for (i in 0 until NUMBER_OF_ROWS) {
156146
for (j in 0 until NUMBER_OF_COLUMNS) {
157147
if (startPosition == Position(i, j)) {
158-
Log.i("MYTAG", "START POSITION: $i, $j")
159148
mutableGrid[i][j] = CellData(CellType.START, Position(i, j))
160149
} else if (finishPosition == Position(i, j)) {
161-
Log.i("MYTAG", "FINISH POSITION: $i, $j")
162150
mutableGrid[i][j] = CellData(CellType.FINISH, Position(i, j))
163151
} else {
164152
mutableGrid[i][j] = CellData(CellType.BACKGROUND, Position(i, j))

0 commit comments

Comments
 (0)