Click here to Skip to main content
15,937,012 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
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?
Posted
Updated 21-Jul-15 23:29pm
v2

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:
C++
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;
 
		}
	}
 
Share this answer
 
v2
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.
 
Share this answer
 
Comments
Member 11851565 22-Jul-15 4:31am    
But I don't know how to use debugger!
Frankie-C 22-Jul-15 5:45am    
This is a good reason to start to learn ;-)
Moreover even without debugger you need to learn better how to implement program flows and function calls works.
Generally when a function is called you come back before to recall that function again, if you call it inside itself this is called recursion, and in this case you must check that the whole calling flow will stop after a while, or you'll fill the stack with return addresses up to overflow.
But you made something even worst: you have a couple of functions that call each other (GetChoice and Decider) without any control. The program workflow is inexistent and you continue to go in one function than inside the other without ever return...

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

 
Share this answer
 
Hey, Finally I came up with my own solution!

The problem was in Rand function!

This is my original Rand fn:


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);
    }
}



Here, I defined "q" as an "int", not "char"!

As '7' is not equal to 7, It had to go to "Rand" again and again, thereby causing stack overflow!


Now that I found it, I corrected it!

Here is my corrected "Rand" function:


int Rand(char a, char b, char c, char d, char e, char f, char g, char h, char i, int q)
    {
        srand(time(NULL)); \\I searched this in the web
        q = rand() % 9 + 1;

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

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

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

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

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

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

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

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

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


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


Ha! Ha! So that's It!

And I have made some changes in MasterMind() and some others too!
 
Share this answer
 
Comments
CPallini 22-Jul-15 7:32am    
please note
srand(time(NULL)); \I searched this in the web
should be called once at the start of the game.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900