Marking path in my maze - c++

Im trying to mark the path through the maze. I'm stucked at this point. It only mark one way to the right. But the position when i write it out is X=1 Y=2. Its really strange. My idea was to make a while loop for the if statements but then the if statements not even run.. Please give me some ideas.
if (strcmp(argv[1], "-input") == 0)
{
ifstream ifs(argv[2]);
if(!ifs)
{
cout << "Felaktig textfil";
}
vector<vector<char>> maze;
vector<vector<char>> path;
string line;
unsigned int j=0;
while (!ifs.eof())
{
getline(ifs, line);
maze.push_back(vector<char>());
for (int i=0; i < line.size(); i++)
{
maze[j].push_back(line[i]);
}
j++;
}
//cout << maze.size();
int startX,startY;
for (int i = 0; i < maze.size(); i++)
{
for (int j = 0; j < maze[i].size(); j++)
{
if (maze[i][j] == 'S')
{
startX = j;
startY = i;
break;
}
}
}
if (startX + 1 < maze.size() && maze[startX + 1][startY] != '*')
{
startX++;
maze[startY][startX]='x';
}
if (startX - 1 > 0 && maze[startX - 1][startY] != '*')
{
startX++;
maze[startY][startX] = 'x';
}
if (startY - 1 > 0 && maze[startX][startY - 1] != '*')
{
startY--;
maze[startY][startX] = 'x';
}
if (startY + 1 < maze.size() && maze[startX][startY + 1] != '*')
{
startY++;
maze[startY][startX]='x';
}
if (maze[startY][startX]=='X')
{
cout << "done";
}
cout << startX <<startY << endl;
PrintMaze(maze);
}

Related

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.

Looping through arrays, up and left direction work, down and right direction returning error?

Sorry this question isn't worded very well, i'm not exactly sure how to ask it.
This statement works correctly
if (direction == 'w' || direction == 'W')
{
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < columns; j++)
{
if (board[i][j] == playerTile)
{
if (board[i-1][j] == ' ')
{
board[i - 1][j] = playerTile;
board[i][j] = ' ';
}
else
{
std::cout << "Invalid Move" << std::endl;
_getch();
}
}
}
}
}
while this one causes invalid error, and the player moves to the bottom of the board, I think it's a problem to do with the [i+1] section, as when its changed to [i - 1]; like the previous if statement it works
else if (direction == 's' || direction == 'S')
{
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < columns; j++)
{
if (board[i][j] == playerTile)
{
if (board[i + 1][j] == ' ')
{
board[i + 1][j] = playerTile;
board[i][j] = ' ';
}
else
{
std::cout << "Invalid Move" << std::endl;
_getch();
}
}
}
}
}
Your safest solution is to test your array expressions before you use them:
if (i > 0)
{
if (board[i-1][j] /*... */
and
if ((i + 1) < rows)
{
if (board[i+1][j] /* ... */
This should demonstrate why you are seeing issues in your code.

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