I am trying to write an application, in which the user inputs an integer
1 = up,
2 = down
3 = left
4 = right and
x : moves along the 3x3 grid.
I am not sure what I have done wrong, so any help would be appreciated.
#include "stdafx.h"
#include <iostream>
using namespace std;
char player = 'x';
char grid[3][3] = {{ player, '.' ,'.'},{'.', '.', '.' },{'.', '.', '.' } };
void Draw() {
for (int row = 0; row <= 2; row++) {
for (int col = 0; col <= 2; col++) {
cout << grid[row][col];
}
cout << endl;
}
}
int main() {
int posX = 0;
int posY = 0;
int in;
Draw();
while (1) {
cin >> in;
if (in == 1) {
grid[posY][posX] = '.';
posY = posY - 1;
grid[posY][posX] = player;
}
else if (in == 2) {
grid[posY][posX] = '.';
posY = posY + 1;
grid[posY][posX] = player;
}
else if (in == 3) {
grid[posY][posX] = '.';
posX = posX - 1;
grid[posY][posX] = player;
}
else if (in == 4) {
grid[posY][posX] = '.';
posX = posX + 1;
grid[posY][posX] = player;
}
else {
grid[posY][posX] = player;
}
system("cls");
Draw();
}
cin.get();
return 0;
}
I have compile it and everything is ok.... But you must check if the player is on the max side of grid, and then if player want to move you must stop him, because of wall of course;>
Example :
while (1)
{
cin >> in;
if (in == 1)
{
if(posY>0) // HERE
{
grid[posY][posX] = '.';
posY = posY - 1;
grid[posY][posX] = player;
}
}
...
}
Related
I working on my project this project have a frame to [100] x [25] matrix and i try to add animation but my character is going left but it's not going right.
i tried with "counter" variable but its not work.
int counter = 1;
int counter2 = 1;
int left_border = 1;
int matris1 = sizeof(map)/100;
int matris2 = sizeof(map[0])/4;
int startx = 19;
int starty = 8;
while (true)
...
int right = 0, left = 0;
...
for (int a = 0; a < matris2; a++)
cout << "\n#"; //i have this because i make it square map.
for (int k = 0; k < matris1 - 2; k++)
{
if (left == 1)
{
if (((startx+2)-counter) == left_border)
{
counter = 0;
//cout << "SINIR!!"<< endl ;
}
if (k == (startx-counter) and a == starty)
{
counter += 1;
cout << "O";
}
else {
cout << " ";
}
}
else if (right == 1)
{
if (k == (startx+counter2) and a == starty)
{
counter2 += 1;
cout << "O";
}
its need to be going right but its not.
if you need full code.
https://codeshare.io/UbKVU
[![This is the map and "O" is the character]
https://i.stack.imgur.com/uyGQo.png
The code is very difficult to follow - you should have a coordinate system. I've made a simple example below. Update the player coordinate when a key is pressed and redraw the map x by y position, if the player is there then draw the 'O', otherwise if its a wall draw an 'X' (in this case), otherwise draw a space ' '.
using namespace std;
#include <iostream>
#include <conio.h>
#include <stdlib.h>
#define MAPW 15 // map width
#define MAPH 15 // map height
int map[MAPW][MAPH];
#define WALL 1
#define EMPTY 0
void initmap()
{
// just set the map to have walls around the border
for (int x = 0; x < MAPW; x++)
{
for (int y = 0; y < MAPH; y++)
{
if (x == 0 || y == 0 || x == (MAPW - 1) || y == (MAPH - 1))
map[x][y] = WALL;
else
map[x][y] = EMPTY;
}
}
}
int px = MAPW / 2; // player x
int py = MAPH / 2; // player y
void main()
{
initmap(); // initialize map
cout << "Press A/W/S/D to begin and move";
while (1)
{
if (kbhit()) // key pressed?
{
switch (getch()) // which key?
{
case 'a':
if (px > 0 && map[px - 1][py] != WALL) // can go left?
px--; // update x coordinate
break;
case 'd':
if (px < (MAPW-1) && map[px + 1][py] != WALL) // can go right?
px++; // update x coordinate
break;
case 'w':
if (py > 0 && map[px][py - 1] != WALL) // can go up?
py--; // update y coordinate
break;
case 's':
if (py < MAPH && map[px][py + 1] != WALL) // can go down?
py++; // update y coordinate
break;
}
// update map - clear screen and redraw
system("CLS");
// draw map each line
for (int y = 0; y < MAPH; y++)
{
for (int x = 0; x < MAPW; x++)
{
// its a wall?
if (map[x][y] == WALL)
cout << "X";
else
{
// is the player there?
if (x == px && y == py)
{
// draw the player
cout << "O";
}
else // empty space
cout << " ";
}
}
// next line
cout << "\n";
}
}
}
}
I am making a whack-a-mole game for my class but I am stuck on the basic controls. I setup a basic board, using an array with a border using ascii symbols, with O representing the holes and X the hammer. When I go to move the hammer, lets say to the right, I have to press it twice for the hammer to move and I don't know why. It has to go through the whole loop 2 times before moving the hammer the right way.
#include <iostream>
#include <windows.h>
using namespace std;
bool gamerunning = true;
const int num = 20; //width
const int num2 = 40; //height
int x, y, score, perx, pery;
int hole1x, hole1y;
int hole2x, hole2y;
int hole3x, hole3y;
int hole4x, hole4y;
void setup(){
x= 5;
y=5;
hole1x = 15;
hole1y = 5;
hole2x = 15;
hole2y = 10;
hole3x = 25;
hole3y = 5;
hole4x = 25;
hole4y = 10;
score = 0;
perx = 15;
pery = 6;
}
//creating board
void draw(){
system("cls");
int i,j;
char Layout[num][num2];
for (i=0;i<num;i++){
for (j=0;j<num2;j++){
//boarder for play area
if (i==0 && j==0) //Top Left
Layout [i][j] = 201;
else if( i==0 && j==num2-1) //top right
Layout [i][j] = 187;
else if(i==num-1 && j==0) //bottom left
Layout [i][j] = 200;
else if(i ==num-1 && j==num2-1) //bottom right
Layout [i][j] = 188;
else if (i==0 || i==num - 1)
Layout[i][j]=205;
else if(j==0 || j==num2-1)
Layout [i][j] = 186;
else
Layout[i][j]=' ';
//holes
if(i == hole1y && j == hole1x)
Layout[i][j]= 'O';
if(i == hole2y && j == hole2x)
Layout[i][j]= 'O';
if(i == hole3y && j == hole3x)
Layout[i][j]= 'O';
if(i == hole4y && j == hole4x)
Layout[i][j]= 'O';
//character
if(i == pery && j == perx)
Layout[i][j]= 'X';
cout << Layout[i][j];
}
cout << endl;
}
}
void input(){
if(GetAsyncKeyState(VK_RIGHT)){
if(perx<=15)
perx +=10;
}
if(GetAsyncKeyState(VK_LEFT)){
if(perx>=25)
perx -=10;
}
if(GetAsyncKeyState(VK_DOWN)){
if(pery<=10)
pery +=5;
}
if(GetAsyncKeyState(VK_UP)){
if(pery>=10)
pery -=5;
}
if(GetAsyncKeyState(VK_ESCAPE)){
gamerunning = false;
}
}
void logic(){
}
int main(){
setup();
while(gamerunning == true){
draw();
input();
logic();
system("pause>nul");
}
system("cls");
cout << "GAME OVER" << endl;
return 0;
}
Here :
while(gamerunning == true)
{
draw();
input();
system("pause>nul");
logic();
}
You first draw your game board then you get the input, drawing will not happen until the next time loop execution, so your drawing will not update.
You need to put first draw call outside the loop (for initial drawing) then inside the loop call draw after input. like this :
draw();
while(gamerunning == true)
{
input();
draw();
system("pause>nul");
logic();
}
beginner to C++ and attempting a dungeon crawler beginner task, upon testing one of the classes I found that printing the 2D array works, however if it is edited and printed, it resets and prints original values it was initialised with.
InitGrid is used to initialize the array.
class MAP
{
public:
/*
Difficulty used in number of enemies and traps created.
1-5 Difficulty
| 1 - Too easy | 2 - Easy | 3 - Normal | 4 - Hard | 5 - Insane |
*/
int Difficulty = Hard; //### Temporary, user selection needs implemented ###
int SpawnPos;
int TPosX; //Treasure Postion, used to checkwinstate.
int TPosY; //Treasure Postion, used to checkwinstate.
char Grid[MAPHeight][MAPWidth];
void InitGrid()
{
for (int y = 0; y < 9; y++) //Row loop
{
for (int x = 0; x < 14; x++) //Column loop
{
Grid[y][x] = { '.' };
}
}
}
void PrintMap()
{
for (int y = 0; y < 9; y++) //This loops on the rows.
{
for (int PrintX = 0; PrintX < 14; PrintX++) //This loops on the columns
{
cout << Grid[y][PrintX] << " ";
}
cout << endl;
}
}
void GenerateEnemies()
{
for (int i = 0; i < Difficulty; i++)
{
int TotEnemies = (Difficulty * 1.5);
for (TotEnemies; TotEnemies == 0; TotEnemies--)
{
int x = rand() % (MAPWidth - 1);
int y = rand() % (MAPHeight - 1);
if (Grid[y][x] == '.')
{
Grid[y][x] = '#';
}
else
{
GenerateEnemies();
}
}
}
}
// Generate Enemies
void GenerateTraps()
{
for (int i = 0; i < Difficulty; i++)
{
int TotTraps = (Difficulty * 1.5);
for (TotTraps; TotTraps == 0; TotTraps--)
{
int x = rand() % (MAPWidth - 1);
int y = rand() % (MAPHeight - 1);
if (Grid[y][x] == '.')
{
Grid[y][x] = 'T';
}
else
{
GenerateTraps();
}
}
}
}
void GenerateTreasure()
{
int x = rand() % MAPWidth;
int y = rand() % MAPHeight;
/*
Randomly selects spawn location
uses tmp variables to overwrite
that grid location.
*/
if (Grid[y][x] == '.')
{
Grid[y][x] = 'X';
}
else
{
GenerateTreasure();
}
TPosX = x;
TPosY = y;
}
};
//PLAYER CLASS
class PLAYER : public MAP
{
public:
int Health = (Difficulty * 1.5);
int PPosX;
int PPosY;
char Direction; //Use cin to get user input after map is updated, used in switch case to move player.
void GenerateSpawn()
{
int x = rand() % (MAPWidth - 1);
int y = rand() % (MAPHeight - 1);
/*
Randomly selects spawn location
uses tmp variables to overwrite
that grid location.
*/
Grid[y][x] = 'P';
PPosX = x;
PPosY = y;
}
void AllowMove(int y, int x)
{
if (Grid[y][x] == '.')
{
Grid[y][x] = '#';
}
else if (Grid[y][x] == 'X')
{
//GameWin();
}
else if (Grid[y][x] == '#')
{
//DamagePlayer();
}
else {}
}
void MovePlayer()
{
switch (Direction)
{
case 'w':
{
int x = PPosX;
int y = (PPosY + 1);
void AllowMove(int y, int x);
}
break;
case 'a':
{
int x = (PPosX - 1);
int y = PPosY;
void AllowMove(int y, int x);
}
break;
case 's':
{
int x = (PPosX);
int y = PPosY;
void AllowMove(int y, int x);
}
break;
case 'd':
{
int x = (PPosX + 1);
int y = PPosY;
void AllowMove(int y, int x);
}
break;
default:
cout << "invalid character, try again." << endl;
Sleep(5000);
//Call function to retry
}
}
};
//######### End #########
//Main Function
int main() {
srand(time(NULL)); //Used to seed rand() values.
SetConsoleTitle(TEXT("Dungeon Crawler"));
//Objects
MAP Map;
PLAYER Player;
Map.InitGrid();
Player.GenerateSpawn();
//Map.GenerateTreasure();
//Map.GenerateEnemies();
//Map.GenerateTraps();
Map.PrintMap();
cout << endl;
}
However, when I run these, I get the following image:
I've attempted debugging in visual studio using breakpoints and at some point it does set the grid value to 'P' but I couldn't find where I gets 'reset' for lack of a better term.
char Grid[MAPHeight][MAPWidth]; needs to be moved outside of the class as a global variable. Currently as the PLAYER class inherits from the MAPS class, when GenerateSpawn() edits the Grid that is created specific to the object linked to PLAYER.
When it is a global variable, it is separate, then when edited by GenerateSpawn() and called by void PrintMap() they both use the same Grid.
That way when it is printed to console it correctly prints out the map.
Answered my own question in case someone else stumbles upon this.
Run-Time Check Failure #2 Stack around the variable 'maze' were corrupted.
Whenever I compile and run my program, I receive this error whenever the program finishes running. I believe the problem is happening in my addPaths function in my implementation. I posted all my code just in case. This program is creating a maze and the addPaths function is "digging" the paths for the user to move through. The path direction is chosen at random and the paths are only drawn at even number spaces on the maze.
HEADER:
const int HEIGHT = 3;
const int WIDTH = 5;
class Coordinate
{
public:
int row, column;
};
class Maze
{
public:
Maze();
~Maze();
void buildMaze();
void displayMaze();
void addPaths();
void startGame();
void movePlayer(int);
bool solved();
int getKey();
void addDestinationToGrid();
private:
char grid[WIDTH][HEIGHT];
Coordinate player;
const static char PLAYER = 'P';
const static char DESTINATION = 'X';
const static char START = 'S';
const static char PATH = ' ';
const static char WALL = (char)219;
};
IMPLEMENTATION:
#include <iostream>
#include "maze.h"
#include <windows.h>
#include <stack>
using std::cout;
using std::endl;
Maze::Maze()
{
buildMaze();
}
Maze::~Maze()
{
cout << "yay";
}
void Maze::buildMaze()
{
for (int x = 0; x <= HEIGHT-1; x++)
{
for (int y = 0; y <= WIDTH-1; y++)
{
grid[x][y] = WALL;
//SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 4);
}
}
}
void Maze::displayMaze()
{
for (int x = 0; x <= HEIGHT-1; x++)
{
for (int y = 0; y <= WIDTH-1; y++)
{
cout << grid[x][y];
}
cout << endl;
}
}
void Maze::startGame()
{
int input;
do
{
input = getKey();
movePlayer(input);
} while (!solved());
}
bool Maze::solved()
{
return true;
}
void Maze::movePlayer(int direction)
{
if (direction == VK_UP || direction == VK_DOWN || direction == VK_LEFT || direction == VK_RIGHT)
{
COORD newCoord = { player.column + 1, player.row + 1 };
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), newCoord);
if (grid[player.row][player.column] == START)
{
cout << START;
}
else
{
cout << PATH;
}
}
}
int Maze::getKey()
{
int result = 0;
while (!solved() && result == 0)
{
short MAX_SHORT = 0x7FFF; //111111111111111
if (GetAsyncKeyState(VK_LEFT) & MAX_SHORT)
{
result = VK_LEFT;
}
else if (GetAsyncKeyState(VK_UP) & MAX_SHORT)
{
result = VK_UP;
}
else if (GetAsyncKeyState(VK_RIGHT) & MAX_SHORT)
{
result = VK_RIGHT;
}
else if (GetAsyncKeyState(VK_DOWN) & MAX_SHORT)
{
result = VK_DOWN;
}
}
return result;
}
void Maze::addPaths()
{
Coordinate currentLocation;
Coordinate startLocation;
//Coordinate endLocation; //not used yet
std::stack<Coordinate> myStack;
currentLocation.row = (((rand() % HEIGHT) / 2) * 2);
currentLocation.column = (((rand() % WIDTH) / 2) * 2);
startLocation = currentLocation;
grid[currentLocation.row][currentLocation.column] = START;
player = currentLocation;
do
{
bool canMoveUp = !(currentLocation.row == 0 || grid[currentLocation.row - 2][currentLocation.column] != WALL);
bool canMoveDown = !(currentLocation.row == HEIGHT - 1 || grid[currentLocation.row + 2][currentLocation.column] != WALL);
bool canMoveLeft = !(currentLocation.column == 0 || grid[currentLocation.row][currentLocation.column - 2] != WALL);
bool canMoveRight = !(currentLocation.column == WIDTH - 1 || grid[currentLocation.row][currentLocation.column + 2] != WALL);
if (canMoveUp || canMoveDown || canMoveLeft || canMoveRight)
{
myStack.push(currentLocation);
//choose random location to dig
bool moveFound = false;
while (moveFound != true)
{
int direction = rand() % 4;
if (direction == 0 && canMoveUp)
{
moveFound = true;
grid[currentLocation.row - 2][currentLocation.column] = PATH;
grid[currentLocation.row - 1][currentLocation.column] = PATH;
currentLocation.row -= 2;
}
else if (direction == 1 && canMoveDown)
{
moveFound = true;
grid[currentLocation.row + 2][currentLocation.column] = PATH;
grid[currentLocation.row + 1][currentLocation.column] = PATH;
currentLocation.row += 2;
}
else if (direction == 2 && canMoveLeft)
{
moveFound = true;
grid[currentLocation.row][currentLocation.column - 2] = PATH;
grid[currentLocation.row][currentLocation.column - 1] = PATH;
currentLocation.column -= 2;
}
else if (direction == 3 && canMoveRight)
{
moveFound = true;
grid[currentLocation.row][currentLocation.column + 2] = PATH;
grid[currentLocation.row][currentLocation.column - 2] = PATH;
currentLocation.column += 2;
}
}
}
else if (!myStack.empty())
{
currentLocation = myStack.top();
myStack.pop();
}
}
while (!myStack.empty());
addDestinationToGrid();
}
void Maze::addDestinationToGrid()
{
int randomRow = rand() % HEIGHT;
int randomColumn = rand() % WIDTH;
while (grid[randomRow][randomColumn] != PATH)
{
randomRow = rand() % HEIGHT;
randomColumn = rand() % WIDTH;
}
grid[randomRow][randomColumn] = DESTINATION;
}
MAIN:
#include <iomanip>
#include <iostream>
#include "maze.h"
using namespace std;
int main()
{
Maze maze;
maze.addPaths();
maze.displayMaze();
maze.startGame();
/*if (maze.solved())
{
cout << " You Win!";
}*/
}
There are two problems. One is that you are not consistent in the order you access elements of grid. It is declared grid[WIDTH][HEIGHT] but most (but not all) accesses use a HEIGHT based index first. This isn't causing your problems since WIDTH is greater than HEIGHT and you stay within the object's memory when doing normal accesses to it.
The problem is this line:
grid[currentLocation.row][currentLocation.column - 2] = PATH;
in the moveRight handler. The column offset should be + 1, not - 2. The way it is can cause you to write to memory before the first element of grid.
Okay so I am a college student and our professor gave us this code to examine, and I was wondering if there was another way to do this but for OS X. My professor is using a HANDLE which I barely understand what that is, the professor was telling me he create the HANDLE as a pointer to the output stream so what would be the equivalent to it for mac since we don't have #include Windows.h obviously. Everything you see in this code is my professor's, including the comments.
//This is an example of a simple platformer made in the console. This
//makes no claims as the best way of doing things as I created this
//live before a class (while taking suggestions from them).
#include <iostream>
#include <string>
#include <vector>
#include <Windows.h>
using namespace std;
const int MAX_ROWS = 20;
const int MAX_COLS = 60;
//this is a reference to cout (we got this when we changed the output color)
//we can use this to setCursorPosition
HANDLE output = GetStdHandle(STD_OUTPUT_HANDLE);
//this is the place that we can set the cursor to when we are not using it
COORD zero;
//basic cardinal directions
enum Direction
{
UP = 8,
DOWN = 2,
RIGHT = 6,
LEFT = 4,
NORTH = UP,
SOUTH = DOWN,
EAST = RIGHT,
WEST = LEFT
};
//each place on the gameboard is a tile (tiles in this game are 1 character in length, though they do not have to be)
class Tile
{
public:
char display;
bool isPassible;
COORD pos;
Tile(char d, bool b, int y, int x)
{
display = d;
isPassible = b;
pos.X = x;
pos.Y = y;
}
void Display()
{
SetConsoleCursorPosition(output, pos);
cout << display;
SetConsoleCursorPosition(output, zero);
}
};
class Player
{
public:
COORD pos;
char display;
int JumpAmt;
//player constructor (x and y are starting location)
Player(int x, int y)
{
pos.X = x;
pos.Y = y;
display = 'C';
JumpAmt = 0;
}
//This gets the input and decides how to use it (this should be called in the main game loop)
bool Act(vector<vector<Tile>> GameBoard)
{
bool didMove = false;
COORD oldPos;
oldPos.X = pos.X;
oldPos.Y = pos.Y;
if (GetAsyncKeyState(VK_RIGHT) & 0x8000)
{
//make sure the movement is not off the game board and that there is not a wall in the way
if (pos.X + 1 < MAX_COLS && GameBoard[pos.Y][pos.X + 1].isPassible)
{
//actually move the character
pos.X += 1;
didMove = true;
}
}
if (GetAsyncKeyState(VK_LEFT) & 0x8000)
{
if (pos.X - 1 > 0 && GameBoard[pos.Y][pos.X - 1].isPassible)
{
pos.X -= 1;
didMove = true;
}
}
//You can only jump if you are on the ground
if (pos.Y + 1 < MAX_ROWS && !(GameBoard[pos.Y + 1][pos.X].isPassible))
{
if (GetAsyncKeyState(VK_UP) & 0x8000)
{
if (pos.Y - 1 > 0 && GameBoard[pos.Y - 1][pos.X].isPassible)
{
pos.Y -= 1;
didMove = true;
JumpAmt = 4;
}
}
}
//When you are not jumping fall (gravity)
if (JumpAmt == 0)
{
if (pos.Y + 1 < MAX_ROWS && GameBoard[pos.Y + 1][pos.X].isPassible)
{
pos.Y += 1;
didMove = true;
}
}
//This is what happens during your jump
if (JumpAmt > 0)
{
JumpAmt--;
if (pos.Y - 1 > 0 && GameBoard[pos.Y - 1][pos.X].isPassible)
{
pos.Y -= 1;
didMove = true;
}
}
//If you did move anywhere then update the board
if (didMove)
{
Display(oldPos, GameBoard);
}
return didMove;
}
void Display()
{
//draw myself at my position
SetConsoleCursorPosition(output, pos);
cout << display;
SetConsoleCursorPosition(output, zero);
}
void Display(COORD fix, vector<vector<Tile>> GameBoard)
{
//clear my old position
GameBoard[fix.Y][fix.X].Display();
Display();
}
};
int main()
{
//zero is used after anything is drawn to reset the cursor (this should never be changed after this)
zero.X = 0;
zero.Y = 0;
//this is a 2 dimentional array of tiles
vector<vector<Tile>> GameBoard;
//init all the tiles to blank (we will later add in platforms and stuff over top of these)
for (int row = 0; row < MAX_ROWS; row++)
{
vector<Tile> thisRow;
for (int col = 0; col < MAX_COLS; col++)
{
thisRow.push_back(Tile(' ', true, row, col));
}
GameBoard.push_back(thisRow);
}
//Build the game specific tiles (in a perfect world these would be read in from a file)
GameBoard[4][2] = Tile('-', false,4,2);
GameBoard[4][3] = Tile('-', false, 4,3);
GameBoard[4][4] = Tile('-', false, 4,4);
GameBoard[4][5] = Tile('-', false, 4,5);
GameBoard[4][6] = Tile('-', false, 4,6);
GameBoard[7][9] = Tile('-', false, 7,9);
GameBoard[7][10] = Tile('-', false, 7,10);
GameBoard[5][10] = Tile('-', false, 5,10);
GameBoard[8][14] = Tile('*', false, 8, 14); //this marks the win square
//display the board once
for (int row = 0; row < MAX_ROWS; row++)
{
for (int col = 0; col < MAX_COLS; col++)
{
GameBoard[row][col].Display();
}
}
//Bob is our hero
Player bob = Player(3, 3);
while (true)
{
bob.Act(GameBoard);
bob.Display();
Sleep(50);
//if bob falls down he dies
if (bob.pos.Y > 18)
{
bob.pos.X = 3;
bob.pos.Y = 3;
//bob.display = 65 + rand() % 26;
}
//if bob gets here he wins
if (bob.pos.Y == 7 && bob.pos.X == 14)
{
COORD pos;
pos.Y = 20;
pos.X = 0;
SetConsoleCursorPosition(output, pos);
cout << "You are Awesome";
break;
}
}
COORD pos;
pos.Y = 21;
pos.X = 0;
SetConsoleCursorPosition(output, pos);
system("Pause");
return 0;
}