I'm writing Tic Tac Toe console game at the moment and I have one very funny problem. The program is working great, but the problem is in matrix of Tic Tac Toe. The last element (last row, last column) is a smile and it's sometimes changing. It is sometimes laughing smile, or it is a heart. What's wrong?
The whole code:
#include <iostream>
#include <string>
#include <string.h>
#include <vector>
#include <stdlib.h>
using namespace std;
char matrix[3][3];
int orow, ocolumn, xrow, xcolumn;
int drawcounter = 0;
void paint() {
for (int i = 1; i < 4; i++) {
for (int j = 1; j < 4; j++)
matrix[i][j] = '_';
}
}
void board() {
for (int i = 1; i < 4; i++)
for (int j = 1; j < 4; j++) {
if (i != 1 && j == 1)
cout << endl;
cout << matrix[i][j] << " ";
}
cout << endl;
//cout << matrix[3][3] << endl;
}
void action() {
while (0 == 0) {
puts("Time for player X. Enter index");
cin >> xcolumn >> xrow;
matrix[xcolumn][xrow] = 'X';
drawcounter += 1;
if (drawcounter == 9) {
puts("It's a draw.");
break;
}
board();
cout << endl;
if ((matrix[1][1] == 'X' && matrix[2][2] == 'X' && matrix[3][3] == 'X') || (matrix[1][3] == 'X' && matrix[2][2] == 'X' && matrix[3][1] == 'X')) {
puts("X Wins! Congrats X!");
break;
}
if ((matrix[1][1] == 'X' && matrix[1][2] == 'X' && matrix[1][3] == 'X') || (matrix[2][1] == 'X' && matrix[2][2] == 'X' && matrix[2][3] == 'X') || (matrix[3][1] == 'X' && matrix[3][2] == 'X' && matrix[3][3] == 'X')) {
puts("X Wins! Congrats X!");
break;
}
if ((matrix[1][1] == 'X' && matrix[2][1] == 'X' && matrix[3][1] == 'X') || (matrix[1][2] == 'X' && matrix[2][2] == 'X' && matrix[3][2] == 'X') || (matrix[1][3] == 'X' && matrix[2][3] == 'X' && matrix[3][3] == 'X')) {
puts("X Wins! Congrats X!");
break;
}
puts("Time for player O. Enter index");
cin >> ocolumn >> orow;
matrix[ocolumn][orow] = 'O';
drawcounter += 1;
board();
cout << endl;
if ((matrix[1][1] == 'O' && matrix[2][2] == 'O' && matrix[3][3] == 'O') || (matrix[1][3] == 'O' && matrix[2][2] == 'O' && matrix[3][1] == 'O')) {
puts("O Wins! Congrats O!");
break;
}
if ((matrix[1][1] == 'O' && matrix[1][2] == 'O' && matrix[1][3] == 'O') || (matrix[2][1] == 'O' && matrix[2][2] == 'O' && matrix[2][3] == 'O') || (matrix[3][1] == 'O' && matrix[3][2] == 'O' && matrix[3][3] == 'O')) {
puts("O Wins! Congrats O!");
break;
}
if ((matrix[1][1] == 'O' && matrix[2][1] == 'O' && matrix[3][1] == 'O') || (matrix[1][2] == 'O' && matrix[2][2] == 'O' && matrix[3][2] == 'O') || (matrix[1][3] == 'O' && matrix[2][3] == 'O' && matrix[3][3] == 'O')) {
puts("O Wins! Congrats O!");
break;
}
}
}
int main() {
paint();
board();
action();
system("pause");
return 0;
}
Output pictures:
Array indexing in C/C++ start from 0, not from 1 - so you have to rewrite your code:
void paint() {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++)
matrix[i][j] = '_';
}
}
void board() {
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++) {
if (i != 0 && j == 0)
cout << endl;
cout << matrix[i][j] << " ";
}
cout << endl;
//cout << matrix[3][3] << endl;
}
What's actually is going on here, in detail: when you define your array, you should remember that indexing starts from 0, so for example when you declare an array of 3 elements, matrix[3], it's not going like matrix[1], matrix[2], and matrix[3], but rather matrix[0], matrix[1], and matrix[2].
So in this case you're getting out of an array bounds - and it's "here be dragons" territory outside of a memory region assigned to an array. So basically you're working with raw memory here, which in your situation contains a character code for a smiley face (and that's why it's different every time - because memory content isn't determined in this region - e.g., you can even try to get a value of matrix[123], though its size is only 3 elements - and you get an undefined random value as a result).
And you should remember that C/C++ arrays behavior is very similar to pointers in this regard - you might even say that it's the same thing.
In C++, arrays are indexed from 0. So in your loop in paint()
for(int i = 1; i < 4; ++i) // out of bounds when `i = 3`
you have an out of bound access, as matrix is declared as
char matrix[3][3];
You have to replace all such loops with loops from 0 to 3. Also, your if conditions are probably wrong
if ((matrix[1][6] == 'X' && matrix[2][7] .... // 6 and 7 ?!?!
as the row/column indexes cannot be greater than 2
char matrix[3][3];
[...]
matrix[3][3] == 'O'
This won't work. Array indices start at 0. So you've declared an array of size 3 and then access its 4th element. This is undefined behaviour. Which means anything can happen, including crashes or printing seemingly random characters.
Note that using raw arrays like this may raise an eyebrow or two. If you ever want the ability to determine matrix size dynamically (e.g. via user input), you will want to use std::vector anyway. And if the size is really conceptually meant to be known at compile time (which admittedly may be the case for a game like this), consider using std::array, or at least get informed on its syntax and benefits.
Maybe you are trying to store 1 in a char array as
#include<iostream>
using namespace std;
int main()
{
char n=1;
cout << n;
return 0;
}
The output will be a smiley
Related
I was creating the program for my friend who is interested in numerology and wants a way to calculate the value of words faster. But even though there are no errors and/or warnings, but the words' values aren't being calculated correctly. For example, "mark" has a value of 9, but the program shows 2. If you can figure out what the problem is, then pls help me. Thank you so much!
My Code:
#include <iostream>
#include <string>
int value{0};
void clear();
int main(void)
{
int number{0};
std::string response;
bool run = true;
while (run)
{
clear();
value = 0;
number = 1;
response = "";
std::cout << "How many words to evalute?:\n> ";
std::cin >> number;
std::cin.ignore();
clear();
std::string* pPhrase = new std::string[number];
int* pValue = new int[number];
for (int i = 0; i < number; ++i) // could replace "number" with "sizeof(pPhrase)/sizeof(pPhrase[0])"
{
std::cout << "Enter Word #" << i+1 << " (or type your full phrase):\n> ";
std::cin >> pPhrase[i];
for (char j : pPhrase[i])
{
value = 0;
j = std::tolower(j);
if (j == 'a' || j == 'i' || j == 'j'
|| j == 'q' || j == 'y')
value += 1;
if (j == 'b' || j == 'k' || j == 'r')
value += 2;
if (j == 'c' || j == 'g' || j == 'l'
|| j == 's')
value += 3;
if (j == 'd' || j == 'm' || j == 't')
value += 4;
if (j == 'e' || j == 'h' || j == 'n'
|| j == 'x')
value += 5;
if (j == 'u' || j == 'v' || j == 'w')
value += 6;
if (j == 'o' || j == 'z')
value += 7;
if (j == 'f' || j == 'p')
value += 8;
pValue[i] = value;
value = 0;
std::cout << '\n';
clear();
}
}
std::cin.ignore();
std::cin.clear();
std::cout << "\n\n";
for (int i = 0; i < number; ++i)
std::cout << "Value of \"" << pPhrase[i] << "\": " << pValue[i] << '\n';
//std::cin.ignore();
std::cin.clear();
std::cout << "Would you like to evaluate another phrase? (Y/n):\n> ";
std::getline(std::cin, response);
delete[] pPhrase;
delete[] pValue;
if (response[0] == 'y' || response[0] == 'Y'
|| response.empty() || response[0] == ' ')
{
std::cout << "\n\n";
continue;
}
break;
}
std::cout << "Exiting...";
system("killall Terminal");
std::cout << "\n\n\n";
return 0;
}
void clear()
{
system("clear");
}
You could make your program run faster by using a lookup table:
static const int table[26] = {
/* a */ 1, /* b */ 2, /* c */ 3, /* d */ 4, /* e */ 5,
/* f */ 8, /* g */ 3, /* h */ 5, /* i */ 1, /* j */ 1,
/* k */ 2, /* l */ 3, /* m */ 4, /* n */ 5, /* o */ 7,
/* p */ 8, /* q */ 1, /* r */ 2, /* s */ 3, /* t */ 4,
/* u */ 6, /* v */ 6, /* w */ 6, /* x */ 5, /* y */ 1,
/* z */ 7,
};
// ...
if (isalpha(j))
{
const int table_index = j - 'a';
const letter_value = table[table_index];
pValue[i] = letter_value;
//...
}
Print the assembly language for your code fragment, then print the assembly language for the above code fragment. Compare.
Look at all the places where you set value to zero. You do it before main() begins (which is not very useful, actually). Then, bizarrely, you set value to zero at both the start and end of your inner for loop, which means that all the value += statements in that for loop might as well be value = statements. You keep value from accumulating value.
How to solve this? First, get rid of all the value = 0 statements inside your inner for loop. Second, add int value = 0; before the inner for loop, like this:
int value = 0;
for (char j : pPhrase[i])
{
// ...
}
At this point, you might as well get rid of int value{0}; above main(). That step isn't absolutely necessary, but that declaration of value is totally unneeded.
Also, DO NOT put system("killall Terminal"); in your sample code. It's very unfriendly, since it kills the very command line on which you want others to run your sample code.
(In general, using system() at all is a bad idea, since it's unportable.)
There are several issues. The main issue is that on line 70, pValue[i] = value; is incorrectly positioned inside the for loop.
Here is a fixed version:
#include <iostream>
#include <string>
using namespace std;
int value{0};
void clear();
int main() {
int number{0};
string response;
while (true) {
clear();
value = 0;
number = 1;
response = "";
cout << "How many words to evaluate?:\n> ";
cin >> number;
cin.ignore();
clear();
auto *pPhrase = new string[number]{};
int *pValue = new int[number]{};
for (int i = 0; i < number; ++i) // could replace "number" with "sizeof(pPhrase)/sizeof(pPhrase[0])"
{
cout << "Enter Word #" << i + 1 << " (or type your full phrase):\n> ";
cin >> pPhrase[i];
for (char j: pPhrase[i]) {
j = tolower(j);
if (j == 'a' || j == 'i' || j == 'j'
|| j == 'q' || j == 'y')
value += 1;
if (j == 'b' || j == 'k' || j == 'r')
value += 2;
if (j == 'c' || j == 'g' || j == 'l'
|| j == 's')
value += 3;
if (j == 'd' || j == 'm' || j == 't')
value += 4;
if (j == 'e' || j == 'h' || j == 'n'
|| j == 'x')
value += 5;
if (j == 'u' || j == 'v' || j == 'w')
value += 6;
if (j == 'o' || j == 'z')
value += 7;
if (j == 'f' || j == 'p')
value += 8;
cout << '\n';
clear();
}
pValue[i] = value;
value = 0;
}
cin.ignore();
cin.clear();
cout << "\n\n";
for (int i = 0; i < number; ++i)
cout << "Value of \"" << pPhrase[i] << "\": " << pValue[i] << '\n';
cin.clear();
cout << "Would you like to evaluate another phrase? (Y/n):\n> ";
getline(cin, response);
delete[] pPhrase;
delete[] pValue;
if (response[0] == 'y' || response[0] == 'Y'
|| response.empty() || response[0] == ' ') {
cout << "\n\n";
continue;
}
break;
}
cout << "Exiting...";
system("killall Terminal");
cout << "\n\n\n";
return 0;
}
void clear() {
system("clear");
}
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
A few time ago I made a game similar to Gomoku in C++ that is taking between two players.
Now I want to make it Player vs Computer.
I tried to do it in simplest way, by making a function of computer to pick a random cell but I still haven't succeeded.
I understood that in order of getting a random number I can use rand() and for a letter something like this:
char letters[] = "abcdefghijklmnopqrstuvwxyz";
char x = letters[rand() % 26];
Can someone help me and describe how to implement a computer player?
This is my implementation so far:
#include <iostream>
#include <iomanip>
using namespace std;
void print_table(int x[][15]) {
system("cls");
for (int i = 0; i < 15; i++) {//the loop that use to print out the english character row
if (i == 0)
cout << setw(4) << "A";
else if (i == 1)
cout << " B";
else if (i == 2)
cout << " C";
else if (i == 3)
cout << " D";
else if (i == 4)
cout << " E";
else if (i == 5)
cout << " F";
else if (i == 6)
cout << " G";
else if (i == 7)
cout << " H";
else if (i == 8)
cout << " I";
else if (i == 9)
cout << " J";
else if (i == 10)
cout << " K";
else if (i == 11)
cout << " L";
else if (i == 12)
cout << " M";
else if (i == 13)
cout << " N";
else if (i == 14)
cout << " O";
else if (i == 15)
cout << " P";
}
cout << endl;
for (int i = 0; i < 15; i++) {
cout << setw(2) << i;//print out the row number
for (int j = 0; j < 15; j++) {//print out the board game.
if (x[i][j] == 0) {//the inital value is 0, so when the block is 0 then print out the '.'
cout << " .";
}
else if (x[i][j] == 1) {//when the player O input the block then the value will adding one then if check the block is one then output the 'o'
cout << " O";
}
else if (x[i][j] == 2) {//when the player X input the block then the value will adding two then if check the block is two then output the 'x'
cout << " X";
}
}
cout << endl;
}
}
int check_player(int p) {
if (p == 1) {//change the player everytime before the next loop compile
p++;
}
else {
p--;
}
return p;
}
void input_value(int &t, int &n, int p, int x[][15]) {
char eng;
int number;
do {//the loop that ask for the user input the location.
cout << "player ";
if (p == 1) {
cout << "O";
}
else {
cout << "X";
}
cout << ", make a move: ";
cin >> eng;//input the location
cin >> number;
if (eng == 'A')//change the character to different number
t = 0;
else if (eng == 'B')
t = 1;
else if (eng == 'C')
t = 2;
else if (eng == 'D')
t = 3;
else if (eng == 'E')
t = 4;
else if (eng == 'F')
t = 5;
else if (eng == 'G')
t = 6;
else if (eng == 'H')
t = 7;
else if (eng == 'I')
t = 8;
else if (eng == 'J')
t = 9;
else if (eng == 'K')
t = 10;
else if (eng == 'L')
t = 11;
else if (eng == 'M')
t = 12;
else if (eng == 'N')
t = 13;
else if (eng == 'O')
t = 14;
if (!(eng >= 'A'&&eng <= 'M') || !(number >= 0 && number <= 14) || x[number][t] != 0) {//when the input wrong, output the statement to ask anouther input and loop again.
cout << "Invaid input, Try again!" << endl;
continue;
}
else {//if no problem then this input loop is break and jump to the next statement
break;
}
} while (1);//Because it will break as well so the do-while loop is no any requirement
n = number;
}
int main() {
const int num = 15;//the number for constant the array row and column value
char check_e;//for the user input the column
int R[num][num] = { 0 }, check_n, player = 1, buger = 0, transfer, playerO_win = 0, playerX_win = 0, draw = 0, check_draw;//the variable that for user input or checking the game statment
do {//launch the loop for the user input again and again
check_draw = 0;//reset the checking of draw
print_table(R);
input_value(transfer, check_n, player, R);
R[check_n][transfer] += player;//change the value according the player's input and the player name.
for (int i = 0; i < num; i++) {
for (int j = 0; j < num; j++) {
if (i <= 8 && R[j][i] != 0 && (R[j][i] == R[j][i + 1] && R[j][i] == R[j][i + +2] && R[j][i] == R[j][i + 3] && R[j][i] == R[j][i + 4])) {//the checking for the row bingo
if (R[j][i] == 1) {
playerO_win++;
break;
}
else {
playerX_win++;
break;
}
}
else if (j <= 8 && R[j][i] != 0 && (R[j][i] == R[j + 1][i] && R[j][i] == R[j + 2][i] && R[j][i] == R[j + 3][i] && R[j][i] == R[j + 4][i])) {//the checking for the column bingo
if (R[j][i] == 1) {
playerO_win++;
break;
}
else {
playerX_win++;
break;
}
}
else if (j <= 8 && i <= 8 && R[j][i] != 0 && (R[j][i] == R[j + 1][i + 1] && R[j][i] == R[j + 2][i + 2] && R[j][i] == R[j + 3][i + 3] && R[j][i] == R[j + 4][i + 4])) {//the checking for the \ situation.
if (R[j][i] == 1) {
playerO_win++;
break;
}
else {
playerX_win++;
break;
}
}
else if ((j >= 4 || i >= 4 || i <= 8) && R[j][i] != 0 && (R[j][i] == R[j - 1][i + 1] && R[j][i] == R[j - 2][i + 2] && R[j][i] == R[j - 3][i + 3] && R[j][i] == R[j - 4][i + 4])) {//the checking for the / situation
if (R[j][i] == 1) {
playerO_win++;
break;
}
else {
playerX_win++;
break;
}
}
for (int i = 0; i < num; i++) {//the loop for checking the draw
for (int j = 0; j < num; j++) {//this loop will check for every time compilation.
if (R[j][i] == 0)//when there are any empty block then the check_draw will adding, the draw situation is the check_draw be 0
check_draw++;
}
}
if (check_draw == 0) {//when the check_draw equal to 0 which mean the situation is no empty block
draw++;
break;
}
}
if (playerO_win != 0 || playerX_win != 0 || draw == 1)//break the second loop
break;
}
if (playerO_win == 1 && playerX_win == 0) {// when the player win print the block game again and print out the win statement
print_table(R);
cout << "player O wins!" << endl;
break;
}
else if (playerX_win == 1 && playerO_win == 0) {//the other player win the game
print_table(R);
cout << "player X wins!" << endl;
break;
}
else if (draw == 1) {//the draw block game print
print_table(R);
cout << "Draw game!" << endl;
break;
}
player = check_player(player);
} while (1);//in fact it is no need for the loop statement, because most of the situation will have a break statement for out of the loop
return 0;
}
Here's how I would implement it probably based on your initial implementation:
#include <iostream>
#include <iomanip>
#include <cstdlib>
using namespace std;
#define SIZE 10
#define LINE_LENGTH 4
#define COMPUTER_O_PLAYER true
#define COMPUTER_X_PLAYER false
void print_board(unsigned char x[SIZE][SIZE]) {
cout << " ";
for (int i = 0; i < SIZE; i++) { // The loop that use to print out the english character row.
cout << (char) ('A' + i) << " ";
}
cout << endl;
for (int i = 0; i < SIZE; i++) {
cout << setw(2) << i; // Print out the row number.
for (int j = 0; j < SIZE; j++) {//print out the board game.
if (x[i][j] == 0) { // Unoccupied tile.
cout << " .";
} else if (x[i][j] == 1) { // The tile belongs to X.
cout << " X";
} else { // The tile belongs to O.
cout << " O";
}
}
cout << endl;
}
}
void get_position(int &x, int &y, bool player, unsigned char board[SIZE][SIZE]) {
char eng;
// The loop that ask for the user input the location.
do {
cout << "Player " << (player ? "X" : "O") << ", make a move: ";
cin >> eng;
y = toupper(eng) - 'A';
cin >> x;
if (!(x >= 0 && x < SIZE) || !(y >= 0 && y < SIZE) || board[x][y] != 0) {
// When the input wrong, output the statement to ask another input and loop again.
cout << "Invalid input, Try again!" << endl;
continue;
} else { // If no problem then this input loop is break and jump to the next statement.
break;
}
} while (true);
}
void get_random_position(int &x, int &y, bool player, unsigned char board[SIZE][SIZE]) {
do {
x = rand() % SIZE;
y = rand() % SIZE;
} while ((!(x >= 0 && x < SIZE) || !(y >= 0 && y < SIZE) || board[x][y] != 0));
cout << "Player " << (player ? "X" : "O") << " chose: " << (char) ('A' + y) << x << endl;
}
unsigned int
count_in_direction(unsigned char board[SIZE][SIZE], unsigned int x, unsigned int y, short int m_x, short int m_y) {
unsigned int count = 0;
unsigned char tile = board[x][y];
while (((x + m_x >= 0) && (x + m_x < SIZE)) && ((y + m_y >= 0) && (y + m_y < SIZE)) &&
(board[x + m_x][y + m_y] == tile)) {
x += m_x;
y += m_y;
count++;
}
return count;
}
bool full_line(unsigned char board[SIZE][SIZE], unsigned int x, unsigned int y) {
const short int directions[4][2] = {{1, 0},
{1, -1},
{0, 1},
{1, 1}};
for (const auto &direction : directions) {
if (LINE_LENGTH - 1 <= (count_in_direction(board, x, y, direction[0], direction[1]) +
count_in_direction(board, x, y, -direction[0], -direction[1])))
return true;
}
return false;
}
int main() {
// The variable that for user input or checking the game state.
unsigned char board[SIZE][SIZE] = {0};
int x, y;
bool player = true;
bool draw;
srand(time(nullptr));
// Run the game.
do {
print_board(board);
if ((player && COMPUTER_X_PLAYER) || (!player && COMPUTER_O_PLAYER)) {
get_random_position(x, y, player, board);
} else {
get_position(x, y, player, board);
}
board[x][y] = player ? 1 : 2;
if (full_line(board, x, y)) {
print_board(board);
cout << "player " << (player ? "X" : "O") << " wins!" << endl;
break;
}
draw = true;
for (int k = 0; (k < SIZE) && draw; k++) {
for (int l = 0; (l < SIZE) && draw; l++) {
if (board[k][l] == 0) draw = false;
}
}
if (draw) {
print_board(board);
cout << "Draw game!" << endl;
break;
}
player = !player;
} while (true);
return 0;
}
Please take a deep look in this implementation and internalize its approach, it also support both players as user, user and computer, and both computer.
Some insights:
Don't use long if ... else when there are simpler ways.
Use the correct data types for variables.
Use indicative variables naming.
Use loops where possible, again, not long if ... else.
Keep the code well formatted.
Use #define to define global constants to use, for easier changes later and readability.
You can indeed use rand, but you don't need to get a character, you can get an index straight away and avoid the conversion.
I'm trying to solve a problem on a competitive programming book where the output only appears after entering in the last input. I seem to have gotten the logic down but I'm still confuse as to how to do the input/output portion.
Here is the code:
#include <bits/stdc++.h>
int main()
{
std::ios_base::sync_with_stdio(false);
std::cin.tie(NULL);
std::vector<int>soundex;
std::string word;
for(int i = 0; i < word.length(); i++)
{
if (word[i] == 'B'|| word[i] == 'F' || word[i] == 'P' || word[i] == 'V')
{
soundex.push_back(1);
}
if (word[i] == 'C' || word[i] == 'G' || word[i] == 'J' || word[i] == 'K' || word[i] == 'Q' || word[i] == 'S' || word[i] == 'X' || word[i] == 'Z')
{
soundex.push_back(2);
}
if (word[i] == 'D' || word[i] == 'T')
{
soundex.push_back(3);
}
if (word[i] == 'L')
{
soundex.push_back(4);
}
if (word[i] == 'M' || word[i] == 'N')
{
soundex.push_back(5);
}
if (word[i] == 'R')
{
soundex.push_back(6);
}
}
for (int j = 0; j < soundex.size(); j++)
{
if (soundex[j] == soundex[j+1])
{
soundex.erase(soundex.begin() + 1);
}
std::cout << soundex[j];
}
std::cout << "\n";
return 0;
}
It behaves like this:
Input:
KHAWN
Output:
25
Input:
PFISTER
Output:
1236
Input:
BOBBY
Output:
11
But I need it to behave like this, per the instructions of the problem:
Input:
KHAWN
PFISTER
BOBBY
Output:
25
1236
11
Use while(cin >> word){ ... your code ... } to read until EOF (End Of File) in case every line only contains a word (no spaces allowed). You can keep the output as it is.
I'm writing the code for a game with C++, and when a player is supposed to win, for example all x's on the top row, the game keeps on prompting the next player for their move even when there is supposed to already be a winner. I don't know what's wrong with it, so any help in catching the problem is appreciated! Below is my full code.
#include <iostream>
#include <string>
using namespace std;
enum status{X_WON, O_WON, DRAW, UNFINISHED};
class Board{
public:
char boardArray[3][3];
Board();
bool makeMove(int, int, char);
status gameState();
void print();
};
Board::Board(){
for(int i = 0; i < 3; i++){
for(int j = 0; j < 3; j++){
boardArray[i][j] = '*';
};
};
};
bool Board::makeMove(int xIn, int yIn, char player){
if (boardArray[xIn][yIn] == '*'){
boardArray[xIn][yIn] = player;
return true;
}else{
return false;
};
};
status Board::gameState(){
status result;
if(boardArray[0][0] == 'x' && boardArray[0][1] == 'x' && boardArray[0] [2] == 'x'){
result = X_WON;
};
if(boardArray[0][0] == 'o' && boardArray[0][1] == 'o' && boardArray[0][2] == 'o'){
result = O_WON;
};
if(boardArray[1][0] == 'x' && boardArray[1][1] == 'x' && boardArray[1][2] == 'x'){
result = X_WON;
};
if(boardArray[1][0] == 'o' && boardArray[1][1] == 'o' && boardArray[1][2] == 'o'){
result = O_WON;
};
if(boardArray[2][0] == 'x' && boardArray[2][1] == 'x' && boardArray[2][2] == 'x'){
result = X_WON;
};
if(boardArray[2][0] == 'o' && boardArray[2][1] == 'o' && boardArray[2][2] == 'o'){
result = O_WON;
};
if(boardArray[0][0] == 'x' && boardArray[1][0] == 'x' && boardArray[2][0] == 'x'){
result = X_WON;
};
if(boardArray[0][0] == 'o' && boardArray[1][0] == 'o' && boardArray[2][0] == 'o'){
result = O_WON;
};
if(boardArray[0][1] == 'x' && boardArray[1][1] == 'x' && boardArray[2][1] == 'x'){
result = X_WON;
};
if(boardArray[0][1] == 'o' && boardArray[1][1] == 'o' && boardArray[2][1] == 'o'){
result = O_WON;
};
if(boardArray[0][2] == 'x' && boardArray[1][2] == 'x' && boardArray[2][2] == 'x'){
result = X_WON;
};
if(boardArray[0][2] == 'o' && boardArray[1][2] == 'o' && boardArray[2][2] == 'o'){
result = O_WON;
};
if(boardArray[0][0] == 'x' && boardArray[1][1] == 'x' && boardArray[2][2] == 'x'){
result = X_WON;
};
if(boardArray[0][0] == 'o' && boardArray[1][1] == 'o' && boardArray[2][2] == 'o'){
result = O_WON;
};
if(boardArray[0][2] == 'x' && boardArray[1][1] == 'x' && boardArray[2][0] == 'x'){
result = X_WON;
};
if(boardArray[0][2] == 'o' && boardArray[1][1] == 'o' && boardArray[2][0] == 'o'){
result = O_WON;
};
int taken = 0;
for(int i = 0; i < 3; i++){
for(int j = 0; j < 3; j++){
if(boardArray[i][j] != '*'){
taken++;
};
};
};
if(taken == 9 && (result != X_WON || result != O_WON)){
result = DRAW;
};
if(taken != 9 && (result != X_WON || result != O_WON || result != DRAW)){
result = UNFINISHED;
};
return result;
};
void Board::print(){
cout << " " << "0 " << "1 " << "2" << endl;
for(int i = 0; i < 3; i++){
cout << i << " ";
for(int j = 0; j < 3; j++){
cout << boardArray[i][j] << " ";
};
cout << endl;
};
};
class Ttt {
private:
char player;
public:
Board newBoard;
Ttt();
void play();
};
Ttt::Ttt(){
do{
cout << "Who should have the first move? x or o?" << endl;
cin >> player;
if (player == 'x' || player == 'o'){
break;
}else{
cout << "Not a valid player. Try again." << endl;
};
}while(true);
};
void Ttt::play(){
do{
int xcoord, ycoord;
do{
cout << "Player " << player << " , please enter your move. Example: 0 [enter] 0 (numbers from 0 - 2)" << endl;
cin >> xcoord >> ycoord;
if(newBoard.makeMove(xcoord, ycoord, player) == false){
cout << "That move is not valid. Try again." << endl;
}else{
break;
};
}while(true);
newBoard.makeMove(xcoord, ycoord, player);
newBoard.print();
if(player == 'x'){
player = 'o';
}else{
player = 'x';
};
if(newBoard.gameState() == X_WON){
cout << "Player X is the winner!" << endl;
break;
};
if(newBoard.gameState() == O_WON){
cout << "Player O is the winner!" << endl;
break;
};
if(newBoard.gameState() == DRAW){
cout << "Draw!" << endl;
break;
};
}while(true);
};
int main(){
Ttt newgame;
newgame.play();
}
The test
(result != X_WON || result != O_WON || result != DRAW)
is always true, since result can't be equal to all 3 values.
result should be initialised to UNFINISHED and the test changed to:
(taken != 9 && result == UNFINISHED)
This question already has answers here:
How to define member array size at runtime
(3 answers)
Closed 6 years ago.
I was trying to make a simple program that counts the number of vowels and consonants the user's name has. The size of the array is dependent on how many letters does the user's name has. I'm using queue to display the letters. When ever I run the program, the .Exe file crashes. So I tried to change the array size to a number instead of a variable and it worked. The problem is in using a variable for the size of the array, I think. Is there anyway to fix it? So that I can still use a variable for the size of my array. Here is my code
#include <iostream>
#include <queue>
using namespace std;
int main()
{
int i;
char bin[i];
queue<char> name;
int v = 0, c = 0;
cout << "how many letters does your name have?:";
cin >> i;
cout << "Enter the letters of your name one by one:\n";
do {
for (int k = 0; k < i; k++) {
cout << " ";
cin >> bin[k];
name.push(bin[k]);
if (bin[k] == 'a' || bin[k] == 'A') {
v++;
}
if (bin[k] == 'e' || bin[k] == 'E') {
v++;
}
if (bin[k] == 'i' || bin[k] == 'I') {
v++;
}
if (bin[k] == 'o' || bin[k] == 'O') {
v++;
}
if (bin[k] == 'u' || bin[k] == 'U') {
v++;
}
if (bin[k] == 'b' || bin[k] == 'B') {
c++;
}
if (bin[k] == 'c' || bin[k] == 'C') {
c++;
}
if (bin[k] == 'i' || bin[k] == 'D') {
c++;
}
if (bin[k] == 'f' || bin[k] == 'F') {
c++;
}
if (bin[k] == 'g' || bin[k] == 'G') {
c++;
}
if (bin[k] == 'h' || bin[k] == 'H') {
c++;
}
if (bin[k] == 'j' || bin[k] == 'J') {
c++;
}
if (bin[k] == 'k' || bin[k] == 'K') {
v++;
}
if (bin[k] == 'l' || bin[k] == 'L') {
v++;
}
if (bin[k] == 'm' || bin[k] == 'M') {
c++;
}
if (bin[k] == 'n' || bin[k] == 'N') {
c++;
}
if (bin[k] == 'P' || bin[k] == 'p') {
c++;
}
if (bin[k] == 'q' || bin[k] == 'Q') {
c++;
}
if (bin[k] == 'r' || bin[k] == 'R') {
c++;
}
if (bin[k] == 's' || bin[k] == 'S') {
c++;
}
if (bin[k] == 't' || bin[k] == 'T') {
c++;
}
if (bin[k] == 'v' || bin[k] == 'V') {
c++;
}
if (bin[k] == 'w' || bin[k] == 'W') {
c++;
}
if (bin[k] == 'x' || bin[k] == 'X') {
c++;
}
if (bin[k] == 'y' || bin[k] == 'Y') {
c++;
}
if (bin[k] == 'z' || bin[k] == 'Z') {
c++;
}
}
} while (bin[100] != '1');
cout << "\n\nYour name is:\n";
for (queue<char> run = name; !run.empty(); run.pop()) {
cout << " " << run.front() << endl;
}
cout << "\nVowels= " << v;
cout << "\nConsonants= " << c << "\n";
cout << "\n\n\n\n";
system("PAUSE");
return 0;
}
Your code has undefined behavior. int i; creates an uninitialized int named i. Then you use the uninitialized garbage variable in char bin[i];. So now we have an array with undefined size.
At this point we can't go any further. Once undefined behavior is invoked we can no longer reason how the code should work. If you need an array and you are not going to know what the size is until run time then you should use a std::vector and push_back()