如何修复我的Tic-Tac-Toe程序中的“堆栈溢出异常”? [英] How to fix 'stack overflow exception' in my Tic-Tac-Toe program?

查看:71
本文介绍了如何修复我的Tic-Tac-Toe程序中的“堆栈溢出异常”?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你好,

我试图创造我的第一个'游戏',即Tic-Tac-Toe。

我成功为两个玩家创造了一个游戏。

然后我扩展了我的想法并创建了'this',CPU vs Human Tic-Tac-Toe。

但是当轮到CPU时,

它会导致这个错误

由于stackoverflow异常导致进程终止

这是我的程序:

Hello,
I tried to create my first 'game' i.e., Tic-Tac-Toe.
I successfully created a game for two players.
Then I extended my idea and created 'this' , CPU vs Human Tic-Tac-Toe.
But when it is CPU's turn,
It causes this error
"Process is terminated due to stackoverflow exception"
Here is my program:

#include "stdafx.h"
#include <iostream>
using namespace std;
using namespace System;

void Loop(char a, char b, char c, char d, char e, char f, char g, char h, char i, int P);
int GetChoice(char a, char b, char c, char d, char e, char f, char g, char h, char i, int P);



void Board(char a, char b, char c, char d, char e, char f, char g, char h, char i)

{
    system("cls");

    cout << "\n\t    Tic-Tac-Toe\n\n\n";

    cout <<
        "\t+-----+-----+-----+\n"
        "\t|     |     |     |\n"
        "\t|  " << a << "  |  " << b << "  |  " << c << "  |\n"
        "\t|     |     |     |\n"
        "\t+-----+-----+-----+\n"
        "\t|     |     |     |\n"
        "\t|  " << d << "  |  " << e << "  |  " << f << "  |\n"
        "\t|     |     |     |\n"
        "\t+-----+-----+-----+\n"
        "\t|     |     |     |\n"
        "\t|  " << g << "  |  " << h << "  |  " << i << "  |\n"
        "\t|     |     |     |\n"
        "\t+-----+-----+-----+\n\n\n";

}

void Layout()
{
    Board('7', '8', '9', '4', '5', '6', '1', '2', '3');
    cout << "\n\t This is the layout"
        "\n\n\n\tUse your number pad "
        "\n\t       without"
        "\n      worrying about numbers!"
        "\n\n\n    Enter anything to start! : ";
    int x;
    cin >> x;
}


int Win(char a, char b, char c, char d, char e, char f, char g, char h, char i)
{
    if (a == b && b == c && b != ' ')
        return 1;
    else if (d == e && e == f && e != ' ')
        return 1;
    else if (g == h && h == i && h != ' ')
        return 1;

    else if (a == e && e == i && e != ' ')
        return 1;
    else if (c == e && e == g && e != ' ')
        return 1;

    else if (a == d && d == g && d != ' ')
        return 1;
    else if (b == e && e == h && e != ' ')
        return 1;
    else if (c == f && f == i && f != ' ')
        return 1;

    else if (a != ' ' && b != ' ' && c != ' ' &&
        d != ' ' && e != ' ' && f != ' ' &&
        g != ' ' && h != ' ' && i != ' ')
        return 2;

    else
        return 0;
}


int WinCheck(char a, char b, char c, char d, char e, char f, char g, char h, char i, char Z, int P)
{
    int X = Win(a, b, c, d, e, f, g, h, i);
    if (X == 0)
    {
        P = P + 1;
        Loop(a, b, c, d, e, f, g, h, i, P);
    }
    else if (X == 1)
    {
        Board(a, b, c, d, e, f, g, h, i);
        cout << "\t  Player '" << Z << "' wins!\n\n\n\n";
    }
    else
    {
        Board(a, b, c, d, e, f, g, h, i);
        cout << "\t  Match is Draw!\n\n\n\n";
        return 0;

    }
}



void Decider(char a, char b, char c, char d, char e, char f, char g, char h, char i, int q, int P)

{
    char Z;
    Z = (P % 2 == 1) ? 'X' : 'O';


    if (q == '7' && a != 'X' && a != 'O')
        a = Z;

    else if (q == '8' && b != 'X' && b != 'O')
        b = Z;

    else if (q == '9' && c != 'X' && c != 'O')
        c = Z;

    else if (q == '4' && d != 'X' && d != 'O')
        d = Z;

    else if (q == '5' && e != 'X' && e != 'O')
        e = Z;

    else if (q == '6' && f != 'X' && f != 'O')
        f = Z;

    else if (q == '1' && g != 'X' && g != 'O')
        g = Z;

    else if (q == '2' && h != 'X' && h != 'O')
        h = Z;

    else if (q == '3' && i != 'X' && i != 'O')
        i = Z;


    else
    {
        cout << "\n\nInvalid Move!\n\n";
        GetChoice(a, b, c, d, e, f, g, h, i, P);
    }

    WinCheck(a, b, c, d, e, f, g, h, i, Z, P);
}



int GetChoice(char a, char b, char c, char d, char e, char f, char g, char h, char i, int P)
{
    char Z;
    Z = (P % 2 == 1) ? 'X' : 'O';

    cout << "Player " << Z << "'s Choice: ";
    char q;
    cin >> q;
    Decider(a, b, c, d, e, f, g, h, i, q, P);
    return 0;
}



int Rand(char a, char b, char c, char d, char e, char f, char g, char h, char i, int q)
{
    q = rand() % 9 + 1;

    if (q == '7' && a != 'X' && a != 'O')
        return q;

    else if (q == '8' && b != 'X' && b != 'O')
        return q;

    else if (q == '9' && c != 'X' && c != 'O')
        return q;

    else if (q == '4' && d != 'X' && d != 'O')
        return q;

    else if (q == '5' && e != 'X' && e != 'O')
        return q;

    else if (q == '6' && f != 'X' && f != 'O')
        return q;

    else if (q == '1' && g != 'X' && g != 'O')
        return q;

    else if (q == '2' && h != 'X' && h != 'O')
        return q;

    else if (q == '3' && i != 'X' && i != 'O')
        return q;


    else
    {
        Rand(a, b, c, d, e, f, g, h, i, q);
    }
}


int MasterMind(char a, char b, char c, char d, char e, char f, char g, char h, char i, int P)
{
    int q = 0;

    if ((b == 'X' && c == 'X') || (d == 'X' && g == 'X') || (e == 'X' && i == 'X'))
        q = 7;
    else if ((a == 'X' && c == 'X') || (e == 'X' && h == 'X'))
        q = 8;
    else if ((a == 'X' && b == 'X') || (g == 'X' && e == 'X') || (f == 'X' && i == 'X'))
        q = 9;

    else if ((e == 'X' && f == 'X') || (a == 'X' && g == 'X'))
        q = 4;
    else if ((a == 'X' && i == 'X') || (b == 'X' && h == 'X') || (c == 'X' && g == 'X') || (d == 'X' && f == 'X'))
        q = 5;
    else if ((d == 'X' && e == 'X') || (c == 'X' && i == 'X'))
        q = 6;

    else if ((a == 'X' && d == 'X') || (c == 'X' && e == 'X') || (h == 'X' && i == 'X'))
        q = 1;
    else if ((g == 'X' && i == 'X') || (b == 'X' && e == 'X'))
        q = 2;
    else if ((g == 'X' && h == 'X') || (a == 'X' && e == 'X') || (c == 'X' && f == 'X'))
        q = 3;

    else
        q = Rand(a, b, c, d, e, f, g, h, i, q);

    Decider(a, b, c, d, e, f, g, h, i, q, P);

    return 0;
}



void Loop(char a, char b, char c, char d, char e, char f, char g, char h, char i, int P)
{
    char Z;
    Z = (P % 2 == 1) ? 'X' : 'O';

    if (Z == 'X')
    {
        Board(a, b, c, d, e, f, g, h, i);
        GetChoice(a, b, c, d, e, f, g, h, i, P);
        Board(a, b, c, d, e, f, g, h, i);

    }

    else if (Z == 'O')
    {
        Board(a, b, c, d, e, f, g, h, i);
        MasterMind(a, b, c, d, e, f, g, h, i, P);

    }
}



int main()
{
    Console::SetWindowSize(36, 40);

    Layout();

    char a = ' '; char b = ' '; char c = ' ';
    char d = ' '; char e = ' '; char f = ' ';
    char g = ' '; char h = ' '; char i = ' ';

    int P = 1;
    Loop(a, b, c, d, e, f, g, h, i, P);

    return 0;
}



那么,我该如何解决这个问题呢?


So, How do I fix this?

推荐答案

记忆管理对我来说很好



i假设它是一个无限递归循环

1.循环

2. GetChoice

3.决策者

4. WinCheck

5.循环



start它处于调试模式并在函数调用中检查您的参数或使用单步执行代码。



- >如果Win返回0,Wincheck将再次启动循环



- Wincheck中缺少返回值 - >不要忽略编译器警告



请调试你的代码





也许是一个可能的解决方案:

memory management looks good for me

i assume it's an infinite recursion-loop
1. Loop
2. GetChoice
3. Decider
4. WinCheck
5. Loop

start it in debug mode and check your parameters in function calls or use stepping through your code.

--> Wincheck start your Loop again if Win return with 0

- missing return values in Wincheck -> don't ignore compiler warnings

Please debug your code


maybe a possible solution:
int WinCheck(char a, char b, char c, char d, char e, char f, char g, char h, char i, char Z, int P)
	{
		int X = Win(a, b, c, d, e, f, g, h, i);
		if (X == 0)
		{
			P = P + 1;
			//Loop(a, b, c, d, e, f, g, h, i, P);
                        return XXXXXXXXX;
		}
		else if (X == 1)
		{
			Board(a, b, c, d, e, f, g, h, i);
			cout << "\t  Player '" << Z << "' wins!\n\n\n\n";
                        return XXXXXXXXX;
		}
		else
		{
			Board(a, b, c, d, e, f, g, h, i);
			cout << "\t  Match is Draw!\n\n\n\n";
			return 0;
 
		}
	}


正如每个开发人员都应该知道的那样,调试器是一个非常宝贵的工具(并且 Visual Studio 提供了一个很好的调试器):用它来找出实际问题。

当你编写递归函数时,你必须确保停止条件总是遇到每个可能的输入,不正确编写的递归函数通常是堆栈溢出的原因。
As every developer should know, the debugger is an invaluable tool (and Visual Studio provides a great debugger): use it to find out the actual problem.
When you write recursive functions you have to make sure that the stop condition is always met for every possible input, an improperly written recursive function is often the cause of a stack overflow.


GetChoice 函数调用 Decider 函数, Decider 调用 GetChoice 功能。这可以很容易地填充调用堆栈......

The GetChoice function calls the Decider function and, the Decider calls the GetChoice function. That can easily fill the call stack...


这篇关于如何修复我的Tic-Tac-Toe程序中的“堆栈溢出异常”?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆