c++ Gomoku diagonal checker - c++

so I am a relatively new to coding. So I have to make a Gomoku game for a project. Gomoku is like tic-tac-toe, but have to get five in a row. Have been given certain restrictions such as a board size of 6x6 to 15x15. The use of at least one class. I have chosen to use arrays. I have created PlayerOne as an algorithm which bases its moves on PlayerOne's last move, and moves one random block away from it in next move. The second algorithm is random. For when checking for a win, my horizontal and vertical checkers seem to work but both my diagonal checkers are giving problems, with them saying that 3 consecutive blocks in a row diagonally is 5 in a row. I created my checkers separately, filling in each row manually to test, and the diagonal checkers were fine there, but they're not fine in the whole code.
I'll share both the diagonal checkers up here, and then the whole code a little below so hopefully easier to read. Also quite a bit of it has cout statements as was trying to see where problems where earlier in the process. If anyone can see where the issue is occurring if could point out where, would be so appreciative.
int game::diagonalCheckerNegSlope(int arr[15][15], int size) {
int count1;
int count2;
int whoWon = 0;
for (int i = 0; i < size; i++) {
count1 = 0;
count2 = 0;
for (int j = 0; j < size; j++) {
if (arr[j][i] == 1) {
for (int d = 0; (i + d < size) && (j + d < size); d++)
if (arr[i + d][j + d] == 1) {
count1++;
if (count1 == 5) {
whoWon = 1;
}
} else {
count1 = 0;
}
}
if (arr[j][i] == 2) {
for (int d = 0; (i + d < size) && (j + d < size); d++)
if (arr[i + d][j + d] == 2) {
count2++;
if (count2 == 5) {
whoWon = 2;
}
} else {
count2 = 0;
}
}
}
}
if (whoWon != 1 && whoWon != 2) {
whoWon = 3;
}
return whoWon;
}
int game::diagonalCheckerPosSlope(int arr[15][15], int size) {
int count1;
int count2;
int whoWon = 0;
for (int i = 0; i < size; i++) {
count1 = 0;
count2 = 0;
for (int j = 0; j < size; j++) {
if (arr[i][j] == 1) {
for (int d = 0; (i + d < size) && (j - d < size); d++)
if (arr[i + d][j - d] == 1) {
count1++;
if (count1 == 5) {
whoWon = 1;
}
} else {
count1 = 0;
}
}
if (arr[i][j] == 2) {
for (int d = 0; (i + d < size) && (j - d < size); d++)
if (arr[i + d][j - d] == 2) {
count2++;
if (count2 == 5) {
whoWon = 2;
}
} else {
count2 = 0;
}
}
}
}
if (whoWon != 1 && whoWon != 2) {
whoWon = 3;
}
return whoWon;
}
int main code
#include <iostream>
#include <fstream>
#include "game.h"
#include <iomanip>
#include <ctime>
using namespace std;
int main() {
string inputSize = "input.txt";
int size =0;
srand(time(0));
int arr[15][15];
game Gomuko;
size = Gomuko.getSize(inputSize, arr);
if(size >=6 && size <=15){
Gomuko.initZero(arr, size);
// Gomuko.printArr(arr,size);
Gomuko.Play(arr, size);
Gomuko.printArr(arr,size);
}else{
cout << "Invalid input" << endl;
}
return 0;
}
The .h file of the class
#ifndef GAME_H_
#define GAME_H_
#include <string>
#include <ctime>
using namespace std;
class game {
public:
game();
int getSize(string inputFileName, int dataArray[15][15]);
void initZero(int arr[15][15], int size);
void printArr(int arr[15][15], int size);
void movePlayerOne(int arr[15][15], int size, int counter2);
void movePlayerTwo(int arr[15][15], int size);
void Play(int arr[15][15], int size);
int PlayerOneSurroundRow(int arr[15][15],int size);
int PlayerOneSurroundCol(int arr[15][15],int size);
int findFirstMoveRow(int arr[15][15], int size);
int findFirstMoveCol(int arr[15][15], int size);
bool isValid(int newRow, int newCol, int size);
int horizontalChecker(int arr[15][15], int size);
int verticalChecker(int arr[15][15], int size);
int diagonalCheckerNegSlope(int arr[15][15], int size);
int diagonalCheckerPosSlope(int arr[15][15], int size);
int WholeWinnerChecker(int arr[15][15], int size);
private:
int randRow(int size);
int randCol(int size);
};
#endif /* GAME_H_ */
And finally the .cpp file of the class
#include "game.h"
#include <iostream>
#include <fstream>
#include <iomanip>
#include <ctime>
using namespace std;
game::game() {
// TODO Auto-generated constructor stub
}
int game::getSize(string inputFileName, int dataArray[15][15]) {//make between 6 and 15.
ifstream inputData;
int size = 0;
int counter = 0;
inputData.open(inputFileName);
if (!inputData) {
cout << "Cannot open the file \"" << inputFileName << "\"" << endl;
}
else {
while (inputData >> size) {
counter++;
}
cout << "There are " << counter << " board sizes in the inputFile"
<< endl;
cout << "The size of the board is " << size << "x" << size << endl
<< endl;
}
return size;
}
void game::initZero(int arr[15][15], int size) {
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
arr[i][j] = 0;
}
}
}
void game::printArr(int arr[15][15], int size) {
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
cout << arr[i][j] << " ";
}
cout << endl;
}
cout << endl << endl;
}
int game::randRow(int size) {
int randNoRow = 0;
randNoRow = rand() % size;
return randNoRow;
}
int game::randCol(int size) {
int randNoCol = 0;
randNoCol = rand() % size;
return randNoCol;
}
int game::findFirstMoveRow(int arr[15][15], int size) {
int positionRow;
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
if (arr[i][j] == 1) {
positionRow = i;
}
}
}
return positionRow;
}
int game::findFirstMoveCol(int arr[15][15], int size) {
int positionCol;
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
if (arr[i][j] == 1) {
positionCol = j;
}
}
}
return positionCol;
}
int game::PlayerOneSurroundRow(int arr[15][15], int size) {
int positionRow = game::findFirstMoveRow(arr, size);
// cout << "The old row is " << positionRow << endl;
int oldRow = positionRow;
int randChoice = 0;
int newRow = 0;
randChoice = (rand() % 3);
// cout << "randChoice Row case: " << randChoice << endl;
switch (randChoice) {
case 0:
newRow = oldRow - 1;
break;
case 1:
newRow = oldRow;
break;
case 2:
newRow = oldRow + 1;
break;
}
// cout << "Test2" << endl << endl;
if (newRow > size - 1) {
// cout << "Row too big as Row is " << newRow << endl;
newRow = newRow - 1;
// cout << "Row is now " << newRow << endl;
}
if (newRow < 0) {
// cout << "Row too small as row is " << newRow << endl;
newRow = newRow + 1;
// cout << "Row is now " << newRow << endl;
}
// cout << "The new row is: " << newRow << endl;
return newRow;
}
int game::PlayerOneSurroundCol(int arr[15][15], int size) {
int positionCol = findFirstMoveCol(arr, size);
// cout << "The old col is " << positionCol << endl;
int oldCol = positionCol;
int randChoice = 0;
int newCol = 0;
randChoice = (rand() % 3);
cout << "randChoice Col case: " << randChoice << endl;
switch (randChoice) {
case 0:
newCol = oldCol - 1;
break;
case 1:
newCol = oldCol;
break;
case 2:
newCol = oldCol + 1;
break;
}
// cout << "Test2" << endl << endl;
if (newCol > size - 1) {
// cout << "Col too big as is " << newCol << endl;
newCol = newCol - 1;
// cout << "Col is now " << newCol << endl;
}
if (newCol < 0) {
// cout << "Col too small as is " << newCol << endl;
newCol = newCol + 1;
// cout << "Col is now " << newCol << endl;
}
// cout << "The new col is: " << newCol << endl;
return newCol;
}
bool game::isValid(int newRow, int newCol, int size) {
bool valid = false;
if (((newRow < size) && (newCol < size))
&& ((newRow >= 0) && (newCol >= 0))) {
valid = true;
}
return valid;
}
void game::movePlayerOne(int arr[15][15], int size, int counter2) {
int newRow = 0;
int newCol = 0;
int oldRow = 0;
int oldCol = 0;
int count3 = 0;
if (counter2 == 0) {
oldRow = randRow(size);
oldCol = randCol(size);
arr[oldRow][oldCol] = 1;
// cout << "Test1" << endl << endl << endl;
counter2++;
}
else {
// cout << "Test 3" << endl;
newRow = game::PlayerOneSurroundRow(arr, size);
newCol = game::PlayerOneSurroundCol(arr, size);
if (arr[newRow][newCol] == 0 && isValid(newRow, newCol, size)) {
arr[newRow][newCol] = 1;
// cout << "Test4" << endl;
// cout << "randNoRow = " << newRow << endl;
// cout << "randNoCol = " << newCol << endl;
oldRow = newRow;
oldCol = newCol;
}
else if ((arr[newRow][newCol] == 1) || (arr[newRow][newCol] == 2)
|| (newRow > size) || (newCol > size) || (newRow < 0)
|| (newCol < 0)) {
cout
<< "There has been a match, or even out of bounds, going again. "
<< endl << endl;
while ((arr[newRow][newCol] == 1) || (arr[newRow][newCol] == 2)) {
// cout << "Test5" << endl;
newRow = game::PlayerOneSurroundRow(arr, size);
newCol = game::PlayerOneSurroundCol(arr, size);
// cout << "randNoRow = " << newRow << endl;
// cout << "randNoCol = " << newCol << endl;
count3++;
if ((arr[newRow][newCol] != 1 && arr[newRow][newCol] != 2)
&& isValid(newRow, newCol, size)) {
arr[newRow][newCol] = 1;
// cout << "Test6" << endl;
//
// cout << "randNoRow = " << newRow << endl;
// cout << "randNoCol = " << newCol << endl;
oldRow = newRow;
oldCol = newCol;
break;
}
if (count3++ > 3) {
// cout << "Test 7" << endl;
// newRow = randRow(size);
// newCol = randCol(size);
while (arr[newRow][newCol] == 1 || arr[newRow][newCol] == 2) {
newRow = randRow(size);
newCol = randCol(size);
// cout << "Test 8" << endl;
// cout << "randNoRow = " << newRow << endl;
// cout << "randNoCol = " << newCol << endl;
if (arr[newRow][newCol] == 0) {
arr[newRow][newCol] = 1;
// cout << "Test 9" << endl;
// cout << "randNoRow = " << newRow << endl;
// cout << "randNoCol = " << newCol << endl;
oldRow = newRow;
oldCol = newCol;
break;
}
}
break;
}
}
}
}
}
void game::movePlayerTwo(int arr[15][15], int size) {
// cout << "Test" << endl;
int randNoRow = 0;
int randNoCol = 0;
randNoRow = randRow(size);
cout << "randNoRow = " << randNoRow << endl;
randNoCol = randCol(size);
cout << "randNoCol = " << randNoCol << endl;
cout << endl;
if ((arr[randNoRow][randNoCol] == 1) || (arr[randNoRow][randNoCol] == 2)) {
//cout << "There has been a match, going again. " << endl << endl;
while ((arr[randNoRow][randNoCol] == 1)
|| (arr[randNoRow][randNoCol] == 2)) {
int randNoRow = 0;
int randNoCol = 0;
randNoRow = randRow(size);
//cout << "randNoRow = " << randNoRow << endl;
randNoCol = randCol(size);
//cout << "randNoCol = " << randNoCol << endl;
//cout << endl;
if (arr[randNoRow][randNoCol] == 0) {
arr[randNoRow][randNoCol] = 2;
break;
}
}
} else {
arr[randNoRow][randNoCol] = 2;
}
}
int game::horizontalChecker(int arr[15][15], int size) {
int count1;
int count2;
int whoWon = 0;
for (int i = 0; i < size; i++) {
count1 = 0;
count2 = 0;
for (int j = 0; j < size; j++) {
if (arr[i][j] == 1) {
count1++;
if (count1 == 5) {
whoWon = 1;
}
} else {
count1 = 0;
}
if (arr[j][i] == 2) {
count2++;
if (count2 == 5) {
whoWon = 2;
}
} else {
count2 = 0;
}
}
if (whoWon != 1 && whoWon != 2) {
whoWon = 3;
}
}
return whoWon;
}
int game::verticalChecker(int arr[15][15], int size) {
int count1;
int count2;
int whoWon = 0;
for (int i = 0; i < size; i++) {
count1 = 0;
count2 = 0;
for (int j = 0; j < size; j++) {
if (arr[j][i] == 1) {
count1++;
if (count1 == 5) {
whoWon = 1;
}
} else {
count1 = 0;
}
if (arr[j][i] == 2) {
count2++;
if (count2 == 5) {
whoWon = 2;
}
} else {
count2 = 0;
}
}
if (whoWon != 1 && whoWon != 2) {
whoWon = 3;
}
}
return whoWon;
}
int game::diagonalCheckerNegSlope(int arr[15][15], int size) {
int count1;
int count2;
int whoWon = 0;
for (int i = 0; i < size; i++) {
count1 = 0;
count2 = 0;
for (int j = 0; j < size; j++) {
if (arr[j][i] == 1) {
for (int d = 0; (i + d < size) && (j + d < size); d++)
if (arr[i + d][j + d] == 1) {
count1++;
if (count1 == 5) {
whoWon = 1;
}
} else {
count1 = 0;
}
}
if (arr[j][i] == 2) {
for (int d = 0; (i + d < size) && (j + d < size); d++)
if (arr[i + d][j + d] == 2) {
count2++;
if (count2 == 5) {
whoWon = 2;
}
} else {
count2 = 0;
}
}
}
}
if (whoWon != 1 && whoWon != 2) {
whoWon = 3;
}
return whoWon;
}
int game::diagonalCheckerPosSlope(int arr[15][15], int size) {
int count1;
int count2;
int whoWon = 0;
for (int i = 0; i < size; i++) {
count1 = 0;
count2 = 0;
for (int j = 0; j < size; j++) {
if (arr[i][j] == 1) {
for (int d = 0; (i + d < size) && (j - d < size); d++)
if (arr[i + d][j - d] == 1) {
count1++;
if (count1 == 5) {
whoWon = 1;
}
} else {
count1 = 0;
}
}
if (arr[i][j] == 2) {
for (int d = 0; (i + d < size) && (j - d < size); d++)
if (arr[i + d][j - d] == 2) {
count2++;
if (count2 == 5) {
whoWon = 2;
}
} else {
count2 = 0;
}
}
}
}
if (whoWon != 1 && whoWon != 2) {
whoWon = 3;
}
return whoWon;
}
int game::WholeWinnerChecker(int arr[15][15], int size) {
int finalWinner = 0;
int outcome1 = horizontalChecker(arr, size);
if ((outcome1 == 1) || (outcome1 == 2)) {
finalWinner = outcome1;
cout << "Horizontal Win" << endl;
}
int outcome2 = verticalChecker(arr, size);
if ((outcome2 == 1) || (outcome2 == 2)) {
finalWinner = outcome2;
cout << "Vertical Win" << endl;
}
int outcome3 = diagonalCheckerPosSlope(arr, size);
if ((outcome3 == 1) || (outcome3 == 2)) {
finalWinner = outcome3;
cout << "Diag Pos Win" << endl;
}
int outcome4 = diagonalCheckerNegSlope(arr, size);
if ((outcome4 == 1) || (outcome4 == 2)) {
finalWinner = outcome4;
cout << "Diag Neg Win" << endl;
}
else if ((finalWinner != 1) && (finalWinner != 2)) {
finalWinner = 3;
}
return finalWinner;
}
void game::Play(int arr[15][15], int size) {
int counter = 0;
int Winner=0;
int boardFull= size*size;
while(((Winner != 1)&&(Winner != 2))&& (counter < boardFull)){
cout << "This is turn " << counter + 1 << endl;
if (counter % 2 == 0) {
cout << "PlayerOne: " << endl;
game::movePlayerOne(arr, size, counter);
if (counter >= 4) {
Winner = game::WholeWinnerChecker(arr, size);
if(Winner ==1){
cout << endl <<"======================" << endl;
cout << "Winner = " << Winner << endl;
cout <<"======================" << endl;
}
}
}
if (counter % 2 == 1) {
cout << "PlayerTwo:" << endl;
game::movePlayerTwo(arr, size);
if (counter >= 5) {
Winner = game::WholeWinnerChecker(arr, size);
if (Winner == 2) {
cout << endl << "======================" << endl;
cout << "Winner = " << Winner << endl;
cout << "======================" << endl;
}
}
}
if(counter == boardFull){
cout << "Draw" << endl;
}
counter++;
}
}
I have also been using an input of
6

The problem could be that you don't set count1 and count2 inside the j-loop, but rather count on the variable being reset in the else statement. But if your d-loop ends before the else statement is executed ((i + d < size) && (j - d < size) becomes false "prematurely") then the counter is not reset. Solution: move the zero-initialization to inside the j-loop.
Some improvements:
If lots of methods have the same parameter (such as int arr[15][15] and int size) then this could be the sign that these parameters should become members of the class.
It is possible to have only one checker function. Parameters of this function would be the direction of the search (int deltaX, int deltaY), and also the value that is being checked (1 or 2). Delta-values for all 8 directions are these:
(1, 0), (1, 1), (0, 1), (-1, 1), (-1, 0), (-1, 1), (0, 1), (1, 1)
So, in your d-loop you would not add or subtract d to and from i and j, but you would always add deltaX to i, and deltaY to j.
Also, a bit advanced, but also fun. It is possible to arrange the code in such a way that you can have three types of games: human vs human, human vs computer, computer vs computer. You just for instance assign object of a class HumanPlayer to player 1 and object of a class ComputerPlayer to player 2. This would enable you to pick who plays first, and also have several algorithms battling it out. Both classes would have to be derived from the base class Player with some known methods (like 'move'), and some GameCoordinator would in a loop call this method 'move' on both objects, update the game state, and check if game has ended.

Related

Run-Time Check Failure #2 - Stack around the variable 'board' was corrupted

I am running project called Horse Board Game. When it got almost done, it happened an error at the end of the execution part. The error is:
Run-Time Check Failure #2 - Stack around the variable 'board' was corrupted.
Where is the mistake here? Everything seems to work properly, only that error occurs.
#include <iostream>
#include <ctime>
#include <Windows.h>
using namespace std;
void printHorizontalLine(int size) {
for (int i = 0; i < size; i++) {
cout << " -----------";
}
cout << "\n";
}
void printVerticalLine(int size) {
cout << "|";
for (int i = 0; i < size; i++) {
cout << " |";
}
cout << "\n";
}
void displayBoard(int size, char board[50][50]) {
for (int i = 0; i < size; i++) {
printHorizontalLine(size);
printVerticalLine(size);
cout << "|";
if (i % 2 == 0) {
for (int j = 0; j < size; j++) {
cout << " " << board[i][j] << " |";
}
}
else {
for (int j = size - 1; j >= 0; j--) {
cout << " " << board[i][j] << " |";
}
}
cout << "\n";
printVerticalLine(size);
}
printHorizontalLine(size);
}
void init_board(char board[50][50], int size) {
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
board[i][j] = ' ';
}
}
}
void enteringPlayerName(char name[], int n) {
for (int i = 0; i < n; i++) {
cout << "Player " << i + 1 << " enter name: " << "\n";
cin >> name[i];
}
}
void beginningPos(int n, int pos[]) {
for (int i = 0; i < n; i++) {
pos[i] = -1;
}
}
void rollDice(int max, char board[50][50], int pos[], char name[], int size, int n, int cur) {
int step = rand() % max + 1;
cout << name[cur] << " roll " << step << "\n";
if (step + pos[cur] > size * size - 1) {
cout << "Cannot move forward\n";
}
else {
pos[cur] += step;
for (int i = 0; i < n; i++) {
if ((pos[cur] == pos[i]) && (i != cur)) {
pos[i] = -1;
cout << name[i] << " is kicked to the Start!!\n";
}
}
}
}
void updatingBoard(char board[50][50], char name[], int pos[], int n, int size) {
init_board(board, size);
for (int k = 0; k < n; k++)
{
int x, i, j;
x = pos[k];
i = x / size;
j = x % size;
board[i][j] = name[k];
}
}
char playGame(int max, int n, int size, char board[50][50], int pos[], char name[], int finish_point) {
char winner = ' ';
int cur_turn = 0;
while (winner == ' ') {
rollDice(max, board, pos, name, size, n, cur_turn % n);
updatingBoard(board, name, pos, n, size);
displayBoard(size, board);
if (pos[cur_turn % n] == finish_point) winner = name[cur_turn % n];
cur_turn++;
}
return winner;
}
int main() {
int size, n;
cin >> size;
cin >> n;
const int MAX = 50;
int max = 3;
int pos[200];
char name[10];
char winner = ' ';
char board[MAX][MAX];
int finish_point = size * size - 1;
srand(time(0));
enteringPlayerName(name, n);
init_board(board, size);
beginningPos(n, pos);
winner = playGame(max, n, size, board, pos, name, finish_point);
if (winner == ' ') cout << "Tie game";
else cout << winner << " is the winner";
return 0;
}```
When I set size to 4 and n to 2 as recommended in the comments section, then the line
board[i][j] = name[k];
in the function updatingBoard causes a buffer underflow.
The first time that line is executed, i has the value 0 and j has the value 0, which is ok, but the second time that line is executed, i has the value 0 but j has the value -1. This is obviously wrong, because board[0][-1] is accessing the array out of bounds.
That is the reason for the error message that you are receiving.
You can easily see this by running your program line by line in a debugger.

array class pointer lost values in the main

I am new to c++. I wrote a program which gives a set of states, the problem is when a try to print the state in the main program because I have a pointer of Nodo of [5]; I print the states in the same function and these states are generated the problem is when I call the function in the main program and when I try to print some state this print a number like 912222558. Please help me.
#include <iostream>
using namespace std;
class State {
public:
int dsc[3];
State()
{
dsc[0] = 3;
dsc[1] = 3;
dsc[2] = 1;
}
void printstate()
{
for (int i = 0; i < 3; i++) {
cout << " " << dsc[i] << " ";
}
cout << endl;
}
bool checkObjetivo()
{
if (dsc[0] == 0 && dsc[1] == 0 && dsc[2] == 0) {
return true;
}
else {
return false;
}
}
bool validState()
{
if ((dsc[0] >= 0 && dsc[0] <= 3) && (dsc[1] >= 0 && dsc[1] <= 3) && (dsc[2] >= 0 && dsc[2] <= 1) && (dsc[1] <= dsc[0])) {
return true;
}
else {
return false;
}
}
};
class Nodo {
public:
State state;
Nodo* father;
Nodo* child[5];
int level;
bool solution;
Nodo()
{
father = NULL;
for (int i = 0; i < 5; i++) {
child[i] = NULL;
}
level = 0;
solution = false;
}
Nodo childGeneration()
{
Nodo nuevoNodo;
if (state.validState()) {
if (state.checkObjetivo()) {
for (int i = 0; i < 3; i++) {
nuevoNodo.state.dsc[i] = state.dsc[i];
}
nuevoNodo.solution = true;
return nuevoNodo;
}
else {
int h0[3], h1[3], h2[3], h3[3], h4[3];
Nodo nH0, nH1, nH2, nH3, nH4;
for (int i = 0; i < 3; i++) {
h0[i] = state.dsc[i];
h1[i] = state.dsc[i];
h2[i] = state.dsc[i];
h3[i] = state.dsc[i];
h4[i] = state.dsc[i];
}
if (state.dsc[2] == 1) {
cout << "Paso dsc es 1 " << endl;
//MC
h0[0] = h0[0] - 1;
h0[1] = h0[1] - 1;
h0[2] = h0[2] - 1;
//CC
h1[1] = h1[1] - 2;
h1[2] = h1[2] - 1;
//MM
h2[0] = h2[0] - 2;
h2[2] = h2[2] - 1;
//C_
h3[1] = h3[1] - 1;
h3[2] = h3[2] - 1;
//M_
h4[0] = h4[0] - 1;
h4[2] = h4[2] - 1;
}
if (state.dsc[2] == 0) {
//MC
h0[0] = h0[0] + 1;
h0[1] = h0[1] + 1;
h0[2] = h0[2] + 1;
//CC
h1[1] = h1[1] + 2;
h1[2] = h1[2] + 1;
//MM
h2[0] = h2[0] + 2;
h2[2] = h2[2] + 1;
//C_
h3[1] = h3[1] + 1;
h3[2] = h3[2] + 1;
//M_
h4[0] = h4[0] + 1;
h4[2] = h4[2] + 1;
}
for (int i = 0; i < 3; i++) {
nH0.state.dsc[i] = h0[i];
nH1.state.dsc[i] = h1[i];
nH2.state.dsc[i] = h2[i];
nH3.state.dsc[i] = h3[i];
nH4.state.dsc[i] = h4[i];
}
cout << "nH0 state: " << endl;
for (int j = 0; j < 3; j++) {
cout << nH0.state.dsc[j];
}
cout << endl;
cout << "nH1 state: " << endl;
for (int j = 0; j < 3; j++) {
cout << nH1.state.dsc[j];
}
cout << endl;
cout << "nH2 state: " << endl;
for (int j = 0; j < 3; j++) {
cout << nH2.state.dsc[j];
}
cout << endl;
cout << "nH3 state: " << endl;
for (int j = 0; j < 3; j++) {
cout << nH3.state.dsc[j];
}
cout << endl;
cout << "nH4 state: " << endl;
for (int j = 0; j < 3; j++) {
cout << nH4.state.dsc[j];
}
cout << endl;
nuevoNodo.child[0] = &nH0;
nuevoNodo.child[1] = &nH1;
nuevoNodo.child[2] = &nH2;
nuevoNodo.child[3] = &nH3;
nuevoNodo.child[4] = &nH4;
cout << "New nodo child[0] " << endl;
for (int j = 0; j < 3; j++) {
cout << nuevoNodo.child[0]->state.dsc[j];
}
cout << endl;
cout << "New nodo child[1] " << endl;
for (int j = 0; j < 3; j++) {
cout << nuevoNodo.child[1]->state.dsc[j];
}
cout << endl;
return nuevoNodo;
}
}
}
};
int main()
{
State est;
est.printstate();
Nodo nNodo;
nNodo.state = est;
Nodo nRes;
Nodo verN;
verN = nRes.childGeneration();
cout << "child[0] " << endl;
verN.child[0]->state.printstate();
return 0;
}
You have undefined behavior.
In the childGeneration function, you are storing pointers to stack variables. Those pointers are only valid from within that function.
You should consider using dynamic memory allocation instead, or rethink your program in some other way.

compare value to array element

when i get user input cin >> x; and cin >> y;
I want to then compare this to an array "Location cord" L1[i][j], but when i use an if statement
- if (x && y == L1[i][j])
- if (x == L1[i] && y == L1[j])
Im not getting the result of "HIT" which is what i need.
This is a sort of minesweeper project. Any help, or pointers would be much appreciated!
#include "stdafx.h"
#include <iostream>
#include <cstdlib>
#include <iomanip>
#include <string>
char L1[8][8], L2[16][16], L3[24][24]; // grid location of cords
char B1[8][8], B2[16][16], B3[24][24]; // grid location of bombs
int i, j;
using namespace std;
// load and print grids L1 L2 L3
void loadgrid_L1()
{
for ( i = 0; i < 8; i++)
{
for ( j = 0; j < 8; j++)
{
L1[i][j] = 'X';
}
}
}
void printgrid_L1()
{
for ( i = 0; i < 8; i++)
{
for ( j = 0; j < 8; j++)
{
cout << L1[i][j];
}
cout << ("\n");
}
}
void loadgrid_L2()
{
for (i = 0; i < 16; i++)
{
for (j = 0; j < 16; j++)
{
L2[i][j] = 'X';
}
}
}
void printgrid_L2()
{
for (i = 0; i < 16; i++)
{
for (j = 0; j < 16; j++)
{
cout << L2[i][j];
}
cout << ("\n");
}
}
void loadgrid_L3()
{
for (i = 0; i < 24; i++)
{
for (j = 0; j < 24; j++)
{
L3[i][j] = 'X';
}
}
}
void printgrid_L3()
{
for (i = 0; i < 24; i++)
{
for (j = 0; j < 24; j++)
{
cout << L3[i][j];
}
cout << ("\n");
}
}
void bomb1()
{
L1[1][5] = 'O';
}
void bomb2()
{
L2[3][4] = 'O';
}
void bomb3()
{
L3[6][6] = 'O';
}
void menu() //need to work on this section
{
string lvl, x, y;
cout << "Please select a lvl to play L1, L2, L3 " << endl;
getline(cin, lvl);
if (lvl == "L1")
{
loadgrid_L1();
//moved bomb() from here
cout << "Please enter your co-ordinates for your move" << endl;
cout << "Cord 1: ";
getline(cin, x);
cout << "Cord 2: ";
getline(cin, y);
if (x == L1[i])
{
cout << "HIT!" << endl;
}
else if (x != L1[i])
{
cout << "SUCCESS!" << endl;
}
bomb1();
printgrid_L1();
}
else if (lvl == "L2")
{
loadgrid_L2();
bomb2();
printgrid_L2();
}
else if (lvl == "L3")
{
loadgrid_L3();
bomb3();
printgrid_L3();
}
else if ((lvl != "L1") && (lvl != "L2") && (lvl != "L3"))
{
cout << "You must pick a lvl" << endl;
while ((lvl != "L1") && (lvl != "L2") && (lvl != "L3"))
{
getline(cin, lvl);
if (lvl == "L1")
{
loadgrid_L1();
bomb1();
printgrid_L1();
}
else if (lvl == "L2")
{
loadgrid_L2();
bomb2();
printgrid_L2();
}
else if (lvl == "L3")
{
loadgrid_L3();
bomb3();
printgrid_L3(); // needs to stop
}
}
}
}
int main()
{
menu();
return 0;
}
You can easily change each of your loadgrid & printgrid functions to be 2 single functions as such:
void loadgrid( unsigned int lvl ) {
if ( lvl < 0 || lvl > 3 ) {
std::cout << "Error: invalid level entered: " << lvl << std::endl;
return;
}
int size = 0;
if ( lvl == 1 )
size = 8;
else if ( lvl == 2 )
size = 16;
else if ( lvl == 3 )
size = 24;
for ( int i = 0; i < size; i++ ) {
for ( int j = 0; j < size; j++ ) {
if ( lvl == 1 )
L1[i][j] = 'X';
else if ( lvl == 2 )
L2[i][j] = 'X';
else if ( lvl == 3 )
L3[i][j] = 'X';
}
}
}
And you can follow the same pattern above for print grid.
Then when you call the function you just pass what lvl you want to load and or print.

Two-Dimensional Array Searching Algorithm Optimisation

I have been given a "Sand box" of variable length and width. I've been given instructions to find a "shovel" of static size, which may be oriented either horizontally or vertically. I implement the following algorithm in order to search the least amount of times to find one valid location (one which corresponds to a "part of the object") in the grid:
found = false;
nShift = 0;
shovelSize = 4;
for(int i = 0; i < SandBoxRows; i++) {
for(int j = 0; j < SandBoxColumns; j+=shovelSize) {
found = probeSandBoxTwo(('A' + i), (j + 1 + nShift));
}
if(nShift >= shovelSize - 1 || nShift > SandBoxColumns) {
nShift = 0;
} else {
nShift++;
}
}
In this case, the "Sand box" will be tested by the function as described below.
I completely recreate this scenario with a "Sand box" whose size is fixed (though easily manipulated) whose shovel is still randomly placed and oriented within the following code:
#include <cstdlib>
#include <ctime>
#include <iostream>
using namespace std;
const int ROW = 12;
const int COL = 16;
char sandbox[ROW][COL];
bool probeSandBoxTwo(char c, int i);
void displayResults(int sCount, bool found, int x, int y);
void displaySandbox();
void displaySearchPattern();
void fillSandbox();
void placeShovel();
int main() {
fillSandbox();
placeShovel();
displaySandbox();
//define your variables here
bool found;
int nShift,
sCount,
shovelSize,
x,
y;
found = false;
nShift = 0;
shovelSize = 4;
sCount = 0;
for(int i = 0; i < ROW && !found; i++) {
for(int j = 0; j < COL && !found; j+=shovelSize) {
found = probeSandBoxTwo(('A' + i), (j + 1 + nShift));
x = i;
y = j + nShift;
sCount++;
cout << "Search conducted at (" << i << ", " << (j + nShift) << ")" << endl;
}
if(nShift >= shovelSize - 1 || nShift > ROW) {
nShift = 0;
} else {
nShift++;
}
}
displayResults(sCount, found, x, y);
displaySearchPattern();
}
bool probeSandBoxTwo(char c, int i) {
if(sandbox[c-'A'][i-1] == 'X') {
return true;
} else {
return false;
}
}
void displayResults(int sCount, bool found, int x, int y) {
cout << endl;
cout << "Total searches: " << sCount << endl;
cout << endl;
if(found) {
cout << "Shovel found at coordinates: (" << x << ", " << y << ")" << endl;
}
}
void displaySandbox() {
cout << " ";
for(int i = 0; i < COL; i++) {
cout << (i % 10); //show index numbers [col]
}
cout << endl;
for(int i = 0; i < ROW; i++) {
cout << (i % 10) << " "; //show index numbers [row]
for(int j = 0; j < COL; j++) {
cout << sandbox[i][j];
}
cout << endl;
}
cout << endl;
}
void displaySearchPattern() {
int nShift = 0;
int shovelSize = 4;
cout << endl << " ";
for(int i = 0; i < COL; i++) {
cout << (i % 10); //show index numbers [col]
}
cout << endl;
for(int i = 0; i < ROW; i++) {
cout << (i % 10) << " "; //show index numbers [row]
for(int j = 0; j < COL; j++) {
if(!((j + nShift) % shovelSize)) {
cout << 'o';
} else {
cout << '.';
}
}
if(nShift >= shovelSize - 1 || nShift > COL) {
nShift = 0;
} else {
nShift++;
}
cout << endl;
}
}
void fillSandbox() {
for(int i = 0; i < ROW; i++) {
for(int j = 0; j < COL; j++) {
sandbox[i][j] = '.';
}
}
}
void placeShovel() {
srand(time(NULL));
int shovelRow,
shovelCol,
shovelSize = 4;
if(rand() % 2) {
//horizontal
shovelRow = rand() % ROW + 1;
shovelCol = rand() % (COL - (shovelSize - 1)) + 1;
for(int i = shovelCol - 1; i < shovelSize + (shovelCol - 1); i++) {
sandbox[shovelRow - 1][i] = 'X';
}
} else {
//vertical
shovelRow = rand() % (ROW - (shovelSize - 1)) + 1;
shovelCol = rand() % COL + 1;
for(int i = shovelRow - 1; i < shovelSize + (shovelRow - 1); i++) {
sandbox[i][shovelCol - 1] = 'X';
}
}
}
In this code, I also graphically display the pattern (when run) with which my algorithm searches.
Is this truly the optimal search pattern for such a scenario, is my implementation correct, and if so, why might I be having incorrect results returned?
A given test driver reports the following results:
The source code for this result (and its test driver).
found = false;
nShift = 0;
shovelSize = 4;
for(int i = 0; i < SandBoxRows; i++) {
for(int j = 0; (j + nShift) < SandBoxColumns; j+=shovelSize) {
found = probeSandBoxTwo(('A' + i), (j + 1 + nShift));
}
if(nShift >= shovelSize - 1 || nShift > SandBoxColumns) {
nShift = 0;
} else {
nShift++;
}
}
This corrects an error in the conditional portion of the for loop header which did not account for the index-shifting variable nShift.

Eight Queens C++ utilizing a Stack Backtracking

So I'm doing this for homework, and I can't figure out where my bug is. Any help is greatly appreciate.
My understanding is this.
Initialize a stack for tracking which row & column has a queen in it.
Place a queen on the first square, push its location onto the stack. Push (0,0); Then set a variable that the row has been filled. filled+;
3.Then Loop
check if the current row or column have a conflict with another queen.
a. no conflict. push to stack. increase the filled row variable. filled++; move up a row.
b. there is a conflict. Move right. col++;
c. cant move right anymore. pop the stack and set to row and col. subtract the filled. then move over. col++; and try again.
int main(){
bool board[8][8];
for(int i = 0; i < 8; i++){
for(int j = 0; j < 8; j++){
board[i][j] = false;}}
int row = 0, col = 0, filled = 0;
StackLi<int> rowStack;
StackLi<int> colStack;
rowStack.push(row);
colStack.push(col);
board[row][col] = true;
//cout << "push: " << "(" << row << "," << col << ")" << endl;
row++;
while(filled < 7)
{
if(!isSafe(board,row,col) )
{
filled++;
rowStack.push(row);
colStack.push(col);
board[row][col] = true;
//cout << "push: " << "(" << row << "," << col << ")" << endl;
if(filled > 8)
{
print(board);
return 0;
}
row++;
}
else{
col++;
//cout << "move: " << "(" << row << "," << col << ")" << endl;
}
if(col > 7)
{
row = rowStack.topAndPop();
col = colStack.topAndPop();
board[row][col] = false;
cout << "pop: " << "(" << row << "," << col << ")" << endl;
filled--;
}
}
return 0;
}
bool isSafe(bool board[8][8], int row, int col)
{
for(int i = 0; i < 8; i++)
{
if(board[row][i] || board[i][col]) return true;
}
for(int i = 0; (row - i)>=0 && (col-i) >= 0; i++)
{
if(board[row-i][col-i]) return true;
}
for(int i = 0; (row - i)<=8 && (col-i) >= 0; i++)
{
if(board[row+i][col+i]) return true;
}
return false;
}
#include <iostream>
using namespace std;
class Node {
public:
int data;
Node* next;
Node()
{
data = 0;
next = NULL;
}
};
class Stack {
Node* top;
public:
Stack()
{
top = NULL;
}
bool is_empty()
{
if (top == NULL)
return true;
else
return false;
}
void push(int item)
{
Node* new_node = new Node();
new_node->data = item;
if (is_empty())
{
new_node->next = NULL;
top = new_node;
}
else {
new_node->next = top;
top = new_node;
}
}
int pop() {
int value;
Node* delet_ptr = top;
value = top->data;
top = top->next;
delete delet_ptr;
return value;
}
};
bool isSafe(bool board[8][8], int row, int col)
{
for (int i = 0; i < 8; i++)
{
if (board[row][i] || board[i][col]) {return true;}
}
for (int r = row, c = col; r < 8 && c >=0; r++,c--)
{
if (board[r][c]) {return true;}
}
for (int r = row, c = col; r < 8 && c < 8; r++,c++)
{
if (board[r][c]) {return true;}
}
for (int r = row, c = col; r >= 0 && c >= 0; r--,c--)
{
if (board[r][c]) {return true;}
}
for (int r = row, c = col; r >= 0 && c < 8; r--,c++)
{
if (board[r][c]) {return true;}
}
return false;
}
int main() {
bool board[8][8];
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
board[i][j] = false;
}
}
int row = 0, col = 0, filled = 0;
Stack rowStack, colStack;
rowStack.push(row);
colStack.push(col);
board[row][col] = true;
cout << "push: " << "(" << row << " , " << col << ")\n" << endl;
row++;
while (filled < 7)
{
if (!isSafe(board, row, col))
{
filled++;
rowStack.push(row);
colStack.push(col);
board[row][col] = true;
cout << "push: " << "(" << row << " , " << col << ")" << endl;
row++;
col=0;
}else {
col++;
cout << "move: " << "(" << row << " , " << col << ")" << endl;
if (col > 7) {
row = rowStack.pop();
col = colStack.pop();
board[row][col] = false;
cout << "pop: " << "(" << row << " , " << col << ")" << endl;
col++;
filled--;
}
}
}
system("pause");
return 0;
}