C++ Ignores While Loop Condition - c++

Recently, I created a text-based RPG in C++ and am now trying to incorporate a simple pathfinding algorithm. I have tested the algorithm itself and found that it works, however the while loop condition in the function started being ignored when I tried to incorporate it into the RPG. Here's my code:
int Strategy::path(char (&map)[25][100], int current_y, int current_x, int Target_x, int Target_y)
{
int i;
int n;
bool up=false;
bool down=false;
bool left=false;
bool right=false;
while (map[Target_y-1][Target_x]!='_'&&map[Target_y-1][Target_x]!='-'&&map[Target_y-1][Target_x]!='='&&map[Target_y+1][Target_x]!='_'&&map[Target_y+1][Target_x]!='-'&&map[Target_y+1][Target_x]!='='&&map[Target_y][Target_x-1]!='_'&&map[Target_y][Target_x-1]!='-'&&map[Target_y][Target_x-1]!='='&&map[Target_y][Target_x+1]!='_'&&map[Target_y][Target_x+1]!='-'&&map[Target_y][Target_x+1]!='=')
{
bool f=false;
int m=0;
system("cls");
printf("Time left: %i\n", time);
int x;
int y;
using namespace std;
for (y = 0; y<25; y++)
{
for (x = 0; x<100; x++)
{
cout << map[y][x];
}
printf("\n");
}
if (current_y > 0 && map[current_y - 1][current_x] ==' ')
{
map[current_y - 1][current_x] = '-';
}
if (current_y < 25 && map[current_y + 1][current_x] ==' ')
{
map[current_y + 1][current_x] = '-';
}
if (current_x > 0 && map[current_y][current_x - 1] ==' ')
{
map[current_y][current_x - 1] = '-';
}
if (current_x<100 && map[current_y][current_x + 1] ==' ')
{
map[current_y][current_x + 1] = '-';
}
map[current_y][current_x] = '=';
for (i = 0; i < 25; i++)
{
for (n = 0; n < 100; n++)
{
if (map[i][n] == '_')
{
current_y = i;
current_x = n;
f=true;
break;
}
}
if (f==true)
{
break;
}
}
for (i = 0; i < 25; i++)
{
for (n = 0; n < 100; n++)
{
if (map[i][n] == '-')
{
map[i][n] = '_';
m++;
}
}
}
if (m==0)
{
return 4;
}
}
bool r=false;
while (true)
{
int d=rand()%4;
if (map[Target_y + 1][Target_x] == '_' && d==0)
{
for (i = 0; i < 25; i++)
{
for (n = 0; n < 100; n++)
{
if (map[i][n] == '-'||map[i][n]=='_'||map[i][n]=='=')
{
map[i][n] = ' ';
}
}
}
return 0;
}
else if (map[Target_y - 1][Target_x] == '_' && d==1)
{
for (i = 0; i < 25; i++)
{
for (n = 0; n < 100; n++)
{
if (map[i][n] == '-'||map[i][n]=='_'||map[i][n]=='=')
{
map[i][n] = ' ';
}
}
}
return 1;
}
else if (map[Target_y][Target_x+1] == '_' && d==2)
{
for (i = 0; i < 25; i++)
{
for (n = 0; n < 100; n++)
{
if (map[i][n] == '-'||map[i][n]=='_'||map[i][n]=='=')
{
map[i][n] = ' ';
}
}
}
return 2;
}
else if (map[Target_y][Target_x-1] == '_' && d==3)
{
for (i = 0; i < 25; i++)
{
for (n = 0; n < 100; n++)
{
if (map[i][n] == '-'||map[i][n]=='_'||map[i][n]=='=')
{
map[i][n] = ' ';
}
}
}
return 3;
}
}
}

As all the other comments pointed out, you definitely should use a function in your while-condition. This really is an unreadable expression.
Maybe this will help you:
bool conditionValid(char (&map)[25][100], int target_x, int target_y)
{
char c='0';
for(int i = 0; i<4; ++i)
{
switch(i)
{
case 0: c = map[target_y-1][target_x]; break; //check the first character
case 1: c = map[target_y+1][target_x]; break; //check the second character
case 2: c = map[target_y][target_x-1]; break; //check the third character
case 3: c = map[target_y][target_x+1]; break; //check the forth character
}
switch(c)
{
case '_': std::cout << "aborting ... c" << i << "= " << c << std::endl; return false;
case '-': std::cout << "aborting ... c" << i << "= " << c << std::endl; return false;
case '=': std::cout << "aborting ... c" << i << "= " << c << std::endl; return false;
}
}
return true;
}
int Strategy::path(char (&map)[25][100], int current_y, int current_x, int Target_x, int Target_y)
{
int i;
int n;
bool up=false;
bool down=false;
bool left=false;
bool right=false;
while (conditionValid(map, Target_x, Target_y))
{
...
}
}
As soon as you understand, why your loop aborted, you can remove the std::cout's

Related

How to fix signal SIGSEGV, Segmentation fault

I'm getting an error message in Codeblocks C++ 'Program received signal SIGSEGV, Segmentation fault' in comparison between a vector element and a size of vector of vectors inside for loop (line 133 if (parz_przestrzenie[i] != parz_dystanse[i].size())).
Could anyone tell me why?
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int bloki_parz[100000], bloki_nieparz[100000];
int silnia(int n)
{
int liczba = 1;
for (int i = 1; i <= n; i++)
{
liczba *= i;
}
return liczba;
}
int main()
{
int n, czapka, wolne_miejsca = 0, wynik = 1;
vector<int> parz, nieparz, parz_przestrzenie, nieparz_przestrzenie, parz_przestrzenie2, nieparz_przestrzenie2;
vector<vector<int>> parz_dystanse;
vector<vector<int>> nieparz_dystanse;
cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> czapka;
if (i % 2 == 0)
{
parz.push_back(czapka);
}
else
{
nieparz.push_back(czapka);
}
}
int parz_size = parz.size(), nieparz_size = nieparz.size();
// sprawdzamy czy dane nie sÂą sprzeczne ; gdy zabraknie nam miejsc do rozmieszczania
vector<int> parz_duplicate = parz;
vector<int> nieparz_duplicate = nieparz;
parz_duplicate.erase(unique(parz_duplicate.begin(), parz_duplicate.end()), parz_duplicate.end());
nieparz_duplicate.erase(unique(nieparz_duplicate.begin(), nieparz_duplicate.end()), nieparz_duplicate.end());
int parz_dupl_size = parz_duplicate.size(), nieparz_dupl_size = nieparz_duplicate.size();
if (parz_size < nieparz_dupl_size)
{
cout << 0 << endl;
return 0;
}
if (nieparz_size < parz_dupl_size)
{
cout << 0 << endl;
return 0;
}
for (int i = 0; i < parz_size - 1; i++)
{
if (parz[i] == parz[i + 1])
{
bloki_parz[i + 1] = 1;
}
}
for (int i = 0; i < nieparz_size - 1; i++)
{
if (nieparz[i] == nieparz[i + 1])
{
bloki_nieparz[i] = 1;
}
}
for (int i = 0; i < parz_size; i++)
{
vector<int> bloczek;
for (int j = i; j < parz_size; j++)
{
if (parz[j] != parz[j + 1])
{
bloczek.push_back(parz[j]);
}
else
{
i += 1;
break;
}
}
if (bloczek.size() != 0)
{
parz_dystanse.push_back(bloczek);
}
}
int parz_dyst_size = parz_dystanse.size();
if (parz[parz_size - 1] != parz[parz_size - 2])
{
parz_dystanse[parz_dyst_size - 1].push_back(parz[parz_size - 1]);
}
for (int i = 0; i < nieparz_size; i++)
{
vector<int> bloczek;
for (int j = i; j < nieparz_size; j++)
{
if (nieparz[j] != nieparz[j + 1])
{
bloczek.push_back(nieparz[j]);
}
else
{
i += 1;
break;
}
}
if (bloczek.size() != 0)
{
nieparz_dystanse.push_back(bloczek);
}
}
int nieparz_dyst_size = nieparz_dystanse.size();
int current_wynik = 0;
for (int i = 0; i < nieparz_size; i++)
{
if (bloki_parz[i] == 0)
{
current_wynik++;
}
else
{
if (current_wynik != 0)
{
parz_przestrzenie.push_back(current_wynik);
}
current_wynik = 0;
}
}
parz_przestrzenie.push_back(current_wynik);
current_wynik = 0;
for (int i = 0; i < parz_size; i++)
{
if (bloki_nieparz[i] == 0)
{
current_wynik++;
}
else
{
if (current_wynik != 0)
{
nieparz_przestrzenie.push_back(current_wynik);
}
current_wynik = 0;
}
}
nieparz_przestrzenie.push_back(current_wynik);
int parz_przest_size = parz_przestrzenie.size(), nieparz_przest_size = nieparz_przestrzenie.size();
for (int i = 0; i < 1; i++)
{
if (parz_przestrzenie[i] != parz_dystanse[i].size())
{
wynik *= parz_przestrzenie[i];
wolne_miejsca++;
}
}
for (int i = 0; i < nieparz_przest_size; i++)
{
if (nieparz_przestrzenie[i] != nieparz_dystanse[i].size())
{
wynik *= nieparz_przestrzenie[i];
wolne_miejsca++;
}
}
cout << wynik * silnia(wolne_miejsca) << endl;
}
parz_dystanse is a vector of a vector. In this case the return value of parz_dystanse.size() is a long unsigned int, whereas an element of parz_przestrzenie is an int.
You need to make explicit that parz_dystanse.size() returns an int in order to make comparitions between integer expressions of different signedness.
This will fix that problem:
if (parz_przestrzenie[i] != (int)parz_dystanse[i].size())

unbeatable Tic Tac Toe

i'm trying to make a unbeatable tic tac toe for a side project and i can't make it right (i can actually beat it ironically).
It's actually a implementation of the MiniMax algorithm; i came with this code
#include <iostream>
#include <string>
using namespace std;
struct Move
{
int line, columns;
};
//Return the number of remainings turn based on the number of lest boxes
int remainingsTurns(char grid[3][3])
{
int remainingTurn = 0;
for (int k = 0; k < 3; k++)
{
for (int i = 0; i < 3; i++)
{
if (grid[k][i] == ' ')
{
remainingTurn++;
}
}
}
return remainingTurn;
}
//Print the grid on screen
void printGrid(char grid[3][3])
{
for (int k = 0; k < 3; k++)
{
for (int i = 0; i < 3; i++)
{
cout << "| " << grid[k][i] << " ";
}
cout << "|" << endl;
}
}
//Give a value to the board
int evaluateBoard(char grid[3][3])
{
//Check the board for lines
for (int k = 0; k < 3; k++)
{
if (grid[k][0] == grid[k][1] && grid[k][1] == grid[k][2])
{
if (grid[k][0] == 'x')
{
return +10;
}
else if (grid[k][0] == 'o')
{
return -10;
}
}
}
//Check the board for columns
for (int k = 0; k < 3; k++)
{
if (grid[0][k] == grid[1][k] && grid[1][k] == grid[2][k])
{
if (grid[0][k] == 'x')
{
return +10;
}
else if (grid[0][k] == 'o')
{
return -10;
}
}
}
//Check the board for diagonals
if (grid[0][0] == grid[1][1] && grid[0][0] == grid[2][2])
{
if (grid[0][0] == 'x')
{
return +10;
}
else if (grid[0][0] == 'o')
{
return -10;
}
}
if (grid[0][2] == grid[1][1] && grid[0][2] == grid[2][0])
{
if (grid[0][0] == 'x')
{
return +10;
}
else if (grid[0][0] == 'o')
{
return -10;
}
}
//if no ictory return 0
return 0;
}
// MiniMax algorithm
int miniMax(char grid[3][3], int turn, bool maxMove)
{
int score = evaluateBoard(grid);
if (score == 10)
{
return score;
}
if (score == -10)
{
return score;
}
//Check if the game is a tie
if (remainingsTurns(grid) == 0)
{
return 0;
}
if (maxMove)
{
int best = -1000;
for (int k = 0; k < 3; k++)
{
for (int i = 0; i < 3; i++)
{
if (grid[k][i] == ' ')
{
grid[k][i] = 'x';
best = max(best, miniMax(grid, turn + 1, !maxMove));
grid[k][i] = ' ';
}
}
}
return best;
}
else
{
int best = 1000;
for (int k = 0; k < 3; k++)
{
for (int i = 0; i < 3; i++)
{
if (grid[k][i] == ' ')
{
grid[k][i] = 'o';
best = min(best, miniMax(grid, turn + 1, !maxMove));
grid[k][i] = ' ';
}
}
}
return best;
}
}
Move playerMov(char grid[3][3])
{
Move playerMove;
int input = -1;
cout << "Enter the column you want to play (1, 2 or 3)" << endl;
cin >> input;
if (input == 1 || input == 2 || input == 3)
{
playerMove.columns = input-1;
input = -1;
}
else
{
cout << "Error, enter a valid number!" << endl;
playerMov(grid);
}
cout << "Enter the line you want to play (1, 2 or 3)" << endl;
cin >> input;
if (input == 1 || input == 2 || input == 3)
{
playerMove.line = input-1;
input = -1;
}
else
{
cout << "Error, enter a valid number!" << endl;
playerMov(grid);
}
return playerMove;
}
//return the best move using the MiniMax
Move findMove(char grid[3][3])
{
int best = -1000;
Move move;
move.line = -1;
move.columns = -1;
//Check all move to find if this move is the best possible move
for (int k = 0; k < 3; k++)
{
for (int i = 0; i < 3; i++)
{
if (grid[k][i] == ' ')
{
grid[k][i] = 'x';
int moveValue = miniMax(grid, 0, false);
grid[k][i] = ' ';
if (moveValue > best)
{
move.line = k;
move.columns = i;
}
}
}
}
return move;
}
int main()
{
char grid[3][3];
int turn = 0;
Move playerMove, algoMove;
for (int k = 0; k < 3; k++)
{
for (int i = 0; i < 3; i++)
{
grid[k][i] = ' ';
}
}
cout << "Welcome to the unbeatable Tic Tac Toe !" << endl;
do
{
printGrid(grid);
playerMove = playerMov(grid);
grid[playerMove.line][playerMove.columns] = 'o';
Move computerMove = findMove(grid);
grid[computerMove.line][computerMove.columns] = 'x';
} while (remainingsTurns(grid) > 0);
cout << endl;
}
but the movements of the algorithm doesn't seems right, it always choose the bottom right corner and i don't understand why...
This implementation is largely inspired by this article from Geek for Geek where i tried to steal the algorithm but i can't get it right to make it fit for single player.
What do i miss?
There are multiple bugs in your code:
You are checking the value of grid[0][0] in grid[0][2] == grid[1][1] && grid[0][2] == grid[2][0] case of the function evaluateBoard. It should be grid[0][2].
playerMov(grid); in the function playerMov should be return playerMov(grid);. Otherwise, the re-entered "correct" values will be dropped and (partly) uninitalized playerMov will be returned.
You should update best to moveValue when moveValue > best in the function findMove. (this should be the cause of the issue on your question)

I made the 2048 game but its not running as it was supposed to [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I decided to make the 2048 game. It is a very popular game for beginners.
The game is almost complete now but there's this error because of which my game keeps getting closed again and again as soon as I make my first move. I have tested a lot thoroughly and couldn't trace the error(s). I am new to programming.
#include<iostream>
#include<conio.h>
#include<ctime>
#include<string>
#include<cstdlib>
#include<fstream>
#include<Windows.h>
using namespace std;
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
const int limit = 4;
int board[limit][limit] = {};
int score = 0;
string name;
int highestScore;
void newGame();
void displayBoard();
bool gameOver();
int generateNum(); //generate random 2 or 4
void moveInDirection(int);
void generateNumInBoard();
int main()
{
int currentDirection;
char command, choice;
char direction[128];
string currentName;
direction['s'] = 0;
direction['w'] = 1;
direction['a'] = 3;
direction['d'] = 2;
ifstream inFile;
inFile.open("Score.txt");
inFile >> name >> highestScore;
inFile.close();
ofstream outFile;
outFile.open("Score.txt");
cout << "Please enter your name = ";
getline(cin, currentName);
newGame();
while (true)
{
system("CLS");
displayBoard();
cout << "\nEnter what you want to do = ";
command = _getche();
if (command == 'n')
{
newGame();
}
else if (command == 'e')
{
break;
}
else
{
currentDirection = direction[command];
moveInDirection(currentDirection);
}
if (gameOver())
{
if (score > highestScore)
{
outFile << currentName << " " << score;
}
do {
system("CLS");
cout << "YOU HAVE LOST :("
<< "Your score was " << score << endl
<< "Do you want to play again ( New game (n) / Exit (e) ) = ";
command = _getche();
} while (command != 'n' && command != 'e');
if (command == 'e')
{
exit(1);
}
}
}
return 0;
}
void newGame()
{
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
board[i][j] = 0;
}
}
board[0][0] = 2;
}
void displayBoard()
{
SetConsoleTextAttribute(hConsole, 9);
cout << "\n2048 THE GAME\n\n a = left , s = down , w = up , d = right , n = newgame , e = exit\n\n If all boxes get filled you lose\n\nBest player = " << name << " Best score = " << highestScore << "\n\n Your Score = " << score << "\n\n" << endl;
for (int i = 0; i < limit; i++)
{
cout << "\t\t|";
for (int j = 0; j < limit; j++)
{
if (board[i][j] == 0)
{
cout << " - |";
}
else
{
cout << " " << board[i][j] << " |";
}
}
cout << endl;
}
}
void moveInDirection(int currentDirection)
{
int count = 0;
bool flag = false;
if (currentDirection == 2)
{
while (count != 4)
{
for (int i = 0; i < limit; i++)
{
for (int j = limit - 1; j > 0; j--)
{
if ((board[i][j] == board[i][j - 1]) && board[i][j] != 0 && board[i][j - 1] != 0)
{
board[i][j] += board[i][j - 1];
board[i][j - 1] = 0;
score += board[i][j];
}
else if ((board[i][j] == 0) && (board[i][j - 1] != 0))
{
flag = true;
swap(board[i][j], board[i][j - 1]);
}
}
}
count++;
}
if (flag)
{
generateNumInBoard();
}
}
else if (currentDirection == 3)
{
while (count != 4)
{
for (int i = 0; i < limit; i++)
{
for (int j = 0; j < limit - 1; j++)
{
if ((board[i][j] == board[i][j + 1]) && board[i][j] != 0 && board[i][j + 1] != 0)
{
board[i][j] += board[i][j + 1];
board[i][j + 1] = 0;
score += board[i][j];
}
else if ((board[i][j] == 0) && (board[i][j + 1] != 0))
{
flag = true;
swap(board[i][j], board[i][j + 1]);
}
}
}
count++;
}
if (flag)
{
generateNumInBoard();
}
}
else if (currentDirection == 1)
{
while (count != 4)
{
for (int i = 0; i < limit - 1; i++)
{
for (int j = 0; j < limit; j++)
{
if ((board[i][j] == board[i + 1][j]) && board[i][j] != 0 && board[i + 1][j] != 0)
{
board[i][j] += board[i + 1][j];
board[i + 1][j] = 0;
score += board[i][j];
}
else if ((board[i][j] == 0) && (board[i + 1][j] != 0))
{
flag = true;
swap(board[i][j], board[i + 1][j]);
}
}
}
count++;
}
if (flag)
{
generateNumInBoard();
}
}
else if (currentDirection == 0)
{
while (count != 4)
{
for (int i = limit - 1; i >= 0; i--)
{
for (int j = 0; j < limit; j++)
{
if ((board[i][j] == board[i - 1][j]) && board[i][j] != 0 && board[i - 1][j] != 0)
{
board[i][j] += board[i - 1][j];
board[i - 1][j] = 0;
score += board[i][j];
}
else if ((board[i][j] == 0) && (board[i - 1][j] != 0))
{
flag = true;
swap(board[i][j], board[i - 1][j]);
}
}
}
count++;
}
if (flag)
{
generateNumInBoard();
}
}
}
int generateNum()
{
srand(time(NULL));
int randomNum = rand() % 4;
if (randomNum <= 2)
{
return 2;
}
else
{
return 4;
}
}
void generateNumInBoard()
{
bool flag = true;
for (int i = 0; i < limit; i++)
{
for (int j = 0; j < limit; j++)
{
if (board[i][j] == 0)
{
board[i][j] = generateNum();
flag = false;
break;
}
}
if (flag == false)
{
break;
}
}
}
bool gameOver()
{
for (int i = 0; i < limit; i++)
{
for (int j = 0; j < limit; j++)
{
if (board[i][j] == 0)
{
return true;
}
}
}
return false;
}
You made a small blunder at the fucntion gameOver() as you are making the game end if the compiler finds any 0 in the 2D array and you are display the zero as - in front end , You just need to make he false part true and viceversa.The game will work AOK :-)
bool gameOver()
{
for (int i = 0; i < limit; i++)
{
for (int j = 0; j < limit; j++)
{
if (board[i][j] == 0)
{
return false; //You need to make this false to not end game as soon as it starts
}
}
}
return true; //You need to make this true as the end condition
}

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.

Why is my simple recursive method's final return value always off by 1?

I'm attempting to create a text-based version of this game.
Code:
#include <iostream>
#include <vector>
#include <ctime>
class Clickomania {
public:
Clickomania();
std::vector<std::vector<int> > board;
int move(int, int);
bool isSolved();
void print();
void pushDown();
bool isValid();
};
Clickomania::Clickomania()
: board(12, std::vector<int>(8,0)) {
srand((unsigned)time(0));
for(int i = 0; i < 12; i++) {
for(int j = 0; j < 8; j++) {
int color = (rand() % 3) + 1;
board[i][j] = color;
}
}
}
void Clickomania::pushDown() {
for(int i = 0; i < 8; i++) {
for(int j = 0; j < 12; j++) {
if (board[j][i] == 0) {
for(int k = j; k > 0; k--) {
board[k][i] = board[k-1][i];
}
board[0][i] = 0;
}
}
}
}
int Clickomania::move(int row, int col) {
bool match = false;
int totalMatches = 0;
if (row > 12 || row < 0 || col > 8 || col < 0) {
return 0;
}
int currentColor = board[row][col];
board[row][col] = 0;
if ((row + 1) < 12) {
if (board[row+1][col] == currentColor)
{
match = true;
totalMatches++;
totalMatches += move(row+1, col);
}
}
if ((row - 1) >= 0) {
if (board[row-1][col] == currentColor) {
match = true;
totalMatches++;
totalMatches += move(row-1, col);
}
}
if ((col + 1) < 8) {
if (board[row][col+1] == currentColor) {
match = true;
totalMatches++;
totalMatches += move(row, col+1);
}
}
if ((col - 1) >= 0) {
if (board[row][col-1] == currentColor) {
match = true;
totalMatches++;
totalMatches += move(row, col-1);
}
}
return totalMatches;
}
void Clickomania::print() {
for(int i = 0; i < 12; i++) {
for(int j = 0; j < 8; j++) {
std::cout << board[i][j];
}
std::cout << "\n";
}
}
int main() {
Clickomania game;
game.print();
int row;
int col;
std::cout << "Enter row: ";
std::cin >> row;
std::cout << "Enter col: ";
std::cin >> col;
int numDestroyed = game.move(row,col);
game.print();
std::cout << "Destroyed: " << numDestroyed << "\n";
}
The method that is giving me trouble is my "move" method. This method, given a pair of coordinates, should delete all the squares at that coordinate with the same number and likewise with all the squares with the same number connected to it.
If you play the link I gave above you'll see how the deletion works on a click.
int Clickomania::move(int row, int col) {
bool match = false;
int totalMatches = 0;
if (row > 12 || row < 0 || col > 8 || col < 0) {
return 0;
}
int currentColor = board[row][col];
board[row][col] = 0;
if ((row + 1) < 12) {
if (board[row+1][col] == currentColor) {
match = true;
totalMatches++;
totalMatches += move(row+1, col);
}
}
if ((row - 1) >= 0) {
if (board[row-1][col] == currentColor) {
match = true;
totalMatches++;
totalMatches += move(row-1, col);
}
}
if ((col + 1) < 8) {
if (board[row][col+1] == currentColor)
{
match = true;
totalMatches++;
totalMatches += move(row, col+1);
}
}
if ((col - 1) >= 0) {
if (board[row][col-1] == currentColor) {
match = true;
totalMatches++;
totalMatches += move(row, col-1);
}
}
return totalMatches;
}
My move() method above works fine, as in it will delete the appropriate "blocks" and replace them with zeros, however the number of destroyed (value returned) is always one off (too small). I believe this is because the first call of move() isn't being counted, but I don't know how to differentiate between the first call or subsequent calls in that recursive method.
How can I modify my move() method so it returns the correct number of destroyed blocks?
It looks like you're incrementing totalMoves in the wrong place(s). You should count the match at the point where you set board[r][c] = 0 and remove the other references to totalMoves++.
You are right that the first call isn't being counted, it's only counting the recursive calls.
0 based indexing. You dont want to check > you want >=
you wanna check row >= 12 col >= 8