8732c4142c
- Created UnoTheme.kt with light/dark color schemes - Added dark mode toggle (moon/sun icon) in GameInfoBar - Wrapped all entry points (Desktop, Android, Web) with UnoTheme - Fixed Web entry point to use CanvasBasedWindow - Fixed Math.random() for WASM compatibility
110 lines
3.6 KiB
Kotlin
110 lines
3.6 KiB
Kotlin
package com.uno.desktop
|
|
|
|
import androidx.compose.foundation.layout.*
|
|
import androidx.compose.material3.*
|
|
import androidx.compose.runtime.*
|
|
import androidx.compose.ui.Alignment
|
|
import androidx.compose.ui.Modifier
|
|
import androidx.compose.ui.unit.DpSize
|
|
import androidx.compose.ui.unit.dp
|
|
import androidx.compose.ui.window.Window
|
|
import androidx.compose.ui.window.WindowState
|
|
import androidx.compose.ui.window.application
|
|
import com.uno.game.GameEngine
|
|
import com.uno.game.model.*
|
|
import com.uno.shared.UnoGameScreen
|
|
import com.uno.shared.UnoTheme
|
|
import kotlinx.coroutines.delay
|
|
|
|
fun main() = application {
|
|
Window(
|
|
onCloseRequest = ::exitApplication,
|
|
title = "UNO - Kotlin Multiplatform",
|
|
state = WindowState(size = DpSize(900.dp, 700.dp))
|
|
) {
|
|
UnoDesktopApp()
|
|
}
|
|
}
|
|
|
|
@Composable
|
|
fun UnoDesktopApp() {
|
|
val engine = remember { GameEngine() }
|
|
var gameState by remember { mutableStateOf(engine.startGame()) }
|
|
var gameStarted by remember { mutableStateOf(false) }
|
|
var isAiThinking by remember { mutableStateOf(false) }
|
|
|
|
// KI-Züge mit Verzögerung
|
|
LaunchedEffect(gameState.currentPlayerIndex, gameState.phase) {
|
|
if (gameState.currentPlayerIndex != 0
|
|
&& gameState.phase == GamePhase.PLAYING
|
|
&& !gameState.isFinished
|
|
) {
|
|
isAiThinking = true
|
|
var currentState = gameState
|
|
while (currentState.currentPlayerIndex != 0 && !currentState.isFinished) {
|
|
delay(800)
|
|
currentState = engine.aiPlay(currentState, currentState.currentPlayerIndex)
|
|
gameState = currentState
|
|
}
|
|
isAiThinking = false
|
|
}
|
|
}
|
|
|
|
UnoTheme {
|
|
if (!gameStarted) {
|
|
DesktopStartScreen(onStartGame = { playerCount ->
|
|
gameState = engine.startGame(playerCount)
|
|
gameStarted = true
|
|
})
|
|
} else {
|
|
UnoGameScreen(
|
|
state = gameState,
|
|
onPlayCard = { card, color ->
|
|
gameState = engine.playCard(gameState, 0, card, color)
|
|
},
|
|
onDrawCard = {
|
|
gameState = engine.drawCard(gameState, 0)
|
|
},
|
|
onCallUno = { gameState = engine.callUno(gameState, 0) }
|
|
)
|
|
|
|
if (gameState.isFinished) {
|
|
DesktopGameOverScreen(
|
|
winner = gameState.winner,
|
|
onPlayAgain = {
|
|
gameState = engine.startGame()
|
|
gameStarted = false
|
|
}
|
|
)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@Composable
|
|
fun DesktopStartScreen(onStartGame: (Int) -> Unit) {
|
|
Column(
|
|
modifier = Modifier.fillMaxSize(),
|
|
horizontalAlignment = Alignment.CenterHorizontally,
|
|
verticalArrangement = Arrangement.Center
|
|
) {
|
|
Text("UNO", style = MaterialTheme.typography.displayLarge, color = MaterialTheme.colorScheme.primary)
|
|
Spacer(modifier = Modifier.height(8.dp))
|
|
Text("Desktop Edition", style = MaterialTheme.typography.titleMedium, color = MaterialTheme.colorScheme.onSurfaceVariant)
|
|
Spacer(modifier = Modifier.height(24.dp))
|
|
Button(onClick = { onStartGame(4) }) { Text("Spiel starten (4 Spieler)") }
|
|
}
|
|
}
|
|
|
|
@Composable
|
|
fun DesktopGameOverScreen(winner: Player?, onPlayAgain: () -> Unit) {
|
|
AlertDialog(
|
|
onDismissRequest = onPlayAgain,
|
|
title = { Text("Spiel vorbei!") },
|
|
text = { Text(if (winner != null) "${winner.name} hat gewonnen!" else "Unentschieden!") },
|
|
confirmButton = {
|
|
Button(onClick = onPlayAgain) { Text("Nochmal spielen") }
|
|
}
|
|
)
|
|
}
|