Tic Tac Toe overwritten array user inputs - c++

The issue I am having is this:
I input a choice in square 1 "X" then it is O's turn so just to test things I input square 1 again. The error message pops up about it being an invalid square please enter another square. So I input a valid square and then the board gets drawn by the function and that's when I find out that the "X" in square one has been overwritten. This happens regardless of which character, X or O, is selected at the time. I'm kind of at my wits end and just looking for a little help with that part of the program. I figure once I hammer this part out the random number generator for the computers turn will be simple to implement, as well as checking for a win condition.
#include <iostream>
#include <cmath>
#include <string>
#include <cstdlib>
#include <ctime>
const int yCoordMax = 6;
const int xCoordMax = 2;
int xCoord;
int yCoord;
int square = 0;
const std::string PLAYER1 = "X";
const std::string COMPUTER = "O";
int turnCount = 0;
const int MAXTURN = 9;
int whoIsPlayer = 0; //denotes human with 0 and computer with 1 alternating between
std::string playerChar = " "; //the current turn's player's symbol
const std::string WIN = "You won!\n";
const std::string LOSE = "You lost.\n";
const std::string DRAW = "It's a draw.\n";
const std::string PLAY = "You will be the X's against the computer O's\n\n";
const std::string INSTRUCTIONS = "Enter the number of the square you wish to mark\nwith 1 being top left and 9 being bottom right.\n\n";
const std::string INVALIDSQUARE = "Please enter a correct square number between 1 and 9.\n";
const std::string SQUAREISFULL = "That square is already marked. Choose another.\n";
bool squareIsFilled[9] {0}; // any NON-Zero is true; ZERO is false
//array is zero thru eight
void drawBoard(void);
void convertSquareToCoordinates(std::string);
void validMove (int, std::string);
void drawMove(int, std::string, int, int);
void computerTurn(std::string);
std::string board[7][3] =
{ //0 //1 //2
{"+----", "+----+", "----+\n"}, // 0
{"| ", "| |", " |\n"}, // 1 input here only [1][0], [1][1], [1][2]
{"+----", "+----+", "----+\n"}, // 2
{"| ", "| |", " |\n"}, // 3 input here only [3][0], [3][1], [3][2]
{"+----", "+----+", "----+\n"}, // 4
{"| ", "| |", " |\n"}, // 5 input here only [5][0], [5][1], [5][2]
{"+----", "+----+", "----+\n"} // 6
};
int main()
{
std::srand(time(0));
std::cout << PLAY;
std::cout << INSTRUCTIONS;
drawBoard();
while (turnCount < MAXTURN)
{
if(whoIsPlayer == 0)
{
playerChar = PLAYER1;
convertSquareToCoordinates(playerChar);
whoIsPlayer = 1;
}
else
{
playerChar = COMPUTER;
convertSquareToCoordinates(playerChar);
whoIsPlayer = 0;
}
++turnCount;
}
return 0;
}
void drawBoard()
{
for (int y = 0; y <= yCoordMax; ++y)
{
for (int x = 0; x <= xCoordMax; ++x)
{
std::cout << board[y][x];
}
}
}
void convertSquareToCoordinates(std::string playerChar)
{
int square;
int yCoord;
int xCoord;
std::cout << std::endl;
std::cin >> square;
while(square < 1 || square > 9)
{
std::cout << INVALIDSQUARE;
std::cin >> square;
}
if (square == 1)
{yCoord = 1;
xCoord = 0;} //bool needs to flag invalid if square is filled
if (square == 2) //if square is empty then flag bool as filled
{yCoord = 1; //so validMove will skip execution
xCoord = 1;}
if (square == 3)
{yCoord = 1;
xCoord = 2;}
if (square == 4)
{yCoord = 3;
xCoord = 0;}
if (square == 5)
{yCoord = 3;
xCoord = 1;}
if (square == 6)
{yCoord = 3;
xCoord = 2;}
if (square == 7)
{yCoord = 5;
xCoord = 0;}
if (square == 8)
{yCoord = 5;
xCoord = 1;}
if (square == 9)
{yCoord = 5;
xCoord = 2;}
validMove(square, playerChar);
drawMove(square, playerChar, yCoord, xCoord);
}
void validMove(int square, std::string playerChar)
{
if(square == 1)
{
if(squareIsFilled[square - 1] == true){
if(whoIsPlayer == 0){
std::cout << SQUAREISFULL;}
convertSquareToCoordinates(playerChar);}
else
{squareIsFilled[square - 1] = true;}
}
if(square == 2)
{
if(squareIsFilled[square - 1] == true)
{if(whoIsPlayer == 0){
std::cout << SQUAREISFULL;}
convertSquareToCoordinates(playerChar);}
else
{squareIsFilled[square - 1] = true;}
}
if(square == 3)
{
if(squareIsFilled[square - 1] == true)
{if(whoIsPlayer == 0){
std::cout << SQUAREISFULL;}
convertSquareToCoordinates(playerChar);}
else
{squareIsFilled[square - 1] = true;}
}
// checks middle column for mark
if(square == 4)
{
if(squareIsFilled[square - 1] == true)
{if(whoIsPlayer == 0){
std::cout << SQUAREISFULL;}
convertSquareToCoordinates(playerChar);}
else
{squareIsFilled[square - 1] = true;}
}
if(square == 5)
{
if(squareIsFilled[square - 1] == true)
{if(whoIsPlayer == 0){
std::cout << SQUAREISFULL;}
convertSquareToCoordinates(playerChar);}
else
{squareIsFilled[square - 1] = true;}
}
if(square == 6)
{
if(squareIsFilled[square - 1] == true)
{if(whoIsPlayer == 0){
std::cout << SQUAREISFULL;}
convertSquareToCoordinates(playerChar);}
else
{squareIsFilled[square - 1] = true;}
}
// checks right column for mark
if(square == 7)
{
if(squareIsFilled[square - 1] == true)
{if(whoIsPlayer == 0){
std::cout << SQUAREISFULL;}
convertSquareToCoordinates(playerChar);}
else
{squareIsFilled[square - 1] = true;}
}
if(square == 8)
{
if(squareIsFilled[square - 1] == true)
{if(whoIsPlayer == 0){
std::cout << SQUAREISFULL;}
convertSquareToCoordinates(playerChar);}
else
{squareIsFilled[square - 1] = true;}
}
if(square == 9)
{
if(squareIsFilled[square - 1] == true)
{if(whoIsPlayer == 0){
std::cout << SQUAREISFULL;}
convertSquareToCoordinates(playerChar);}
else
{squareIsFilled[square - 1] = true;}
}
}
void drawMove(int square, std::string playerChar, int yCoord, int xCoord)
{
if(square == 1) //Draws left column move
board[yCoord][xCoord] = "| " + playerChar + " ";
else if(square == 2)
board[yCoord][xCoord] = "| " + playerChar + " |";
else if(square == 3)
board[yCoord][xCoord] = " " + playerChar + " |\n";
if(square == 4) //Draws middle column move
board[yCoord][xCoord] = "| " + playerChar + " ";
else if(square == 5)
board[yCoord][xCoord] = "| " + playerChar + " |";
else if(square == 6)
board[yCoord][xCoord] = " " + playerChar + " |\n";
if(square == 7) //Draws right column move
board[yCoord][xCoord] = "| " + playerChar + " ";
else if(square == 8)
board[yCoord][xCoord] = "| " + playerChar + " |";
else if(square == 9)
board[yCoord][xCoord] = " " + playerChar + " |\n";
drawBoard();
}

Look at convertSquareToCoordinates:
...
validMove(square, playerChar);
drawMove(square, playerChar, yCoord, xCoord);
If square refers to a square that is already filled, this function still calls drawMove on the corresponding (yCoord, xCoord).
More fundamentally, convertSquareToCoordinates and validMove call each other in a weird way. And your function names do not clearly describe what the functions are supposed to do.

Related

Detecting Walls in Multidimensional Arrays C++ Issues

I need some help figuring this out. For some reason, when I move along
my array say for example "e" for east, I have made a detect wall
collision so the player can't go any further. However, when I try to
go "w" for west (back) it goes back 2 instead of 1. Any ideas on how
to fix this?
For now, use the e button to go right and west button to go left. I've used a multidimensional array and a switch to detect what room you're in, also providing player coordinates.
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <windows.h>
using namespace std;
int playerX = 0; // x
int playerY = 0; // y
int nextX; // pY
int nextY; // pX
bool win = false;
string move;
char dungeon[11][11] = {
{ 's','c','c','c','r','w','c','c','c','r','r',},
{ 'w','w','w','c','w','r','c','c','c','r','r',},
{ 's','c','c','r','r','c','c','c','c','r','r',},
{ 's','c','c','r','r','c','c','c','c','r','r',},
{ 's','c','c','r','r','c','c','c','c','r','r',},
{ 's','c','c','r','r','c','c','c','c','r','r',},
{ 's','c','c','r','r','c','c','c','c','r','r',},
{ 's','c','c','r','r','c','c','c','c','r','r',},
{ 's','c','c','r','r','c','c','c','c','r','r',},
{ 's','c','c','r','r','c','c','c','c','r','r',},
{ 's','c','c','r','r','c','c','c','c','r','r',}
};
void movePlayer();
void location(int X, int Y);
int main()
{
do {
movePlayer();
location(playerX, playerY);
} while (win == false);
}
void movePlayer() {
string move;
cin >> move;
// reference Grid-Cave-Mk1 Author: Heather Southall Date: 2017
if (move == "n") {
nextY = playerY - 1;
if ((nextY >= 0) && (nextY < 11)) {
playerY = nextY;
}
else {
cout << "Can't move there" << endl;
}
}
else if (move == "e") {
nextX = playerX + 1;
if ((nextX >= 0) && (nextX < 11)) {
playerX = nextX;
}
else {
cout << "Can't move there" << endl;
}
}
else if (move == "w") {
nextX = playerX - 1;
if ((nextX >= 0) && (nextX < 11)) {
playerX = nextX;
}
else {
cout << "Can't move there" << endl;
}
}
else if (move == "s") {
nextY = playerY + 1;
if ((nextY >= 0) && (nextY < 11)) {
playerY = nextY;
}
else {
cout << "Can't move there" << endl;
}
}
}
void location(int X, int Y) {
cout << "X: " << X << endl;
cout << "Y: " << Y << endl;
char local = dungeon[Y][X];
switch (local) {
case 's':
cout << "Starter Room" << endl;
break;
case 'c':
cout << "Corridor" << endl;
break;
case 'r':
cout << "Room" << endl;
break;
case 'w':
nextX = playerX - 1;
if ((nextX >= 0) && (nextX < 11)) {
playerX = nextX; playerY = nextY;
break;
}
}
}
Its an issue with misleading logs - you don't print the current position, but the one which "type" is being checked. So you can get to logs [5, 0] and [3, 0] when:
You move east from the [4, 0] room. You check what's at [5, 0] (first print). You hit a wall, so the current position is moved back to [4, 0].
Discouraged, you move west. You check what's at [3, 0] (second print).
You should change the printed message, so that the user is notified about both the current position, and the tested one.
ps. hitting a wall should move you to the previous location instead of translating the position by [-1, 0].

DiceSum - How to extend if/ if-else statement to reroll dice if dice sum is not a certain number

#include <iostream>
#include <ctime>
#include <cstdlib>
#include <iomanip>
using namespace std;
int main()
{
int n;
int win = 0;
int lose = 0;
int dice1;
int dice2;
int diceSum;
srand(time(0));
cout << "How many turns would you like? ";
cin >> n;
for (int i = 1; i <= n; i++)
{
dice1 = rand()%6 + 1;
dice2 = rand()%6 + 1;
diceSum = dice1 + dice2;
if((diceSum == 2) || (diceSum == 3) || (diceSum == 12)){
win++;
}
else if((diceSum == 7) || (diceSum == 11)){
lose++;
}
else{
}
}
cout << "No. of Wins: " << win << endl;
cout << "No. of Losses: " << lose << endl;
cout<< setprecision(4)<<fixed<<showpoint;
cout << "\nThe experimental probability of winning "<< (static_cast<float>(win)/n)*100 <<
"%.\n";
return 0;
}
My assignments states that "...can be shown analytically that the long term probability of winning the dice game you have programmed in PA 8-3 is .4929293. Extend that program you wrote to run a large number of turns and calculate the empirical (experimental) probability." My last assignment I had to make a program to roll two die and reveal the dice sum. If it was a 2, 3, or 12, I won; if it was a 7 or 11 it was a loss, otherwise it would repeat the roll. I was unable to repeat the roll, now for this assignment, I have to do the same thing.This is my output from my current code
I you want to not take into account the cases where the sum is not 2,3,12,7 or 11 you have lot of possibilities, for instance :
closer to your code do i -=1; in the empty else {}
for (int i = 1; i <= n; i++)
{
dice1 = rand()%6 + 1;
dice2 = rand()%6 + 1;
diceSum = dice1 + dice2;
if((diceSum == 2) || (diceSum == 3) || (diceSum == 12)){
win++;
}
else if((diceSum == 7) || (diceSum == 11)){
lose++;
}
else{
i -= 1;
}
}
or increment i only when you win or lose and remove i++ in the for()
for (int i = 1; i <= n;)
{
dice1 = rand()%6 + 1;
dice2 = rand()%6 + 1;
diceSum = dice1 + dice2;
if((diceSum == 2) || (diceSum == 3) || (diceSum == 12)){
win++;
i++;
}
else if((diceSum == 7) || (diceSum == 11)){
lose++;
i++;
}
}
or the variant
i = n;
for (;;)
{
dice1 = rand()%6 + 1;
dice2 = rand()%6 + 1;
diceSum = dice1 + dice2;
if((diceSum == 2) || (diceSum == 3) || (diceSum == 12)){
win++;
if (!--i)
break;
}
else if((diceSum == 7) || (diceSum == 11)){
lose++;
if (!--i)
break;
}
}
or remove all about i and replace your for by do { dice1 = ..... } while ((win + lose) != n); without having the last else branch
do {
dice1 = rand()%6 + 1;
dice2 = rand()%6 + 1;
diceSum = dice1 + dice2;
if((diceSum == 2) || (diceSum == 3) || (diceSum == 12)){
win++;
}
else if((diceSum == 7) || (diceSum == 11)){
lose++;
}
} while ((win + lose) != n);
or the variant
for (;;) {
dice1 = rand()%6 + 1;
dice2 = rand()%6 + 1;
diceSum = dice1 + dice2;
if((diceSum == 2) || (diceSum == 3) || (diceSum == 12)){
if ((++win + lose) == n)
break;
}
else if((diceSum == 7) || (diceSum == 11)){
if ((++lose + win) == n)
break;
}
}
Example of execution whatever the way :
pi#raspberrypi:/tmp $ ./a.out
How many turns would you like? 1000
No. of Wins: 336
No. of Losses: 664
The experimental probability of winning 33.6000%.
This result it normal even it seems opposite of the intuition because the possibilities to make these numbers are :
2 : 1+1
3 : 1+2 2+1
12 : 6+6
and
7: 1+6 6+1 2+5 5+2 3+4 4+3
11 : 5+6 6+5
so 4 possibilities to win ( 1/3/12 ) and 8 possibilities to lose ( 7/11 ), so the probability to lose if two times more than the probability to win
I encourage you to always check the input, replacing
cin >> n;
by something like
if (!(cin >> n)) {
cerr << "invalid number" << endl;
return -1;
}

How can I change a int into a string in C++ or better yet.. How do I make a function to convert it?

What I am trying to do is convert a int value into a string so the output works correctly. The issue I am having is that's obviously giving me an error message because I cannot assign a string to a integer value. So the help I need is how can I create a function that specifically converts them to a string and return them to my print_result function? Thank you!
#include<iostream>
#include<sstream>
#include<string>
using std::cout;
using std::cin;
using std::endl;
using std::stringstream;
using std::string;
int strategy1(int player, int previous_result, int previous_play, int opponent_previous_play);
int strategy2(int player, int previous_result, int previous_play, int opponent_previous_play);
int strategy3(int player, int previous_result, int previous_play, int opponent_previous_play);
int score(int p1, int p2);
void print_result(int round, int p1, int p2, int winner);
int main (){
int result, p1, new_p1, p2, new_p2, rounds;
p1 = 1; // start with rock
p2 = 1; // start with rock
cout << "How many rounds:";
cin >> rounds;
for(int i=0; i<rounds; i++){
result = score(p1,p2);
print_result(i+1, p1, p2, result);
new_p1 = strategy1(1, result, p1, p2);
new_p2 = strategy3(2, result, p2, p1);
p1 = new_p1;
p2 = new_p2;
}
}
int strategy1(int player, int previous_result, int previous_play, int opponent_previous_play){
if(previous_play == 1)
previous_play = 2;
else if(previous_play == 2)
previous_play = 3;
else if(previous_play == 3)
previous_play = 1;
return previous_play;
}
int strategy2(int player, int previous_result, int previous_play, int opponent_previous_play){
if(player == 1){
if(previous_result == 2)
previous_play = opponent_previous_play;
else
previous_play = previous_play;
}
if(player == 2){
if(previous_result == 1)
previous_play = opponent_previous_play;
else
previous_play = previous_play;
}
}
int strategy3(int player, int previous_result, int previous_play, int opponent_previous_play){
if(player == 1){
if(previous_result == 2){
if(previous_play == 1 && opponent_previous_play == 2)
previous_play = 3;
else if(previous_play == 2 && opponent_previous_play == 3)
previous_play = 1;
else
previous_play = 2;
}
}
if(player == 2){
if(previous_result == 1){
if(previous_play == 1 && opponent_previous_play == 2)
previous_play = 3;
else if(previous_play == 2 && opponent_previous_play == 3)
previous_play = 1;
else
previous_play = 2;
}
}
return previous_play;
}
int score(int p1, int p2){
long result = 0;
if( ((p1 == 1) && (p2 == 1)) || ((p1 == 2) && (p2 == 2)) || ((p1 == 3) && (p2 == 3)) )
result = 0;
else if( ((p1 == 1) && (p2 == 3 )) || ((p1 == 2) && (p2 == 1)) || ((p1 == 3) && (p2 == 2)) )
result = 1;
else if(( (p1 == 1) && (p2 == 2) ) || ((p1 == 2) && (p2 == 3)) || ((p1 == 3 ) && (p2 == 1)) )
result = 2;
return result;
}
void print_result(int round, int p1, int p2, int winner){
//ERROR WON'T LET ME CHANGE THE INT INTO A STRING
if(p1 == 1)
p1 = "rock";
else if(p1 == 2)
p1 = "paper";
else
p1 = "scissors";
//ERROR WON'T LET ME CHANGE THE INT INTO A STRING
if(p2 == 1)
p2 = "rock";
else if(p2 == 2)
p2 = "paper";
else
p2 = "scissors";
if(winner == 0)
cout << "Round " << round << ":" << " p1=" << p1 << " vs" << " p2=" << p2 << ": tie" << endl;
else if(winner == 1)
cout << "Round " << round << ":" << " p1=" << p1 << " vs" << " p2=" << p2 << ": p1" << endl;
else if(winner == 2)
cout << "Round " << round << ":" << " p1=" << p1 << " vs" << " p2=" << p2 << ": p2" << endl;
}
You have an int. You need to convert from an integer to a particular string, "mapping" a string to an integer. You can solve this by creating a temporary string, assigning the selection string to the temp string and then displaying the temp string.
string player1choice;
if(p1 == 1)
player1choice = "rock";
else if(p1 == 2)
player1choice = "paper";
else
player1choice = "scissors";
But that's a bit slow.
Instead, try:
static std::string choices[] =
{
"Rock",
"Paper",
"Scissors"
};
Then you can use choices[p1-1] wherever you need the string. For example,
cout << p1 << " = " << choices[p1-1];
Caveat: Make darn sure you never pass in anything but 1,2, or 3 or you'll wander out of the array's bounds. Look into using an enum to instead of an int for the player's choice. That way the compiler can more easily catch missuse.
enum choicesenum
{
ROCK = 1,
PAPER = 2,
SCISSORS = 3
};
Now rather than writing 1 to mean rock, you can write ROCK. Yeah, you type more characters, but it's a heck of a lot easier to read:
int strategy1(int player,
choicesenum previous_result,
choicesenum previous_play,
choicesenum opponent_previous_play){
if(previous_play == ROCK)
previous_play = PAPER;
else if(previous_play == PAPER)
previous_play = SCISSORS;
else if(previous_play == SCISSORS)
previous_play = ROCK;
return previous_play;
}
If you try to use numbers not in the enum, it's really easy to catch:
strategy1(1, ROCK, PAPER, HAND_GRENADE); // compiler rejects this
strategy1(1, ROCK, PAPER, 4); // compiler can warn you
Also the 4 stands out visually a lot more than in the old case:
strategy1(1, 2, 3, 4);
And now that I think about it
enum choicesenum
{
ROCK = 0,
PAPER = 1,
SCISSORS = 2
};
eliminates the need for the -1 in accessing the array.
cout << p1 << " = " << choices[p1];
cout << choices[ROCK]
You can't use the same variable for both a string and an integer. Here's one possible solution:
void print_result(int round, int p1, int p2, int winner){
std::string play1, play2, win;
if(p1 == 1)
play1 = "rock";
else if(p1 == 2)
play1 = "paper";
else
play1 = "scissors";
if(p2 == 1)
play2 = "rock";
else if(p2 == 2)
play2 = "paper";
else
play2 = "scissors";
if(winner == 0)
win = "tie";
else if(winner == 1)
win = "p1";
else
win = "p2";
cout << "Round " << round << ":"
<< " p1=" << play1 << " vs p2=" << play2 << ": "
<< win << endl;
}
You should refactor that, of course. You could use a function which looks up a name from an integer; it would probably be clearer if it used a switch statement rather than a series of ifs. Or you could just use a std::vector or names.
And really, you should use enums rather than magic integers.

Tic-Tac-Toe Array Error

This program is a simple Tic Tac Toe game between a player and the computer. The computer just generates a random space to move to if said space is not already occupied. Also, I have the x-coordinates on the vertical axis while the y-coordinates are on the horizontal axis. I did this because I use a two dimensional array, and that is just how they are structured.
When running the program, some of the spaces are faulty and I cannot find out why. When the user inputs the point (0,2) the program also fills in the point (1,0) and vise versa. This also occurs with the points (1,2) and (2,0).
#include<iostream>
#include<string>
#include<stdlib.h>
#include<ctime>
using namespace std;
int board[2][2];
int chooseFirstPlayer();
void userMove(int boardArray[2][2]);
void compMove(int boardArray[2][2]);
int checkIfWinner(int boardArray[2][2]);
void displayBoard(int boardArray[2][2]);
int main(){
srand(time(NULL));
int x,y,winner;
for(x = 0; x <= 2; x++){ //sets the enitre board array to 0
for(y = 0; y <= 2; y++){
board[x][y] = 0;
}
}
if (chooseFirstPlayer() == 1){ //the user gets to movve first
do{//it will loop this until there is a winner
displayBoard(board);
userMove(board);
displayBoard(board);
winner = checkIfWinner(board);
if (winner == 0){//after the player moves, it will see if he won. If not, then the computer willbe able to move.
compMove(board);
displayBoard(board);
winner = checkIfWinner(board);
}
}while (winner == 0);//it will loop until a winner is found
}
else{//same structure as above just slightly altered to allow the computer to move first
do{
compMove(board);
displayBoard(board);
winner = checkIfWinner(board);
if (winner == 0){
userMove(board);
displayBoard(board);
winner = checkIfWinner(board);
}
}while(winner == 0);
}
if (winner = 1){
cout << "Congratulations, you won!";
}
else if (winner = 2){
cout << "Sorry, you lost!";
}
}
int chooseFirstPlayer(){//randomly genereate a number 1 or 2 to choose who moves first
return rand() % 2 + 1;
}
void userMove(int boardArray[2][2]){
int userX, userY;
do{
cout << "Enter an x coordinate: "<<endl;
cin >> userX;
cout << "Enter a y coordinate: "<<endl;
cin >> userY;
if (boardArray[userX][userY] != 0){
cout << "That loaction is already occupied"<<endl;
}
}while(boardArray[userX][userX] != 0);
boardArray[userX][userY] = 1;
}
void compMove(int boardArray[2][2]){
int compX,compY;
do{
compX = rand() % 3;
compY = rand() % 3;
}while(boardArray[compX][compY] != 0);
boardArray[compX][compY] = 2;
}
int checkIfWinner(int boardArray[2][2]){
if(boardArray[0][0] == boardArray[0][1] && boardArray[0][1] == boardArray[0][2]){ //across
return boardArray[0][0];}
else if (boardArray[1][0] == boardArray[1][1] && boardArray[1][1] == boardArray[1][2]){
return boardArray[1][0];}
else if (boardArray[2][0] == boardArray[2][1] && boardArray[2][1] == boardArray[2][2]){
return boardArray[2][0];}
else if (boardArray[0][0] == boardArray[1][0] && boardArray[1][0] == boardArray[2][0]){//down
return boardArray[0][0];}
else if (boardArray[0][1] == boardArray[1][1] && boardArray[1][1] == boardArray[2][1]){
return boardArray[0][1];}
else if (boardArray[0][2] == boardArray[1][2] && boardArray[1][2] == boardArray[2][2]){
return boardArray[0][2];}
else if (boardArray[0][0] == boardArray[1][1] && boardArray[1][1] == boardArray[2][2]){//diagonal
return boardArray[0][0];}
else if (boardArray[2][0] == boardArray[1][1] && boardArray[1][1] == boardArray[0][2]){
return boardArray[2][0];}
else{
return 0;
}
}
void displayBoard(int boardArray[2][2]){
system("CLS");
cout <<" "<<" Y1 "<<" Y2 "<<" Y3 "<<endl;
cout <<" X1 "<< "__"<<boardArray[0][0]<<"__|__"<<boardArray[0][1]<<"__|__"<<boardArray[0][2]<<"__"<<endl;
cout <<" X2 "<< "__"<<boardArray[1][0]<<"__|__"<<boardArray[1][1]<<"__|__"<<boardArray[1][2]<<"__"<<endl;
cout <<" X3 "<< " "<<boardArray[2][0]<<" | "<<boardArray[2][1]<<" | "<<boardArray[2][2]<<" "<<endl;
}
My IDE is Dev-C++ (5.4.2)
Your array is 2x2 and you do:
for(x = 0; x <= 2; x++){ //sets the enitre board array to 0
for(y = 0; y <= 2; y++){
board[x][y] = 0;
}
}
and you access memory you shouldn't. That means you are going out of bounds!
Here x and y will take a value equal to 2 eventually.
Indexing of an array starts from 0 until it's size - 1.
So, you could use an array of 3x3, or change your code (and the function checkIfWinner that goes until 2).
Side note:
You have missed the equality operator here:
if (winner = 1){
cout << "Congratulations, you won!";
}
else if (winner = 2){
cout << "Sorry, you lost!";
}
What will happen if you leave it as is? The assignment will take place and will result in logical true, thus the first condition will be always true (and the second, but the code won't go that far).
So, change = with ==.

C++ Tic Tac Toe project

I'm now working on a Tic Tac Toe project. I'm having the problem that whenever I input into the console an ordinate,for example [6][0] (and the program will put the mark 'X' or 'O' into that position) for an array with the size of [15][15],it will automatically save the mark 'X' or 'O' into another position which is not in the array range (in my case is [5][15]).This is my program (P/S: I'm Vietnamese so just ignore the parts that are in Vietnamese):
int size = 15;
int inputAmount;
int inputX = 0;
int inputY = 0;
char board[15][15];
bool checkWin = false;
char mark = 'X';
// Interdisciplinary examination of scale loss
bool checkWinLose() {
int max;
int x,y;
x = inputX;
y = inputY;
// Looking horizontally under investigation
for (; max < 3; max++)
{
if ((board[x][y] == 'X' || board[x][y] == 'O') && (board[x][y] == board[x - 1][y] && board[x - 1][y] == board[x - 2][y]))
{
cout << "Game over ngang!" << endl;
return 1;
}
x++;
}
x = inputX;
y = inputY;
max = 0;
// Interdisciplinary examination of vertical
for (; max < 3; max++)
{
if ((board[x][y] == 'X' || board[x][y] == 'O') && (board[x][y] == board[x][y - 1] && board[x][y - 1] == board[x][y - 2]))
{
cout << "Game over doc!" << endl;
return 1;
}
y++;
}
x = inputX;
y = inputY;
max = 0;
// Interdisciplinary examination of under the cliff cave from left to right
for (; max < 3; max++)
{
if ((board[x][y] == 'X' || board[x][y] == 'O') && (board[x][y] == board[x - 1][y - 1] && board[x - 1][y - 1] == board[x - 2][y - 2]))
{
cout << "Game over trai sang phai!" << endl;
return 1;
}
x++;
y++;
}
x = inputX;
y = inputY;
max = 0;
// Interdisciplinary examination of under the cliff cave from right to left
for (; max < 3; max++)
{
if ((board[x][y] == 'X' || board[x][y] == 'O') && (board[x][y] == board[x + 1][y - 1] && board[x + 1][y - 1] == board[x + 2][y - 2]))
{
cout << "Game over phai sang trai!" << endl;
return 1;
}
x--;
y++;
}
// Flower test case
if (inputAmount == 225)
{
cout << "Game over hoa!" << endl;
return 1;
}
}
// Lay-coordinate of the muon practice player list
void takeInput() {
do {
// Lay gia tri toa do x
do {
cout << "Please choose the horizontal (rightward) number (smaller than " << size + 1 << "): ";
cin >> inputX;
} while ((inputX > size) || (inputX <= 0));
// Lay y coordinate values
do {
cout << "Please choose the vertical (downward) number (smaller than " << size + 1 << "): ";
cin >> inputY;
} while ((inputY > size) || (inputY <= 0));
inputX--;
inputY--;
if (board[inputX][inputY] != '.')
cout << "Already chosen!" << endl ;
} while (board[inputX][inputY] != '.');
board[inputX][inputY] = mark;
if (mark == 'X')
mark = 'O';
else
mark = 'X';
cout << endl << endl << endl;
}
// Hien game board on the screen
void loadGameboard () {
int x,y;
////TODO: check win or lose
while (!checkWin) {
for (; y < size ; y++)
{
for (; x < size ; x++)
{
cout << board[x][y] << " ";
}
cout << endl;
x = 0;
}
checkWin = checkWinLose();
if (checkWin == true)
return;
x,y = 0;
takeInput();
inputAmount++;
}
}
// At first preparation game board
void prepareGameboard () {
int x,y;
for (; y < size ; y++)
{
for (; x < size ; x++)
{
board[x][y] = '.' ;
}
x = 0;
}
}
int main(array<System::String ^> ^args)
{
char reset = 'y';
do {
prepareGameboard();
loadGameboard();
checkWin = 0;
inputAmount = 0;
cout << "Do you want to replay ? (y/n): ";
cin >> reset;
if ((reset == 'y') || (reset == 'Y'))
{
system("CLS");
}
} while ((reset == 'y') || (reset == 'Y'));
return 0;
}
I would change x,y = 0 to x = y = 0 at line 123 in the code you pasted. And also add return 0 to the function checkWinLose().
You are not initializing the values for x and y in ther for's.
Try to use :
void prepareGameboard () {
int x,y;
for (y = 0; y < size ; y++)
{
for (x = 0; x < size ; x++)
{
board[x][y] = '.' ;
}
}
}
And:
void loadGameboard () {
int x,y;
////TODO: check win or lose
while (!checkWin) {
for (y = 0; y < size ; y++)
{
for (x = 0; x < size ; x++)
{
cout << board[x][y] << " ";
}
cout << endl;
}
checkWin = checkWinLose();
if (checkWin == true)
return;
takeInput();
inputAmount++;
}
}
Also, like #Heinz said, and a return 0; at the end of the checkWinLose function;
Looking at your code, I believe the you are assuming the int always are initialized with 0 and that checkWinLose will return 0 by the default. Local variables have undefined initialization values and when no explicity return is called, the function just return so 'garbage' value.
Try to always add the returned value to the functons and initialize your variables (specially counters).
Update
This is how the function checkWinLose should be with the return 0;
// Interdisciplinary examination of scale loss
bool checkWinLose() {
int max;
int x,y;
x = inputX;
y = inputY;
// Looking horizontally under investigation
for (; max < 3; max++)
{
if ((board[x][y] == 'X' || board[x][y] == 'O') && (board[x][y] == board[x - 1][y] && board[x - 1][y] == board[x - 2][y]))
{
cout << "Game over ngang!" << endl;
return 1;
}
x++;
}
x = inputX;
y = inputY;
max = 0;
// Interdisciplinary examination of vertical
for (; max < 3; max++)
{
if ((board[x][y] == 'X' || board[x][y] == 'O') && (board[x][y] == board[x][y - 1] && board[x][y - 1] == board[x][y - 2]))
{
cout << "Game over doc!" << endl;
return 1;
}
y++;
}
x = inputX;
y = inputY;
max = 0;
// Interdisciplinary examination of under the cliff cave from left to right
for (; max < 3; max++)
{
if ((board[x][y] == 'X' || board[x][y] == 'O') && (board[x][y] == board[x - 1][y - 1] && board[x - 1][y - 1] == board[x - 2][y - 2]))
{
cout << "Game over trai sang phai!" << endl;
return 1;
}
x++;
y++;
}
x = inputX;
y = inputY;
max = 0;
// Interdisciplinary examination of under the cliff cave from right to left
for (; max < 3; max++)
{
if ((board[x][y] == 'X' || board[x][y] == 'O') && (board[x][y] == board[x + 1][y - 1] && board[x + 1][y - 1] == board[x + 2][y - 2]))
{
cout << "Game over phai sang trai!" << endl;
return 1;
}
x--;
y++;
}
// Flower test case
if (inputAmount == 225)
{
cout << "Game over hoa!" << endl;
return 1;
}
return 0; //<- Returning false if the all other tests failed
}