Skip to content

Instantly share code, notes, and snippets.

@wldomiciano wldomiciano/snake.c
Last active Apr 22, 2018

Embed
What would you like to do?
A simple Snake clone implementation in C with SDL 2
#include <stdlib.h>
#include <stdbool.h>
#include <SDL2/SDL.h>
#define TIMEOUT 150
#define SIZE 25
#define BOARD_COLS 10
#define BOARD_ROWS 10
#define BOARD_SIZE (BOARD_COLS * BOARD_ROWS)
int head = 0;
int apple = 45;
int direction = 1;
int tail[BOARD_SIZE] = {0};
int accumulator = 0;
int length = 0;
int i = 0;
bool isDead = false;
SDL_Renderer* ctx = NULL;
SDL_Window* canvas = NULL;
Uint32 previousTicks = 0;
void draw(int position, int r, int g, int b) {
SDL_Rect rect = {position % BOARD_COLS, position / BOARD_COLS, SIZE, SIZE};
rect.x *= SIZE;
rect.y *= SIZE;
SDL_SetRenderDrawColor(ctx, r, g, b, SDL_ALPHA_OPAQUE);
SDL_RenderFillRect(ctx, &rect);
}
int random() {
return rand() % BOARD_SIZE;
}
bool isOnLimits() {
return (direction == 1 && head % BOARD_COLS == 0) ||
(direction == -1 && (head + 1) % BOARD_COLS == 0);
}
bool hasCollisionWithTail(int position) {
for (int i = 0; i < length; i++)
if (tail[i] == position) return true;
return false;
}
void placeApple() {
do apple = random();
while (head == apple || hasCollisionWithTail(apple));
}
void setDirection(int dir) {
if (dir != -direction || length == 0)
direction = dir;
}
void drawBoard() {
for (int i = 0; i < length; ++i)
draw(tail[i], 0, 255, 0);
draw(head, 0, 0, 255);
draw(apple, 255, 0, 0);
}
void move() {
tail[i] = head;
head += direction;
if (++i >= length) i = 0;
if (isOnLimits())
head -= BOARD_COLS * direction;
else if (head < 0)
head += BOARD_SIZE;
else if (head >= BOARD_SIZE)
head -= BOARD_SIZE;
}
void update(int delta) {
accumulator += delta;
if (accumulator >= TIMEOUT && !isDead) {
accumulator = 0;
move();
if (head == apple) {
placeApple();
tail[length++] = head;
} else if (hasCollisionWithTail(head)) isDead = true;
}
drawBoard();
}
int main(int argc, char **argv) {
if (SDL_Init(SDL_INIT_VIDEO) < 0) return EXIT_FAILURE;
if (SDL_CreateWindowAndRenderer(SIZE * BOARD_COLS, SIZE * BOARD_ROWS, 0, &canvas, &ctx) < 0) return EXIT_FAILURE;
while (!SDL_QuitRequested()) {
if (SDL_GetKeyboardState(NULL)[SDL_SCANCODE_UP]) setDirection(-BOARD_COLS);
else if (SDL_GetKeyboardState(NULL)[SDL_SCANCODE_DOWN]) setDirection( BOARD_COLS);
else if (SDL_GetKeyboardState(NULL)[SDL_SCANCODE_LEFT]) setDirection(-1);
else if (SDL_GetKeyboardState(NULL)[SDL_SCANCODE_RIGHT]) setDirection( 1);
SDL_SetRenderDrawColor(ctx, 0, 0, 0, SDL_ALPHA_OPAQUE);
SDL_RenderClear(ctx);
Uint32 current = SDL_GetTicks();
Uint32 delta = current - previousTicks;
previousTicks = current;
update(delta);
SDL_RenderPresent(ctx);
}
SDL_DestroyRenderer(ctx);
SDL_DestroyWindow(canvas);
SDL_Quit();
return EXIT_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.