diff --git a/game-of-life-multiplatform/common/src/main/kotlin/com/novoda/gol/data/SimulationBoardEntity.kt b/game-of-life-multiplatform/common/src/main/kotlin/com/novoda/gol/data/SimulationBoardEntity.kt index 3929d9914..f1b72ad7f 100644 --- a/game-of-life-multiplatform/common/src/main/kotlin/com/novoda/gol/data/SimulationBoardEntity.kt +++ b/game-of-life-multiplatform/common/src/main/kotlin/com/novoda/gol/data/SimulationBoardEntity.kt @@ -8,7 +8,7 @@ data class SimulationBoardEntity(private val cellMatrix: CellMatrix) : BoardEnti val seeds = this.cellMatrix.getSeeds().toMutableList() seeds.addAll(patternEntity.getSeeds()) - val cellMatrix = ListBasedMatrix(width = 50, height = 50, seeds = seeds) + val cellMatrix = ListBasedMatrix(width = cellMatrix.getWidth(), height = cellMatrix.getHeight(), seeds = seeds) return SimulationBoardEntity(cellMatrix) } diff --git a/game-of-life-multiplatform/game-of-life-jvm/build.gradle b/game-of-life-multiplatform/game-of-life-jvm/build.gradle index e5a92a99e..a8823d60d 100644 --- a/game-of-life-multiplatform/game-of-life-jvm/build.gradle +++ b/game-of-life-multiplatform/game-of-life-jvm/build.gradle @@ -2,6 +2,7 @@ apply plugin: 'kotlin-platform-jvm' dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" + compile group: 'io.reactivex.rxjava2', name: 'rxjava', version: '2.1.1' expectedBy project(":common") testCompile "junit:junit:4.12" testCompile "org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version" diff --git a/game-of-life-multiplatform/game-of-life-jvm/src/main/kotlin/com/novoda/gol/GameLoop.kt b/game-of-life-multiplatform/game-of-life-jvm/src/main/kotlin/com/novoda/gol/GameLoop.kt new file mode 100644 index 000000000..54536f42a --- /dev/null +++ b/game-of-life-multiplatform/game-of-life-jvm/src/main/kotlin/com/novoda/gol/GameLoop.kt @@ -0,0 +1,27 @@ +package com.novoda.gol + +import io.reactivex.Flowable +import io.reactivex.disposables.Disposable +import java.util.concurrent.TimeUnit + +actual class GameLoop actual constructor() { + + private var gameLoop: Disposable? = null + + actual var onTick: () -> Unit = {} + + actual fun startWith(intervalMs: Int) { + gameLoop = Flowable.interval(intervalMs.toLong(), TimeUnit.MILLISECONDS).subscribe { + onTick() + } + } + + actual fun stop() { + gameLoop?.dispose() + gameLoop = null + + } + + actual fun isLooping() = gameLoop != null + +} diff --git a/game-of-life-multiplatform/game-of-life-jvm/src/main/kotlin/com/novoda/gol/presentation/AppTerminalView.kt b/game-of-life-multiplatform/game-of-life-jvm/src/main/kotlin/com/novoda/gol/presentation/AppTerminalView.kt new file mode 100644 index 000000000..68f7feae5 --- /dev/null +++ b/game-of-life-multiplatform/game-of-life-jvm/src/main/kotlin/com/novoda/gol/presentation/AppTerminalView.kt @@ -0,0 +1,49 @@ +package com.novoda.gol.presentation + +import com.novoda.gol.patterns.Glider +import com.novoda.gol.patterns.PatternEntity +import io.reactivex.Observable +import io.reactivex.schedulers.Schedulers +import java.io.BufferedReader +import java.io.InputStreamReader + +class AppTerminalView : AppView { + + override var onControlButtonClicked: () -> Unit = {} + + override var onPatternSelected: (pattern: PatternEntity) -> Unit = {} + + private val presenter = AppPresenter() + + fun onCreate() { + presenter.bind(this) + + Observable + .fromCallable { + readString() + } + .filter { it == "yes" } + .subscribeOn(Schedulers.io()) + .subscribe { + onPatternSelected(Glider.create()) + onControlButtonClicked() + } + } + + override fun renderControlButtonLabel(controlButtonLabel: String) { + print("$controlButtonLabel\n") + } + + private fun readString(): String { + val bufferedReader = BufferedReader(InputStreamReader(System.`in`)) + return bufferedReader.readLine().toString() + } + + override fun renderPatternSelectionVisibility(visibility: Boolean) { + //TODO: pattern selection is ignored in first iteration + } + + override fun renderBoard(boardViewState: BoardViewState) { + BoardTerminalView().onCreate(boardViewState) + } +} diff --git a/game-of-life-multiplatform/game-of-life-jvm/src/main/kotlin/com/novoda/gol/presentation/BoardTerminalView.kt b/game-of-life-multiplatform/game-of-life-jvm/src/main/kotlin/com/novoda/gol/presentation/BoardTerminalView.kt new file mode 100644 index 000000000..952e1b6f3 --- /dev/null +++ b/game-of-life-multiplatform/game-of-life-jvm/src/main/kotlin/com/novoda/gol/presentation/BoardTerminalView.kt @@ -0,0 +1,38 @@ +package com.novoda.gol.presentation + +import com.novoda.gol.data.BoardEntity +import com.novoda.gol.data.PositionEntity +import com.novoda.gol.patterns.PatternEntity + +class BoardTerminalView : BoardView { + + override var onPatternSelected: (pattern: PatternEntity) -> Unit = {} + override var onCellClicked: (position: PositionEntity) -> Unit = {} + override var onStartSimulationClicked: () -> Unit = {} + override var onStopSimulationClicked: () -> Unit = {} + + private var presenter = BoardPresenter(width = 20, height = 20) + + fun onCreate(boardViewState: BoardViewState) { + presenter.bind(this) + if (boardViewState.selectedPattern != null) { + onPatternSelected(boardViewState.selectedPattern!!) + onStartSimulationClicked() + } + } + + override fun renderBoard(boardEntity: BoardEntity) { + for (y in 0 until boardEntity.getHeight()) { + for (x in 0 until boardEntity.getWidth()) { + val cellAtPosition = boardEntity.cellAtPosition(x, y) + if (cellAtPosition.isAlive) { + print("X") + } else { + print(" ") + } + + } + print("\n") + } + } +} diff --git a/game-of-life-multiplatform/game-of-life-jvm/src/main/kotlin/com/novoda/gol/terminal/Main.kt b/game-of-life-multiplatform/game-of-life-jvm/src/main/kotlin/com/novoda/gol/terminal/Main.kt index 85374737d..cd43ca538 100644 --- a/game-of-life-multiplatform/game-of-life-jvm/src/main/kotlin/com/novoda/gol/terminal/Main.kt +++ b/game-of-life-multiplatform/game-of-life-jvm/src/main/kotlin/com/novoda/gol/terminal/Main.kt @@ -1,58 +1,14 @@ package com.novoda.gol.terminal -import com.novoda.gol.data.BoardEntity -import com.novoda.gol.data.ListBasedMatrix -import com.novoda.gol.data.PositionEntity -import com.novoda.gol.data.SimulationBoardEntity -import java.io.BufferedReader -import java.io.InputStreamReader - -const val EXIT = "exit" +import com.novoda.gol.presentation.AppTerminalView fun main(args: Array) { + AppTerminalView().onCreate() - var keepLooping = true - val br = BufferedReader(InputStreamReader(System.`in`)) - - print("enter width: ") - val width = br.readLine().toInt() - - print("enter height: ") - val height = br.readLine().toInt() - - val cellMatrix = ListBasedMatrix(width = width, height = height, seeds = listOf(PositionEntity(2, 1), PositionEntity(2, 2), PositionEntity(2, 3))) - - var boardEntity: BoardEntity = SimulationBoardEntity(cellMatrix) - + while (true){ - while (keepLooping) { - val input = br.readLine() - keepLooping = input != EXIT - - render(boardEntity) - - if (keepLooping) { - boardEntity = boardEntity.nextIteration() - } } } -fun render(boardEntity: BoardEntity) { - for (y in 0 until boardEntity.getHeight()) { - for (x in 0 until boardEntity.getWidth()) { - val cellAtPosition = boardEntity.cellAtPosition(x, y) - if (cellAtPosition.isAlive) { - print("X") - } else { - print(" ") - } - - } - print("\n") - } - - print("exit: Stop Simulation\n") - print("next: Next Iteration\n") -}