I am in need of help for this code that i am working on for a assignment. I am have the issue where if i have any X's on the board that is either in the left 2 columns it will display a X in the row above. I used my debugger and it seems that it is trying to access something outside the array bounds, but it shouldnt be. any advice on how to do this?
#include <iostream>
using namespace std;
void printTTT(char a[3][3]);
void insertX(/*PASS BY REFERENCE*/);
void insertO(char (&arr)[3][3]);
void checkForWin(/*PASS BY REFERENCE*/); // IGNORE THIS FOR NOW
int main() {
char TTTarray[3][3] = { { 'X','-','-' },
{ '-','-','-' },
{ 'X','-','-' } };
//char TTTarray[3][3] = { {'-','X','-'},
// {'-','X','-'},
// {'-','-','O'}};
//char TTTarray[3][3] = { {'-','-','-'},
// {'-','X','-'},
// {'-','O','-'}};
//char TTTarray[3][3] = { {'X','-','X'},
// {'-','-','-'},
// {'O','-','-'}};
//char TTTarray[3][3] = { {'X','-','X'},
// {'O','X','-'},
// {'O','-','O'}};
//insertX(/*CALL*/);
//OR
insertO(TTTarray);
printTTT(TTTarray);
/*****************
I have included the declaratoin of the array, initialized to - for each spot.
The '-' represents an empty position. You should fill it with either a
capital 'O' or a capital 'X'. I have also included a number of initialized arrays
to test; just comment out the ones you don't want for that moment
*****************/
return 0;
}
void printTTT(char a[3][3])
{
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
cout << a[i][j];
}
cout << endl;
}
}
void insertX(/*PASS BY REFERENCE*/) {
}
void insertO(char (&arr)[3][3])
{
int x1x;
int x1y;
//int x2x;
//int x2y;
for (int i = 0; i < 3; i++)
{
int go = 0;
for (int j = 0; j < 3; j++)
{
if (arr[i][j] == '-')
{
x1x = i;
x1y = j;
// looking for 2 x's for the block lol
if (x1x == 0 && go == 0)
{
if (arr[x1x][x1y + 1] == 'X' && arr[x1x][x1y + 2] == 'X')
{
arr[i][j] = 'O';
go = 1;
}
if (arr[x1x][x1y - 1] == 'X' && arr[x1x][x1x + 1] == 'X')
{
arr[i][j] = 'O';
go = 1;
}
if (arr[x1x][x1y - 1] == 'X' && arr[x1x][x1x - 2] == 'X')
{
arr[i][j] = 'O';
go = 1;
}
}
if (x1x == 1 && go == 0)
{
if (arr[x1x][x1y + 1] == 'X' && arr[x1x][x1y + 2] == 'X')
{
arr[i][j] = 'O';
go = 1;
}
if (arr[x1x][x1y - 1] == 'X' && arr[x1x][x1x + 1] == 'X')
{
arr[i][j] = 'O';
go = 1;
}
if (arr[x1x][x1y - 1] == 'X' && arr[x1x][x1x - 2] == 'X')
{
arr[i][j] = 'O';
go = 1;
}
}
if (x1x == 2 && go == 0)
{
if (arr[x1x][x1y + 1] == 'X' && arr[x1x][x1y + 2] == 'X')
{
arr[i][j] = 'O';
go = 1;
}
if (arr[x1x][x1y - 1] == 'X' && arr[x1x][x1x + 1] == 'X')
{
arr[i][j] = 'O';
go = 1;
}
if (arr[x1x][x1y - 1] == 'X' && arr[x1x][x1x - 2] == 'X')
{
arr[i][j] = 'O';
go = 1;
}
}
if (x1y == 0 && go == 0)
{
if (arr[x1x + 1][x1y] == 'X' && arr[x1x + 2][x1y] == 'X')
{
arr[i][j] = 'O';
go = 1;
}
if (arr[x1x - 1][x1y] == 'X' && arr[x1x + 1][x1x] == 'X')
{
arr[i][j] = 'O';
go = 1;
}
if (arr[x1x - 1][x1y] == 'X' && arr[x1x - 2][x1x] == 'X')
{
arr[i][j] = 'O';
go = 1;
}
}
if (x1y == 1 && go == 0)
{
if (arr[x1x + 1][x1y] == 'X' && arr[x1x + 2][x1y] == 'X')
{
arr[i][j] = 'O';
go = 1;
}
if (arr[x1x - 1][x1y] == 'X' && arr[x1x + 1][x1x] == 'X')
{
arr[i][j] = 'O';
go = 1;
}
if (arr[x1x - 1][x1y] == 'X' && arr[x1x - 2][x1x] == 'X')
{
arr[i][j] = 'O';
go = 1;
}
}
if (x1y == 2 && go == 0)
181,1-8 83%
{
if (arr[x1x + 1][x1y] == 'X' && arr[x1x + 2][x1y] == 'X')
{
arr[i][j] = 'O';
go = 1;
}
if (arr[x1x - 1][x1y] == 'X' && arr[x1x + 1][x1x] == 'X')
{
arr[i][j] = 'O';
go = 1;
}
if (arr[x1x - 1][x1y] == 'X' && arr[x1x - 2][x1x] == 'X')
{
arr[i][j] = 'O';
go = 1;
}
}
}
}
}
}
Take a look at these lines from your insertD function:
if (x1x == 0 && go == 0)
{
if (arr[x1x][x1y + 1] == 'X' && arr[x1x][x1y + 2] == 'X')
In this case you have checked that x1x is zero, but you haven't checked x1y. So in this case you will go out of bounds if x1y is non-zero.
A couple of lines below you have
if (arr[x1x][x1y - 1] == 'X' && arr[x1x][x1x + 1] == 'X')
This will go out of bounds too, when x1y is zero.
You need to add more checks, or rethink the logic.
Related
I'm making a tic tac toe program. Right now, the two player option hasn't been created, but I will have no problem with that. My current issue is working on the bot function. Essentially, it's got 2 main ways of going about: botmove() where a random number is generated and it places its piece based on that number, of course testing that it is unoccupies, and smartmove() which is the function im struggling with. I've essentially given it an algoritm to test any win conditions (horizontal, vertical, and diagonal) and told it that, if it detects one, to place its piece to prevent loss. I have a " ..." and pause for a second to give it some time as well as to see whether or not its using smartmove() or botmove(). When you run the program, if the bot encounters a possible smartmove, it simply does nothing and moves onto the user's next term.
Here's the whole program, but main() and smartmove() are here for convenience.
Here's my main():
int main() {
char replaya;
replaya = 'y';
intro();
while (replaya == 'y' || replaya == 'Y') {
char friendorbota;
friendorbota = friendorbot();
if (friendorbota == 'f' || friendorbota == 'F') {
cout << "friend";
}
else if (friendorbota == 'b' || friendorbota == 'B') {
char arr[9] = { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' };
//1
placepiece(arr);
if (determinewin(arr) == true) {
replaya = replay();
}
if (isFilled(arr) == true) {
replaya = replay();
}
//2
smartmove(arr);
if (determinewin(arr) == true) {
replaya = replay();
}
if (isFilled(arr) == true) {
replaya = replay();
}
//3
placepiece(arr);
if (determinewin(arr) == true) {
replaya = replay();
}
if (isFilled(arr) == true) {
replaya = replay();
}
//4
smartmove(arr);
if (determinewin(arr) == true) {
replaya = replay();
}
if (isFilled(arr) == true) {
replaya = replay();
}
//5
placepiece(arr);
if (determinewin(arr) == true) {
replaya = replay();
}
if (isFilled(arr) == true) {
replaya = replay();
}
//6
smartmove(arr);
if (determinewin(arr) == true) {
replaya = replay();
}
if (isFilled(arr) == true) {
replaya = replay();
}
//7
placepiece(arr);
if (determinewin(arr) == true) {
replaya = replay();
}
if (isFilled(arr) == true) {
replaya = replay();
}
//8
smartmove(arr);
if (determinewin(arr) == true) {
replaya = replay();
}
if (isFilled(arr) == true) {
replaya = replay();
}
//9
placepiece(arr);
if (determinewin(arr) == true) {
replaya = replay();
}
if (isFilled(arr) == true) {
replaya = replay();
}
}
cout << "\nThanks for playing!\n";
exit(0);
}
}
And my smartmove():
void smartmove(char arr[9]) {
this_thread::sleep_for(chrono::milliseconds(500));
cout << "\n\n . . . \n\n";
this_thread::sleep_for(chrono::milliseconds(500));
// Check if player has two in a row
for (int i = 0; i < 9; i += 3) {
if (arr[i] == 'X' && arr[i + 1] == 'X' && arr[i + 2] == ' ') {
arr[i + 2] = 'O';
return;
}
else if (arr[i] == 'X' && arr[i + 1] == ' ' && arr[i + 2] == 'X') {
arr[i + 1] = 'O';
return;
}
else if (arr[i] == ' ' && arr[i + 1] == 'X' && arr[i + 2] == 'X') {
arr[i] = 'O';
return;
}
}
// Check if player has two in a column
for (int i = 0; i < 3; i++) {
if (arr[i] == 'X' && arr[i + 3] == 'X' && arr[i + 6] == ' ') {
arr[i + 6] = 'O';
return;
}
else if (arr[i] == 'X' && arr[i + 3] == ' ' && arr[i + 6] == 'X') {
arr[i + 3] = 'O';
return;
}
else if (arr[i] == ' ' && arr[i + 3] == 'X' && arr[i + 6] == 'X') {
arr[i] = 'O';
return;
}
}
// Check if player has two in a diagonal
if (arr[0] == 'X' && arr[4] == 'X' && arr[8] == ' ') {
arr[8] = 'O';
}
else if (arr[0] == 'X' && arr[4] == ' ' && arr[8] == 'X') {
arr[4] = 'O';
}
else if (arr[0] == ' ' && arr[4] == 'X' && arr[8] == 'X') {
arr[0] = 'O';
}
else if (arr[2] == 'X' && arr[4] == 'X' && arr[6] == ' ') {
arr[6] = 'O';
}
else if (arr[2] == 'X' && arr[4] == ' ' && arr[6] == 'X') {
arr[4] = 'O';
}
else if (arr[2] == ' ' && arr[4] == 'X' && arr[6] == 'X') {
arr[2] = 'O';
}
else {
// Default to botmove() if no smart move is available
botmove(arr);
}
}
I've tested every function to ensure that everything is working fine, and I know that my main function could probably be organized a bit better but I wanted it as simple as possible while trying to solve this smartmove() issue. I've tested every function to ensure that everything is working fine other than smartmove(), so it seems like the only issue is with smartmove() or main() to my knowledge, although I've included all of the code in the link. And yes, I've done debugging by myself of every single section and both visual studio.
I'm having trouble with g++ producing this error code when I try to compile my code:
maze.h:16:29: error: array bound is not an integer constant before ‘]’ token
bool canMove(int m[mazeSize][mazeSize], int r, int c);
Now, I have already done some research into this error and it seems to be causes by the array size not being known at compile time. I have tried making the array constant, but that ends up causing more errors later on as the array is reassigned later on in the code and produces this error:
maze.cpp: In member function ‘int Maze::startMazeGen()’:
maze.cpp:185:15: error: assignment of read-only location ‘maze[i][j]’
maze[i][j] = 1;
^
I have also seen people mention that it would just be easier to work with vectors instead, but I'm also having issues with trying to repurpose the code to work with vectors instead of arrays.
Here's the rest of my code:
movement.h
#pragma once
#include <iostream>
#include <curses.h>
#ifndef MOVEMENT_H
#define MOVEMENT_H
class Movement
{
public:
static const int playerX = 2; // sets player starting position
static const int playerY = 2;
};
#endif
movement.cpp
#include <iostream>
#include <curses.h>
#include <ctime>
#include "maze.h"
//#include "movement.h"
bool running = true;
int playerX = 2;
int playerY = 2;
//Maze::maze Maze::mazeGen;
//int Maze::mazeGen.Maze::maze::generateMaze::maze(int m[Maze::mazeSize]
[Maze::mazeSize], int r, int c);
// Detect Char input
// and move player in direction
void getUserInput()
{
char userInput = getch();
if (userInput == 'w') {
int playerY2 = playerY - 1;
if (Maze::maze[playerY2][playerX] == ' ') {
Maze::maze[playerY][playerX] = ' ';
playerY--;
Maze::maze[playerY][playerX] = 'x';
}
}
if (userInput == 'a') {
int playerX2 = playerX - 1;
if (Maze::maze[playerY][playerX2] == ' ') {
Maze::maze[playerY][playerX] = ' ';
playerX--;
Maze::maze[playerY][playerX] = 'x';
}
}
if (userInput == 's') {
int playerY2 = playerY + 1;
if (Maze::maze[playerY2][playerX] == ' ') {
Maze::maze[playerY][playerX] = ' ';
playerY++;
Maze::maze[playerY][playerX] = 'x';
}
}
if (userInput == 'd') {
int playerX2 = playerX + 1;
if (Maze::maze[playerY][playerX2] == ' ') {
Maze::maze[playerY][playerX] = ' ';
playerX++;
Maze::maze[playerY][playerX] = 'x';
}
}
}
// Main game update
// Runs through all functions required
void update()
{
getUserInput();
clear();
Maze::generateMaze;
refresh();
}
//
//
/*int main()
{
// Initate nCurses display
initscr();
while (true) {
update();
}
// End nCurses display
endwin();
return 0;
}*/
maze.h
#pragma once
// MAZE.h
#include <iostream>
#include <ctime>
#ifndef MAZE_H
#define MAZE_H
extern int r;
extern int c;
extern int mazeSize; //number can be changed to make some big sweaty mazes making it an even number makes it act a bit weird sometimes so its better to use an odd number
extern int maze[mazeSize][mazeSize];
class Maze
{
public:
int blockedSquare = 1;
void move(int m[mazeSize][mazeSize], int &r, int &c);
bool canMove(int m[mazeSize][mazeSize], int r, int c);
void solve(int m[mazeSize][mazeSize], int &r, int &c);
bool canSolve(int m[mazeSize][mazeSize], int r, int c);
void generateMaze(int m[mazeSize][mazeSize], int r, int c);
int findStart();
void printMaze(int m[mazeSize][mazeSize]);
int startMazeGen();
};
#endif
maze.cpp
#include <iostream>
#include <ctime>
#include <vector>
#include "maze.h"
bool foundExit = false;
int mazeSize = 31;
int maze[mazeSize][mazeSize] = { 0 };
void Maze::generateMaze(int const m[mazeSize][mazeSize], int r, int c)
{
bool made = false;
while (made == false)
{
if (c == mazeSize - 1)
foundExit = true;
if (canSolve(m, r, c))
{
solve(m, r, c);
}
else if (canMove(m, r, c))
{
m[r][c] = 2; //2 means you can't move from that square, setting any lower stops maze from being made
move(m, r, c); //move to first open space that can be found
}
else
made = true;
}
}
void Maze::move(int m[mazeSize][mazeSize], int &r, int &c)
{
if (m[r][c + 1] == 0)
c++;
else if (m[r + 1][c] == 0)
r++;
else if (m[r][c - 1] == 0)
c--;
else if (m[r - 1][c] == 0)
r--;
else
generateMaze(maze, r, c); //if maze cant be solved it generates a new one so the player doesnt have something that is impossible to solve
}
bool Maze::canMove(int m[mazeSize][mazeSize], int r, int c) //if there is an adjacent zero space, return true
{
if (m[r][c + 1] == 0)
return true;
else if (m[r + 1][c] == 0)
return true;
else if (m[r][c - 1] == 0)
return true;
else if (m[r - 1][c] == 0)
return true;
else
return false;
}
void Maze::solve(int m[mazeSize][mazeSize], int &r, int &c) //solves maze through with dijkstras algorithmto ensure it can be solved
{
bool foundSolution = false;
while (foundSolution == false)
{
int direction = (1 + rand() % 4) * 3;
switch (direction)
{
case 3:
if (c + 1 <= mazeSize - 1 && m[r][c + 2] == blockedSquare && m[r - 1][c + 1] == blockedSquare && m[r + 1][c + 1] == blockedSquare && m[r][c + 1] == blockedSquare)
{
if (c == mazeSize - 2 && foundExit == true)
; //do nothing
else
{
c++;
foundSolution = true;
}
}
break;
case 6:
if (r + 1 <= mazeSize - 2 && m[r + 2][c] == blockedSquare && m[r + 1][c + 1] == blockedSquare && m[r + 1][c - 1] == blockedSquare && m[r + 1][c] == blockedSquare && c != 0 && c != mazeSize - 1)
{
r++;
foundSolution = true;
}
break;
case 9:
if (c - 1 >= 0 && m[r][c - 2] == blockedSquare && m[r - 1][c - 1] == blockedSquare && m[r + 1][c - 1] == blockedSquare && m[r][c - 1] == blockedSquare && c - 1 != 0)
{
c--;
foundSolution = true;
}
break;
case 12:
if (r - 1 >= 1 && m[r - 2][c] == blockedSquare && m[r - 1][c + 1] == blockedSquare && m[r - 1][c - 1] == blockedSquare && m[r - 1][c] == blockedSquare && c != 0 && c != mazeSize - 1)
{
r--;
foundSolution = true;
}
break;
}
}
m[r][c] = 0;
}
bool Maze::canSolve(int m[mazeSize][mazeSize], int r, int c) //if an adjacent square can be moved to, return true
{
bool solvable = false;
if (r <= mazeSize - 3 && m[r + 2][c] == blockedSquare && m[r + 1][c + 1] == blockedSquare && m[r + 1][c - 1] == blockedSquare && m[r + 1][c] == blockedSquare && c != 0 && c != mazeSize - 1) //if adjacent space can be moved to
{
solvable = true;
}
else if (c <= mazeSize - 2 && m[r][c + 2] == blockedSquare && m[r - 1][c + 1] == blockedSquare && m[r + 1][c + 1] == blockedSquare && m[r][c + 1] == blockedSquare)
{
if (c == mazeSize - 2 && foundExit == true)
; //do nothing
else
{
solvable = true;
}
}
else if (r >= 2 && m[r - 2][c] == blockedSquare && m[r - 1][c + 1] == blockedSquare && m[r - 1][c - 1] == blockedSquare && m[r - 1][c] == blockedSquare && c != 0 && c != mazeSize - 1) //if not on extreme left or right
{
solvable = true;
}
else if (c >= 1 && m[r][c - 2] == blockedSquare && m[r - 1][c - 1] == blockedSquare && m[r + 1][c - 1] == blockedSquare && m[r][c - 1] == blockedSquare && c - 1 != 0)
{
solvable = true;
}
return solvable;
}
int Maze::findStart()
{
return 1 + rand() % (mazeSize - 2);
}
void Maze::printMaze(int m[mazeSize][mazeSize])
{
std::cout << std::endl;
for (int i = 0; i < mazeSize; ++i) {
for (int j = 0; j < mazeSize; ++j)
{
switch (m[i][j])
{
case 0:
std::cout << " ";
break;
case 1:
std::cout << "▓▓";
break;
case 2:
std::cout << " ";
break;
case 3:
std::cout << " ";
break;
}
}
std::cout << std::endl;
}
}
int Maze::startMazeGen()
{
srand(time(0));
for (int i = 0; i < mazeSize; ++i)
for (int j = 0; j < mazeSize; ++j)
maze[i][j] = 1;
int r = findStart();
//int r = 0;
int c = 0;
maze[r][c] = 0;
generateMaze(maze, r, c);
maze[r][c] = 2;
printMaze(maze);
std::cout << "Press enter to continue ...";
std::cin.get();
}
The purpose of this code is to randomly generate a maze, solve it, and then print it to the screen if it can be solved. If the maze can't be solved, it keeps generating a new one until it can be solved.I aim to make this work with the movement code so that the user can navigate the maze.
Any help is appreciated on this issue. Thank you!
"Now, I have already done some research into this error and it seems to be causes by the array size not being known at compile time. I have tried making the array constant, but that ends up causing more errors later on as the array is reassigned later on in the code"
You're conflating two things here, the array and the array size.
The array size should be a a compile-time constant. Since you're assigning to the array, the array elements shouldn't be const at all.
const int arrSize = 3;
int arr[arrSize][arrSize];
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
}
Please help me figure this out, I have tested it and tested it and re-read and re-wrote for the past 11 hours and I give up. I found a working code that someone else wrote, but it still doesn't explain to me why his works and mine doesn't because the problem that I am having works on his but not on mine
Got it people, code edited for anyone who has had a similiar problem...
The original code that I had is here http://pastebin.com/h7fXHKzf
the problem I was having was that it kept hanging up on the if(board[x][y - 1] == '.') checks.
Spoke too soon....The program will sometimes crash...it's rare but has crashed 3x in a row before...most of the time when I run it everything works.
// Chapter 8 Programming Project #9
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <time.h>
#define SIZE 10
#define PATH_SIZE ((int) (sizeof(brd_path)))
#define ROW_SIZE ((int) (sizeof(board) / sizeof(board[0])))
int main(void)
{
char board[SIZE][SIZE] = {};
char brd_path[25] = {'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O',
'P', 'Q', 'R', 'S', 'T', 'U', 'V',
'W', 'X', 'Y', 'Z'};
// 0 = Up, 1 = Down, 2 = Left, 3 = Right
bool path_dir_chk[4] = {false};
bool blocked = false;
unsigned short i, j, x = 0, y = 0;
// Generate a random number
srand((unsigned) time(NULL));
int dir = rand() % 4;
// Set all positions of board to '.'
for (x = 0; x < ROW_SIZE; x++) {
for (y = 0; y < ROW_SIZE; y++)
board[x][y] = '.';
}
x = 0;
y = 0;
board[0][0] = 'A';
// Generate the path
while (blocked != true && i != PATH_SIZE) {
for (i = 0; i < PATH_SIZE;) {
// Reset path_dir_chk values if empty
for (j = 0; j < 4; j++) {
if (board[x][y - 1] == '.')
path_dir_chk[0] = false;
if (board[x][y + 1] == '.')
path_dir_chk[1] = false;
if (board[x - 1][y] == '.')
path_dir_chk[2] = false;
if (board[x + 1][y] == '.')
path_dir_chk[3] = false;
}
// Check the direction and replace that char
switch (dir) {
case 0: if ((y - 1) >= 0 && board[x][y - 1] == '.') {
board[x][--y] = brd_path[i];
path_dir_chk[0] = true;
printf("I is now: %d\n", ++i);
} break;
case 1: if ((y + 1) >= 0 && board[x][y + 1] == '.') {
board[x][++y] = brd_path[i];
path_dir_chk[1] = true;
printf("I is now: %d\n", ++i);
} break;
case 2: if ((x - 1) >= 0 && board[x - 1][y] == '.') {
board[--x][y] = brd_path[i];
path_dir_chk[2] = true;
printf("I is now: %d\n", ++i);
} break;
case 3: if ((x + 1) >= 0 && board[x + 1][y] == '.') {
board[++x][y] = brd_path[i];
path_dir_chk[3] = true;
printf("I is now: %d\n", ++i);
} break;
}
// if all path's are true exit
if (path_dir_chk[0] == true &&
path_dir_chk[1] == true &&
path_dir_chk[2] == true &&
path_dir_chk[3] == true)
blocked = true;
// Reset the random direction
dir = rand() % 4;
}
}
// Print the board
for (x = 0; x < ROW_SIZE; x++) {
for (y = 0; y < ROW_SIZE; y++)
printf("%c ", board[x][y]);
printf("\n");
}
return 0;
}
OK I have made changes to reflect what I have so far, no it is printing 'I is now:' numbers 1 - 25 and then it starts over but it stops on 12 the second time around and freezes into some kind of loop
Below is the working code I found online, you can compare the two and see the similarity's but the lines of code on his that are exactly like mine do not work on mine.....
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ROWS 10
#define COLS 10
int main (void)
{
int i, j, k, direction;
char board[ROWS][COLS];
const char letters[] = {'A', 'B', 'C', 'D', 'E', 'F',
'G', 'H', 'I', 'J', 'K', 'L',
'M', 'N', 'O', 'P', 'Q', 'R',
'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z'};
srand ((unsigned) time(NULL));
for (i = 0; i < ROWS; i++)
for (j = 0; j < COLS; j++)
board[i][j] = '.';
i = 0;
j = 0;
k = 1;
//set array[0][0] to first element
board[i][j] = letters[0];
while (k < 26) {
direction = rand() % 4;
if (board[i][j] == '.')
board[i][j] = letters[k++];
if ((board[i][j + 1] != '.' || j == ROWS - 1 )&&
(board[i + 1][j] != '.' || i == COLS -1) &&
(board[i - 1][j] != '.' || i == 0) &&
(board[i][j - 1] != '.' || j == 0))
break;
switch (direction) {
case 0: if (j < ROWS - 1 && board[i][j + 1] == '.'){ //move right
j++;
break; }
case 1: if (i < COLS -1 && board[i + 1][j] == '.') { //move down
i++;
break; }
case 2: if (i > 0 && board[i - 1][j] == '.'){ //move up
i--;
break; }
case 3: if (j > 0 && board[i][j - 1] == '.') { //move left
j--;
break; }
}
}
for (i = 0; i < ROWS; i++) {
for (j = 0; j < COLS; j++)
printf ("%4c", board[i][j]);
printf ("\n");
}
return 0;
}
You aren't setting x and y back to 0 after this code
for (x = 0; x < ROW_SIZE; x++) {
for (y = 0; y < ROW_SIZE; y++)
board[x][y] = '.';
}
Thus x and y will start at 10. Also you aren't range checking x and y, which means that x and y might wander off the board.
This code
if ((board[x][y - 1] != '.' || y - 1 < 0) &&
(board[x][y + 1] != '.' || y + 1 > ROW_SIZE) &&
(board[x - 1][y] != '.' || x - 1 < 0) &&
(board[x + 1][y] != '.' || x + 1 > ROW_SIZE))
should be this
if ((y - 1 < 0 || board[x][y - 1] != '.') &&
(y + 1 >= ROW_SIZE || board[x][y + 1] != '.') &&
(x - 1 < 0 || board[x - 1][y] != '.') &&
(x + 1 >= ROW_SIZE || board[x + 1][y] != '.'))
There are two subtle differences.
First y+1 and x+1 are not allowed to be equal to ROW_SIZE, since ROW_SIZE is 10, but the valid array indices are 0 to 9.
Second, order is important. When evaluating a logical OR, the left side is evaluated first, and if it's true, then the right side is not evaluated. This is important, since on some machines, even reading outside of the array bounds will cause a crash.
for (x = 0; x < ROW_SIZE; x++) {
for (y = 0; y < ROW_SIZE; y++)
board[x][y] = '.';
}
After the initialization you are not resetting the value of x and y. While value of X= ROW_SIZE, you are trying to access board[x + 1][y] and board[x][y + 1].
x = 0;
y = 0;
Thanks user3386109 your input was invaluable as was the rest of y'alls help I appreciate it, the working code is below :)
// Chapter 8 Programming Project #9
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <time.h>
#define SIZE 10
#define PATH_SIZE 25
#define ROW_SIZE ((int) (sizeof(board) / sizeof(board[0])))
int main(void)
{
char board[SIZE][SIZE];
// 0 = Up, 1 = Down, 2 = Left, 3 = Right
unsigned short i = 0, x, y;
// Generate a random number
srand((unsigned) time(NULL));
int dir = rand() % 4;
// Set all positions of board to '.'
for (x = 0; x < ROW_SIZE; x++) {
for (y = 0; y < ROW_SIZE; y++)
board[x][y] = '.';
}
x = 0;
y = 0;
board[0][0] = 'A';
// Generate the path
for (i = 0; i < PATH_SIZE;) {
// Check that the last character has not been cornered
if ((board[x][y - 1] != '.' || y - 1 < 0) &&
(board[x][y + 1] != '.' || y + 1 > ROW_SIZE) &&
(board[x - 1][y] != '.' || x - 1 < 0) &&
(board[x + 1][y] != '.' || x + 1 > ROW_SIZE))
break;
// Check the direction and replace that char
switch (dir) {
case 0: if ((y - 1) >= 0
&& board[x][y - 1] == '.') {
board[x][--y] = i + 'B';
++i;
} break;
case 1: if ((y + 1) < ROW_SIZE
&& board[x][y + 1] == '.') {
board[x][++y] = i + 'B';
++i;
} break;
case 2: if ((x - 1) >= 0
&& board[x - 1][y] == '.') {
board[--x][y] = i + 'B';
++i;
} break;
case 3: if ((x + 1) < ROW_SIZE
&& board[x + 1][y] == '.') {
board[++x][y] = i + 'B';
++i;
} break;
default: if (board[x][y] == '.')
board[x][y] = i + 'B';
break;
}
// Reset the random directions
dir = rand() % 4;
}
// Print the board
for (x = 0; x < ROW_SIZE; x++) {
for (y = 0; y < ROW_SIZE; y++)
printf("%4c ", board[x][y]);
printf("\n");
}
return 0;
}
the program does not enter the if statement it suppose to enter.for example when the sentence1 is oguzhan and the sentence2 is bugrahan for first characters it should enter the first if statement end substitution should be 4 but it doesn't.
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <cmath>
using namespace std;
int main() {
char sentence1[50];
char sentence2[50];
int m, n, k, l;
int i, j, substitution;
cout << "Enter the first word:" << endl;
cin >> sentence1;
cout << "Enter the second word:" << endl;
cin >> sentence2;
m = strlen(sentence1);
n = strlen(sentence2);
int cost[m + 1][n + 1];
cost[0][0] = 0;
for (i = 1; i < m + 1; i++) {
cost[i][0] = cost[i - 1][0] + 2;
}
for (j = 1; j < n + 1; j++) {
cost[0][j] = cost[0][j - 1] + 2;
}
for (i = 1; i < m + 1; i++) {
for (j = 1; j < n + 1; j++) {
if ((sentence1[i - 1] == 'a' || sentence1[i - 1] == 'u' ||
sentence1[i - 1] == 'e' || sentence1[i - 1] == 'i' ||
sentence1[i - 1] == 'o') &&
(sentence2[j - 1] != 'a' || sentence2[j - 1] != 'u' ||
sentence2[j - 1] != 'e' || sentence2[j - 1] != 'i' ||
sentence2[j - 1] != 'o')) {
substitution = 4;
}
if ((sentence1[i - 1] != 'a' || sentence1[i - 1] != 'u' ||
sentence1[i - 1] != 'e' || sentence1[i - 1] != 'i' ||
sentence1[i - 1] != 'o') &&
(sentence2[j - 1] == 'a' || sentence1[i - 1] != 'u' ||
sentence1[i - 1] != 'e' || sentence1[i - 1] != 'i' ||
sentence1[i - 1] != 'o')) {
substitution = 4;
}
if (sentence1[i - 1] == sentence2[j - 1]) {
substitution = 0;
}
if ((sentence1[i - 1] == 'a' || sentence1[i - 1] == 'u' ||
sentence1[i - 1] == 'e' || sentence1[i - 1] == 'i' ||
sentence1[i - 1] == 'o') &&
(sentence2[j - 1] == 'a' || sentence2[j - 1] == 'u' ||
sentence2[j - 1] == 'e' || sentence2[j - 1] == 'i' ||
sentence2[j - 1] == 'o')) {
substitution = 3;
}
if ((sentence1[i - 1] != 'a' || sentence1[i - 1] != 'u' ||
sentence1[i - 1] != 'e' || sentence1[i - 1] != 'i' ||
sentence1[i - 1] != 'o') &&
(sentence2[j - 1] != 'a' || sentence2[j - 1] != 'u' ||
sentence2[j - 1] != 'e' || sentence2[j - 1] != 'i' ||
sentence2[j - 1] != 'o')) {
substitution = 3;
}
cost[i][j] = min(min(cost[i - 1][j] + 2, cost[i][j - 1] + 2),
cost[i - 1][j - 1] + substitution);
}
}
for (i = 0; i < m + 1; i++) {
for (j = 0; j < n + 1; j++) {
cout << cost[i][j] << " ";
}
cout << endl;
}
cout << sentence1[0];
return 0;
}
A condition like: sentence2[j-1]!='a'||sentence2[j-1]!='u' is always true -- no single character can be equal to both a and u, so one of these has to be true.
If you're using !=, it must almost always be joined by &&, not ||, otherwise the result will always be true, regardless of input.