Skip to content

Instantly share code, notes, and snippets.

@Fizzyhex
Last active November 29, 2024 14:09
Show Gist options
  • Select an option

  • Save Fizzyhex/a7df36a9d359b3fcd64be496c615e702 to your computer and use it in GitHub Desktop.

Select an option

Save Fizzyhex/a7df36a9d359b3fcd64be496c615e702 to your computer and use it in GitHub Desktop.
🐍 C++ Snake
// SNAKE.cpp : This file contains the 'main' function. Program execution begins and ends there.
//
#include <iostream>
#include <vector>
#include <windows.h>
#include <random>
using namespace std;
int random(int from, int to) {
return rand() % (to - from + 1) + from;
}
struct Vector2 {
int x;
int y;
Vector2 operator+(const Vector2 &other) const
{
return { x + other.x, y + other.y };
}
};
enum class Tile
{
EMPTY,
SNAKE,
SNAKE_HEAD,
PELLET,
WALL,
};
class Game
{
public:
bool isGameOver;
void start()
{
snakeSize = startingSnakeSize;
movePellet();
}
void movePellet()
{
pelletPosition = { random(1, width - 2), random(1, height - 2) };
}
void render()
{
system("cls");
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
cout << get_char(get_tile(x, y));
}
cout << "\n";
}
cout << "Score: " << (snakeSize - startingSnakeSize);
}
void moveSnake()
{
snakePosition = snakePosition + moveDirection;
Tile newTile = get_tile(snakePosition.x, snakePosition.y);
if (newTile == Tile::WALL || newTile == Tile::SNAKE || newTile == Tile::SNAKE_HEAD)
{
isGameOver = true;
return;
}
snakePositions.push_back(snakePosition);
if (snakePositions.size() > snakeSize)
{
snakePositions.erase(snakePositions.begin());
}
if (pelletPosition.x == snakePosition.x && pelletPosition.y == snakePosition.y) {
snakeSize++;
movePellet();
}
}
void processUserInput()
{
int x = 0;
int y = 0;
if (GetAsyncKeyState(VK_UP))
{
y--;
}
if (GetAsyncKeyState(VK_DOWN))
{
y++;
}
if (GetAsyncKeyState(VK_LEFT))
{
x--;
}
if (GetAsyncKeyState(VK_RIGHT))
{
x++;
}
if (x != 0 || y != 0)
{
moveDirection = { x, y };
}
}
void tick()
{
processUserInput();
moveSnake();
render();
}
Tile get_tile(int x, int y)
{
if ((y == 0 || y == height - 1) || (x == 0 || x == width - 1))
{
return Tile::WALL;
}
for (Vector2 pos : snakePositions)
{
if (pos.x == x && pos.y == y)
{
if (x == snakePosition.x && y == snakePosition.y)
{
return Tile::SNAKE_HEAD;
}
return Tile::SNAKE;
}
}
if (pelletPosition.x == x && pelletPosition.y == y)
{
return Tile::PELLET;
}
return Tile::EMPTY;
}
char get_char(Tile tile)
{
switch (tile)
{
case Tile::EMPTY:
return '_';
case Tile::SNAKE:
return 'o';
case Tile::SNAKE_HEAD:
return '0';
case Tile::PELLET:
return '*';
case Tile::WALL:
return '#';
default:
return '?';
}
}
private:
const int width = 30;
const int height = 10;
int snakeSize = 5;
int startingSnakeSize = 5;
Vector2 pelletPosition;
vector<Vector2> snakePositions;
Vector2 moveDirection = { 1, 0 };
Vector2 snakePosition = { 2, 2 };
};
int main()
{
Game game;
game.start();
while (!game.isGameOver)
{
game.tick();
Sleep(200);
}
cout << "Game Over!\n";
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment