Skip to content

Commit

Permalink
Migrate Game object to ViewModel
Browse files Browse the repository at this point in the history
Part of Issue #9
  • Loading branch information
Tadaboody committed Nov 19, 2018
1 parent 7eba381 commit c29fda2
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 39 deletions.
2 changes: 2 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
implementation 'com.android.support:support-v4:28.0.0'
implementation 'android.arch.lifecycle:extensions:1.1.1'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
Expand Down
14 changes: 8 additions & 6 deletions app/src/main/java/com/keren/tomer/minesweeper/GameActivity.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.keren.tomer.minesweeper

import android.arch.lifecycle.Observer
import android.arch.lifecycle.ViewModelProviders
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.util.Log
Expand All @@ -22,16 +24,16 @@ class GameActivity : AppCompatActivity() {
val width = intent.getIntExtra(INTENT_WIDTH, 15)
val height = intent.getIntExtra(INTENT_HEIGHT, 15)
val mines = intent.getIntExtra(INTENT_MINES, 15)
val game = Game(height, width, mines)
game.endCallback = {
val model = ViewModelProviders.of(this, GameViewModelFactory(width, height, mines)).get(GameViewModel::class.java)
model.winnState.observe(this, Observer {
game_zoom.engine.zoomTo(1.0F, true)
when (it) {//TODO
Game.EndState.WON -> game.revealBoard()
Game.EndState.LOST -> ""
Game.EndState.WON -> Log.i(TAG,"GAME WON!")
Game.EndState.LOST -> Log.i(TAG,"GAME LOST")
Game.EndState.UNDECIDED -> Log.e(TAG, "INVALID_STATE")
}
}
game_board.addGame(game)
})
game_board.addGame(model)
// game = Game(width = width,height=height,amountOfMines = mines)

}
Expand Down
24 changes: 12 additions & 12 deletions app/src/main/java/com/keren/tomer/minesweeper/GameBoardLayout.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,32 +11,32 @@ import utils.DoublyIndexedItem
* Adds a Minesweeper game to an existing GridLayout for rendering
* @param game The minesweeper instance to be added
*/
fun GridLayout.addGame(game: Game) {
rowCount = game.height
columnCount = game.width
game.board.flatten().forEach { item ->
fun GridLayout.addGame(viewModel: GameViewModel) {
rowCount = viewModel.height
columnCount = viewModel.width
viewModel.board.forEach { item ->
val params = GridLayout.LayoutParams(spec(item.i), spec(item.j))
addView(createView(game, item), params)
addView(createView(viewModel, item), params)
}
}

/**
* Creates a View to represent a game tile
* @param game The game the tile belongs to
* Creates a View to represent a viewModel tile
* @param viewModel The viewModel the tile belongs to
* @param item The IndexedTile that the View represent
* @return A View representing item
*/
fun GridLayout.createView(game: Game, item: DoublyIndexedItem<Tile>): View {
fun GridLayout.createView(viewModel: GameViewModel, item: DoublyIndexedItem<Tile>): View {
return ImageView(context).apply {
setImageResource(R.drawable.hidden_tile)
setOnLongClickListener {
game.holdTile(item.i, item.j)
updateBoard(game)
viewModel.holdTile(item.i, item.j)
updateBoard(viewModel.game)
true
}
setOnClickListener {
game.clickTile(item.i, item.j)
updateBoard(game)
viewModel.clickTile(item.i, item.j)
updateBoard(viewModel.game)
}
}
}
Expand Down
42 changes: 42 additions & 0 deletions app/src/main/java/com/keren/tomer/minesweeper/GameViewModel.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.keren.tomer.minesweeper

import android.arch.lifecycle.MutableLiveData
import android.arch.lifecycle.ViewModel
import android.arch.lifecycle.ViewModelProvider

class GameViewModel(height: Int, width: Int, amountOfMines: Int) : ViewModel() {
val game: Game = Game(height, width, amountOfMines).apply { endCallback = { winnState.value = it } }
val height = game.height
val width = game.width
val board = game.board.flatten()
val winnState: MutableLiveData<Game.EndState> = MutableLiveData()
val flagsLeft: MutableLiveData<Int> = MutableLiveData()
val tiles: List<MutableLiveData<IndexedTile>> = board.map { MutableLiveData<IndexedTile>().apply { value = it } }
val gameState = MutableLiveData<Game.EndState>()
private fun flagsLeft_() = game.amountOfMines - board.count { it.value.isFlagged }
fun holdTile(i: Int, j: Int) {
game.holdTile(i, j)
updateData()
}

private fun updateData() {
flagsLeft.value = flagsLeft_()
gameState.value = game.winState
}

fun clickTile(i: Int, j: Int) {
game.clickTile(i, j)
updateData()
}

}

class GameViewModelFactory(private val height: Int, private val width: Int, private val amountOfMines: Int) : ViewModelProvider.Factory {

override fun <T : ViewModel?> create(modelClass: Class<T>): T {
@Suppress("UNCHECKED_CAST")
return GameViewModel(height, width, amountOfMines) as T
}
}


2 changes: 2 additions & 0 deletions app/src/main/java/com/keren/tomer/minesweeper/Tile.kt
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ open class Tile {
}
}

fun isFalslyFlagged() = isFlagged and isMine

override fun toString(): String {
return when (state) {
State.MINE -> "MINE"
Expand Down
17 changes: 0 additions & 17 deletions app/src/test/java/com/keren/tomer/minesweeper/ExampleUnitTest.kt

This file was deleted.

7 changes: 3 additions & 4 deletions app/src/test/java/com/keren/tomer/minesweeper/GameTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,8 @@ class GameTest {

override fun plantMines(startingTile: IndexedTile) {
for ((lineNum, line) in gameString.lines().withIndex()) {
for ((charNum, char) in line.withIndex()) {
if (char == '1')
board[lineNum][charNum].value.plantMine()
line.filter { it == '1' }.withIndex().forEachIndexed { charNum, _ ->
board[lineNum][charNum].value.plantMine()
}
}
}
Expand Down Expand Up @@ -127,4 +126,4 @@ class GameTest {
assertEquals(true, notFlagged.all { it.value.isRevealed })
}

}
}

0 comments on commit c29fda2

Please sign in to comment.