summaryrefslogtreecommitdiff
path: root/sw-bot/src
diff options
context:
space:
mode:
Diffstat (limited to 'sw-bot/src')
-rw-r--r--sw-bot/src/main/kotlin/org/luxons/sevenwonders/bot/SevenWondersBot.kt62
1 files changed, 37 insertions, 25 deletions
diff --git a/sw-bot/src/main/kotlin/org/luxons/sevenwonders/bot/SevenWondersBot.kt b/sw-bot/src/main/kotlin/org/luxons/sevenwonders/bot/SevenWondersBot.kt
index 7530b40e..4442ad32 100644
--- a/sw-bot/src/main/kotlin/org/luxons/sevenwonders/bot/SevenWondersBot.kt
+++ b/sw-bot/src/main/kotlin/org/luxons/sevenwonders/bot/SevenWondersBot.kt
@@ -7,6 +7,7 @@ import org.luxons.sevenwonders.model.*
import org.luxons.sevenwonders.model.api.ConnectedPlayer
import org.luxons.sevenwonders.model.api.actions.BotConfig
import org.luxons.sevenwonders.model.api.actions.Icon
+import org.luxons.sevenwonders.model.api.events.GameEvent
import org.luxons.sevenwonders.model.resources.noTransactions
import org.luxons.sevenwonders.model.wonders.AssignedWonder
import org.slf4j.LoggerFactory
@@ -21,7 +22,7 @@ suspend fun SevenWondersClient.connectBot(
): SevenWondersBot {
logger.info("Connecting new bot '$name' to $serverUrl")
val session = connect(serverUrl)
- val player = session.chooseName(name, Icon("desktop"), isHuman = false)
+ val player = session.chooseNameAndAwait(name, Icon("desktop"), isHuman = false)
return SevenWondersBot(player, config, session)
}
@@ -62,40 +63,51 @@ class SevenWondersBot(
return withContext(Dispatchers.Default) {
otherBots.forEach {
- launch {
- val turn = it.session.watchGameStarted().first()
- it.autoPlayUntilEnd(turn)
- }
+ launch { it.autoPlayUntilEnd() }
}
- val firstTurn = session.startGameAndAwaitFirstTurn()
- autoPlayUntilEnd(firstTurn)
+ val endTurn = async { autoPlayUntilEnd() }
+ session.startGame()
+ endTurn.await()
}
}
- suspend fun joinAndAutoPlay(gameId: Long): PlayerTurnInfo<*> {
- val firstTurn = session.joinGameAndAwaitFirstTurn(gameId)
- return autoPlayUntilEnd(firstTurn)
+ suspend fun joinAndAutoPlay(gameId: Long) = coroutineScope {
+ launch { autoPlayUntilEnd() }
+ session.joinGame(gameId)
}
- private suspend fun autoPlayUntilEnd(currentTurn: PlayerTurnInfo<*>) = coroutineScope {
+ private suspend fun autoPlayUntilEnd(): PlayerTurnInfo<TurnAction.WatchScore> = coroutineScope {
val endGameTurnInfo = async {
- session.watchTurns().filter { it.action is TurnAction.WatchScore }.first()
+ @Suppress("UNCHECKED_CAST")
+ session.watchTurns()
+ .filter { it.action is TurnAction.WatchScore }
+ .first() as PlayerTurnInfo<TurnAction.WatchScore>
}
- session.watchTurns()
- .onStart {
- session.sayReady()
- emit(currentTurn)
- }
- .takeWhile { it.action !is TurnAction.WatchScore }
- .catch { e -> logger.error("BOT $player: error in turnInfo flow", e) }
- .collect { turn ->
- botDelay()
- logger.info("BOT $player: playing turn (action ${turn.action})")
- session.autoPlayTurn(turn)
+ session.watchGameEvents()
+ .catch { e -> logger.error("BOT $player: error in game events flow", e) }
+ .takeWhile { it !is GameEvent.LobbyLeft }
+ .collect { event ->
+ when (event) {
+ is GameEvent.NameChosen -> error("Unexpected name chosen event in bot")
+ is GameEvent.GameStarted -> session.sayReady()
+ is GameEvent.NewTurnStarted -> if (event.turnInfo.action is TurnAction.WatchScore) {
+ logger.info("BOT $player: leaving the game")
+ session.leaveGame()
+ } else {
+ botDelay()
+ logger.info("BOT $player: playing turn (action ${event.turnInfo.action})")
+ session.autoPlayTurn(event.turnInfo)
+ }
+ is GameEvent.LobbyJoined,
+ is GameEvent.LobbyUpdated,
+ is GameEvent.PlayerIsReady,
+ is GameEvent.MovePrepared,
+ GameEvent.MoveUnprepared,
+ is GameEvent.CardPrepared -> Unit // ignore those
+ GameEvent.LobbyLeft -> error("Unexpected lobby left event in bot") // collect should have ended
+ }
}
val lastTurn = endGameTurnInfo.await()
- logger.info("BOT $player: leaving the game")
- session.leaveGameAndAwaitEnd()
session.disconnect()
logger.info("BOT $player: disconnected")
lastTurn
bgstack15