fix: 7-0自由选择交换对象、解除死锁、出牌记录优化、万能牌摸牌选色
This commit is contained in:
parent
8ac938cb2b
commit
548fbef889
@ -432,6 +432,7 @@ fun UnoApp() {
|
||||
myPlayerId = myPlayerId,
|
||||
isMyTurn = state.currentPlayer.id == myPlayerId,
|
||||
errorMessage = errorMessage,
|
||||
isSevenZeroMode = false,
|
||||
onPlayCard = { index ->
|
||||
errorMessage = ""
|
||||
val colorToSend = if (index >= 0 && index < myCards.size && myCards[index].type.isWild) {
|
||||
|
||||
@ -124,7 +124,8 @@ class GameEngine(private val rules: GameRules = GameRules.forMode(GameMode.NORMA
|
||||
sealed class PlayResult {
|
||||
data class Success(
|
||||
val state: GameState,
|
||||
val drawnCardPlayableIndex: Int = -1
|
||||
val drawnCardPlayableIndex: Int = -1,
|
||||
val needsSwapTarget: Boolean = false
|
||||
) : PlayResult()
|
||||
data class Error(val message: String) : PlayResult()
|
||||
}
|
||||
@ -133,7 +134,8 @@ class GameEngine(private val rules: GameRules = GameRules.forMode(GameMode.NORMA
|
||||
state: GameState,
|
||||
playerId: String,
|
||||
cardIndex: Int,
|
||||
chosenColor: CardColor? = null
|
||||
chosenColor: CardColor? = null,
|
||||
swapTargetId: String? = null
|
||||
): PlayResult {
|
||||
val playerIndex = state.players.indexOfFirst { it.id == playerId }
|
||||
if (playerIndex != state.currentPlayerIndex)
|
||||
@ -162,7 +164,7 @@ class GameEngine(private val rules: GameRules = GameRules.forMode(GameMode.NORMA
|
||||
!card.matches(topCard, state.currentWildColor, state.flipped))
|
||||
return PlayResult.Error("不能出这张牌")
|
||||
|
||||
return executeCardPlay(state, player, playerIndex, cardIndex, card, chosenColor, canStack)
|
||||
return executeCardPlay(state, player, playerIndex, cardIndex, card, chosenColor, canStack, swapTargetId)
|
||||
}
|
||||
|
||||
private fun executeCardPlay(
|
||||
@ -172,7 +174,8 @@ class GameEngine(private val rules: GameRules = GameRules.forMode(GameMode.NORMA
|
||||
cardIndex: Int,
|
||||
card: Card,
|
||||
chosenColor: CardColor?,
|
||||
isStacking: Boolean
|
||||
isStacking: Boolean,
|
||||
swapTargetId: String? = null
|
||||
): PlayResult {
|
||||
val newDiscard = discardPile.toMutableList()
|
||||
newDiscard.add(card)
|
||||
@ -187,7 +190,8 @@ class GameEngine(private val rules: GameRules = GameRules.forMode(GameMode.NORMA
|
||||
var nextIndex = state.nextPlayerIndex()
|
||||
var direction = state.direction
|
||||
var flipped = state.flipped
|
||||
var message = "${player.name} 出了 ${card.displayText}"
|
||||
val cardColorText = if (card.color == CardColor.WILD) "万能" else card.color.displayName
|
||||
var message = "${player.name} 出了 ${cardColorText} ${card.displayText}"
|
||||
|
||||
val activeCard = card.activeCard(flipped)
|
||||
|
||||
@ -303,13 +307,38 @@ class GameEngine(private val rules: GameRules = GameRules.forMode(GameMode.NORMA
|
||||
pendingDraw = 0
|
||||
sevenZeroDone = true
|
||||
} else if (pendingDraw == -2) {
|
||||
// 7: swap hand with the next player
|
||||
val nextIdx = state.nextPlayerIndex()
|
||||
val nextCards = state.players[nextIdx].cards
|
||||
// 7: swap hand with player of choice
|
||||
val targetIdx = if (swapTargetId != null) {
|
||||
state.players.indexOfFirst { it.id == swapTargetId }
|
||||
} else {
|
||||
state.nextPlayerIndex()
|
||||
}
|
||||
// If target not specified and more than 2 players, need UI to choose
|
||||
if (swapTargetId == null && state.players.size > 2) {
|
||||
// Return state with 7 removed but no swap yet, flag for target selection
|
||||
val partialPlayers = state.players.mapIndexed { i, p ->
|
||||
if (i == playerIndex) p.copy(cards = newCards, cardCount = newCards.size)
|
||||
else p.copy(isCurrentTurn = false)
|
||||
}
|
||||
return PlayResult.Success(
|
||||
state.copy(
|
||||
players = partialPlayers,
|
||||
currentPlayerIndex = playerIndex,
|
||||
discardPile = discardPile.toList(),
|
||||
drawPileCount = drawPile.size,
|
||||
pendingDrawCount = 0,
|
||||
flipped = flipped,
|
||||
turnNumber = state.turnNumber + 1,
|
||||
message = message + ",选择交换对象"
|
||||
),
|
||||
needsSwapTarget = true
|
||||
)
|
||||
}
|
||||
val nextCards = state.players[targetIdx].cards
|
||||
modifiedPlayers = state.players.mapIndexed { i, p ->
|
||||
when (i) {
|
||||
playerIndex -> p.copy(cards = nextCards, cardCount = nextCards.size)
|
||||
nextIdx -> p.copy(cards = newCards, cardCount = newCards.size)
|
||||
targetIdx -> p.copy(cards = newCards, cardCount = newCards.size)
|
||||
else -> p
|
||||
}
|
||||
}
|
||||
@ -424,8 +453,28 @@ class GameEngine(private val rules: GameRules = GameRules.forMode(GameMode.NORMA
|
||||
if (drawPile.isNotEmpty()) drawPile.removeAt(0) else null
|
||||
}
|
||||
|
||||
if (drawnCards.isEmpty())
|
||||
return PlayResult.Error("牌堆已空,无法摸牌")
|
||||
if (drawnCards.isEmpty()) {
|
||||
// Can't draw - just pass turn
|
||||
val nextIndex = state.nextPlayerIndex()
|
||||
val updatedPlayers = state.players.mapIndexed { i, p ->
|
||||
when (i) {
|
||||
playerIndex -> p.copy(isCurrentTurn = false)
|
||||
else -> if (i == nextIndex) p.copy(isCurrentTurn = true) else p.copy(isCurrentTurn = false)
|
||||
}
|
||||
}
|
||||
return PlayResult.Success(
|
||||
state.copy(
|
||||
players = updatedPlayers,
|
||||
currentPlayerIndex = nextIndex,
|
||||
discardPile = discardPile.toList(),
|
||||
drawPileCount = 0,
|
||||
pendingDrawCount = if (state.pendingDrawCount > 0) 0 else state.pendingDrawCount,
|
||||
flipped = state.flipped,
|
||||
turnNumber = state.turnNumber + 1,
|
||||
message = "${player.name} 无法摸牌,跳过回合"
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
val newCards = player.cards.toMutableList()
|
||||
newCards.addAll(drawnCards)
|
||||
@ -489,6 +538,69 @@ class GameEngine(private val rules: GameRules = GameRules.forMode(GameMode.NORMA
|
||||
)
|
||||
}
|
||||
|
||||
fun finishSwap(state: GameState, playerId: String, swapTargetId: String): PlayResult {
|
||||
val playerIndex = state.players.indexOfFirst { it.id == playerId }
|
||||
val targetIdx = state.players.indexOfFirst { it.id == swapTargetId }
|
||||
if (playerIndex < 0 || targetIdx < 0) return PlayResult.Error("玩家不存在")
|
||||
if (playerIndex == targetIdx) return PlayResult.Error("不能和自己交换")
|
||||
|
||||
val currentPlayer = state.players[playerIndex]
|
||||
val targetPlayer = state.players[targetIdx]
|
||||
|
||||
val updatedPlayers = state.players.mapIndexed { i, p ->
|
||||
when (i) {
|
||||
playerIndex -> p.copy(
|
||||
cards = targetPlayer.cards,
|
||||
cardCount = targetPlayer.cards.size,
|
||||
isCurrentTurn = false
|
||||
)
|
||||
targetIdx -> p.copy(
|
||||
cards = currentPlayer.cards,
|
||||
cardCount = currentPlayer.cards.size
|
||||
)
|
||||
else -> p.copy(isCurrentTurn = false)
|
||||
}
|
||||
}
|
||||
|
||||
val nextIndex = state.nextPlayerIndex()
|
||||
val updatedWithTurn = updatedPlayers.mapIndexed { i, p ->
|
||||
if (i == nextIndex) p.copy(isCurrentTurn = true) else p
|
||||
}
|
||||
|
||||
val isWinner = currentPlayer.cards.isEmpty()
|
||||
if (isWinner) {
|
||||
return PlayResult.Success(
|
||||
state.copy(
|
||||
players = updatedWithTurn,
|
||||
isGameOver = true,
|
||||
winner = currentPlayer.copy(cards = emptyList(), cardCount = 0),
|
||||
discardPile = discardPile.toList(),
|
||||
drawPileCount = drawPile.size,
|
||||
turnNumber = state.turnNumber + 1,
|
||||
message = "${currentPlayer.name} 与 ${targetPlayer.name} 交换手牌,${currentPlayer.name} 赢了!"
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
val calledUno = currentPlayer.cards.size == 1
|
||||
val finalPlayers = updatedWithTurn.mapIndexed { i, p ->
|
||||
if (i == playerIndex) p.copy(calledUno = calledUno) else p
|
||||
}
|
||||
|
||||
return PlayResult.Success(
|
||||
state.copy(
|
||||
players = finalPlayers,
|
||||
currentPlayerIndex = nextIndex,
|
||||
discardPile = discardPile.toList(),
|
||||
drawPileCount = drawPile.size,
|
||||
pendingDrawCount = 0,
|
||||
flipped = state.flipped,
|
||||
turnNumber = state.turnNumber + 1,
|
||||
message = "${currentPlayer.name} 与 ${targetPlayer.name} 交换手牌"
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun skipAfterDraw(state: GameState): PlayResult {
|
||||
val nextIndex = state.nextPlayerIndex()
|
||||
val updatedPlayers = state.players.mapIndexed { i, p ->
|
||||
@ -521,7 +633,13 @@ class GameEngine(private val rules: GameRules = GameRules.forMode(GameMode.NORMA
|
||||
|
||||
private fun reshuffleDiscard() {
|
||||
if (discardPile.size <= 1 && drawPile.isNotEmpty()) return
|
||||
if (discardPile.isEmpty()) return
|
||||
val topCard = discardPile.removeAt(discardPile.size - 1)
|
||||
if (discardPile.isEmpty()) {
|
||||
// Only the top card exists - put it back, can't reshuffle
|
||||
discardPile.add(topCard)
|
||||
return
|
||||
}
|
||||
drawPile.addAll(discardPile)
|
||||
shuffle(drawPile)
|
||||
discardPile.clear()
|
||||
|
||||
@ -30,17 +30,26 @@ object SimpleAI {
|
||||
data class AIMove(
|
||||
val type: MoveType,
|
||||
val cardIndex: Int = -1,
|
||||
val chosenColor: CardColor? = null
|
||||
val chosenColor: CardColor? = null,
|
||||
val swapTargetId: String? = null
|
||||
)
|
||||
|
||||
enum class MoveType { PLAY, DRAW }
|
||||
|
||||
fun pickSwapTarget(players: List<Player>, selfId: String): String? {
|
||||
val others = players.filter { it.id != selfId }
|
||||
if (others.isEmpty()) return null
|
||||
return others.random(Random).id
|
||||
}
|
||||
|
||||
fun decideMove(
|
||||
player: Player,
|
||||
topCard: Card?,
|
||||
wildColor: CardColor?,
|
||||
flipped: Boolean = false,
|
||||
difficulty: AIDifficulty = AIDifficulty.NORMAL
|
||||
difficulty: AIDifficulty = AIDifficulty.NORMAL,
|
||||
otherPlayers: List<Player> = emptyList(),
|
||||
isSevenZero: Boolean = false
|
||||
): AIMove {
|
||||
val hand = player.cards
|
||||
if (hand.isEmpty()) return AIMove(MoveType.DRAW)
|
||||
@ -62,11 +71,15 @@ object SimpleAI {
|
||||
// Easy: play random card
|
||||
if (difficulty == AIDifficulty.EASY) {
|
||||
val chosen = playable.random()
|
||||
if (chosen.second.type.isWild || chosen.second.activeCard(flipped).type.isWild) {
|
||||
val idx = hand.indexOf(chosen.second)
|
||||
return if (chosen.second.type.isWild || chosen.second.activeCard(flipped).type.isWild) {
|
||||
val color = pickBestColor(hand, flipped)
|
||||
return AIMove(MoveType.PLAY, hand.indexOf(chosen.second), color)
|
||||
AIMove(MoveType.PLAY, idx, color)
|
||||
} else if (isSevenZero && chosen.second.type == CardType.NUMBER && chosen.second.number == 7) {
|
||||
AIMove(MoveType.PLAY, idx, swapTargetId = pickSwapTarget(otherPlayers, player.id))
|
||||
} else {
|
||||
AIMove(MoveType.PLAY, idx)
|
||||
}
|
||||
return AIMove(MoveType.PLAY, hand.indexOf(chosen.second))
|
||||
}
|
||||
|
||||
// Hard: prefer cards that hurt the opponent most
|
||||
@ -106,6 +119,10 @@ object SimpleAI {
|
||||
return AIMove(MoveType.PLAY, hand.indexOf(chosen.second), color)
|
||||
}
|
||||
|
||||
if (isSevenZero && chosen.second.type == CardType.NUMBER && chosen.second.number == 7) {
|
||||
return AIMove(MoveType.PLAY, hand.indexOf(chosen.second), swapTargetId = pickSwapTarget(otherPlayers, player.id))
|
||||
}
|
||||
|
||||
return AIMove(MoveType.PLAY, hand.indexOf(chosen.second))
|
||||
}
|
||||
|
||||
|
||||
@ -34,6 +34,8 @@ fun GameScreen(
|
||||
onCallUno: () -> Unit = {},
|
||||
onChallengeUno: (String) -> Unit = {},
|
||||
onShowLog: () -> Unit = {},
|
||||
onPlaySeven: (Int) -> Unit = {},
|
||||
isSevenZeroMode: Boolean = false,
|
||||
errorMessage: String
|
||||
) {
|
||||
val scrollState = rememberScrollState()
|
||||
@ -289,6 +291,8 @@ fun GameScreen(
|
||||
if (realCard.type.isWild) {
|
||||
selectedAutoCard = sortedCards.indexOf(realCard)
|
||||
showColorPicker = true
|
||||
} else if (isSevenZeroMode && realCard.type == CardType.NUMBER && realCard.number == 7 && gameState.players.size > 2) {
|
||||
onPlaySeven(myCards.indexOf(realCard))
|
||||
} else {
|
||||
selectedCardIndex = index
|
||||
onPlayCard(myCards.indexOf(realCard))
|
||||
|
||||
@ -25,6 +25,7 @@ import com.unogame.game.GameMode
|
||||
import com.unogame.game.GameRules
|
||||
import com.unogame.game.SimpleAI
|
||||
import com.unogame.model.*
|
||||
import com.unogame.ui.components.ColorPickerDialog
|
||||
import com.unogame.ui.theme.*
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
@ -122,8 +123,14 @@ fun LocalGameScreen(
|
||||
var showDrawPlayPopup by remember { mutableStateOf(false) }
|
||||
var pendingDrawState by remember { mutableStateOf<GameState?>(null) }
|
||||
var pendingDrawnCardIndex by remember { mutableIntStateOf(-1) }
|
||||
var pendingDrawIsWild by remember { mutableStateOf(false) }
|
||||
var showDrawPlayWildPicker by remember { mutableStateOf(false) }
|
||||
var pendingDrawStateForWild by remember { mutableStateOf<GameState?>(null) }
|
||||
var pendingDrawCardIdxForWild by remember { mutableIntStateOf(-1) }
|
||||
var gameLog by remember { mutableStateOf(listOf<String>()) }
|
||||
var showLogDialog by remember { mutableStateOf(false) }
|
||||
var showSwapTargetPicker by remember { mutableStateOf(false) }
|
||||
var pendingSwapState by remember { mutableStateOf<GameState?>(null) }
|
||||
|
||||
val myPlayerId = "human"
|
||||
val currentPlayer = gameState.currentPlayer
|
||||
@ -134,7 +141,7 @@ fun LocalGameScreen(
|
||||
myCards = state.players.find { it.id == myPlayerId }?.cards ?: myCards
|
||||
errorMessage = ""
|
||||
if (state.message.isNotEmpty()) {
|
||||
gameLog = gameLog + state.message
|
||||
gameLog = listOf(state.message) + gameLog
|
||||
}
|
||||
if (state.isGameOver) {
|
||||
isGameOver = true
|
||||
@ -165,10 +172,17 @@ fun LocalGameScreen(
|
||||
}
|
||||
}
|
||||
|
||||
fun executePlay(cardIndex: Int, chosenColor: CardColor? = null) {
|
||||
val result = engine.playCard(gameState, myPlayerId, cardIndex, chosenColor)
|
||||
fun executePlay(cardIndex: Int, chosenColor: CardColor? = null, swapTargetId: String? = null) {
|
||||
val result = engine.playCard(gameState, myPlayerId, cardIndex, chosenColor, swapTargetId)
|
||||
when (result) {
|
||||
is GameEngine.PlayResult.Success -> updateState(result.state)
|
||||
is GameEngine.PlayResult.Success -> {
|
||||
if (result.needsSwapTarget) {
|
||||
pendingSwapState = result.state
|
||||
showSwapTargetPicker = true
|
||||
} else {
|
||||
updateState(result.state)
|
||||
}
|
||||
}
|
||||
is GameEngine.PlayResult.Error -> errorMessage = result.message
|
||||
}
|
||||
}
|
||||
@ -180,6 +194,8 @@ fun LocalGameScreen(
|
||||
if (result.drawnCardPlayableIndex >= 0) {
|
||||
pendingDrawState = result.state
|
||||
pendingDrawnCardIndex = result.drawnCardPlayableIndex
|
||||
val drawnCard = result.state.players.find { it.id == myPlayerId }?.cards?.getOrNull(result.drawnCardPlayableIndex)
|
||||
pendingDrawIsWild = drawnCard?.type?.isWild == true
|
||||
showDrawPlayPopup = true
|
||||
} else {
|
||||
updateState(result.state)
|
||||
@ -195,10 +211,14 @@ fun LocalGameScreen(
|
||||
if (current.id != myPlayerId) {
|
||||
delay(1200L)
|
||||
|
||||
val move = SimpleAI.decideMove(current, gameState.topCard, gameState.currentWildColor, gameState.flipped, aiDiff)
|
||||
val move = SimpleAI.decideMove(
|
||||
current, gameState.topCard, gameState.currentWildColor, gameState.flipped, aiDiff,
|
||||
otherPlayers = gameState.players,
|
||||
isSevenZero = mode == GameMode.SEVEN_ZERO
|
||||
)
|
||||
when (move.type) {
|
||||
SimpleAI.MoveType.PLAY -> {
|
||||
val result = engine.playCard(gameState, current.id, move.cardIndex, move.chosenColor)
|
||||
val result = engine.playCard(gameState, current.id, move.cardIndex, move.chosenColor, move.swapTargetId)
|
||||
if (result is GameEngine.PlayResult.Success) {
|
||||
updateState(result.state)
|
||||
} else {
|
||||
@ -246,13 +266,22 @@ fun LocalGameScreen(
|
||||
TextButton(onClick = {
|
||||
val state = pendingDrawState!!
|
||||
val cardIdx = pendingDrawnCardIndex
|
||||
showDrawPlayPopup = false
|
||||
pendingDrawState = null
|
||||
if (cardIdx >= 0) {
|
||||
val result = engine.playCard(state, myPlayerId, cardIdx)
|
||||
when (result) {
|
||||
is GameEngine.PlayResult.Success -> updateState(result.state)
|
||||
is GameEngine.PlayResult.Error -> errorMessage = result.message
|
||||
val isWild = pendingDrawIsWild
|
||||
if (isWild) {
|
||||
showDrawPlayPopup = false
|
||||
selectedWildColor = null
|
||||
showDrawPlayWildPicker = true
|
||||
pendingDrawStateForWild = state
|
||||
pendingDrawCardIdxForWild = cardIdx
|
||||
} else {
|
||||
showDrawPlayPopup = false
|
||||
pendingDrawState = null
|
||||
if (cardIdx >= 0) {
|
||||
val result = engine.playCard(state, myPlayerId, cardIdx)
|
||||
when (result) {
|
||||
is GameEngine.PlayResult.Success -> updateState(result.state)
|
||||
is GameEngine.PlayResult.Error -> errorMessage = result.message
|
||||
}
|
||||
}
|
||||
}
|
||||
}) { Text("出牌", color = GoldAccent) }
|
||||
@ -308,6 +337,85 @@ fun LocalGameScreen(
|
||||
)
|
||||
}
|
||||
|
||||
// Color picker for draw-then-play wild card
|
||||
if (showDrawPlayWildPicker) {
|
||||
ColorPickerDialog(
|
||||
flipped = gameState.flipped,
|
||||
onColorSelected = { color ->
|
||||
showDrawPlayWildPicker = false
|
||||
val state = pendingDrawStateForWild!!
|
||||
val cardIdx = pendingDrawCardIdxForWild
|
||||
pendingDrawStateForWild = null
|
||||
if (cardIdx >= 0) {
|
||||
val result = engine.playCard(state, myPlayerId, cardIdx, color)
|
||||
when (result) {
|
||||
is GameEngine.PlayResult.Success -> updateState(result.state)
|
||||
is GameEngine.PlayResult.Error -> errorMessage = result.message
|
||||
}
|
||||
}
|
||||
},
|
||||
onDismiss = {
|
||||
showDrawPlayWildPicker = false
|
||||
// Fall back to skip on dismiss
|
||||
val state = pendingDrawStateForWild!!
|
||||
val result = engine.skipAfterDraw(state)
|
||||
if (result is GameEngine.PlayResult.Success) updateState(result.state)
|
||||
pendingDrawStateForWild = null
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
// 7-0 swap target picker
|
||||
if (showSwapTargetPicker && pendingSwapState != null) {
|
||||
val otherPlayers = gameState.players.filter { it.id != myPlayerId }
|
||||
AlertDialog(
|
||||
onDismissRequest = {
|
||||
// Cancel swap, just finish the turn
|
||||
if (pendingSwapState != null) {
|
||||
gameState = pendingSwapState!!
|
||||
updateState(gameState)
|
||||
showSwapTargetPicker = false
|
||||
}
|
||||
},
|
||||
title = { Text("选择交换对象", color = GoldAccent) },
|
||||
text = {
|
||||
Column {
|
||||
Text("选择要交换手牌的玩家:", color = Color.White.copy(alpha = 0.7f), fontSize = 14.sp)
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
otherPlayers.forEach { p ->
|
||||
TextButton(
|
||||
onClick = {
|
||||
val state = pendingSwapState!!
|
||||
showSwapTargetPicker = false
|
||||
pendingSwapState = null
|
||||
val result = engine.finishSwap(state, myPlayerId, p.id)
|
||||
when (result) {
|
||||
is GameEngine.PlayResult.Success -> updateState(result.state)
|
||||
is GameEngine.PlayResult.Error -> errorMessage = result.message
|
||||
}
|
||||
},
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
) {
|
||||
Icon(Icons.Default.Person, null, tint = GoldAccent, modifier = Modifier.size(18.dp))
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
Text(p.name, color = Color.White, fontSize = 14.sp)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
confirmButton = {
|
||||
TextButton(onClick = {
|
||||
if (pendingSwapState != null) {
|
||||
gameState = pendingSwapState!!
|
||||
updateState(gameState)
|
||||
}
|
||||
showSwapTargetPicker = false
|
||||
}) { Text("取消", color = Color.White.copy(alpha = 0.5f)) }
|
||||
},
|
||||
containerColor = DarkSurface
|
||||
)
|
||||
}
|
||||
|
||||
if (isGameOver) {
|
||||
GameOverScreen(
|
||||
winnerName = winnerName,
|
||||
@ -326,7 +434,9 @@ fun LocalGameScreen(
|
||||
myPlayerId = myPlayerId,
|
||||
isMyTurn = isMyTurn,
|
||||
errorMessage = errorMessage,
|
||||
isSevenZeroMode = mode == GameMode.SEVEN_ZERO,
|
||||
onPlayCard = { index -> executePlay(index, selectedWildColor) },
|
||||
onPlaySeven = { index -> executePlay(index, null) },
|
||||
onDrawCard = { executeDraw() },
|
||||
onChooseColor = { selectedWildColor = it },
|
||||
onShowLog = { showLogDialog = true },
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user