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)
Related
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 made binary calculator. It works, but only when numbers doesnt start with 0. if yes, it shows this:
How I should repair the program, please? (vysledek means result)
Part of code with substr:
while(vysledek[0] == '0')
{
vysledek = vysledek.substr(1, vysledek.length());
w++;
}
int aa;
aa = p-w;
for(o; o < aa; o++)
{
cout << vysledek[o];
}
Whole program:`
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
using namespace std;
int main()
{
cout << "Zadejte dve binarni cisla:" << endl;
string cislo1, cislo2;
cin >> cislo1 >> cislo2;
int c = 0;
for (c; c < cislo1.length(); c++)
{
if ((cislo1[c] == '0') || (cislo1[c] == '1'))
{
continue;
}
else
{
cout << "Nespravny vstup.";
return 0;
}
}
int d = 0;
for (d; d < cislo2.length(); d++)
{
if ((cislo2[d] == '0') || (cislo2[d] == '1'))
{
continue;
}
else
{
cout << "Nespravny vstup.";
return 0;
}
}
string stringS2 = "";
for(unsigned i = 0; i < cislo1.length(); i++)
{
stringS2 += cislo1[cislo1.length()-1-i];
}
cislo1 = stringS2;
string stringS3 = "";
for(unsigned i = 0; i < cislo2.length(); i++)
{
stringS3 += cislo2[cislo2.length()-1-i];
}
cislo2 = stringS3;
/*
cout << cislo1 << endl;
cout << cislo2 << endl;
cout << cislo1.length() << endl;
cout << cislo2.length() << endl;
*/
int p;
if (cislo1.length() > cislo2.length())
{
p = cislo1.length();
int f = cislo2.length();
for(f; f < cislo1.length(); f++)
{
cislo2[f] = '0';
}
}
else
{
p = cislo2.length();
int f = cislo1.length();
for(f; f < cislo2.length(); f++)
{
cislo1[f] = '0';
}
}
int e = 0;
//cout << p << endl;
string vysledek;
int t;
t = (p - 1);
cislo1[p];
cislo2[p];
for(e; e < p; e++)
{
/*nasledujici podminky jsou pro pripad, kdy cisla maji odlisny pocet znaku
if(cislo1[e] == NULL)
{
cislo1[e] == '0';
}
if(cislo2[e] == NULL)
{
cislo2[e] == '0';
}*/
if (cislo1[e] == '0' && cislo2[e] == '0')
{
if ((cislo1[e-1] == '1' && cislo2[e-1] == '1')|| ((cislo1[e-1] == '0' && cislo2[e-1] == '1')&& vysledek[t+1] == '0') || ((cislo1[e-1] == '1' && cislo2[e-1] == '0')&& vysledek[t+1] == '0') || ((cislo1[e-1] == '1' && cislo2[e-1] == '1')&& vysledek[t+1] == '1') )
{
vysledek[t] = '1';
}
else
{
vysledek[t] = '0';
}
//cout << vysledek[t] << endl;
t--;
}
else if ((cislo1[e] == '1' && cislo2[e] == '0') || (cislo1[e] == '0' && cislo2[e] == '1') )
{
if ((cislo1[e-1] == '1' && cislo2[e-1] == '1') || ((cislo1[e-1] == '0' && cislo2[e-1] == '1')&& vysledek[t+1] == '0') || ((cislo1[e-1] == '1' && cislo2[e-1] == '0')&& vysledek[t+1] == '0') || ((cislo1[e-1] == '1' && cislo2[e-1] == '1')&& vysledek[t+1] == '1'))
{
vysledek[t] = '0';
}
else
{
vysledek[t] = '1';
}
// cout << vysledek[t] << endl;
t--;
}
else if (cislo1[e] == '1' && cislo2[e] == '1')
{
if ((cislo1[e-1] == '1' && cislo2[e-1] == '1') || ((cislo1[e-1] == '0' && cislo2[e-1] == '1')&& vysledek[t+1] == '0') || ((cislo1[e-1] == '1' && cislo2[e-1] == '0')&& vysledek[t+1] == '0') || ((cislo1[e-1] == '1' && cislo2[e-1] == '1')&& vysledek[t+1] == '1'))
{
vysledek[t] = '1';
}
else
{
vysledek[t] = '0';
}
//cout << vysledek[t] << endl;
t--;
}
}
cout << "Soucet: ";
int u;
u = (p - 1);
if(((cislo1[u] == '0' && cislo2[u] == '1')&& vysledek[0] == '0') || ((cislo1[u] == '1' && cislo2[u] == '0')&& vysledek[0] == '0') || (cislo1[u] == '1' && cislo2[u] == '1') )
cout << '1';
int o = 0;
int z;
int w = 0;
while(vysledek[0] == '0')
{
vysledek = vysledek.substr(1, vysledek.length());
w++;
}
int aa;
aa = p-w;
for(o; o < aa; o++)
{
cout << vysledek[o];
}
return 0;
}
`
string vysledek; creates an empty string. It is never given any other size.
All following uses of vysledek[t] and vysledek.substr are all out of range.
Trying to make an else statement that get rid of all other letter and spaces then the ones i want. This function is to change user inputted letters into other letters
using namespace std;
void dna_to_rna(char rna[])
{
for (int i = 0; i < 100; i++)
{
if (rna[i] == 'a' || rna[i] == 'A')
rna[i] = 'U';
else if (rna[i] == 'c' || rna[i] == 'C')
rna[i] = 'G';
else if (rna[i] == 'g' || rna[i] == 'G')
rna[i] = 'C';
else if (rna[i] == 't' || rna[i] == 'T')
rna[i] = 'A';
}
What should the else statement look like in order to drop all other chars?
If the input parameter can be changed to std::string, then you can use one of the following implementation:
void dna_to_rna(std::string& rna)
{
auto it = rna.begin();
while (it != rna.end())
{
if (*it == 'a' || *it == 'A') *it = 'U';
else if (*it == 'c' || *it == 'C') *it = 'G';
else if (*it == 'g' || *it == 'G') *it = 'C';
else if (*it == 't' || *it == 'T') *it = 'A';
else
{
it = rna.erase(it);
continue; // it already "points" to the next element
}
++it;
}
}
std::string dna_to_rna(const std::string& dna)
{
std::string rna;
for (auto c : dna)
{
if (c == 'a' || c == 'A') rna += 'U';
else if (c == 'c' || c == 'C') rna += 'G';
else if (c == 'g' || c == 'G') rna += 'C';
else if (c == 't' || c == 'T') rna += 'A';
}
return rna;
}
Maybe like this:
using namespace std;
void dna_to_rna(char rna[])
{
string s = "";
for (int i = 0; i < 100; i++)
{
if (rna[i] == 'a' || rna[i] == 'A')
s += 'U';
else if (rna[i] == 'c' || rna[i] == 'C')
s += 'G';
else if (rna[i] == 'g' || rna[i] == 'G')
s += 'C';
else if (rna[i] == 't' || rna[i] == 'T')
s += 'A';
}
strcpy(rna, s.c_str());
}
The idea is simply to use a std::string as a temporary buffer. The string is empty to start with. Then you add the characters you want one-by-one. When done with the loop, copy the content of the std::string back to the rna-array.
To make you code much simpler, and easier to read:
using namespace std;
void dna_to_rna(char rna[]) {
int arrLength = sizeof(rna)/sizeof(rna[0]); // Get size of array
for (int i = 0; i < arrLength; i++){
if (toupper(rna[i]) == 'A'){
rna[i] = 'U';
}
else if (toupper(rna[i]) == 'C') {
rna[i] = 'G';
}
else if (toupper(rna[i]) == 'G'){
rna[i] = 'C';
}
else if (toupper(rna[i]) == 'T'){
rna[i] = 'A';
}
}
}
I created a second array and as long as the information that I was looking for met the criteria that was necessary I placed it into the second array making sure that the position that I was placing it in the array was always in the right spot by creating a second variable that would count the the proper position in the array then just cout array
using namespace std;
void dna_to_rna(char rna[])
{
int x = 0;
char newrna[100];
for (int i = 0; i < 100; i++)
{
if (rna[i] == 'a' || rna[i] == 'A')
{
newrna[x] = 'U';
x++;
}
else if (rna[i] == 'c' || rna[i] == 'C')
{
newrna[x] = 'G';
x++;
}
else if (rna[i] == 'g' || rna[i] == 'G')
{
newrna[x] = 'C';
x++;
}
else if (rna[i] == 't' || rna[i] == 'T')
{
newrna[x] = 'A';
x++;
}
}
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()
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