C++ program S.O.S

Hello, I'm new to programming and my professor asked me to make a S.O.S game that will allow 2 players to enter their names, have and 8x8 board, count the wins of each player and it will ask the player in every turn if they want to pic S or O. So, I had watched this tut on youtube on how to create a simple tic tac toe program, and I thought its the same so I did it. The only problem is that, how can I make this an S.O.S. I know that the tic tac toe and S.O.S have the same mechanics. Its really hard for me. Please help me to understand and give me some advice on how can I make this program more efficient and bug free. Here is the code. I appreciate your help!
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
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
#include <iostream>
using namespace std;
char matrix[8][8] = { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',' ',' ',' ',' ',' ',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};
char player = 'X';
void Input();
void Draw()
{
    system("cls");
    cout << "S.O.S" << endl;
    cout<<"+===+===+===+===+===+===+===+===+"<<endl;
     
    
    for(int i=0;i<8;i++){
            cout<<"! ";
            for(int j=0;j<8;j++)
            cout<<matrix[i][j]<<" ! ";
            cout<<endl<<"+===+===+===+===+===+===+===+===+"<<endl;
            }       
}
void Input()
{
    int a;
    cout << "Press the number of the field: ";
    cin >> a;
 
    if (a == 1)
        matrix[0][0] = player;
    else if (a == 2)
        matrix[0][1] = player;
    else if (a == 3)
        matrix[0][2] = player;
    else if (a == 4)
        matrix[0][3] = player;
    else if(a == 5)
    	matrix[0][4] = player;
    else if(a == 6)
    	matrix[0][5] = player;
    else if (a == 7)
        matrix[0][6] = player;
    else if (a == 8)
        matrix[0][7] = player;
    else if (a == 9)
        matrix[1][0] = player;
    else if(a == 10)
    	matrix[1][1] = player;
    else if(a == 11)
    	matrix[1][2] = player;
    else if (a == 12)
        matrix[1][3] = player;
    else if (a == 13)
        matrix[1][4] = player;
    else if (a == 14)
        matrix[1][5] = player;
    else if(a == 15)
    	matrix[1][6] = player;
    else if(a == 16)
    	matrix[1][7] = player;
    else if (a == 17)
        matrix[2][0] = player;
    else if (a == 18)
        matrix[2][1] = player;
    else if (a == 19)
        matrix[2][2] = player;
    else if(a == 20)
    	matrix[2][3] = player;
    else if(a == 21)
    	matrix[2][4] = player;
    else if (a == 22)
        matrix[2][5] = player;
    else if (a == 23)
        matrix[2][6] = player;
    else if (a == 24)
        matrix[2][7] = player;
    else if(a == 25)
    	matrix[3][0] = player;
    else if(a == 26)
    	matrix[3][1] = player;
    else if (a == 27)
        matrix[3][2] = player;
    else if (a == 28)
        matrix[3][3] = player;
    else if (a == 29)
        matrix[3][4] = player;
    else if(a == 30)
    	matrix[3][5] = player;
    else if(a == 31)
    	matrix[3][6] = player;
    else if (a == 32)
        matrix[3][7] = player;
    else if (a == 33)
        matrix[4][0] = player;
    else if (a == 34)
        matrix[4][1] = player;
    else if(a == 35)
    	matrix[4][2] = player;
    else if(a == 36)
    	matrix[4][3] = player;
    else if (a == 37)
        matrix[4][4] = player;
    else if (a == 38)
        matrix[4][5] = player;
    else if (a == 39)
        matrix[4][6] = player;
    else if(a == 40)
    	matrix[4][7] = player;
    else if(a == 41)
    	matrix[5][0] = player;
    else if (a == 42)
        matrix[5][1] = player;
    else if (a == 43)
        matrix[5][2] = player;
    else if (a == 44)
        matrix[5][3] = player;
    else if(a == 45)
    	matrix[5][4] = player;
    else if(a == 46)
    	matrix[5][5] = player;
    else if (a == 47)
        matrix[5][6] = player;
    else if (a == 48)
        matrix[5][7] = player;
    else if (a == 49)
        matrix[6][0] = player;
    else if(a == 50)
    	matrix[6][1] = player;
    else if(a == 51)
    	matrix[6][2] = player;
    else if (a == 52)
        matrix[6][3] = player;
    else if (a == 53)
        matrix[6][4] = player;
    else if (a == 54)
        matrix[6][5] = player;
    else if(a == 55)
    	matrix[6][6] = player;
    else if(a == 56)
    	matrix[6][7] = player;
    else if (a == 57)
        matrix[7][0] = player;
    else if (a == 58)
        matrix[7][1] = player;
    else if (a == 59)
        matrix[7][2] = player;
    else if(a == 60)
    	matrix[7][3] = player;
    else if(a == 61)
    	matrix[7][4] = player;
    else if (a == 62)
        matrix[7][5] = player;
    else if (a == 63)
        matrix[7][6] = player;
    else if (a == 64)
        matrix[7][7] = player;

}

void TogglePlayer()
{
    if (player == 'X')
        player = 'O';
    else
        player = 'X';
}
char Win()
{
    //first player
    if (matrix[0][0] == 'X' && matrix[0][1] == 'X' && matrix[0][2] == 'X')
        return 'X';
    if (matrix[1][0] == 'X' && matrix[1][1] == 'X' && matrix[1][2] == 'X')
        return 'X';
    if (matrix[2][0] == 'X' && matrix[2][1] == 'X' && matrix[2][2] == 'X')
        return 'X';
 
    if (matrix[0][0] == 'X' && matrix[1][0] == 'X' && matrix[2][0] == 'X')
        return 'X';
    if (matrix[0][1] == 'X' && matrix[1][1] == 'X' && matrix[2][1] == 'X')
        return 'X';
    if (matrix[0][2] == 'X' && matrix[1][2] == 'X' && matrix[2][2] == 'X')
        return 'X';
 
    if (matrix[0][0] == 'X' && matrix[1][1] == 'X' && matrix[2][2] == 'X')
        return 'X';
    if (matrix[2][0] == 'X' && matrix[1][1] == 'X' && matrix[0][2] == 'X')
        return 'X';
 
    //second player
    if (matrix[0][0] == 'O' && matrix[0][1] == 'O' && matrix[0][2] == 'O')
        return 'O';
    if (matrix[1][0] == 'O' && matrix[1][1] == 'O' && matrix[1][2] == 'O')
        return 'O';
    if (matrix[2][0] == 'O' && matrix[2][1] == 'O' && matrix[2][2] == 'O')
        return 'O';
 
    if (matrix[0][0] == 'O' && matrix[1][0] == 'O' && matrix[2][0] == 'O')
        return 'O';
    if (matrix[0][1] == 'O' && matrix[1][1] == 'O' && matrix[2][1] == 'O')
        return 'O';
    if (matrix[0][2] == 'O' && matrix[1][2] == 'O' && matrix[2][2] == 'O')
        return 'O';
 
    if (matrix[0][0] == 'O' && matrix[1][1] == 'O' && matrix[2][2] == 'O')
        return 'O';
    if (matrix[2][0] == 'O' && matrix[1][1] == 'O' && matrix[0][2] == 'O')
        return 'O';
 
    return '/';
}
int main()
{
    Draw();
    while (1)
    {
        Input();
        Draw();
        if (Win() == 'X')
        {
            cout << "X wins!" << endl;
            break;
        }
        else if (Win() == 'O')
        {
            cout << "O wins!" << endl;
            break;
        }
        TogglePlayer();
    }
    system("pause");
    return 0;
}
Last edited on
Any time you find yourself writing nearly identical code for pages and pages, you should look for a way to factor it out. In this case, lines 29-156 could be:

1
2
3
int row = (a-1) / 8;
int col= (a-1) % 8;  // % is the modulo or remainder function
matrix[row][col] = player;

Okay ill do that. But how am i suppose to make it like an s.o.s game? Can you give me any idea how?
I wasn't familiar with SOS so I just https://en.wikipedia.org/wiki/SOS_(game) to get familiar with it.

You'll need functions to:
- get an input square from a player.
- Draw the board
- Given the location of a newly placed letter, return the number of SOS's that it creates.

With these, pseudocode for the main program might be:
Decide who goes first
1
2
3
4
5
6
7
8
9
10
11
12
13
14
set variable currentPlayer to the first player
while (the board is not full) {
    DrawTheBoard();
    GetMove(currentPlayer, letter, row, col);   <<< letter, row and col are output parameters
    board[row][col] = letter;
    newSOSs = countNewSOS(row, col);
    score[currentPlayer] += newSOSs;
    if (newSOSs == 0) {
        currentPlayer = the Other player
    } else {
        score[currentPlayer] += newSOSs;
    }
}
printTheWinner();

Thanks ill work on it !:)
I have one question, what is the use of newSOSs = countNewSOS(row,col);
?
I'm really getting a hard time figuring out how I can make my program to ask the p1's move and then p2's move.
Last edited on
@dhayden Okay, I already build it. So this is it, the only problem is whenever I check from the first line if the p1 wins. And then I put another S or O. It counts the wins even though I haven't got any S.O.S. Here it is.
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
#include <iostream>
using namespace std;
int player = 0;
char board[8][8] = {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',' ',' ',' ',' ',' ',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};
void gameboard();
void getmove();
int main();
char choice;
int player1,player2;
int score1 = 0, score2 = 0;
char letter;
void gather_all();
void win1();
int row, col;
int a;
void gameboard()
{
	system("cls");
    cout << "player1: " <<score1<<"\t"<< "player2: "<<score2<< endl;
    cout<<"+===+===+===+===+===+===+===+===+"<<endl;
     
    
    for(int i=0;i<8;i++){
            cout<<"! ";
            for(int j=0;j<8;j++)
            cout<<board[i][j]<<" ! ";
            cout<<endl<<"+===+===+===+===+===+===+===+===+"<<endl;
            }       
}
void getmove()
{
	int row, col;
	if(player <=0)
	{
		cout<<"P1 enter the block(NUMBERS ONLY!): ";
		while(!(cin>>a))
		{
			cout<<"I SAID NUMBERS ONLY!!!!";
			cin.clear();
			cin.ignore(1000,'\n');
		}
		cout<<"Enter S or O(USE CAPITALS ONLY!): ";
		cin>>letter;
		if(letter == 'S' || letter == 'O')
		{
			row = (a-1)/8;
			col = (a-1)%8;
			board[row][col] = letter;
			player++;
			win1();
		}
		}
		else
		{
			cout<<"I SAID CAPITALS ONLY!!!!. ALSO USE S OR O.";
			system("pause");
			system("cls");
		}
		
	
	
		if(player > 0 )
	{
		cout<<"P2 enter the block(NUMBERS ONLY!): ";
		cin>>a;
		cout<<"Enter S or O(USE CAPITALS ONLY!): ";
		cin>>letter;
		if(letter == 'S' || letter == 'O')
		{
			row = (a-1)/8;
			col = (a-1)%8;
			board[row][col] = letter;
			player--;

		}
		else
		{
			cout<<"I SAID CAPITALS ONLY!!!!. ALSO USE S OR O.\n\n";
			system("cls");
		}
		
		
	}
}
void win1()
{
	if(board[0][0] == 'S' && board[1][0] == 'O' && board[2][0] == 'S')//vertical 1,9,17
	{
		score1++;
	}
	if(board[0][0] == 'S' && board[0][1] == 'O' && board[0][2] == 'S')//horizontal 1,2,3
	{
		score1++;
	}
	if(board[0][3] == 'S' && board[0][4] == 'O' && board[0][5] == 'S')//horizontal 4,5,6
	{
		score1++;
	}
	
	
}
void gather_all()
{
	gameboard();
	while(1)
	{
		getmove();
		gameboard();
		
	}	
}
int main()
{
	gather_all();
	return 0;
}
Last edited on
Lines 56-61: this else matches the if at line 36, which doesn't seem to be what you intended.
Line 117: rather than having main simply call another function, move the logic into main.

I would create a currentPlayer variable whose value is 0 or 1 to indicate if the current player is 1 or 2. I know this seems weird to a beginner, but you'll get used to always counting things starting with 0 instead of 1. The reason is...

... store the scores in an array int score[2]. Now to access the current player's score, you just say score[currentPlayer]. Nice and easy! This will also make the getmove() code a lot easier because you won't need duplicated code for each player.

Speaking of getmove(), a person won't want to enter the square number because it will be hard for them to calculate. Why not let them enter the row and column number instead? Of course, they will want to enter them as numbers 1-8, but internally you'll want to store them as indexes into board array (0-7). You can pass the these back to the caller in references.

To keep from getting confused, you should make it a policy to always store the player and the row/column in the program as 0-based numbers. Convert to/from 1-based numbers only when you're doing the I/O. That will make the code easy to maintain.

When getting the move, what if the number is out of range? What if the square is already taken? You should check all of these.

Here is your code with these changes.
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
#include <iostream>
using namespace std;
int currentPlayer = 0;		// 0-> player 1. 1->player 2
int score[2];			// indexed by currentPlayer
char board[8][8] = { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
    ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
    ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
    ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '
};


void gameboard();
void getmove(int &row, int &col);
void gather_all();
void win1();

void
gameboard()
{
    system("cls");
    cout << "player1: " << score[0] << "\t" << "player2: " << score[1] << endl;
    cout << "+===+===+===+===+===+===+===+===+" << endl;

    for (int i = 0; i < 8; i++) {
	cout << "! ";
	for (int j = 0; j < 8; j++)
	    cout << board[i][j] << " ! ";
	cout << endl << "+===+===+===+===+===+===+===+===+" << endl;
    }
}


// Get a move from the current player.  Set the value in the board and return the row/column
// that they set.
void
getmove(int &row, int &col)
{
    char letter;

    while (true) {
	if (currentPlayer == 0) {
	    cout << "Player 1 enter the row and column (NUMBERS ONLY!): ";
	} else {
	    cout << "Player 2 enter the row and column (NUMBERS ONLY!): ";
	}

	if (!(cin >> row >> col)) {
	    cout << "I SAID NUMBERS ONLY!!!!\n";
	    cin.clear();
	    cin.ignore(1000, '\n');
	    continue;		// go back to the start of the loop
	}
	row--;			// immediately convert from 1-8 to 0-7
	col--;

	// Is the number valid?
	if (row < 0 || col < 0 || row > 7 || col > 7) {
	    cout << "Row and column numbers must be 1-8\n";
	    continue;
	}

	if (board[row][col] != ' ') {
	    cout << "That square is already taken\n";
	    continue;
	}

	break;  // success
    }


    // Get the value for the square
    while (true) {
	cout << "Enter S or O(USE CAPITALS ONLY!): ";
	cin >> letter;
	if (letter == 'S' || letter == 'O') {
	    break;
	} else {
	    cout << "I SAID CAPITALS ONLY!!!!. ALSO USE S OR O.";
	    system("pause");
	    system("cls");
	}
    }

    board[row][col] = letter;
}


void
win1()
{
}


int
main()
{
    int row, col;
    while (1) {
	gameboard();
	getmove(row, col);
	currentPlayer = !currentPlayer;  // switch players

    }
    return 0;
}

OK, but let me ask one more favor, I already made the game, the only problem is that the score count is unstable, The first 2 wins either p1 or p2, the score is good. But whenever p1 or p2 moves it counts the score and adds 1 or even greater amount in both score counts. Example if p1 wins: 1 and p2 wins: 1, the third move p1 wins:2 and p2 wins: 3. Even though there is no winner. forgive me hahhaa, I'm just trying my best to create this program. I can't post my program here its over 1.5k lines. I made the checking manually. Can you just give me an advice on how I can make this program stable, you can check it here.

https://mega.nz/#!ZFBXVSia!7bXuK__1bhkMWRH7UpN64SyC54yFaPtKqlwELdpAbUE
If you call win1() it will increment score1 for each "SOS" on the board, even the ones that player2 put there. Similarly, if you call win2(), it will increment score2 for each SOS on the board, even ones that player 1 put there.

If I understand the rules right, you should increment the score of one player after each move based on now many new SOS's the move creates. So you need a function that takes the position of the current move, and it will count up the SOS's that include that square. Something like:
int newSOSes(int row, int col);
Note that you should do this with some loops, not like you're current win1() and win2() functions. Those could be made much simpler with loops too.

After each move you will adjust the score accordingly. Something like:
1
2
3
4
5
6
int count = newSOSes(row, col);
if (player <= 0) {
    score1 += count;
} else {
    score2 += count;
}

It might not matter, but you do no checking of the square number in getmove(). The user could enter -17, or 867, or a square that is already taken.


Really appreciate it. Thanks !:)
Topic archived. No new replies allowed.