Last active
February 3, 2021 11:35
-
-
Save maxpushka/85a33306ddd0cfbeeeb59af569cf8aa9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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