猜数游戏问题c#

时间:2010-02-24 19:25:27

标签: c# .net winforms

我一直收到stackOverflow错误(没有双关语):“NumberGuessingGame.exe中发生了'System.StackOverflowException'类型的未处理异常”

我猜这会有用,如果你看到我的代码和alswo的地方:

来源 - testClass:

namespace NumberGuessingGame_08029490
{
public class testClass : Form1
{
    public bool _gameWon;
    public bool _gameRunning;
    public int _number;
    public int _guessesRemaining;

    public int guessesRemaining
    {
        get { return _guessesRemaining; }
    }

    public bool gameEnded
    {
        get { return !_gameRunning; }
    }

    public bool gameWon
    {
        get { return _gameWon; }
    }
    public testClass()
    {
        _gameRunning = false;
        _gameWon = false;
    }

    public void saveNewTestGame(int numberGuesses)
    {

        if (numberGuessesComboBox.SelectedIndex == 0)
        {
            numberGuesses = 1;
        }
        if (numberGuessesComboBox.SelectedIndex == 1)
        {
            numberGuesses = 3;
        }
        if (numberGuessesComboBox.SelectedIndex == 2)
        {
            numberGuesses = 5;
        }

        _guessesRemaining = numberGuesses;
        _gameRunning = true;
    }

    public bool makeGuess(int guessNumber)
    {
        if (_gameRunning)
        {
            _guessesRemaining--;
            if (_guessesRemaining <= 0)
            {
                _gameWon = false;
                _gameRunning = false;
                return false;


            }
            if (guessNumber == _number)
            {
                _gameWon = true;
                return true;
            }
            if (guessNumber > _number)
            {
                guessResultTextBox.Text = "Your Guess is too high, try again";
                _gameWon = false;
                return false;
            }
            if (guessNumber < _number)
            {
                guessResultTextBox.Text = "Your Guess is too low, try again";
                _gameWon = false;
                return false;
            }
            else
            {
                return false;
            }
        }

        else
        {
            throw new Exception("The game is not running. Call newGame() before making a guess.");

        }

    }
}
}

来源 - gameClass:

namespace NumberGuessingGame_08029490
{
public class gameClass : Form1
{

    public bool _gameWon;
    public bool _gameRunning;
    public static Random randomNum = new Random();
    public int _number;
    public int _guessesRemaining;

    public int guessesRemaining
    {
        get { return _guessesRemaining; }
    }

    public bool gameEnded
    {
        get { return !_gameRunning; }
    }

    public bool gameWon
    {
        get { return _gameWon; }
    }

    public gameClass()
    {
        _gameRunning = false;
        _gameWon = false;
    }
    public void saveNewGame(int numberGuesses)
    {

        if (numberGuessesComboBox.SelectedIndex == 0)
        {
            numberGuesses = 1;
        }
        if (numberGuessesComboBox.SelectedIndex == 1)
        {
            numberGuesses = 3;
        }
        if (numberGuessesComboBox.SelectedIndex == 2)
        {
            numberGuesses = 5;
        }
        if (rangeNumbersComboBox.SelectedIndex == 0)
        {
            int randomNumFive = randomNum.Next(1, 5);
            randomNumFive = _number;
        }
        if (rangeNumbersComboBox.SelectedIndex == 1)
        {
            int randomNumTen = randomNum.Next(1, 10);
            randomNumTen = _number;
        }
        if (rangeNumbersComboBox.SelectedIndex == 2)
        {
            int randomNumTwenty = randomNum.Next(1, 20);
            randomNumTwenty = _number;
        }
        _guessesRemaining = numberGuesses;
        _gameRunning = true;
    }

    public bool makeGuess(int guessNumber)
    {
        if (_gameRunning)
        {
            _guessesRemaining--;
            if (_guessesRemaining <= 0)
            {
                _gameWon = false;
                _gameRunning = false;
                return false;

            }
            if (guessNumber == _number)
            {
                _gameWon = true;
                return true;
            }
            if (guessNumber > _number)
            {
                guessResultTextBox.Text = "Your Guess is too high, try again";
                _gameWon = false;
                return false;
            }
            if (guessNumber < _number)
            {
                guessResultTextBox.Text = "Your Guess is too low, try again";
                _gameWon = false;
                return false;
            }
            else
            {
                return false;
            }

        }

        else
        {
            throw new Exception("The game is not running. Call newGame() before making a guess.");

        }

    }
}
}

来源 - form1:

namespace NumberGuessingGame_08029490
{
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

    }

    testClass newTest = new testClass();
    gameClass newGame = new gameClass();


    private void saveButton_Click(object sender, EventArgs e)
    {

        if (testCheckBox.Checked == true)
        {
            int numberGuesses = Convert.ToInt32(numberGuessesComboBox.SelectedIndex);
            int _number = Convert.ToInt32(testNumberTextBox.Text);

            newTest.saveNewTestGame(numberGuesses);

        }
        if (testCheckBox.Checked == false)
        {
            int numberGuesses = Convert.ToInt32(numberGuessesComboBox.SelectedIndex);
            int _number = Convert.ToInt32(rangeNumbersComboBox.SelectedIndex);

            newGame.saveNewGame(numberGuesses);
        }

    }

    private void guessButton_Click(object sender, EventArgs e)
    {

        if (testCheckBox.Checked == true)
        {
            int guessNumber = Convert.ToInt32(guessNumberTextBox.Text);
            bool correctAnswer = newTest.makeGuess(guessNumber);

            if (correctAnswer)
            {
                MessageBox.Show("Weldone, you Won!!");
            }

            // if (game.GameEnded)
            //  {
            // disable guess button, show loss label
            //  }
        }
        if (testCheckBox.Checked == false)
        {
            int guessNumber = Convert.ToInt32(guessNumberTextBox.Text);
            bool correctAnswer = newGame.makeGuess(guessNumber);

            if (correctAnswer)
            {
                MessageBox.Show("Weldone, you Won!!");
            }

            // if (game.GameEnded)
            //  {
            // disable guess button, show loss label
            //  }
        }
    }

}
}

编辑:不再有StackOverflowException,代码错误:

谢谢大家的帮助&lt; 3

从顶部删除“表单1”它似乎已经解决了现在的问题,但是现在组合框,文本框变量不再继承我不能在代码中使用它们,所以我无法测试看看解决方案是否有效,是否可以使用它们的任何想法?

Error   1   The name 'numberGuessesComboBox' does not exist in the current context  E:\Projects\NumberGuessingGame\NumberGuessingGame\testClass.cs  46  17  NumberGuessingGame

Error   7   The name 'rangeNumbersComboBox' does not exist in the current context   E:\Projects\NumberGuessingGame_08029490\NumberGuessingGame_08029490\gameClass.cs    58  17  NumberGuessingGame_08029490

Error   10  The name 'guessResultTextBox' does not exist in the current context E:\Projects\NumberGuessingGame_08029490\NumberGuessingGame_08029490\testClass.cs    84  21  NumberGuessingGame_08029490

4 个答案:

答案 0 :(得分:4)

堆栈溢出几乎总是因为你无限递归。换句话说,一个函数在该循环中调用自身而没有中断,因此它会调用数十亿次,直到堆栈溢出。有时函数A调用函数B调用A,但效果是相同的。搜索代码以查找该循环,或查看调试器提供的堆栈跟踪并查看循环是什么。

编辑:我扫描了您发布的代码,但我没有看到。你采取了什么行动来获得错误?只要你点击一个按钮,或者加载程序,或者是什么?

EDIT2:可能是错误的,可能与您从Form1继承了实用程序类有关:

public class testClass : Form1

几乎肯定只是

public class testClass

EDIT3(回答编辑成原始帖子的新问题):要测试Form1,您的类testClass可以具有Form1类型的成员变量,并通过Form1的公共方法和属性进行测试。 Form1甚至可以创建testClass实例(虽然这被认为是草率的)并将自己传递给testClass的构造函数:

// Inside Form1()
private TestClass m_testClass;

Form1()
{
    m_testClass = new testClass(this);
    ....
}

// Inside testClass
private Form1 m_testForm;

testClass(Form1 formToTest)
{
    m_testForm = formToTest;
}

void DoTest()
{
    // use m_testForm here...
}

答案 1 :(得分:1)

与您的StackOverflow异常无关,但有一些关于改进代码的一般注意事项:

  1. 为什么选择所有SelectedIndex if语句,如何使用SelectedValue?
  2. 尝试使用 else if 语句。如果SelIndex == 0,检查SelIndex == 1
  3. 是没用的
  4. 我可以建议以大写字母开头的类和属性吗?
  5. 尝试隔离重复代码(将其放入单独的方法或..)
  6. 使用(变量)和(!变量)代替(变量== true)或(变量== false)用于常规布尔值
  7. 布尔已用false
  8. 初始化

    编辑:Form1继承导致无限循环(因此StackOverflowException

    Form1类有两个字段:testClass和gameClass 但是testClass和gameClass都继承了Form1 所以每个testClass都有两个字段:testClass和gameClass 每个gameClass都有两个字段:testClass和gameClass。

    看到那个循环?

    我很遗憾地说,但是请阅读一些C#原则和面向对象的编程,因为这看起来有点像你不知道你在做什么。我并不是说这会使你失去动力,但是当你理解代码背后的概念时,它会更容易,更有趣。

答案 2 :(得分:0)

  1. 你的代码中没有循环,所以我已经消除了这是一个递归问题,或者你一遍又一遍地循环而没有结束的问题
  2. 我以为你丢失了代码,因为我没有看到主要但后来意识到这是一个表单应用程序(所以忽略顶部的评论)
  3. 为什么要声明一个类然后将表单继承到该类?另外:

    public class testClass:Form1

  4. 因为它只是一个类摆脱了:Form1

答案 3 :(得分:0)

构造函数中有无限递归。

: Form1testClass中删除gameClass

实际上,因为它们继承自Form1,所以它们都是由于这些行而实例化另一个testClass + gameClass的副本:

testClass newTest = new testClass();
gameClass newGame = new gameClass();

编辑:为了清楚这里发生了什么:testClass和gameClass,通过继承Form1,还继承了所有的成员变量,包括成员newText和newGame。从msdn article on C# fields:“在声明字段时,通过使用赋值运算符可以给字段赋予初始值...字段在调用对象实例的构造函数之前立即初始化。”

因此,当最初实例化一个新的Form1时,它首先尝试为其newTest和newGame成员分配初始值。

在创建新的testClass时,在testClass甚至到达其构造函数之前,它将尝试为其自己的newTest和newGame成员提供初始值。

重复广告恶心瞧! Stack Overflow。