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.
Related
I'm a beginner in c++ so I started making a snake game in c++. But just as I complete the program i run into a problem and i just cant find the fix. When the snake picks up the fruit, it generates a segment, but the first segment doesn't follow the snake. The next segments do follow the snake. Any help to the solution is really appreciated.
#include <iostream>
#include <conio.h>
#include <windows.h>
using namespace std;
bool gameOver;
const int width = 40;
const int height = 40;
int x, y, fruitX, fruitY, score;
int tailX[100], tailY[100]; // snail coordinates
int nTail;
enum eDirection {STOP = 0, LEFT,RIGHT,UP,DOWN}; //controls for snake
eDirection dir;
//set fruit position and snake position
void setup(){
gameOver = false;
dir = STOP;
x = width / 2;
y = width / 2;
fruitX = rand() % width;
fruitY = rand() % height;
}
//draw the map
void draw(){
system("cls");
for(int i = 0; i < width+2; i++)
cout << "#";
std::cout << endl;
for(int i = 0; i < height; i++){
for(int j = 0; j < width; j++){
if (j == 0){
std::cout << "|";
}
if(i == y && j == x){
std::cout << "O";
} else if (i == fruitY && j == fruitX) {
std::cout << "F";
} else {
bool segment = false;
for(int l = 0; l < nTail; l++){
if (tailX[l] == j && tailY[l] == i){
std::cout << "o";
segment = true;
};
}
if(!segment){
std::cout << " ";
}
}
if(j == width-1) {
std::cout << "|";
}
}
std::cout << endl;
}
for(int i = 0; i < width+2; i++)
cout << "#";
std::cout << endl;
//display score
std::cout << " Score: " << score << endl;
}
//set snake direction
void movement(){
if(_kbhit()){
switch(_getch()){
case 'a':
dir = LEFT;
break;
case 'w':
dir = UP;
break;
case 's':
dir = DOWN;
break;
case 'd':
dir = RIGHT;
break;
case 'x':
gameOver = true;
break;
}
}
}
//update snake direction
void movementUpdate(){
// make tail and coordinate tail
int prevX = tailX[0];
int prevY = tailY[0];
int prev2X, prev2Y;
tailX[0] = x;
tailY[0] = y;
for(int i = 0; i < nTail; i++){
prev2X = tailX[i];
prev2Y = tailY[i];
tailX[i] = prevX;
tailY[i] = prevY;
prevX = prev2X;
prevY = prev2Y;
}
switch(dir){
case STOP:
break;
case LEFT:
x--;
break;
case RIGHT:
x++;
break;
case UP:
y--;
break;
case DOWN:
y++;
break;
default:
break;
}
//allow player to move through left and right walls
if(x >= width){
x = 0;
} else if ( x < 0) {
x = width -1;
}
if(y >= height){
y = 0;
} else if ( y < 0) {
y = height -1;
}
// check for game over
// if(x > width || x < 0 || y > height || y < 0){
// gameOver = true;
// }
//check if snake hit itself
for(int i = 0; i < nTail; i++){
if(tailX[i] == x && tailY[i] == y){
gameOver = true;
}
}
//check if snake takes fruit
if(x == fruitX && y == fruitY){
nTail++;
score += 10;
fruitX = rand() % width;
fruitY = rand() % height;
}
}
// initialize game
int main(){
setup();
while(!gameOver){
draw();
movement();
movementUpdate();
//sleep(10);
}
return 0;
}
In the first for loop in movement update where you update the tail. If you think about in the case of nTail = 1 you are basically only setting tailX[0] = tailX[0] and tailY[0] = tailY[0].
Simplified for loop when nTail = 1:
// make tail and coordinate tail
int prevX = tailX[0];
int prev2X;
tailX[0] = x;
{
prev2X = tailX[0];
tailX[0] = prevX; // prevX = tailX[0]
prevX = prev2X;
}
This is a working for loop:
// make tail and coordinate tail
int nextX = x;
int nextY = y;
int tX, tY;
for(int i = 0; i < nTail; i++){
tX = tailX[i];
tY = tailY[i];
tailX[i] = nextX;
tailY[i] = nextY;
nextX = tX;
nextY = tY;
}
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 am trying to make a simple game. The basic concept is that the player (P) is moving around on a map. Eventually the player will have to avoid enemies and complete the level. Currently I have the player able to move around grab ammo and fire forward. I am clearing the entire screen and rewriting the map every so often so the user can input and play the game in real time. Here is my current 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, ammoX, ammoY, score;
bool shot;
enum eDirecton { STOP = 0, LEFT, RIGHT, UP, DOWN, ALL};
eDirecton dir,shoot;
void Setup()
{
gameOver = false;
dir = STOP;
x = width / 2;
y = height / 2;
ammoX = rand() % width;
ammoY = rand() % height;
score = 0;
}
void 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(shoot == UP){
if(i < y && j == x && score > 0){
cout << ":";
shot = true;
}
}
/*if(shoot == LEFT || shoot == ALL){
if(i == y && j < x && score > 0){
cout << "~";
shot = true;
}
}
if(shoot == RIGHT || shoot == ALL){
if(i == y && j > x && score > 0){
cout << "~";
shot = true;
}
}
if(shoot == DOWN){
if(i > y && j == x && score > 0){
cout << ":";
shot = true;
}
}*/
else if (i == y && j == x)
cout << "P";
else if (i == ammoY && j == ammoX && score < 50)
cout << "A";
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 << endl;
cout << "Score:" << score << endl;
cout << "x: " << x << endl;
cout << "y: " << y << endl;
/*
if(_kbhit()){
cout << _getch() << endl;
}//*/
}
void Input()
{
if (_kbhit())
{
switch (_getch())
{
case 75:
dir = LEFT;
break;
case 77:
dir = RIGHT;
break;
case 72:
dir = UP;
break;
case 80:
dir = DOWN;
break;
case 'w':
shoot = UP;
break;
case 'a':
shoot = LEFT;
break;
case 's':
shoot = DOWN;
break;
case 'd':
shoot = RIGHT;
break;
case 32:
shoot = ALL;
break;
case 27:
gameOver = true;
break;
}
}
}
void 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;
}
if(x>=width){
x--;
}
else if(x < 0){
x++;
}
if(y>=height){
y--;
}
else if(y < 0){
y++;
}
//if (x > width || x < 0 || y > height || y < 0)
// gameOver = true;
//if (x >= width) x = 0; else if (x < 0) x = width - 1;
//if (y >= height) y = 0; else if (y < 0) y = height - 1;
/* for (int i = 0; i < nTail; i++)
if (tailX[i] == x && tailY[i] == y)
gameOver = true;*/
if (x == ammoX && y == ammoY)
{
score += 10;
ammoX = rand() % width;
ammoY = rand() % height;
//nTail++;
}
if(shot == true){
score -= 10;
}
}
int main()
{
Setup();
while (!gameOver)
{
Draw();
shoot = STOP;
Input();
Logic();
shot = false;
dir = STOP;
Sleep(30); //sleep(10);
}
return 0;
}
Is there a way to rewrite a certain line (such as the line the player is on and the one the player is moving to) so that I only have to rewrite a portion of the map instead of the entire map. It currently flashes and is hard to see since it flashes so often. If I could rewrite certain lines when the user inputs a key. I have tried \r and the setCursorPos() function, but I don't think I understand them entirely. I am using Windows 10 and Windows 7 and am using Microsoft Visual 2010. Please Help!
Thanks
"I have tried \r and the setCursorPos() function, but I don't think I understand them entirely. "
This should work:
void setcp( int x, int y )
{
HANDLE hStdout = GetStdHandle( STD_OUTPUT_HANDLE );
CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
GetConsoleScreenBufferInfo( hStdout, &csbiInfo );
csbiInfo.dwCursorPosition = COORD{ x, y };
SetConsoleCursorPosition( hStdout, csbiInfo.dwCursorPosition );
}
See this for more Windows console functions.
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;
}