C#/ WPF错误:类型未处理的异常&System; .StackOverflow例外' Occured(Tic-Tac-Toe)

时间:2016-06-18 21:10:23

标签: c# wpf

我对C#和WPF都很陌生,所以请耐心等待。我正在做C#/ WPF Tic-Tac-Toe游戏。在游戏开始并做了一些动作后,我不断收到以下错误,我不明白为什么:

"类型未处理的例外' System.StackOverflow异常'"

就计算机而言,并不一定是任何策略。所以,我想要的代码就是随机选择谁先行(计算机或人),当计算机转动时,计算机应该只选择一个随机启用的按钮,并分配一个" X"或者" O"它。任何帮助将不胜感激。

另外,如果有更简单或更短的编码方式,请务必告诉我!正如我所说,我对这一切都很陌生。

注意:我还没有提出一个函数/方法来确定获胜者是谁。我不需要帮助。

*****编辑:按照建议,我宣布并实例化了#34; rnd"一次进入" MainWindow"上课和离开" rnd.Next"在" randomSquare"方法。之前,它在游戏中的许多不同点上抛出了错误。现在,它只会在人类第一次出现时抛出错误并且是第9次移动。对于如何解决这个问题,有任何的建议吗?以下是我编辑的代码。*****

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace Operation6
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        bool player1 = true;
        int playerNumber;
        Random rnd1 = new Random();
        Random rnd2 = new Random();    /// Edit: Instantiated only once.

        public MainWindow()
        {
            InitializeComponent();

            playerNumber = rnd1.Next(1, 3);

            if (playerNumber == 1)
                computer();
        }

        private int randomSquare()
        {
            int number;

            number = rnd2.Next(1, 10);

            return number;
        }

        private void computer()
        {
            int squareNumber = randomSquare();

            if (squareNumber == 1 && square1.IsEnabled == true)
            {
                if (player1)
                    square1.Content = "X";
                else
                    square1.Content = "O";

                square1.IsEnabled = false;
                player1 = !player1;
            }
            else if (squareNumber == 1 && square1.IsEnabled == false)
                computer();
            else if (squareNumber == 2 && square2.IsEnabled == true)
            {
                if (player1)
                    square2.Content = "X";
                else
                    square2.Content = "O";

                square2.IsEnabled = false;
                player1 = !player1;
            }
            else if (squareNumber == 2 && square2.IsEnabled == false)
                computer();
            else if (squareNumber == 3 && square3.IsEnabled == true)
            {
                if (player1)
                    square3.Content = "X";
                else
                    square3.Content = "O";

                square3.IsEnabled = false;
                player1 = !player1;
            }
            else if (squareNumber == 3 && square3.IsEnabled == false)
                computer();
            else if (squareNumber == 4 && square4.IsEnabled == true)
            {
                if (player1)
                    square4.Content = "X";
                else
                    square4.Content = "O";

                square4.IsEnabled = false;
                player1 = !player1;
            }
            else if (squareNumber == 4 && square4.IsEnabled == false)
                computer();
            else if (squareNumber == 5 && square5.IsEnabled == true)
            {
                if (player1)
                    square5.Content = "X";
                else
                    square5.Content = "O";

                square5.IsEnabled = false;
                player1 = !player1;
            }
            else if (squareNumber == 5 && square5.IsEnabled == false)
                computer();
            else if (squareNumber == 6 && square6.IsEnabled == true)
            {
                if (player1)
                    square6.Content = "X";
                else
                    square6.Content = "O";

                square6.IsEnabled = false;
                player1 = !player1;
            }
            else if (squareNumber == 6 && square6.IsEnabled == false)
                computer();
            else if (squareNumber == 7 && square7.IsEnabled == true)
            {
                if (player1)
                    square7.Content = "X";
                else
                    square7.Content = "O";

                square7.IsEnabled = false;
                player1 = !player1;
            }
            else if (squareNumber == 7 && square7.IsEnabled == false)
                computer();
            else if (squareNumber == 8 && square8.IsEnabled == true)
            {
                if (player1)
                    square8.Content = "X";
                else
                    square8.Content = "O";

                square8.IsEnabled = false;
                player1 = !player1;
            }
            else if (squareNumber == 8 && square8.IsEnabled == false)
                computer();
            else if (squareNumber == 9 && square9.IsEnabled == true)
            {
                if (player1)
                    square9.Content = "X";
                else
                    square9.Content = "O";

                square9.IsEnabled = false;
                player1 = !player1;
            }
            else if (squareNumber == 9 && square9.IsEnabled == false)
                computer();
            else
                draw();
        }

        private void draw()
        {
            textBlock1.Text = "It's a tie!";
        }

        private void squareClick(object sender, RoutedEventArgs e)
        {
            Button square = (Button)sender;

            if (player1)
                square.Content= "X";
            else
                square.Content = "O";

            square.IsEnabled = false;
            player1 = !player1;
            computer();
        }
    }
}

1 个答案:

答案 0 :(得分:-1)

在大多数情况下,如果在没有适当的halting子句的情况下调用递归方法,则会发生StackOverflowException。在您的情况下,罪魁祸首可能是非常凌乱computer()方法,该方法在几个位置调用自身,因此很难逻辑推理可能导致的流量无限递归。但在扫描之后,我说核心原因在于你的randomSquare方法。

使用Random类的正确方法是初始化一次,然后在同一个实例上调用Next()。这样你知道它是从一个随机种子初始化的,然后所有后续调用都是基于那个种子。默认情况下,随机种子基于当前系统时钟。当您为每个呼叫初始化Random时,您可以根据每个呼叫的系统时钟有效地创建一个新的随机种子,并且因为它是一个非常紧凑的循环,所有这些Randoms将返回相同数量连续多次。这意味着你的computer方法将连续获得几十/百/千个(每个都递归调用computer),直到系统时钟发生了足够的变化。它们可能会连续几十/百/三万。

这会很快耗尽堆栈,导致堆栈溢出。

尝试将rnd更改为成员字段,在构造函数中将其实例化一次,然后只需在rnd.Next方法中调用randomSquare