Skip to content

Instantly share code, notes, and snippets.

@funnbot
Created March 8, 2019 23:49
Show Gist options
  • Save funnbot/ae1f15b14d6e23b7ffde15975310a912 to your computer and use it in GitHub Desktop.
Save funnbot/ae1f15b14d6e23b7ffde15975310a912 to your computer and use it in GitHub Desktop.
Mostly working cross platform snake game in console that requires sfml on mac.
#if defined(WIN32) || defined(_WIN32)
#define iswin
#endif
#include <iostream>
#include <vector>
#include <ctime>
#include <string>
#include <stdlib.h>
#ifdef iswin
#include <Windows.h>
#else
#include <SFML/Window/Keyboard.hpp>
#include <ncurses.h>
#include <unistd.h>
#endif
using namespace std;
#ifdef iswin
const int IKEY_W = 0x57, IKEY_S = 0x53, IKEY_D = 0x44, IKEY_A = 0x41, IKEY_ESC = 0x1B;
#else
const int IKEY_W = 22, IKEY_S = 18, IKEY_D = 3, IKEY_A = 0, IKEY_ESC = 36;
#endif
const int WIDTH = 40, HEIGHT = 30;
struct Coord {
int x;
int y;
};
void buildMap(vector<vector<char>>&);
void drawMap(const vector<vector<char>>&);
void randCoord(Coord&);
void input(Coord&);
bool isKeyDown(int);
void moveCursor(int, int);
void hideCursor();
void slp(int);
void prnt(char);
int main() {
#ifndef iswin
initscr();
#endif
srand(static_cast<int>(time(0)));
hideCursor();
vector<vector<char>> map(WIDTH);
// Init map, build walls
buildMap(map);
// Game vars
vector<Coord> body(4);
body[0] = { 9, 10 };
body[1] = { 8, 10 };
body[2] = { 7, 10 };
body[3] = { 6, 10 };
Coord head = { 10, 10};
Coord dir = { 1, 0 };
Coord apple;
randCoord(apple);
map[apple.x][apple.y] = '@';
bool lost = false;
// Game loop
while (!isKeyDown(IKEY_ESC) && !lost) {
// Get input again
input(dir);
// Erase old snake
map[head.x][head.y] = ' ';
cout << map[head.x][head.y];
for (int i = 0; i < body.size(); i++) {
map[body[i].x][body[i].y] = ' ';
}
// Update snake
for (int i = body.size() - 1; i > 0; i--) {
body[i] = { body[i - 1].x, body[i - 1].y };
}
body[0] = { head.x, head.y };
head = { head.x + dir.x, head.y + dir.y };
// Check apple
if (head.x == apple.x && head.y == apple.y) {
body.resize(body.size() + 1);
map[apple.x][apple.y] = ' ';
randCoord(apple);
map[apple.x][apple.y] = '@';
}
// Lose conditions
if (head.x == 0 || head.x == WIDTH - 1 || head.y == 0 || head.y == HEIGHT - 1) break;
for (int i = 1; i < body.size(); i++) {
if (head.x == body[i].x && head.y == body[i].y) lost = true;
}
// Draw snake
map[head.x][head.y] = '0';
for (int i = 0; i < body.size(); i++) {
map[body[i].x][body[i].y] = '*';
}
// Draw to console
drawMap(map);
// Wait
int wait = 10;
while (--wait) {
input(dir);
slp(15);
}
}
#ifndef iswin
endwin();
#endif
cout << "Score: " << body.size() - 4 << endl;
return 0;
}
void buildMap(vector<vector<char>> &map) {
for (int x = 0; x < WIDTH; x++) {
map[x] = vector<char>(HEIGHT);
for (int y = 0; y < HEIGHT; y++) {
if (x == 0 || x == WIDTH - 1)
map[x][y] = '|';
else if (y == 0 || y == HEIGHT - 1)
map[x][y] = '-';
else map[x][y] = ' ';
}
}
}
void drawMap(const vector<vector<char>> &map) {
moveCursor(0, 0);
for (int y = 0; y < HEIGHT; y++) {
for (int x = 0; x < WIDTH; x++) {
char c = map[x][y];
moveCursor(x, y);
prnt(c);
}
prnt('\n');
}
#ifndef iswin
refresh();
#endif
}
void input(Coord& dir) {
if (isKeyDown(IKEY_W)) dir = { 0, -1 };
else if (isKeyDown(IKEY_S)) dir = { 0, 1 };
else if (isKeyDown(IKEY_D)) dir = { 1, 0 };
else if (isKeyDown(IKEY_A)) dir = { -1, 0 };
}
void randCoord(Coord& c) {
c.x = 1 + rand() % (WIDTH - 2);
c.y = 1 + rand() % (HEIGHT - 2);
}
bool isKeyDown(int key) {
#ifdef iswin
return GetKeyState(key) & 0x8000;
#else
return sf::Keyboard::isKeyPressed(static_cast<sf::Keyboard::Key>(key));
#endif
}
void moveCursor(int x, int y) {
#ifdef iswin
COORD c = {x, y};
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c);
#else
move(y, x);
#endif
}
void hideCursor() {
#ifdef iswin
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO info;
GetConsoleCursorInfo(handle, &info);
info.bVisible = false;
SetConsoleCursorInfo(handle, &info);
#else
curs_set(0);
#endif
}
void slp(int t) {
#ifdef iswin
Sleep(t);
#else
usleep(t * 1000);
#endif
}
void prnt(char c) {
#ifdef iswin
cout << c;
#else
printw("%c", c);
#endif
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment