首页 > 解决方案 > 我正在尝试制作井字游戏应用程序

问题描述

我正在尝试制作井字游戏应用程序,我已经实现了“播放器与播放器”部分,但在实现播放器与计算机时遇到了麻烦。我有一个名为 playgame 的功能。对于 update_player,我是手动执行的,对于更新计算机,我是随机执行的,我认为这是导致问题的原因,因为我正在检查我的 boardStatus 是否已填充,如果已填充,我将再次调用我的函数。我在网上读到所有计算都应该在线程上完成,我尝试实现它,但我认为我做错了。请帮忙!

这是我的代码供参考:

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import kotlinx.android.synthetic.main.activity_computer.*
import java.util.*


class ComputerActivity : AppCompatActivity() {
    var player = true
    var turnCount = 0
    var boardStatus = Array(3) { IntArray(3) }
    lateinit var board: Array<Array<Button>>

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_computer)
        board = arrayOf(
            arrayOf(First, Second, Third),
            arrayOf(Fourth, Fifth, Sixth),
            arrayOf(Seventh, Eighth, Ninth)
        )
        playGame() 
    }
    private fun playGame(){
        Status.text = "Player's Turn"
        for (i in 0..2) {
            var flag: Boolean = false
            for (j in 0..2) {
                if (player) {
                    Status.text = "Player's Turn"
                    update_player(player)
                    Thread.sleep(2000)
                    player = false
                    turnCount++
                    checkWinner()
                    if (turnCount == 9) {
                        Status.text = "Game Draw"
                        flag = true;
                    }

                } else {
                    Status.text = "Computer's Turn"
                    update_computer(player)
                    Thread.sleep(2000)
                    player = true
                    turnCount++
                    checkWinner()
                    if (turnCount == 9){
                        Status.text = "Game Draw"
                        flag = true
                    }

                }

            }
            if(flag == true)
                break
        }
        changeBoard()
        resetBtn.setOnClickListener{
            player = true;
            turnCount = 0
            changeBoard()
        }
    }

    private fun update_player(player:Boolean){

        for(i in board){
            for(button in i){
                button.setOnClickListener{
                    when(it.id){
                        R.id.First->{
                            updateBoardStatus(row = 0, column = 0,player)
                        }
                        R.id.Second->{
                            updateBoardStatus(row = 0, column = 1,player)
                        }
                        R.id.Third->{
                            updateBoardStatus(row = 0, column = 2,player)
                        }
                        R.id.Fourth->{
                            updateBoardStatus(row = 1, column = 0,player)
                        }
                        R.id.Fifth->{
                            updateBoardStatus(row = 1, column = 1,player)
                        }
                        R.id.Sixth->{
                            updateBoardStatus(row = 1, column = 2,player)
                        }
                        R.id.Seventh->{
                            updateBoardStatus(row = 2, column = 0,player)
                        }
                        R.id.Eighth->{
                            updateBoardStatus(row = 2, column = 1,player)
                        }
                        R.id.Ninth->{
                            updateBoardStatus(row = 2, column = 2,player)
                        }
                    }
                }
            }
        }

    }

    private fun update_computer(player:Boolean){

         var row:Int = 0
         var column:Int = 0
       Thread {
            row = (0..2).random()
            column = (0..2).random()
       }.start()

            if(boardStatus[row][column] == 0 || boardStatus[row][column]==1)
               update_computer(player)
            else
                updateBoardStatus(row, column, player)



    }

    private fun updateBoardStatus(row:Int, column:Int, player:Boolean){
        val text = if (player) "X" else "0"
        val value = if (player) 1 else 0
        board[row][column].apply {
            isEnabled = false
            setText(text)
        }
        boardStatus[row][column] = value
    }

    private fun checkWinner(){
        //Horizontal --- rows
        for (i in 0..2) {
            if (boardStatus[i][0] == boardStatus[i][1] && boardStatus[i][0] == boardStatus[i][2]) {
                if (boardStatus[i][0] == 1) {
                    result("Player Won!!")
                    break
                } else if (boardStatus[i][0] == 0) {
                    result("Computer Won")
                    break
                }
            }
        }

        //Vertical --- columns
        for (i in 0..2) {
            if (boardStatus[0][i] == boardStatus[1][i] && boardStatus[0][i] == boardStatus[2][i]) {
                if (boardStatus[0][i] == 1) {
                    result("Player Won!!")
                    break
                } else if (boardStatus[0][i] == 0) {
                    result("Computer Won!!")
                    break
                }
            }
        }



        //First diagonal
        if (boardStatus[0][0] == boardStatus[1][1] && boardStatus[0][0] == boardStatus[2][2]) {
            if (boardStatus[0][0] == 1) {
                result("Player Won!!")
            } else if (boardStatus[0][0] == 0) {
                result("Computer won!!")
            }
        }

        //Second diagonal
        if (boardStatus[0][2] == boardStatus[1][1] && boardStatus[0][2] == boardStatus[2][0]) {
            if (boardStatus[0][2] == 1) {
                result("Player Won!!")
            } else if (boardStatus[0][2] == 0) {
                result("Computer Won!!")
            }
        }
    }

    private fun result(res:String){
        Status.text = res
        if(res.contains("Won")){
            disableButton()
        }
        else{

        }
    }

    private fun disableButton(){
        for(i in board){
            for(button in i){
                button.isEnabled = false
            }
        }
    }

    private fun changeBoard(){
        for (i in 0..2) {
            for (j in 0..2) {
                boardStatus[i][j] = -1
            }
        }

        for (i in board) {
            for (button in i) {
                button.isEnabled = true
                button.text = ""

            }
        }
    }
}

标签: androidkotlin

解决方案


您的代码试图将游戏的整个动作序列放在一个函数中,该函数被调用一次,然后期望玩家按键在内部发生。按钮侦听器将在函数返回后的某个时间触发。您需要考虑每次按下按钮以执行游戏的下一阶段时都会调用一个函数。

要解决这个问题:

删除该playGame()功能。

删除player参数,update_player()因为它始终为真。并将函数名称更改为initializeButtons. 调用一次onCreate()。您只需向按钮添加一次侦听器,它们就会重复工作。

出于与上述相同的原因,也从中删除player参数。update_computer()并删除线程,使其看起来像:

private fun update_computer() {
    val row = (0..2).random()
    val column = (0..2).random()
    if (boardStatus[row][column] == 0 || boardStatus[row][column] == 1)
        update_computer()
    else
        updateBoardStatus(row, column, player)
}

然后在updateBoardStatus函数调用结束时checkWinner()checkWinner()应该返回一个布尔值,所以在 中updateBoardStatus(),如果没有找到获胜条件并且player为真,它应该调用update_computer().

因此,您现在拥有的不是尝试从一个函数运行游戏,而是设置了一次按钮侦听器来启动游戏。当一个按钮被按下时,它需要玩家轮流,然后触发updateBoardStatus,然后触发计算机轮流,然后updateBoardStatus再次触发,如果没有人获胜,则什么也不做。所有这些都在主线程上同步/即时发生,所以现在游戏回到等待用户按下按钮以重复事件序列。

此外,status文本视图的用处有限。由于计算机会立即轮流,因此不可能看到“轮到计算机”这个词。如果你想这样做,你将不得不创造一个人为的延迟,所以你必须禁用所有按钮,然后做一些类似 callpostRunnable({ startPlayerTurn() }, 1000L)的事情,startPlayerTurn()重新启用适当的按钮并让它说,“Player turn”再次。


推荐阅读