So I'm currently working on a small project named dungeon crawl, where the user controls a char, player, and tries to reach another char, treasure. So far I have been able to program this but every time I print the board, it prints another game board right below the previous one! I want the board to constantly update the position of the player, not move the player and then print out a whole new board! I know this is a logic error but I cannot seem to find an answer, thanks in advance guys:
class Player
{
public:
int posX = 5;
int posY = 10;
char avatar = 'G';
};
class Treasure
{
public:
int posX = 2;
int posY = 10;
char avatar = 'X';
};
char board[10][20];
char player_move = 0;
bool player_win = 0;
Player p;
Treasure t;
void fill_board()
{
for (int i = 0; i < 10; ++i)
{
for (int j = 0; j < 20; ++j)
board[i][j] = '.';
}
}
void print_board()
{
for (int i = 0; i < 10; ++i)
{
for (int j = 0; j < 20; ++j)
{
cout << board[i][j];
}
cout << endl;
}
}
void set_player()
{
board[p.posX][p.posY] = p.avatar;
}
void erase_board(char b[][20])
{
for (int i = 0; i < 20; ++i)
{
for (int j = 0; j < 40; ++j)
board[i][j] = 0;
}
}
int main()
{
// Make board
fill_board();
// Set initial player position
board[p.posX][p.posY] = p.avatar;
// Set treasure position
board[t.posX][t.posY] = t.avatar;
// Start of game
player_win = false;
cout << "Welcome to dungeon crawl! To move press 'w', 'a', 's' , 'd' " << endl;
cout << endl;
//Prints board
print_board();
//Player movement
while (player_win == false)
{
cin >> player_move;
switch (player_move)
{
case 'w':
board[p.posX][p.posY] = '.';
p.posX -= 1;
break;
case 's':
board[p.posX][p.posY] = '.';
p.posX += 1;
break;
case 'a':
board[p.posX][p.posY] = '.';
p.posY -= 1;
break;
case 'd':
board[p.posX][p.posY] = '.';
p.posY += 1;
break;
}
set_player();
print_board();
// Check if player has won
if (p.posX == t.posX && p.posY == t.posY)
player_win = true;
}
cout << "\nCongratulations you win!!" << endl;
return 0;
}
Related
I am a beginner in c++ and i made my first game, a snake game. I made it without any graphics library.
So far the things were good, my snake was just running fine and eating the fruit and score is also increasing.
At the moment my snake just runs while the key is pressed, but now I want to run my snake continuously and just change its direction with keys as we have seen in old snake games.
So far I have tried many things from my side, like a loop and all, but the things just didn't work in the way I wanted it to be.
There is my code-
#include<iostream>
#include<conio.h>
#include<Windows.h>
using namespace std;
bool gameOver;
const int width = 20;
const int height = 20;
int x, y, fruitX, fruitY, score;
int tailX[100], tailY[100];
int n_Tail;
enum eDirection {STOP = 0, LEFT , RIGHT ,UP , DOWN};
eDirection dir;
void setup()
{
gameOver = false;
dir = STOP;
x = width / 2;
y = height / 2;
fruitX = rand() % width;
fruitY = rand() % height;
score = 0;
}
void draw()
{
system("cls");
for(int i = 0 ;i < width+1; i++)
{
cout << "#"; //for Upper wall
}
cout << "\n";
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width ; j++)
{
if (j==0)
{
cout <<"#";
}
if (i == y && j == x)
{
cout <<"0";
}
else if (i == fruitY && j == fruitX)
{
cout <<"f";
width - 1;
}
else if (j== width -1)
{
cout << "#";
}
else
{
bool print = false;
for (int k = 0; k <n_Tail; k++)
{
if (tailX[k] == j && tailY[k] == i )
{
cout << "o";
print = true;
}
}
if (!print)
{
cout <<" ";
}
}
}
cout << "\n";
}
for (int i = 0; i < width+1; i++)
{
cout << "#"; //for lower wall
}
cout <<"\n";
cout << "Score = " << score;
}
void input()
{
switch (_getch())
{
case 'a': dir = LEFT;
break;
case 'w': dir = UP;
break;
case 's': dir = DOWN;
break;
case 'd': dir = RIGHT;
break;
}
}
void logics()
{
int prevX = tailX[0];
int prevY = tailY[0];
int prev2X, prev2Y;
tailX[0] = x;
tailY[0] = y;
for (int i = 1; i < n_Tail; i++)
{
prev2X = tailX[i];
prev2Y = tailY[i];
tailX[i] = prevX;
tailY[i] = prevY;
prevX = prev2X;
prevY = prev2Y;
}
switch (dir)
{
case LEFT:
x--;
break;
case RIGHT:
x++;
break;
case UP:
y--;
break;
case DOWN:
y++;
break;
default:
y--;
}
for (int i = 0; i < n_Tail; i++)
{
if (tailX[i] == x && tailY[i] == y)
{
gameOver = true;
}
}
//if (x> width||x<0||y>height||y<0)
//{
//gameOver = true;
//}
if (x > width-2)x = 0; else if (x < 0)x = width - 2;
if (y > height-1)y = 0; else if (y < 0)y = height - 1;
{
}
if (x == fruitX && y == fruitY)
{
score = score + 10;
fruitX = rand() % width;
fruitY = rand() % height;
n_Tail++;
}
}
int main()
{
setup();
while (!gameOver)
{
draw();
input();
logics();
Sleep(10);
}
}
someone please help me with this so i can continue learning c++ peacefully.
As I'm sure you noticed when you used your debugger.
No? No debugger? This is your essential read!
You're using _getch to read the input.
getch is blocking - meaning it will wait until you press a key. It's not really what you want.
This post explains how to make a non-blocking version.
I am writing a snake game, and I have been able to produce a complete result that works as planned.
However, the game seems to randomly crash. I hit another command and the game closes even with the GameOver conditions are not met.
I have attached the code:
#include <iostream>
#include <conio.h>
#include <windows.h>
using namespace std;
bool GameOver;
const int width = 20;
const int height = 20;
int x, y, fruitX, fruitY, score;
int tailX[100], tailY[100];
int nTail;
enum Direction { STOP = 0, LEFT, RIGHT, UP, DOWN};
Direction dir;
int Setup()
{
GameOver = false;
dir = STOP;
x = width / 2;
y = height / 2;
fruitX = rand() % width;
fruitY = rand() % height;
score = 0;
return 0;
}
int Draw()
{
system("cls"); //system("clear");
for (int i = 0; i < width+2; i++)
cout << "#";
cout << endl;
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
if (j == 0)
cout << "#";
if (i == y && j == x)
cout << "O";
else if (i == fruitY && j == fruitX)
cout << "F";
else
{
bool print = false;
for (int k = 0; k < nTail; k++)
{
if (tailX[k] == j && tailY[k] == i)
{
cout << "o";
print = true;
}
}
if (!print)
cout << " ";
}
if (j == width - 1)
cout << "#";
}
cout << endl;
}
for (int i = 0; i < width+2; i++)
cout << "#";
cout << "\n";
cout << "Score:" << score << "\n";
return 0;
}
int Input()
{
if (_kbhit())
{
switch (_getch())
{
case 'a':
dir = LEFT;
break;
case 'd':
dir = RIGHT;
break;
case 'w':
dir = UP;
break;
case 's':
dir = DOWN;
break;
case 'x':
gameOver = true;
break;
}
}
return 0;
}
int Logic()
{
int prevX = tailX[0];
int prevY = tailY[0];
int prev2X, prev2Y;
tailX[0] = x;
tailY[0] = y;
for (int i = 1; i < nTail; i++)
{
prev2X = tailX[i];
prev2Y = tailY[i];
tailX[i] = prevX;
tailY[i] = prevY;
prevX = prev2X;
prevY = prev2Y;
}
switch (dir)
{
case LEFT:
x--;
break;
case RIGHT:
x++;
break;
case UP:
y--;
break;
case DOWN:
y++;
break;
default:
break;
}
for (int i = 0; i < nTail; i++)
if (tailX[i] == x && tailY[i] == y)
GameOver = true;
if (x == fruitX && y == fruitY)
{
score += 10;
fruitX = rand() % width;
fruitY = rand() % height;
nTail++;
}
return 0;
}
int main()
{
Setup();
while (!GameOver)
{
Draw();
Input();
Logic();
Sleep(50);
}
return 0;
}
Your tailX/tailY arrays have a capacity of 100, but you don't enforce a limit on how large nTail gets. So when nTail becomes larger than 100, the behaviour of your program becomes undefined and may randomly crash.
But really, you should 1) learn how to use a debugger, and 2) get a more modern C++ compiler. Very few here would be able to compile or test this.
I'm keeping track of a character's position on a game board through the use of a multidimensional array (board[10][20]). To allow for user movement, I have created a method, movePlayer(), that modifies the value of the index of where 'G' is located.
Whenever I do this, the character 'G' does move, but the previous location of 'G' remains on the gameboard, so there are two 'G's. My question is: How can I move an element (G) in a multidimensional array?
Main Function:
char userInput;
int main()
{
Game obj1;
cout << "New Game (y/n)" << endl;
cin >> userInput;
if(userInput == 'y')
{
obj1.gameBoard();
obj2.movePlayer();
}
}
Game(Class).cpp:
Game::Game()
{
for(int x = 0; x < 10 ; x++)
{
for(int y = 0; y < 20 ; y++)
{
board[x][y]= '.';
}
}
player = 'G';
treasure = 'X';
srand(time(0));
p_Pos1X = rand()%10;
p_Pos1Y = rand()%20;
t_Pos1X = rand()%10;
t_Pos1Y = rand()%20;
endSwitch = 0;
}
void Game::gameBoard()
{
printBoard(p_Pos1X,p_Pos1Y);
}
void Game::printBoard(int px, int py)
{
for(int x = 0; x < 10; x++)
{
for(int y = 0; y < 20 ; y++)
{
board[px][py] = player;
board[t_Pos1X][t_Pos1Y] = treasure;
cout << board[x][y] ;
}
cout << endl;
}
}
void Game:: movePlayer()
{
cin >> playerM;
switch(playerM)
{
case 'W':
case 'w':
movePlayerUp(p_Pos1X);
}
}
void Game::movePlayerUp(int m)
{
m = m - 1;
printBoard(m,p_Pos1Y);
}
If the objetive of the project is not more than a dots matrix and a G reaching a X you dont neds to store a matrix, of course following your approach the code below I hope to be the solution the change is in the printBoard function
Game::Game()
{
for(int x = 0; x < 10 ; x++)
{
for(int y = 0; y < 20 ; y++)
{
board[x][y]= '.';
}
}
player = 'G';
treasure = 'X';
srand(time(0));
p_Pos1X = rand()%10;
p_Pos1Y = rand()%20;
t_Pos1X = rand()%10;
t_Pos1Y = rand()%20;
endSwitch = 0;
}
void Game::gameBoard()
{
printBoard(p_Pos1X,p_Pos1Y);
}
void Game::printBoard(int px, int py)
{
for(int x = 0; x < 10; x++)
{
for(int y = 0; y < 20 ; y++)
{
if(x==px && y==py)
{
cout << player ;
}else if(x== t_Pos1X && y== t_Pos1Y ){
cout << treasure;
}else{
cout << board[x][y] ;
}
}
cout << endl;
}
}
void Game:: movePlayer()
{
cin >> playerM;
switch(playerM)
{
case 'W':
case 'w':
movePlayerUp(p_Pos1X);
}
}
void Game::movePlayerUp(int m)
{
m = m - 1;
printBoard(m,p_Pos1Y);
}
Why not just put a '.' in the player's position just before moving him to the new one?
Hi there I am writing a small console game for school. The problem if have is that pushing 'w' and 'a' works (they minus 1 to the row or col element of 2d array) but the 'd' and 's' do not work (they add 1 to the row or col element of 2d array). If you try the code, you will notice that pushing s or d will make the screen glitch out.
Please refer to Move() and Update() of the CGame class.
TY
#include <iostream>
#include <string>
#include <conio.h>
#include <ctime>
#include <cstdlib>
using namespace std;
const char PLAYER = 'H';
const char WALLS = '=';
const int ROWS = 20;
const int COLS = 50;
//Map class generates map, player and enemies
class CMap{
public:
char m_cMap[20][50];
//Map constructor
CMap(int _row, int _col){
//Spawn boarders
for (int i = 0; i < ROWS; i++){
for (int j = 0; j < COLS; j++){
if (i == 0 || i == ROWS - 1){
m_cMap[i][j] = WALLS;
}else if (j == 0 || j == COLS - 1){
m_cMap[i][j] = WALLS;
}else{
m_cMap[i][j] = ' ';
}
}
}
//Spawn player
m_cMap[_row][_col] = PLAYER;
}
};
class CGame{
private:
void Move(CMap& _map, char _move, int _i, int _j){
_map.m_cMap[_i][_j] = ' ';
switch (_move){
case 'w':
case 'W':
_i--;
break;
case 's':
case 'S':
_i++;
break;
case 'a':
case 'A':
_j--;
break;
case 'd':
case 'D':
_j++;
break;
default:
break;
}
_map.m_cMap[_i][_j] = PLAYER;
}
public:
//Functions for the main gameloop
void Update(CMap& _map, char _move){
for (int i = 0; i < ROWS; i++){
for (int j = 0; j < COLS; j++){
//Move Player
if (_map.m_cMap[i][j] == PLAYER){
Move(_map, _move, i, j);
}
//Move Enemies...
}
}
}
void Check(CMap _map){}
void Display(CMap _map){
system("CLS");
for (int i = 0; i < ROWS; i++){
for (int j = 0; j < COLS; j++){
cout << _map.m_cMap[i][j];
}
cout << endl;
}
}
};
int main(){
//Generate random numbers for player spawn
srand(time(0));
int randRow = (rand() % 17) + 1;
int randCol = randRow + 20;
//Instantiate the game and map objects
CGame game;
CMap map(randRow, randCol);
//Game loop
bool gg = false;
while (!gg){
//PlayerController
char move = 0;
if (_kbhit){
move = _getch();
}
game.Update(map, move);
//game.Check(map);
game.Display(map);
}
}
The problem is that when you move your player you don't break the cycles. And they move it again since the player gets detected again. Modify your Update function like this:
//Functions for the main gameloop
void Update(CMap& _map, char _move){
bool moved = false;
for (int i = 0; i < ROWS; i++){
for (int j = 0; j < COLS; j++){
//Move Player
if (_map.m_cMap[i][j] == PLAYER){
Move(_map, _move, i, j);
moved = true;
break;
}
//Move Enemies...
}
if (moved)
break;
}
}
I wrote a simple Langtons Ant in C++ (console). But (dont really know why) I'm getting a core dumped every time I run my program:
#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;
int main()
{
srand(time(NULL));
bool endGame = false;
enum compass {north, east, south, west};
compass dir = north;
int x = 0, y = 0;
int n = 30, m = 30;
int **board = new int*[n];
for(int i = 0; i <n; i++)
board[i] = new int[m];
for(int i=0; i<n; i++)
for(int j=0; j<m; j++)
board[i][j] = rand()%2;
long count = 0;
while(!endGame)
{
for(int i = 0; i < n; i++)
{
for(int j = 0; j < m; j++)
{
//Print board
if(board[i][j] == 0)
cout << '+';
else
cout << '#';
}
cout << endl;
}
//Ant
if (board[x][y] == 0)
{
board[x][y] = 1;
switch (dir){
case north:
dir = east;
x = ((x+1)%m);
break;
case east:
dir = south;
y = ((y-1) % n);
break;
case south:
dir = west;
x = ((x-1) % m);
break;
case west:
dir = north;
y = ((y+1) %n);
break;
}
}else
{
board[x][y] = 0;
switch(dir){
case north:
dir = west;
x = ((x-1) % m);
break;
case west:
dir = south;
y = ((y-1) % n);
break;
case south:
dir = east;
x = ((x+1)%m);
break;
case east:
dir = north;
y = ((y+1) %n);
break;
}
}
cout << endl << count << endl;
count++;
cin.sync();
cin.get();
}
cin.sync();
cin.get();
return 0;
}
How can I get rid of this error?
It's probably use of modulo like this:
x = ((x-1) % m);
Keep in mind negative % positive = negative, meaning you can get out of bounds.