0

他の人や AI と対戦できる tictactoe ゲームを作成しています。2 つの AI が互いに対戦することもできます。2 つの AI が互いに対戦すると、スタックオーバー フロー、ガード ページ エラーが発生しました。

AIがボタンをクリックすると、私の「ClickHandler」メソッドが呼び出されました。このメソッドの最後に、他のプレイヤーがボタンを選択するためのメソッド (playATurn) を呼び出し、「ClickHandler」が再度呼び出され、無限の再帰が発生します。

この問題は、1 ミリ秒後に "playATurn" を呼び出すメソッドの最後にあるタイマーを使用して修正しましたが、これは遅いです。

私の質問は、私のプログラムが「ClickHandler」で終了した後に「playATurn」を呼び出す、プログラムできるイベントまたは何か他のものがあるということです。

ありがとう!

private void ClickHandler(object sender, System.EventArgs e)
{
    Button tempButton = (Button)sender;

    if (tempButton.Text != "")  // if is it empty
    {
        MessageBox.Show("Button already has value!", "ERROR", MessageBoxButtons.OK);
        return;
    }

    if (_isX)   // put the character in the Text property
    {
        tempButton.Text = "X";
        turn.Text = "O";
    }
    else
    {
        tempButton.Text = "O";
        turn.Text = "X";
    }
    _isX = !_isX;   // prepare for next character

    this._isGameOver = CheckAndProcessWinner();
    if (_isGameOver) gamesRemaining.Text = (--PlayerMenu.counterForNumberOfGames).ToString();
    if (_isGameOver && PlayerMenu.counterForNumberOfGames == 0)
    {
        MessageBox.Show(playerOne.name + " Wins: " + playerOne.numberOfWins + " Loses: " + playerOne.numberOfLoses + " Ties: " + playerOne.numberOfTies);
    }
    else if (_isGameOver && PlayerMenu.counterForNumberOfGames > 0)
    {
        InitTicTacToe();
    }
    else if (!_isGameOver && PlayerMenu.counterForNumberOfGames > 0)
    {
        if (_isX)
            playerOne.pickMove(_buttonArray, playerTwo);
        else
            playerTwo.pickMove(_buttonArray, playerOne);
    }
    myTimer.Start();
}

private void playATurn(object sender, System.EventArgs e)
{
    if (!_isGameOver && PlayerMenu.counterForNumberOfGames > 0)
    {
        if (_isX)
            playerOne.pickMove(_buttonArray, playerTwo);
        else
            playerTwo.pickMove(_buttonArray, playerOne);
    }
}
4

1 に答える 1

2

あまりにもタイトに実行したくないか、Windows メッセージ ループを実行したくて更新されません。おそらく考慮してください:

private void PerformMove() {
    // ... Your existing code
    if(runAgain) {
        this.BeginInvoke((MethodInvoker)delegate{
            PerformMove();
        });
    }
}
private void ClickHandler(object sender, System.EventArgs e) {
    PerformMove();
}

これは、反復ごとにメッセージ ループを経由するため、UI は応答する必要があります。

于 2012-09-08T07:44:31.550 に答える