Skip to content

Instantly share code, notes, and snippets.

@quirinpa
Created February 21, 2016 16:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save quirinpa/0ed192f28a8b965229bf to your computer and use it in GitHub Desktop.
Save quirinpa/0ed192f28a8b965229bf to your computer and use it in GitHub Desktop.
// very simple SDL snake implementation
#include "SDL/SDL.h"
#include <iostream>
const int squareSize=10;
const int squares=30;
const int hsquares=squares/2;
const int size=squareSize*squares;
const int startingSize = 3;
// const int vSquares=30;
struct point {
int x, y;
};
point centerpoint = {hsquares, hsquares};
struct node {
point p;
node *next, *prev;
};
class snake {
point food;
node *tail, *head;
int size, dir;
public:
snake(){
size = startingSize;
dir = 0;
// init snake
head = new node;
head->p = centerpoint;
head->prev = NULL;
node *aux = new node;
head->next = aux;
aux->prev = head;
for (int i=1; i<size; i++) {
aux->p = centerpoint;
aux->next = new node;
aux->next->prev = aux;
aux = aux->next;
}
tail = aux;
tail->next = NULL;
tail->p = centerpoint;
placefood();
}
void placefood(){
bool col;
do {
food.x = rand() % squares;
food.y = rand() % squares;
node *aux = head;
col = false;
do {
col = (aux->p.x == food.x && aux->p.y == food.y);
aux = aux->next;
} while (aux && !col);
} while (col);
}
void draw(SDL_Surface *screen){
node *prev = tail;
do {
SDL_Rect *pos = new SDL_Rect;
pos->x = prev->p.x * squareSize;
pos->y = prev->p.y * squareSize;
pos->w = pos->h = squareSize;
SDL_FillRect(screen, pos, SDL_MapRGBA(screen->format, 255,255,255,255));
prev=prev->prev;
} while (prev!=NULL);
SDL_Rect *foodp = new SDL_Rect;
foodp->x = food.x * squareSize;
foodp->y = food.y * squareSize;
foodp->w = foodp->h = squareSize;
SDL_FillRect(screen, foodp, SDL_MapRGBA(screen->format, 255, 0, 0, 255));
}
void print() {
node *curr = head;
do {
std::cout<<curr->p.x<<';'<<curr->p.y<<';'<<curr->prev<<';'<<curr->next<<' ';
curr = curr->next;
} while (curr!=NULL);
std::cout<<'\n';
}
bool move() {
tail->prev->next = NULL;
node *aux = tail;
tail = tail->prev;
aux->prev = NULL;
aux->next = head;
head->prev = aux;
aux->p = head->p;
head = aux;
switch (dir) {
case 0:
if (head->p.x + 2 > squares)
head->p.x = 0;
else head->p.x += 1;
break;
case 1:
if (head->p.y + 2 > squares)
head->p.y = 0;
else head->p.y += 1;
break;
case 2:
if (head->p.x == 0)
head->p.x = squares - 1;
else head->p.x -= 1;
break;
default:
if (head->p.y == 0)
head->p.y = squares - 1;
else head->p.y -= 1;
}
// print();
aux = aux->next;
do {
if (aux->p.x == head->p.x && aux->p.y == head->p.y) {
std::cout<<"GAME OVER - "<<size<<" points\n";
return false;
}
aux = aux->next;
} while (aux);
if (head->p.x == food.x && head->p.y == food.y) {
node * newtail = new node;
newtail->prev = tail;
newtail->p = tail->p;
tail->next = newtail;
tail = newtail;
size++;
placefood();
}
return true;
}
void changedir(int _dir) {
if ((dir == 0 && _dir == 2) ||
(dir == 1 && _dir == 3) ||
(dir == 2 && _dir == 0) ||
(dir == 3 && _dir == 1)) return;
dir = _dir;
}
};
int main() {
if (SDL_Init(SDL_INIT_EVERYTHING)) {
std::cout<<"Could not initialize SDL.\n";
return 1;
};
SDL_Surface* screen = SDL_SetVideoMode(
size,size,0,SDL_HWSURFACE|SDL_DOUBLEBUF);
snake s;
// s.print();
int lt = SDL_GetTicks(), lm = lt;
bool active=true;
while(active){
// RENDER
SDL_FillRect(screen, NULL, SDL_MapRGBA(screen->format,0,0,0,255));
s.draw(screen);
// draw food
SDL_Flip(screen);
SDL_Event ev;
while(SDL_PollEvent(&ev)) {
switch (ev.type) {
case SDL_QUIT:
active = false;
break;
case SDL_KEYDOWN:
switch ((int)ev.key.keysym.scancode) {
case 114:
s.changedir(0);
break;
case 116:
s.changedir(1);
break;
case 113:
s.changedir(2);
break;
case 111:
s.changedir(3);
}
// std::cout<<(int)ev.key.keysym.scancode<<'\n';
// std::cout.flush();
}
}
int ct = SDL_GetTicks();
if (ct - lt >= 60) {
lt = ct;
active = s.move();
// s.print();
}
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment