Skip to content

Instantly share code, notes, and snippets.

@maxpushka
Last active February 3, 2021 11:35
Show Gist options
  • Save maxpushka/85a33306ddd0cfbeeeb59af569cf8aa9 to your computer and use it in GitHub Desktop.
Save maxpushka/85a33306ddd0cfbeeeb59af569cf8aa9 to your computer and use it in GitHub Desktop.
#include <iostream>
#include <vector>
#include <cstdlib>
#include <ctime>
#include <conio.h>
#include "windows.h"
using namespace std;
bool gameOver = false;
int score = 0;
const unsigned int gameSpeed = 200; // ms per frame
const int SCREEN_WIDTH = 20; // width in symbols
const int SCREEN_HEIGHT = 10;
const char WALL = '#';
const char FRUIT = 'F';
const char HEAD = 'O';
const char BODY = 'o';
/*
x is the row, y is the column:
0 ----> X axis
|
|
v
Y axis
*/
int fruitX, fruitY;
int headX, headY;
vector<COORD> tail;
enum class Dir { STOP, LEFT, RIGHT, UP, DOWN };
Dir dir; // the current heading of head
void setCursorPosition(int x, int y) {
// x is the column, y is the row. The origin (0,0) is top-left.
static const HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
std::cout.flush();
COORD coord = {(SHORT)x, (SHORT)y};
SetConsoleCursorPosition(hOut, coord);
}
void Setup() {
fruitX = rand() % (SCREEN_HEIGHT - 2) + 1;
fruitY = rand() % (SCREEN_WIDTH - 2) + 1;
do {
headX = rand() % (SCREEN_HEIGHT - 2) + 1; // SCREEN_HEIGHT / 2;
headY = rand() % (SCREEN_WIDTH - 2) + 1; // SCREEN_WIDTH / 2;
} while (headX == fruitX && headY == fruitY);
}
void Draw() {
system("cls");
for (size_t j = 0; j < SCREEN_WIDTH; j++) cout << WALL;
cout << endl;
for (size_t i = 1; i < SCREEN_HEIGHT - 1; i++) {
for (size_t j = 0; j < SCREEN_WIDTH; j++) {
if (j == 0 || j == SCREEN_WIDTH - 1)
cout << WALL;
else if (headX == i && headY == j)
cout << HEAD;
else if (fruitX == i && fruitY == j)
cout << FRUIT;
else {
bool print = false;
for (auto t : tail) {
if (t.X == i && t.Y == j) {
cout << BODY;
print = true;
}
}
if (!print) cout << ' ';
}
}
cout << endl;
}
for (size_t j = 0; j < SCREEN_WIDTH; j++) cout << WALL;
cout << endl << "Score: " << score << endl;
}
void Input() {
if (_kbhit()) {
switch (_getch()) {
case 'a': case 'A':
if (dir == Dir::RIGHT) dir = Dir::STOP;
else dir = Dir::LEFT;
break;
case 'd': case 'D':
if (dir == Dir::LEFT) dir = Dir::STOP;
else dir = Dir::RIGHT;
break;
case 'w': case 'W':
if (dir == Dir::DOWN) dir = Dir::STOP;
else dir = Dir::UP;
break;
case 's': case 'S':
if (dir == Dir::UP) dir = Dir::STOP;
else dir = Dir::DOWN;
break;
case 'x': case 'X':
gameOver = true;
break;
default: break;
}
}
}
void Logic() {
// move tail pos
if (tail.size() && dir != Dir::STOP) {
short prevX = tail[0].X;
short prevY = tail[0].Y;
short prev2X, prev2Y;
tail[0].X = headX;
tail[0].Y = headY;
for (size_t i = 1; i < tail.size(); i++) {
prev2X = tail[i].X;
prev2Y = tail[i].Y;
tail[i].X = prevX;
tail[i].Y = prevY;
prevX = prev2X;
prevY = prev2Y;
}
}
// move head pos
switch (dir) {
case Dir::LEFT:
headY--;
break;
case Dir::RIGHT:
headY++;
break;
case Dir::UP:
headX--;
break;
case Dir::DOWN:
headX++;
break;
case Dir::STOP:
break;
}
// check collisions
for (auto t : tail) {
if (headX == t.X && headY == t.Y) gameOver = true;
}
if (headX == fruitX && headY == fruitY) {
score++;
fruitX = rand() % (SCREEN_HEIGHT - 2) + 1;
fruitY = rand() % (SCREEN_WIDTH - 2) + 1;
COORD newTailEl{headX, headY};
tail.push_back(newTailEl);
} else if (headX == 0 || headX == SCREEN_HEIGHT - 1 || headY == 0 ||
headY == SCREEN_WIDTH - 1) {
gameOver = true;
}
}
int main() {
srand(time(NULL));
Setup();
while (!gameOver) {
Draw();
Input();
Logic();
Sleep(gameSpeed);
}
cout << "\nGame over\n";
system("pause");
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment