英文:
How can I get the checkForWinner function to set the correct player correctly in this Tic Tac Toe game?
问题
在这个井字游戏中,checkForWinner
函数应该检查每个按钮并确定是 Player.X
赢了游戏还是 Player.O
。该函数在两名玩家都移动后才确定获胜者。代码应该在每位玩家移动后立即确定获胜者,而不仅仅在两位玩家都移动后才确定。我如何在 checkForWinner
函数中修复这段代码?
英文:
In this tic tac toe game, the function checkForWinner
should check each button and determine if either Player.X
won the game or Player.O
. The function does not determine a winner until after both players have moved. The code should work by determining winners after each move of the player and not only after both have moved. How can I correct this code in checkForWinner
?
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.selection.selectable
import androidx.compose.foundation.selection.selectableGroup
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.RadioButton
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Alignment.Companion.CenterHorizontally
import androidx.compose.ui.Modifier
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.unit.dp
import com.example.tictactoe.ui.theme.TicTacToeTheme
import kotlin.random.Random
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
TicTacToeTheme {
var selectedOption = remember { RadioButtonState() }
ButtonGrid(selectedOption)
// PlayerRow()
}
}
}
}
class RadioButtonState() {
var players by mutableStateOf<String?>(null)
}
@Composable
fun PlayerRow(selectedOption: RadioButtonState = remember {
RadioButtonState()
}, onResetClicked: () -> Unit) {
val radioOptions = listOf("One Player", "Two Players")
// var selectedOption
Row(
Modifier
.selectableGroup()
.fillMaxWidth()
.padding(top = 20.dp)
.height(20.dp),
horizontalArrangement = Arrangement.Center,
// verticalAlignment = Alignment.CenterVertically
) {
radioOptions.forEach { text ->
Row(
Modifier
// .fillMaxWidth()
.selectable(
selected = (text == selectedOption.players),
onClick = { selectedOption.players = text },
role = Role.RadioButton
),
// horizontalArrangement = Arrangement.Center,
// verticalAlignment = Alignment.CenterVertically
) {
RadioButton(
selected = (text == selectedOption.players),
// enabled = (text == radioOptions[0]),
onClick = null
)
Spacer(Modifier.size(4.dp))
Text(text = text)
}
}
}
Row(
Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically
) {
Button(
modifier = Modifier.padding(top = 16.dp),
onClick = {
selectedOption.players = null
onResetClicked()
}
) {
Text(text = "Reset")
}
}
}
enum class Player {
NONE, X, O
}
fun makeAIMove(cells: MutableList<Player>) {
val availableMoves = mutableListOf<Int>()
for (i in cells.indices) {
if (cells[i] == Player.NONE) {
availableMoves.add(i)
}
}
if (availableMoves.isNotEmpty()) {
val randomIndex = Random.nextInt(availableMoves.size)
val moveIndex = availableMoves[randomIndex]
cells[moveIndex] = Player.O
}
}
fun checkForWinner(cells: List<Player>): Player {
val winningCombinations = listOf(
listOf(0, 1, 2), // Rows
listOf(3, 4, 5),
listOf(6, 7, 8),
listOf(0, 3, 6), // Columns
listOf(1, 4, 7),
listOf(2, 5, 8),
listOf(0, 4, 8), // Diagonals
listOf(2, 4, 6)
)
for (combination in winningCombinations) {
val (a, b, c) = combination
if (cells[a] != Player.NONE && cells[a] == cells[b] && cells[b] == cells[c]) {
return cells[a] // Return the winning player
}
}
return Player.NONE // No winner found
}
@Composable
fun ButtonGrid(selectedOption: RadioButtonState = remember {
RadioButtonState()
}, modifier: Modifier = Modifier) {
var currentPlayer by remember { mutableStateOf(Player.X) }
var gameInProgress by remember { mutableStateOf(true) }
val cells = remember {
mutableStateListOf(
Player.NONE, Player.NONE, Player.NONE,
Player.NONE, Player.NONE, Player.NONE,
Player.NONE, Player.NONE, Player.NONE
)
}
val winner = checkForWinner(cells)
// }
if (winner != Player.NONE) {
gameInProgress = false
Text(
text = "Winner: ${winner.name}",
style = MaterialTheme.typography.bodyMedium,
modifier = Modifier
.padding(16.dp)
)
}
Column(modifier = Modifier.fillMaxSize(), verticalArrangement = Arrangement.Center) {
Text(
text = "Current Player: ${currentPlayer.name}",
style = MaterialTheme.typography.bodyMedium,
modifier = Modifier
.align(CenterHorizontally)
.padding(16.dp)
)
for (row in 0 until 3) {
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.Center) {
for (column in 0 until 3) {
val index = row * 3 + column
Button(
modifier = Modifier
.padding(4.dp)
.size(64.dp),
shape = RoundedCornerShape(10),
onClick = {
if (/*gameInProgress && */cells[index] == Player.NONE) {
cells[index] = currentPlayer
if (selectedOption.players == "Two Players") {
currentPlayer =
if (currentPlayer == Player.X) Player.O else Player.X
}
else if (selectedOption.players == "One Player" && gameInProgress) {
makeAIMove(cells)
}
}
},
enabled = cells[index] == Player.NONE && gameInProgress
) {
Text(text = if (cells[index] == Player.NONE) "" else cells[index].name)
}
}
}
}
PlayerRow(selectedOption) {
cells.fill(Player.NONE)
currentPlayer = Player.X
gameInProgress = true
}
}
}```
</details>
# 答案1
**得分**: 0
我明白了。我只是使用了一个代理。
```kotlin
var winner by remember { mutableStateOf(Player.NONE) }
winner = checkForWinner(cells)
英文:
I got it. I simply used a delegate.
var winner by remember { mutableStateOf(Player.NONE) }
winner = checkForWinner(cells)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论