I am a novice and I've run into a problem I can't seem to fix. Namely, I have these two seperate working blocks of code, yet if I use both of them the program crashes (returning an error code of 3221225477).
#include <conio.h>
#include <iostream>
#include <string>
#include <windows.h>
#include <chrono>
#include <thread>
#include <vector>
#include <time.h>
#define KEY_UP 72
#define KEY_DOWN 80
#define KEY_LEFT 75
#define KEY_RIGHT 77
#define ENTER 13
using namespace std;
struct set {
int speed=0;
bool obs=0;
} settings;
void gotoyx( int y, int x ) { //moves the console cursor
COORD coord;
coord.X = x;
coord.Y = y;
SetConsoleCursorPosition(GetStdHandle( STD_OUTPUT_HANDLE ), coord);
}
void setup() { //used to determine the snake's speed, expressed as delay between movement
int c = 0;
string o1=">SLOW", o2=" MEDIUM", o3=" FAST";
while(settings.speed==0)
{
c = 0;
gotoyx(c, c); //sets cursor at top-left
cout << "Please choose your speed setting:\n"<< o1 << endl << o2 << endl << o3 << endl;
switch((c=getch())) {
case KEY_UP:
if(o2.at(0)=='>'){
o1[0]='>';
o2[0]=' ';
}
else if(o3.at(0)=='>'){
o2[0]='>';
o3[0]=' ';
}
break;
case KEY_DOWN:
if(o1.at(0)=='>'){
o2[0]='>';
o1[0]=' ';
}
else if(o2.at(0)=='>'){
o3[0]='>';
o2[0]=' ';
}
break;
case ENTER:
if(o1.at(0)=='>') {
cout << "You chose SLOW.\n";
settings.speed=160;
}
else if(o2.at(0)=='>') {
cout << "You chose MEDIUM.\n";
settings.speed=120;
}
else {
cout << "You chose FAST.\n";
settings.speed=80;
}
settings.obs=1;
cout << "Press a key to continue.";
getch();
break;
default:
break;
}
}
}
void draw_border() {
for(int i=0; i<80; i++){ //80 fills screen vertically - TOP
cout<<"#";
}
for(int i=0; i<23; i++){ //25 fills screen horizontally (2 used for top and bottom)
cout<<"#";
for(int i=0; i<78; i++){
cout<<" ";
}
cout<<"#";
}
for(int i=0; i<80; i++){ //80 fills screen vertically - BOTTOM
cout<<"#";
}
}
void ShowConsoleCursor(bool showFlag) { //blinking-underscore-with-console
HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO cursorInfo;
GetConsoleCursorInfo(out, &cursorInfo);
cursorInfo.bVisible = showFlag; // set the cursor visibility
SetConsoleCursorInfo(out, &cursorInfo);
}
int keypad(int out){ //reads arrow keys during game
if (GetAsyncKeyState(VK_UP) & 0x8000 && out!=1 ) { //MSB set if currently pressed
out=0; //if nothing is pressed it returns
} //the last pressed button
else if (GetAsyncKeyState(VK_DOWN) & 0x8000 && out!=0) {
out=1;
}
else if (GetAsyncKeyState(VK_LEFT) & 0x8000 && out!=3) {
out=2;
}
else if (GetAsyncKeyState(VK_RIGHT) & 0x8000 && out!=2) {
out=3;
}
return out;
}
int main() {
ShowConsoleCursor(false); //disable blinking console cursor
setup();
int tmp=0, cntr_g=0, cntr_o=0;
system("cls"); //clear screen after inital setup
draw_border();
gotoyx(tmp, tmp); //using cursor to scroll to console top
vector<vector<int>> snake_pos; //tracks snake location
snake_pos.emplace(snake_pos.begin(), std::initializer_list<int>{13,40});
int y = snake_pos[0][0]; //Y coordinate of snake head
int x = snake_pos[0][1]; //X coordinate of snake head
gotoyx(y, x);
cout<<"*";
int key, boost_y, boost_x, obstacle_y, obstacle_x;
bool b_flag=0;
vector<vector<int>> boost (1, vector<int>(2, 0));
vector<vector<int>> obstacle (1, vector<int>(2, 0));
while(1){
key=keypad(key);
if (key==0) {
snake_pos.emplace(snake_pos.begin(), std::initializer_list<int> {y-1, x});
}
else if (key==1) {
snake_pos.emplace(snake_pos.begin(), std::initializer_list<int> {y+1, x});
}
else if (key==2) {
snake_pos.emplace(snake_pos.begin(), std::initializer_list<int> {y, x-1});
}
else if (key==3) {
snake_pos.emplace(snake_pos.begin(), std::initializer_list<int> {y, x+1});
}
y = snake_pos[0][0]; x = snake_pos[0][1]; //updating snake head coordinates
if (y==0 | y==24 | x==0 | x==80 ) { //checking whether player hit wall
return 0;
}
for (tmp=1; tmp!=snake_pos.size()-1; ++tmp) { //checking whether player hit self
if (y==snake_pos[tmp][0] && x==snake_pos[tmp][1]) {
return 0;
}
}
//check if obstacle was hit [not here yet]
++cntr_g; //generating growth boost block
if (cntr_g==settings.speed/5) {
label_growth:
srand(time(NULL));
boost_x=(rand()%78)+1;
boost_y=(rand()%23)+1;
for (tmp=0; tmp!=snake_pos.size()-1; ++tmp) {
if (boost_y==snake_pos[tmp][0] && boost_x==snake_pos[tmp][1]) {
goto label_growth;
}
}
gotoyx(boost_y, boost_x); cout<<"O";
boost.emplace_back(std::initializer_list<int> {boost_y, boost_x});
cntr_g=0;
}
/*
++cntr_o; //generating obstacle block
if ((cntr_o==settings.speed/4) && (settings.obs==1)) { //also check if obs enabled
label_obstacle:
srand(time(NULL));
obstacle_x=(rand()%78)+1;
obstacle_y=(rand()%23)+1;
for (tmp=0; tmp!=snake_pos.size()-1; ++tmp) { //check overlap with snake
if (obstacle_y==snake_pos[tmp][0] && obstacle_x==snake_pos[tmp][1]) {
goto label_obstacle;
}
}
for (tmp=0; tmp!=boost.size()-1; ++tmp) { //check overlap with boosts
if (obstacle_y==boost[tmp][0] && obstacle_x==boost[tmp][1]) {
goto label_obstacle;
}
}
gotoyx(obstacle_y, obstacle_x); cout<<"X";
obstacle.emplace_back(std::initializer_list<int> {obstacle_y, obstacle_x});
cntr_o=0;
}*/
gotoyx(y, x); cout<<"*"; b_flag=0; //updating graphics for new snake
for (tmp=0; tmp!=boost.size()-1; ++tmp) {
if (y==boost[tmp][0] && x==boost[tmp][1]) {
boost.erase(boost.begin()+tmp);
b_flag=1;
break;
}
}
if (b_flag==0){ //if snake didn't grow, last block stays
gotoyx(snake_pos.back()[0], snake_pos.back()[1]); cout<<" ";
snake_pos.pop_back();
}
std::this_thread::sleep_for(std::chrono::milliseconds(settings.speed));
}
return 0;
}
Namely, the problem is with the if statement for the growth block portion, and the obstacle block portion. The program(game) works as intended when one of them is commented out, but doesn't if both of them are left in. In fact, even just leaving in the cntr_o++; without the following if statement is enough to crash it.
Aucun commentaire:
Enregistrer un commentaire