Skip to content

Instantly share code, notes, and snippets.

@juaxix
Last active January 8, 2019 08:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save juaxix/5efa9821f27ae1e0916da98c6be8c515 to your computer and use it in GitHub Desktop.
Save juaxix/5efa9821f27ae1e0916da98c6be8c515 to your computer and use it in GitHub Desktop.
ASCII_Snake.cpp
#include <iostream>
#include <conio.h>
#include <chrono>
#include <thread>
using namespace std;
//game state
bool gameOver = false;
//MAP BLOCKS
const int width = 20;
const int height = 20;
//head position
int x, y;
//body
int tailX[100], tailY[100];
int nTail = 0;
//fruit position
int fruitX, fruitY;
//scores
int score;
//direction of the snake
enum eDirection { STOP = 0, LEFT, RIGHT, UP, DOWN };
eDirection dir;
//draw speed
long long lastDrawTime = 0;
const long long millisecondsPerFrame = 60;
chrono::duration<long long, ratio<1, 1000>> SleepTime(100);
long long GetMillisecondsTime(){ return chrono::duration_cast<std::chrono::milliseconds>(chrono::system_clock::now().time_since_epoch()).count();}
void PlaceFruit()
{
fruitX = rand() % width;
fruitY = rand() % height;
}
void Setup()
{
gameOver = false;
dir = STOP;
//position in the head -> middle of the screen
x = width/2;
y = height / 2;
PlaceFruit();
score = 0;
nTail = 0;
lastDrawTime = GetMillisecondsTime() + millisecondsPerFrame;
}
void DrawLine()
{
for (int i = 0; i < width + 2; i++)
{
cout << "#";
}
}
void Draw()
{
const auto time = GetMillisecondsTime();
if (time > lastDrawTime) lastDrawTime = time + millisecondsPerFrame;
else return;
system("cls"); //windows //system("clear"); //Linux
DrawLine();
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 << "X";
else
{
bool printed = false;
for(int k=0;k<nTail;k++)
{
if(tailX[k]==j && tailY[k]==i)
{
cout << "o";
printed = true;
}
}
if (!printed)
cout << " ";
}
//wall
if (j == width - 1)
{
cout << "#";
}
}
cout << endl;
}
//bottom
DrawLine();
cout << endl << "Score: " << score << endl;
}
void Input()
{
if(_kbhit()) //async functions to get keyboard pressed keys
{
switch(_getch())
{
case 'a': if (dir == RIGHT && nTail > 0) gameOver = true; else dir = LEFT; break;
case 'd':if (dir == LEFT && nTail > 0) gameOver = true; else dir = RIGHT; break;
case 'w': if (dir == DOWN && nTail > 0) gameOver = true; else dir = UP; break;
case 's': if (dir == UP && nTail > 0) gameOver = true; else dir = DOWN; break;
case 'x': gameOver = true;break;
default: ;
}
}
}
void Logic()
{
int prevX = tailX[0]; //cache tail
int prevY = tailY[0];
tailX[0] = x;
tailY[0] = y;
for(int i=1;i<nTail; i++) //move the tail
{
int prev2X = tailX[i];
int 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: ;
}
if (x > width || x<0 || y>height || y < 0)
{
gameOver = true;
}
else
{
for (int i = 0; i < nTail && !gameOver; i++)
{
if(tailX[i]==x && tailY[i]==y)
{
gameOver = true;;
}
}
if (!gameOver && x == fruitX && y == fruitY)
{
score += 10;
PlaceFruit();
nTail++;
}
}
}
int main()
{
Setup();
while(!gameOver)
{
Draw();
Input();
Logic();
this_thread::sleep_for(std::chrono::milliseconds(SleepTime));
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment