Проблема с игрой в угадывание чисел c # - PullRequest
3 голосов
/ 24 февраля 2010

Я получаю ошибку stackOverflow (без каламбура): «В NumberGuessingGame.exe возникло необработанное исключение типа« System.StackOverflowException »* *

Полагаю, это помогло бы, если бы вы увидели мой код и также указали, где он происходит:

Источник - 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.");

        }

    }
}
}

Источник - форма1:

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, ошибки кода:

Спасибо всем за помощь <3 </p>

Удаление «формы 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 ]

4 голосов
/ 24 февраля 2010

Переполнение стека происходит почти всегда, потому что вы повторяетесь бесконечно. Другими словами, функция вызывает себя без перерыва в этом цикле, поэтому она вызывает миллион раз, пока стек не переполнится. Иногда функция 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 голос
/ 24 февраля 2010

Не относится к вашему исключению StackOverflow, но есть некоторые общие замечания по улучшению вашего кода:

  1. Почему все if-операторы SelectedIndex, как насчет использования SelectedValue?
  2. Попробуйте использовать else if . Если SelIndex == 0, проверять SelIndex == 1
  3. Могу ли я предложить классы и свойства для запуска в верхнем регистре?
  4. Попробуйте выделить повторяющийся код (поместите его в отдельный метод или ..)
  5. Используйте (переменная) и (! Переменная) вместо (переменная == true) или (переменная == false) для обычных логических значений
  6. логические значения уже инициализированы с ложным

РЕДАКТИРОВАТЬ: наследование Form1 вызывает бесконечный цикл (и поэтому исключение StackOverflowException

Класс Form1 имеет два поля: testClass и gameClass.
Однако testClass и gameClass оба наследуют Form1.
Таким образом, у каждого testClass есть два поля: testClass и gameClass.
И у каждого gameClass есть два поля: testClass и gameClass.

Видите цикл в этом?

Извините, но, пожалуйста, прочитайте некоторые принципы C # и объектно-ориентированное программирование, потому что это похоже на то, что вы понятия не имеете, что делаете. Я не говорю это, чтобы демотивировать вас, но это намного проще и веселее, когда вы понимаете концепции, лежащие в основе кода.

0 голосов
/ 24 февраля 2010

У вас бесконечная рекурсия в конструкторах.

Избавьтесь от : Form1 от ваших testClass и gameClass.

Как таковые, поскольку они наследуют от Form1, каждый из них создает свои собственные копии другого testClass + gameClass из-за строк:

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

Редактировать : Просто чтобы было ясно, что здесь происходит: testClass и gameClass, наследуя от Form1, также наследуют все переменные-члены, включая члены newText и newGame. Из статьи msdn о полях C # : "Поле может быть присвоено начальное значение с помощью оператора присваивания, когда поле объявлено ... Поля инициализируются непосредственно перед вызовом конструктора для экземпляра объекта. «

Итак, когда создается новая форма Form1, она сначала пытается присвоить начальные значения своим членам newTest и newGame.

При создании этого нового testClass, прежде чем testClass даже доберется до своего конструктора, он попытается предоставить начальные значения своим собственным членам newTest и newGame.

Повторите до тошноты и вуаля! Переполнение стека.

0 голосов
/ 24 февраля 2010
  1. В вашем коде нет циклов, поэтому я устранил тот факт, что это рекурсивная проблема или проблема, когда вы циклически повторяетесь без конца
  2. Я думал, что вам не хватает кода, так как я не видел основной, но потом понял, что это приложение формы (поэтому проигнорируйте комментарий вверху)
  3. Почему вы объявляете класс, а затем наследуете форму этому классу? Дополнительно:

    открытый класс testClass: Form1

Так как это просто класс, избавьтесь от : Form1

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...