kotlin 组成跳棋

yyhrrdl8  于 2023-10-23  发布在  Kotlin
关注(0)|答案(1)|浏览(116)

我在jetpack composeKotlin上创建了一个跳棋游戏,但我遇到了结果不显示在屏幕上的问题。也就是说,检查器在日志中移动,但不在屏幕上移动。

enum class Piece {
    EMPTY,
    BLACK,
    WHITE
}

@Composable
fun CheckersScreen(navHostController: NavHostController) {

    val context = LocalContext.current

    var selectedChecker by remember { mutableStateOf<Pair<Int, Int>?>(null) }

    val board = remember { mutableStateOf(Array(8) { Array(8) { Piece.EMPTY } }) }

    var localSelectedChecker by remember { mutableStateOf<Pair<Int, Int>?>(null) }





    for (i in 0 until 3) {
        for (j in 0 until 8) {
            if ((i + j) % 2 == 1) {
                board.value[i][j] = Piece.WHITE
            }
        }
    }

    for (i in 5 until 8) {
        for (j in 0 until 8) {
            if ((i + j) % 2 == 1) {
                board.value[i][j] = Piece.BLACK
            }
        }
    }


    Column(
        Modifier
            .fillMaxSize()
            .padding(bottom = 30.dp)
    ) {

        Box(
            modifier = Modifier
                .padding(top = 152.dp)
                .fillMaxWidth()
                .padding(start = 5.dp, end = 5.dp)
                .size(400.dp)
                .shadow(4.dp, shape = RectangleShape)
        ) {
            Column {
                for (row in 0 until 8) {
                    Row(
                        modifier = Modifier.fillMaxWidth(),
                        horizontalArrangement = Arrangement.Center
                    ) {
                        for (column in 0 until 8) {
                            val color =
                                if ((row + column) % 2 == 0) Color.White else Color(139, 69, 19)

                            val isWhitePiece = board.value[row][column] == Piece.WHITE
                            val isBlackPiece = board.value[row][column] == Piece.BLACK

                            Box(
                                modifier = Modifier
                                    .size(50.dp)
                                    .background(color)
                                    .clickable {
                                        if (isBlackPiece) {
                                            localSelectedChecker = Pair(row, column)
                                        } else if (localSelectedChecker != null) {
                                            val (fromRow, fromColumn) = localSelectedChecker!!
                                            if (!isValidMove(
                                                    fromRow,
                                                    fromColumn,
                                                    row,
                                                    column,
                                                    board.value
                                                )
                                            ) {
                                                board.value[row][column] =
                                                    board.value[fromRow][fromColumn]
                                                board.value[fromRow][fromColumn] = Piece.EMPTY
                                                board.value[row][column] = Piece.BLACK
                                                localSelectedChecker = null
                                                Log.d(
                                                    "pizda",
                                                    "Board state: ${
                                                        board.value.joinToString("\n") {
                                                            it.joinToString(" ")
                                                        }
                                                    }"
                                                )
                                            }
                                        }
                                    },

                                ) {
                                val isSelected = selectedChecker == Pair(row, column)
                                val checkerImage = when {
                                    isWhitePiece -> R.drawable.white_checker
                                    isBlackPiece -> R.drawable.black_checker
                                    else -> 0
                                }

                                if (checkerImage != 0) {
                                    Image(
                                        painter = painterResource(id = checkerImage),
                                        contentDescription = null,
                                        modifier = Modifier
                                            .size(40.dp)
                                            .align(Alignment.Center)
                                            .then(
                                                if (isSelected) {
                                                    Modifier.border(2.dp, Color.Red)
                                                } else {
                                                    Modifier
                                                }
                                            )
                                    )
                                }

                            }

                        }
                    }
                }
            }
        }
    }
}

fun isValidMove(
    fromRow: Int,
    fromColumn: Int,
    toRow: Int,
    toColumn: Int,
    board: Array<Array<Piece>>
): Boolean {
    val piece = board[fromRow][fromColumn]
    val targetPiece = board[toRow][toColumn]
    Log.d("pizda", "fromColumn $fromColumn")
    Log.d("pizda", "fromRow $fromRow")
    Log.d("pizda", "toRow $toRow")
    Log.d("pizda", "toColumn $toColumn")
    val rowDiff = kotlin.math.abs(fromRow - toRow)
    val colDiff = kotlin.math.abs(fromColumn - toColumn)
    if (rowDiff != 1 || colDiff != 1) {
        Log.d("pizda", "here")
        return false
    }

    if (targetPiece != Piece.EMPTY) {
        Log.d("pizda", "here1")
        return false
    }

    if (piece == Piece.BLACK && toRow <= fromRow) {
        Log.d("pizda", "here2")
        return false
    }

    if (piece == Piece.WHITE && toRow >= fromRow) {
        Log.d("pizda", "here3")
        return false
    }

    val rowDirection = if (toRow > fromRow) 1 else -1
    val colDirection = if (toColumn > fromColumn) 1 else -1

    val intermediateRow = fromRow + rowDirection
    val intermediateColumn = fromColumn + colDirection

    if (kotlin.math.abs(toRow - fromRow) == 2 && kotlin.math.abs(toColumn - fromColumn) == 2) {

        val middlePiece = board[intermediateRow][intermediateColumn]

        if (middlePiece == Piece.EMPTY || middlePiece == piece) {
            Log.d("pizda", "here4")
            return false
        }

        Log.d("pizda", "here5")
        return true
    }

    Log.d("pizda", "here6")
    return false
}
iq3niunx

iq3niunx1#

所以你的问题很大一部分是你混合了状态和UI。别这样您的UI和@Composable函数不应写入任何状态。它应该是阅读它,执行很少或没有基于它的逻辑(它所做的所有逻辑都应该是严格的显示逻辑),并且写入应该由于您的状态中的回调而发生。通过将这两者结合起来,您会在技术上(您的初始化代码运行每个绘制,因此每个绘制都会重置状态)和逻辑级别上(您根本没有将业务逻辑与UI分离,这将使您的代码变得难以调试)造成问题。
这种形式的UI的全部要点是完全基于状态绘制每个帧,并将UI与任何状态操作分离开来。在这样做的时候,你隔离了代码库的两个部分,所以它们是独立可测试的。您可以通过生成适当的状态来测试UI,也可以通过生成适当的回调函数来测试业务逻辑。这种混合违反了这一切。

相关问题