Added simon
12
korge-simon/common/build.gradle
Normal file
@@ -0,0 +1,12 @@
|
||||
apply plugin: 'kotlin-platform-common'
|
||||
|
||||
sourceSets {
|
||||
main.resources.srcDirs = [ 'src/main/resources', 'src/generated/resources' ]
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile "com.soywiz:korge-common:$korVersion"
|
||||
compile "com.soywiz:korge-ext-swf-common:$korVersion"
|
||||
compile "com.soywiz:korge-ext-ui-common:$korVersion"
|
||||
compile "com.soywiz:korau-mp3-common:$korVersion"
|
||||
}
|
||||
1
korge-simon/common/settings.gradle
Normal file
@@ -0,0 +1 @@
|
||||
rootProject.name = 'korge-simon-common'
|
||||
135
korge-simon/common/src/generated/resources/kotlin.atlas.json
Normal file
@@ -0,0 +1,135 @@
|
||||
{
|
||||
"frames": {
|
||||
"0.png": {
|
||||
"frame": {
|
||||
"x": 2,
|
||||
"y": 2,
|
||||
"w": 32,
|
||||
"h": 40
|
||||
},
|
||||
"rotated": false,
|
||||
"sourceSize": {
|
||||
"w": 32,
|
||||
"h": 40
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 32,
|
||||
"h": 40
|
||||
},
|
||||
"trimmed": false
|
||||
},
|
||||
"1.png": {
|
||||
"frame": {
|
||||
"x": 2,
|
||||
"y": 42,
|
||||
"w": 32,
|
||||
"h": 40
|
||||
},
|
||||
"rotated": false,
|
||||
"sourceSize": {
|
||||
"w": 32,
|
||||
"h": 40
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 32,
|
||||
"h": 40
|
||||
},
|
||||
"trimmed": false
|
||||
},
|
||||
"2.png": {
|
||||
"frame": {
|
||||
"x": 2,
|
||||
"y": 82,
|
||||
"w": 32,
|
||||
"h": 40
|
||||
},
|
||||
"rotated": false,
|
||||
"sourceSize": {
|
||||
"w": 32,
|
||||
"h": 40
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 32,
|
||||
"h": 40
|
||||
},
|
||||
"trimmed": false
|
||||
},
|
||||
"3.png": {
|
||||
"frame": {
|
||||
"x": 2,
|
||||
"y": 122,
|
||||
"w": 32,
|
||||
"h": 40
|
||||
},
|
||||
"rotated": false,
|
||||
"sourceSize": {
|
||||
"w": 32,
|
||||
"h": 40
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 32,
|
||||
"h": 40
|
||||
},
|
||||
"trimmed": false
|
||||
},
|
||||
"4.png": {
|
||||
"frame": {
|
||||
"x": 2,
|
||||
"y": 162,
|
||||
"w": 32,
|
||||
"h": 40
|
||||
},
|
||||
"rotated": false,
|
||||
"sourceSize": {
|
||||
"w": 32,
|
||||
"h": 40
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 32,
|
||||
"h": 40
|
||||
},
|
||||
"trimmed": false
|
||||
},
|
||||
"5.png": {
|
||||
"frame": {
|
||||
"x": 2,
|
||||
"y": 202,
|
||||
"w": 32,
|
||||
"h": 40
|
||||
},
|
||||
"rotated": false,
|
||||
"sourceSize": {
|
||||
"w": 32,
|
||||
"h": 40
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 32,
|
||||
"h": 40
|
||||
},
|
||||
"trimmed": false
|
||||
}
|
||||
},
|
||||
"meta": {
|
||||
"app": "korge",
|
||||
"format": "RGBA8888",
|
||||
"image": "kotlin.atlas.png",
|
||||
"scale": 1.0,
|
||||
"size": {
|
||||
"w": 32,
|
||||
"h": 240
|
||||
},
|
||||
"version": "0.10.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
{"name":"kotlin.atlas","loaderVersion":0,"sha1":"f096d009db1e83bdd171bdd91f830bcb32e2be70","configSha1":""}
|
||||
BIN
korge-simon/common/src/generated/resources/kotlin.atlas.png
Normal file
|
After Width: | Height: | Size: 664 B |
@@ -5,26 +5,32 @@ import com.soywiz.korge.atlas.Atlas
|
||||
import com.soywiz.korge.audio.SoundFile
|
||||
import com.soywiz.korge.audio.SoundSystem
|
||||
import com.soywiz.korge.audio.readSoundFile
|
||||
import com.soywiz.korge.html.Html
|
||||
import com.soywiz.korge.input.mouse
|
||||
import com.soywiz.korge.plugin.KorgePlugin
|
||||
import com.soywiz.korge.resources.Path
|
||||
import com.soywiz.korge.resources.getPath
|
||||
import com.soywiz.korge.scene.Module
|
||||
import com.soywiz.korge.scene.ScaledScene
|
||||
import com.soywiz.korge.scene.Scene
|
||||
import com.soywiz.korge.scene.sleep
|
||||
import com.soywiz.korge.time.seconds
|
||||
import com.soywiz.korge.ui.UIFactory
|
||||
import com.soywiz.korge.ui.UIPlugin
|
||||
import com.soywiz.korge.ui.korui.koruiFrame
|
||||
import com.soywiz.korge.util.AutoClose
|
||||
import com.soywiz.korge.view.*
|
||||
import com.soywiz.korge.view.Container
|
||||
import com.soywiz.korge.view.Image
|
||||
import com.soywiz.korge.view.image
|
||||
import com.soywiz.korim.color.Colors
|
||||
import com.soywiz.korio.async.Signal
|
||||
import com.soywiz.korio.async.go
|
||||
import com.soywiz.korio.async.waitOne
|
||||
import com.soywiz.korio.inject.AsyncInjector
|
||||
import com.soywiz.korio.inject.Optional
|
||||
import com.soywiz.korio.util.substr
|
||||
import com.soywiz.korio.lang.JvmStatic
|
||||
import com.soywiz.korma.geom.ISize
|
||||
import com.soywiz.korma.geom.SizeInt
|
||||
import com.soywiz.korma.random.MtRand
|
||||
import com.soywiz.korma.random.get
|
||||
import com.soywiz.korui.geom.len.Padding
|
||||
import com.soywiz.korui.geom.len.em
|
||||
@@ -32,29 +38,38 @@ import com.soywiz.korui.style.padding
|
||||
import com.soywiz.korui.ui.button
|
||||
import com.soywiz.korui.ui.click
|
||||
import com.soywiz.korui.ui.horizontal
|
||||
import java.util.*
|
||||
|
||||
object Simon : Module() {
|
||||
@JvmStatic fun main(args: Array<String>) = Korge(this)
|
||||
@JvmStatic
|
||||
fun main(args: Array<String>) = Korge(this, injector = AsyncInjector()
|
||||
.mapPrototype { SelectLevelScene(getPath("kotlin.atlas"), get()) }
|
||||
.mapPrototype {
|
||||
IngameScene(
|
||||
getPath(Atlas::class, "kotlin.atlas"),
|
||||
getPath(SoundFile::class, "sounds/success.wav"),
|
||||
getPath(SoundFile::class, "sounds/fail.mp3"),
|
||||
getOrNull(),
|
||||
get()
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
override val size: SizeInt = SizeInt(1280, 720)
|
||||
override val windowSize: SizeInt = size * 0.75
|
||||
|
||||
override val title: String = "Kotlin Simon"
|
||||
|
||||
override val icon: String = "kotlin/0.png"
|
||||
//override val mainScene: Class<out Scene> = MainScene::class.java
|
||||
override val mainScene: Class<out Scene> = SelectLevelScene::class.java
|
||||
override val size = SizeInt(1280, 720)
|
||||
override val windowSize = size * 0.75
|
||||
override val title = "Kotlin Simon"
|
||||
override val icon = "kotlin/0.png"
|
||||
override val mainScene = SelectLevelScene::class
|
||||
|
||||
override val plugins: List<KorgePlugin> = super.plugins + listOf(UIPlugin)
|
||||
|
||||
class Sequence(
|
||||
val max: Int,
|
||||
val random: Random = Random()
|
||||
val random: MtRand = MtRand()
|
||||
) {
|
||||
val items = arrayListOf<Int>()
|
||||
val items = ArrayList<Int>()
|
||||
|
||||
fun ensure(num: Int): List<Int> {
|
||||
while (items.size < num) items += random[0, max]
|
||||
while (items.size < num) items.add(random[0, max])
|
||||
return items
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 49 KiB |
|
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 49 KiB |
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 49 KiB |
|
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 49 KiB |
|
Before Width: | Height: | Size: 335 B After Width: | Height: | Size: 335 B |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
17
korge-simon/jvm/build.gradle
Normal file
@@ -0,0 +1,17 @@
|
||||
apply plugin: 'kotlin-platform-jvm'
|
||||
apply plugin: 'application'
|
||||
|
||||
mainClassName = 'com.soywiz.korge.samples.simon.Simon'
|
||||
|
||||
sourceSets {
|
||||
main.resources.srcDirs = [ '../common/src/main/resources', '../common/src/generated/resources' ]
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implement project(":korge-simon:common")
|
||||
|
||||
compile "com.soywiz:korge:$korVersion"
|
||||
compile "com.soywiz:korge-ext-swf:$korVersion"
|
||||
compile "com.soywiz:korge-ext-ui:$korVersion"
|
||||
compile "com.soywiz:korau-mp3:$korVersion"
|
||||
}
|
||||
1
korge-simon/jvm/settings.gradle
Normal file
@@ -0,0 +1 @@
|
||||
rootProject.name = 'korge-simon'
|
||||
@@ -2,6 +2,7 @@ package com.soywiz.korge.tictactoe
|
||||
|
||||
import com.soywiz.korge.animate.play
|
||||
import com.soywiz.korge.input.onClick
|
||||
import com.soywiz.korge.input.onUp
|
||||
import com.soywiz.korge.time.milliseconds
|
||||
import com.soywiz.korge.tween.*
|
||||
import com.soywiz.korge.view.View
|
||||
@@ -86,7 +87,7 @@ suspend fun Board.reset() {
|
||||
fun Board.Cell.init(view: View) {
|
||||
this.view = view
|
||||
set(this.value)
|
||||
view["hit"].onClick {
|
||||
view["hit"].onUp {
|
||||
onPress(Unit)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
package com.soywiz.korge.tictactoe
|
||||
|
||||
import com.soywiz.korio.util.Extra
|
||||
import com.soywiz.korma.ds.Array2
|
||||
import com.soywiz.korma.geom.PointInt
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
enum class Chip { EMPTY, CROSS, CIRCLE }
|
||||
|
||||
class Board(val width: Int = 3, val height: Int = width, val lineSize: Int = width) {
|
||||
class Cell(val x: Int, val y: Int) : Extra by Extra.Mixin() {
|
||||
val pos = PointInt(x, y)
|
||||
var value = Chip.EMPTY
|
||||
}
|
||||
|
||||
val cells = Array2(width, height) { Cell(it % width, it / width) }
|
||||
|
||||
fun inside(x: Int, y: Int) = cells.inside(x, y)
|
||||
|
||||
fun select(x: Int, y: Int, dx: Int, dy: Int, size: Int): List<Cell>? {
|
||||
if (!inside(x, y)) return null
|
||||
if (!inside(x + dx * (size - 1), y + dy * (size - 1))) return null
|
||||
return (0 until size).map { cells[x + dx * it, y + dy * it] }
|
||||
}
|
||||
|
||||
val lines = kotlin.collections.ArrayList<List<Cell>>()
|
||||
|
||||
init {
|
||||
fun addLine(line: List<Cell>?) {
|
||||
if (line != null) lines += line
|
||||
}
|
||||
for (y in 0..height) {
|
||||
for (x in 0..width) {
|
||||
addLine(select(x, y, 1, 0, lineSize))
|
||||
addLine(select(x, y, 0, 1, lineSize))
|
||||
addLine(select(x, y, 1, 1, lineSize))
|
||||
addLine(select(width - x - 1, y, -1, 1, lineSize))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
operator fun get(x: Int, y: Int) = cells[x, y]
|
||||
operator fun set(x: Int, y: Int, value: Chip) = run { cells[x, y].value = value }
|
||||
|
||||
val Iterable<Cell>.chipLine: Chip?
|
||||
get() {
|
||||
val expected = this.first().value
|
||||
return if (expected == Chip.EMPTY) null else if (this.all { it.value == expected }) expected else null
|
||||
}
|
||||
|
||||
val moreMovements: Boolean get() = cells.any { it.value == Chip.EMPTY }
|
||||
|
||||
val winnerLine: List<Cell>?
|
||||
get() {
|
||||
val out = kotlin.collections.ArrayList<Cell>()
|
||||
for (line in lines) if (line.chipLine != null) out += line
|
||||
return if (out.isEmpty()) null else out.toSet().toList()
|
||||
}
|
||||
|
||||
val winner: Chip?
|
||||
get() {
|
||||
return winnerLine?.firstOrNull()?.value
|
||||
}
|
||||
}
|
||||
@@ -1,92 +0,0 @@
|
||||
package com.soywiz.korge.tictactoe
|
||||
|
||||
import com.soywiz.korge.animate.play
|
||||
import com.soywiz.korge.input.onClick
|
||||
import com.soywiz.korge.time.milliseconds
|
||||
import com.soywiz.korge.tween.*
|
||||
import com.soywiz.korge.view.View
|
||||
import com.soywiz.korge.view.get
|
||||
import com.soywiz.korio.async.Signal
|
||||
import com.soywiz.korio.async.async
|
||||
import com.soywiz.korio.util.Extra
|
||||
|
||||
var Board.Cell.view by Extra.Property<View?> { null }
|
||||
val Board.Cell.vview: View get() = this.view!!
|
||||
val Board.Cell.onPress by Extra.Property { Signal<Unit>() }
|
||||
|
||||
fun Board.Cell.set(type: Chip) {
|
||||
this.value = type
|
||||
view["chip"].play(when (type) {
|
||||
Chip.EMPTY -> "empty"
|
||||
Chip.CIRCLE -> "circle"
|
||||
Chip.CROSS -> "cross"
|
||||
})
|
||||
}
|
||||
|
||||
suspend fun Board.Cell.setAnimate(type: Chip) {
|
||||
set(type)
|
||||
async {
|
||||
view.tween(
|
||||
(view["chip"]!!::alpha[0.7, 1.0]).linear(),
|
||||
(view["chip"]!!::scale[0.8, 1.0]).easeOutElastic(),
|
||||
time = 300.milliseconds
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
var Board.Cell.highlighting by Extra.Property { false }
|
||||
|
||||
suspend fun Board.Cell.highlight(highlight: Boolean) {
|
||||
view["highlight"].play(if (highlight) "highlight" else "none")
|
||||
this.highlighting = highlight
|
||||
if (highlight) {
|
||||
async {
|
||||
|
||||
val hl = view["highlight"]!!
|
||||
while (highlighting) {
|
||||
hl.tween((hl::alpha[0.7]).easeInOutQuad(), time = 300.milliseconds)
|
||||
hl.tween((hl::alpha[1.0]).easeInOutQuad(), time = 200.milliseconds)
|
||||
}
|
||||
}
|
||||
|
||||
async {
|
||||
val ch = view["chip"]!!
|
||||
ch.tween((ch::scale[0.4]).easeOutQuad(), time = 100.milliseconds)
|
||||
ch.tween((ch::scale[1.2]).easeOutElastic(), time = 300.milliseconds)
|
||||
while (highlighting) {
|
||||
ch.tween((ch::scale[1.0]).easeOutQuad(), time = 300.milliseconds)
|
||||
ch.tween((ch::scale[1.2]).easeOutElastic(), time = 300.milliseconds)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun Board.Cell.lowlight(lowlight: Boolean) {
|
||||
async {
|
||||
view.tween(
|
||||
view!!::scale[1.0, 0.7],
|
||||
view!!::alpha[0.3],
|
||||
time = 300.milliseconds, easing = Easings.EASE_OUT_QUAD
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun Board.reset() {
|
||||
for (cell in cells) {
|
||||
//cell.view?.removeAllComponents()
|
||||
cell.set(Chip.EMPTY)
|
||||
cell.highlight(false)
|
||||
cell.view?.scale = 1.0
|
||||
cell.view?.alpha = 1.0
|
||||
cell.view["chip"]?.scale = 1.0
|
||||
cell.view["chip"]?.alpha = 1.0
|
||||
}
|
||||
}
|
||||
|
||||
fun Board.Cell.init(view: View) {
|
||||
this.view = view
|
||||
set(this.value)
|
||||
view["hit"].onClick {
|
||||
onPress(Unit)
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
package com.soywiz.korge.tictactoe
|
||||
|
||||
import com.soywiz.korge.animate.AnLibrary
|
||||
import com.soywiz.korge.resources.getPath
|
||||
import com.soywiz.korio.inject.AsyncInjector
|
||||
|
||||
// AUTOGENERATED:
|
||||
fun AsyncInjector.generatedInject() = this
|
||||
//.mapPrototype { TicTacToeMainScene(getPath("main.ani")) } // @TODO: kotlin.js bug
|
||||
.mapPrototype { TicTacToeMainScene(getPath(AnLibrary::class, "main.ani")) }
|
||||
@@ -1,146 +0,0 @@
|
||||
package com.soywiz.korge.tictactoe
|
||||
|
||||
import com.soywiz.korge.Korge
|
||||
import com.soywiz.korge.animate.AnLibrary
|
||||
import com.soywiz.korge.animate.AnLibraryPlugin
|
||||
import com.soywiz.korge.input.mouse
|
||||
import com.soywiz.korge.plugin.KorgePlugin
|
||||
import com.soywiz.korge.resources.Path
|
||||
import com.soywiz.korge.scene.Module
|
||||
import com.soywiz.korge.scene.Scene
|
||||
import com.soywiz.korge.view.Container
|
||||
import com.soywiz.korge.view.descendantsWithPropInt
|
||||
import com.soywiz.korge.view.get
|
||||
import com.soywiz.korge.view.setText
|
||||
import com.soywiz.korio.async.Signal
|
||||
import com.soywiz.korio.async.go
|
||||
import com.soywiz.korio.async.waitOne
|
||||
import com.soywiz.korio.error.invalidOp
|
||||
import com.soywiz.korio.inject.AsyncInjector
|
||||
import com.soywiz.korio.lang.JvmStatic
|
||||
import com.soywiz.korma.geom.PointInt
|
||||
|
||||
object TicTacToe {
|
||||
@JvmStatic
|
||||
fun main(args: Array<String>) = Korge(TicTacToeModule, injector = AsyncInjector().generatedInject())
|
||||
}
|
||||
|
||||
object TicTacToeModule : Module() {
|
||||
override val mainScene = TicTacToeMainScene::class
|
||||
override val title: String = "tic-tac-toe"
|
||||
override val icon: String = "icon.png"
|
||||
override val plugins: List<KorgePlugin> = super.plugins + listOf(
|
||||
AnLibraryPlugin
|
||||
)
|
||||
|
||||
suspend override fun init(injector: AsyncInjector) {
|
||||
//injector.get<ResourcesRoot>().mapExtensions("swf" to "ani")
|
||||
//injector.get<ResourcesRoot>().mapExtensionsJustInJTransc("swf" to "ani")
|
||||
}
|
||||
}
|
||||
|
||||
// Controller
|
||||
class TicTacToeMainScene(
|
||||
@Path("main.ani") val mainLibrary: AnLibrary
|
||||
) : Scene() {
|
||||
val board = Board(3, 3)
|
||||
lateinit var game: Game
|
||||
|
||||
suspend override fun sceneInit(sceneView: Container) {
|
||||
sceneView += mainLibrary.createMainTimeLine()
|
||||
|
||||
for ((rowView, row) in sceneView.descendantsWithPropInt("row")) {
|
||||
for ((cellView, cell) in rowView.descendantsWithPropInt("cell")) {
|
||||
board.cells[row, cell].init(cellView)
|
||||
}
|
||||
}
|
||||
|
||||
val p1 = InteractivePlayer(board, Chip.CROSS)
|
||||
val p2 = BotPlayer(board, Chip.CIRCLE)
|
||||
//val p2 = InteractivePlayer(board, Chip.CIRCLE)
|
||||
|
||||
game = Game(board, listOf(p1, p2))
|
||||
cancellables += go {
|
||||
while (true) {
|
||||
game.board.reset()
|
||||
val result = game.game()
|
||||
|
||||
println(result)
|
||||
|
||||
val results = mainLibrary.createMovieClip("Results")
|
||||
//(results["result"] as AnTextField).format?.face = Html.FontFace.Bitmap(font)
|
||||
when (result) {
|
||||
is Game.Result.DRAW -> results["result"].setText("DRAW")
|
||||
is Game.Result.WIN -> {
|
||||
results["result"].setText("WIN")
|
||||
for (cell in result.cells) cell.highlight(true)
|
||||
for (cell in game.board.cells.toList() - result.cells) cell.lowlight(true)
|
||||
}
|
||||
}
|
||||
sceneView += results
|
||||
results["hit"]?.mouse?.onClick?.waitOne()
|
||||
//sceneView -= results
|
||||
results.removeFromParent()
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface Player {
|
||||
val chip: Chip
|
||||
suspend fun move(): PointInt
|
||||
}
|
||||
|
||||
class Game(val board: Board, val players: List<Player>) {
|
||||
interface Result {
|
||||
object DRAW : Result
|
||||
class WIN(val player: Player?, val cells: List<Board.Cell>) : Result
|
||||
}
|
||||
|
||||
suspend fun game(): Result {
|
||||
var turn = 0
|
||||
while (board.moreMovements) {
|
||||
val currentPlayer = players[turn % players.size]
|
||||
while (true) {
|
||||
val pos = currentPlayer.move()
|
||||
println(pos)
|
||||
if (board.cells[pos].value == Chip.EMPTY) {
|
||||
board.cells[pos].setAnimate(currentPlayer.chip)
|
||||
break
|
||||
}
|
||||
}
|
||||
if (board.winner != null) return Result.WIN(currentPlayer, board.winnerLine ?: listOf())
|
||||
turn++
|
||||
}
|
||||
return Result.DRAW
|
||||
}
|
||||
}
|
||||
|
||||
class BotPlayer(val board: Board, override val chip: Chip) : Player {
|
||||
suspend override fun move(): PointInt {
|
||||
for (cell in board.cells) {
|
||||
if (cell.value == Chip.EMPTY) {
|
||||
return cell.pos
|
||||
}
|
||||
}
|
||||
invalidOp("No more movements")
|
||||
}
|
||||
}
|
||||
|
||||
class InteractivePlayer(val board: Board, override val chip: Chip) : Player {
|
||||
val clicked = Signal<PointInt>()
|
||||
|
||||
init {
|
||||
for (cell in board.cells) {
|
||||
cell.onPress {
|
||||
clicked(cell.pos)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
suspend override fun move(): PointInt {
|
||||
return clicked.waitOne()
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,6 +5,10 @@ include(
|
||||
'korge-tic-tac-toe:js',
|
||||
'korge-tic-tac-toe:jvm',
|
||||
|
||||
'korge-simon:common',
|
||||
'korge-simon:js',
|
||||
'korge-simon:jvm',
|
||||
|
||||
//'korge-coffee',
|
||||
//'korge-simon',
|
||||
)
|
||||
|
||||