Tic tac toe-issue

Hello, happy to join this group of people. Have learned a bit from this website about C++. Anyway I have encountered a issue regarding a tic tac toe-game. The game works perfectly fine when I use the standard 3x3 size and players need to have three characters in a row in order to win. However, when I extend the board to e.g. 5x5 and players need to have four characters in a row to win, the game doesn't work properly, i.e. is doesn't say that a player has won when it should have.

KNOWN ISSUES:
1. The game can't check if a player have won on the diagonal other than the two diagonals in the "middle". This is something that I am aware of and think I know how to fix, so no comments on that are neccessary.

2. The game works if I choose e.g. 7x7 and the amount of character in a row is the same as the size (in this case seven). It does however not work if I choose 7x7 and then five in a row to win.

In the end of the main-function it sais decide+=2;
I did that so it would go faster to test the program by running it since I only have to play for one player.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>

using namespace std;

enum TicTacToeCases {
        PLAYER_ONE = 'O',
        PLAYER_TWO = 'X',
        NEUTRAL    = '*'
    };

void printGame(char [][20], int);
void makeMove(char [][20], int, char);
bool checkIfGameOver(char [][20], char, int, int);

int main(){

    srand(time(NULL));
    int decide = rand();
    bool over = false;
    int boardSize = 3;
    int toWin = 3;
    char player;

    char ticTacToe[20][20];

    cout<< "Choose the size of the board: ";
    cin>> boardSize;
    cout<< "Choose the amount of character in a row in order to win: ";
    cin>> toWin;

    for (int i = 0; i < boardSize; i++){
        for (int j = 0; j < boardSize; j++){
            ticTacToe[i][j] = static_cast<char>(NEUTRAL);
        }
    }
    printGame(ticTacToe, boardSize);

    while (!over){

        if (decide % 2 == 0){
            player = static_cast<char>(PLAYER_ONE);
            makeMove(ticTacToe, boardSize, player);
            printGame(ticTacToe, boardSize);
            over = checkIfGameOver(ticTacToe, player, boardSize, toWin);
        }

        else{
            player = static_cast<char>(PLAYER_TWO);
            makeMove(ticTacToe, boardSize, player);
            printGame(ticTacToe, boardSize);
            over = checkIfGameOver(ticTacToe, player, boardSize, toWin);
        }
        decide+=2;
    }
}

void printGame(char ticTacToe[][20], int boardSize){
    for (int i = 0; i < boardSize; i++){
        for (int j = 0; j < boardSize; j++){
            cout<< ticTacToe[i][j]<< "   ";
        }
        cout<< "\n\n";
    }
}

void makeMove(char ticTacToe[][20], int boardSize, char player){

    int i;
    int j;
    bool valid = false;

    while (!valid){
        cout<< "Player one decide position\n";
        cin>> i;
        cin>> j;
        if (ticTacToe[i-1][j-1] == '*'){
            valid = true;
        }
        else{
            cout<< "This position is already taken\n";
        }
    }
    cout<< "\n";
    ticTacToe[i-1][j-1] = static_cast<char>(player);
}

bool checkIfGameOver(char ticTacToe[][20], char player, int boardSize, int toWin){

    int counter = 0;
    int diagonal = 0;
    int otherDiagonal = boardSize - 1;
    int *forTheDiagonal = &diagonal;
    int *forTheOtherDiagonal = &otherDiagonal;

    for (int i = 0; i < boardSize; i++){
        counter = 0;
        for (int j = 0; j < boardSize; j++){
            if (ticTacToe[i][j] == player){
                counter++;
            }
            else{
                counter = 0;
            }
        }
        if (counter == toWin){
            cout<< "Player one wins!\n";
            return true;
        }
    }
    counter = 0;

    for (int i = 0; i < boardSize; i++){
        counter = 0;
        for (int j = 0; j < boardSize; j++){
            if (ticTacToe[j][i] == player){
                counter++;
            }
            else{
                counter = 0;
            }
        }
        if (counter == toWin){
            cout<< "Player one wins!\n";
            return true;
        }
    }
    counter = 0;

    for (int i = 0; i < boardSize; i++){
        counter = 0;
        if (ticTacToe[i][diagonal] == player){
            counter++;
            (*forTheDiagonal)++;
        }
        else{
            *forTheDiagonal = 0;
        }
        if (counter == toWin){
            cout<< "Player one wins!\n";
            return true;
        }
    }
    counter = 0;

    for (int i = 0; i < boardSize; i++){
            counter = 0;
        if (ticTacToe[i][otherDiagonal] == player){
            counter++;
            (*forTheOtherDiagonal)--;
        }
        else{
            *forTheOtherDiagonal = boardSize - 1;
        }
        if (counter == toWin){
            cout<< "Player one wins!\n";
            return true;
        }
    }
    counter = 0;
    return false;
}
Last edited on
I have made you a dynamic programming aproach for your diagonal checkings, basically store in a score matrix all lengths of all diagonals dynamically from the top of the matrix to the bottom if the max length from the score matrix is equal to the "toWin" variable then return true

note that I did not make you a solution for rows and colums checking that's my kind of "homework" for you so you can understand the algorithm better.

check my algorithm on paper on a smaller example so you can understand it better, im sure you will find it easy once you understand it

this algorithm has O(n^2) complexity which is better than trying all possible diagonal positions and getting a O(n!) complexity or worse and waiting ages for a checking to be done on a 10x10 table or something.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
bool checkIfGameOver(char ticTacToe[][20], char player, int boardSize, int toWin){

	//create a score matrix
	int n = boardSize;
	int **score = new int*[n];
	for (int i = 0; i < n; i++){
		score[i] = new int[n]();
	}

	//compute first row
	for (int i = 0; i < n; i++){
		if (ticTacToe[0][i] == player)
			score[0][i] = 1;
	}

	int max = 1; //counter for diagonal
	//compute the longest diagonal
	for (int i = 1; i < n; i++){
		if (ticTacToe[i][0] == player) //compute most left colum
			score[i][0] = 1 + score[i - 1][1];
		for (int j = 1; j < n - 1 ; j++){
			if (ticTacToe[i][j] == player){
				score[i][j] = 1 + maximum(score[i - 1][j - 1], score[i - 1][j + 1]); //select longest current diagonal
				if (score[i][j] > max)
					max = score[i][j];
			}		
		}
		if (ticTacToe[i][n - 1] == player) //compute most right colum
			score[i][n - 1] = 1 + score[i - 1][n - 2];

                //here we compute the maximum from the most left and right colums
		if (maximum(score[i][n - 1], score[i][0]) > max)
			max = maximum(score[i][n - 1], score[i][0]);
	}

	//delete score matrix
	for (int i = 0; i < boardSize; i++){
		delete[] score[i];
	}
	delete[] score;

	if (max == toWin)
		return true;
	return false;
}
Last edited on
Thank you for your time, but do you know the reason my program isn't working? It seems legit.
explain your aproach cause I don't really understand what you wanted to do there
Try copy paste my code into a IDE, or whatever they are called. Then run the program and choose a 6x6 board and choose 4 as the amount of character in a row to win. Then place four character in a row and look. It will not say that this player has won, even though there are four in a row. I have tried to print the value of counter inside one of the checkers and it is indeed four, bur for some reason the program doesn't execute the if-statement.
Here I uploaded a picture to imgur to illustrate what the problem is.

http://imgur.com/Uz9X1hA
Topic archived. No new replies allowed.