Skip to content

Instantly share code, notes, and snippets.

@poseidon4o
Last active August 29, 2015 14:19
Show Gist options
  • Save poseidon4o/3a13c54f3f85de2dfacb to your computer and use it in GitHub Desktop.
Save poseidon4o/3a13c54f3f85de2dfacb to your computer and use it in GitHub Desktop.
Snake
#include "stdafx.h"
#include <Windows.h>
#include <iostream>
using namespace std;
enum Dir {
Up = 0, Left = 1, Down = 2, Right = 3
};
struct coord {
int x, y;
bool operator==(const coord & o) const {
return x == o.x && y == o.y;
}
};
struct Food {
coord pos;
char texture = '@';
};
class Snake {
coord body[1000];
coord & head;
int size;
bool hasGrown;
Dir dir;
public:
Dir getDir() const {
return dir;
}
static const char body_texture, head_texture;
Snake(): head(body[0]), dir(Right), size(1), hasGrown(false) {
for (int c = 0; c < 1000; ++c) {
body[c] = { -1, -1 };
}
head = { 5, 5 };
}
void turn(Dir dir) {
this->dir = dir;
}
const coord & getHead() {
return head;
}
bool inside(coord pos) {
for (int c = 0; c < size; ++c) {
if (pos == body[c]) {
return true;
}
}
return false;
}
void step() {
coord newPos = head;
switch (dir) {
case Up: newPos.y -= 1; break;
case Left: newPos.x -= 1; break;
case Down: newPos.y += 1; break;
case Right: newPos.x += 1; break;
}
if (newPos == body[1]) {
return;
}
if (hasGrown) {
++size;
hasGrown = false;
}
for (int c = size - 1; c > 0; --c) {
body[c] = body[c - 1];
}
head = newPos;
}
void grow() {
hasGrown = true;
}
};
const char Snake::body_texture = 'x';
const char Snake::head_texture = 'X';
class Game {
Snake snake;
Food food;
coord board;
friend class Drawer;
public:
Game(coord board) : board(board) {
spawnFood();
}
void spawnFood() {
do {
food.pos.x = rand() % board.x;
food.pos.y = rand() % board.y;
} while (snake.inside(food.pos));
}
bool step() {
snake.step();
coord head = snake.getHead();
if (food.pos == head) {
snake.grow();
spawnFood();
}
if (head.x < 0 || head.y < 0
|| head.x > board.x || head.y > board.y) {
return false;
}
return true;
}
void read_input() {
if (GetAsyncKeyState(VK_LEFT)) {
snake.turn(Left);
}
else if (GetAsyncKeyState(VK_RIGHT)) {
snake.turn(Right);
}
else if (GetAsyncKeyState(VK_UP)) {
snake.turn(Up);
}
else if (GetAsyncKeyState(VK_DOWN)) {
snake.turn(Down);
}
}
};
class Drawer {
Game & game;
public:
Drawer(Game & g) : game(g) {}
void draw() {
for (int row = 0; row < game.board.y; ++row) {
for (int col = 0; col < game.board.x; ++col) {
coord current = { col, row };
if (game.food.pos == current) {
std::cout << game.food.texture;
}
else if (game.snake.inside(current)) {
std::cout <<
(game.snake.getHead() == current ?
game.snake.head_texture :
game.snake.body_texture);
}
else {
std::cout << ' ';
}
}
}
}
void clear() {
system("cls");
}
private:
};
int main() {
Game g({ 80, 21 });
Drawer d(g);
while (true) {
if (!g.step()) {
cout << "You lost";
}
g.read_input();
d.draw();
Sleep(100);
d.clear();
}
}
@WSJI0
Copy link

WSJI0 commented Apr 20, 2015

Cool :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment