rendered paste body#include "SDL/SDL.h"#include <stdlib.h>#include <limits.h>#include <stdio.h>#include <time.h>void putsymbol(SDL_Surface *surface, int x, int y, const unsigned short symbol[9], Uint32 pixel);const unsigned short apple[9] = {0, 1, 0, 1, 1, 1, 0, 1, 0};const unsigned short shead[9] = {1, 1, 1, 1, 1, 1, 1, 1, 1};const unsigned short sbody[9] = {1, 1, 1, 1, 0, 1, 1, 1, 1};enum direction { DIR_UP = 1, DIR_RIGHT = 2, DIR_DOWN = 4, DIR_LEFT = 8};int main(int argc, char** argv){ srand(time(NULL)); /* Initialize SDL */ atexit(SDL_Quit); SDL_Surface* screen; if(SDL_Init(SDL_INIT_VIDEO) < 0) { fprintf(stderr, "Unable to initialize SDL: %s\n", SDL_GetError()); return INT_MIN;; } SDL_WM_SetCaption("snake", "snake"); if((screen = SDL_SetVideoMode(320, 240, 24, SDL_SWSURFACE|SDL_DOUBLEBUF)) == NULL) { fprintf(stderr, "Unable to set video mode: %s\n", SDL_GetError()); return INT_MIN; } /* Measure window */ int window_width = screen->w; int window_height = screen->h; /* Set offset to center playing field (3x3 tiles with 1px space) */ int offset_x = (1 + (window_width - 1) % 4) / 2; int offset_y = (1 + (window_height - 1) % 4) / 2; int field_w = (window_width - 1) / 4; int field_h = (window_height - 1) / 4; /* Some variables */ unsigned int* snakepos = malloc(16 * sizeof(int)); unsigned int applepos[2]; unsigned int snakelen = 6; unsigned int malloced = 16; signed int score = 0; enum direction snakedir; /* Set up variables */ int i; snakepos[0] = field_w/2; snakepos[1] = field_h/2; for(i=2;i < snakelen*2; i++) { snakepos[i] = field_w*field_h; } applepos[0] = rand()%field_w; applepos[1] = rand()%field_h; snakedir = 1 << (rand()%4); /* The game */ int mvlt = 0; while(1) { /* Input */ SDL_Event event; while(SDL_PollEvent(&event)) { if(event.type == SDL_QUIT) { printf("Final score: %d\n", score); return score; } if(mvlt == 0 && event.type == SDL_KEYDOWN) { switch(event.key.keysym.sym) { case SDLK_ESCAPE: printf("Final score: %d\n", score); return score; break; case SDLK_RIGHT: case SDLK_d: if(snakedir != DIR_LEFT) { snakedir = DIR_RIGHT; mvlt = 1; } break; case SDLK_LEFT: case SDLK_a: if(snakedir != DIR_RIGHT) { snakedir = DIR_LEFT; mvlt = 1; } break; case SDLK_UP: case SDLK_w: if(snakedir != DIR_DOWN) { snakedir = DIR_UP; mvlt = 1; } break; case SDLK_DOWN: case SDLK_s: if(snakedir != DIR_UP) { snakedir = DIR_DOWN; mvlt = 1; } break; default: break; } } } mvlt = 0; /* Logic */ for(i=snakelen*2; i>1; --i) { snakepos[i] = snakepos[i-2]; } snakepos[0] += (snakedir == DIR_RIGHT || snakedir == DIR_LEFT) ? ((snakedir == DIR_RIGHT) ? 1 : -1) : 0; snakepos[1] += (snakedir == DIR_UP || snakedir == DIR_DOWN) ? ((snakedir == DIR_DOWN ) ? 1 : -1) : 0; if(snakepos[0] == applepos[0] && snakepos[1] == applepos[1]) { /* Eating */ score++; applepos[0] = rand()%field_w; applepos[1] = rand()%field_h; snakelen++; if(2*snakelen >= malloced) { void* temp_ptr = realloc((void*)snakepos, (malloced + 16) * sizeof(int)); snakepos = (int*)temp_ptr; malloced += 16; } snakepos[2*snakelen-2] = snakepos[2*snakelen-4]; snakepos[2*snakelen-1] = snakepos[2*snakelen-3]; } for(i=2; i<2*snakelen; i+=2) { if((snakepos[i] == snakepos[0] && snakepos[i+1] == snakepos[1]) || (snakepos[0] < 0 || snakepos[0] >= field_w || snakepos[1] < 0 || snakepos[1] >= field_h)) { /* Dead */ score -= snakelen/3; snakelen = 6; snakedir = 1 << (rand()%4); snakepos[0] = field_w/2; snakepos[1] = field_h/2; for(i=2; i<2*snakelen; i++) { snakepos[i] = field_w*field_h; } i = 2*snakelen; SDL_Delay(1000); } } /* Drawing */ if(SDL_MUSTLOCK(screen)) SDL_LockSurface(screen); SDL_FillRect(screen, &screen->clip_rect, SDL_MapRGB(screen->format, 0x10, 0x10, 0x10)); putsymbol(screen, offset_x+4*applepos[0], offset_y+4*applepos[1], apple, SDL_MapRGB(screen->format, 0xCC, 0x00, 0x00)); putsymbol(screen, offset_x+4*snakepos[0], offset_y+4*snakepos[1], shead, SDL_MapRGB(screen->format, 0x00, 0xCC, 0x00)); for(i=2; i<2*snakelen; i+=2) { if(snakepos[i] < field_w && snakepos[i+1] < field_h) putsymbol(screen, offset_x+4*snakepos[i], offset_y+4*snakepos[i+1], sbody, SDL_MapRGB(screen->format, 0x10, 0xBB, 0x10)); } if(SDL_MUSTLOCK(screen)) SDL_UnlockSurface(screen); SDL_Flip(screen); SDL_Delay((20 + 100 / ((score > 0) ? score : 1)) / (1 + field_w*field_h/10000)); } /* lol^ */} void putsymbol(SDL_Surface *surface, int x, int y, const unsigned short symbol[9], Uint32 pixel){ int bpp = surface->format->BytesPerPixel; int dx, dy; for(dx=0; dx<3; dx++) { for(dy=0; dy<3; dy++) { Uint8 *p = (Uint8 *)surface->pixels + (y+dy) * surface->pitch + (x+dx) * bpp; if(symbol[dx + dy*3] != 0) { switch(bpp) { case 1: *p = pixel; break; case 2: *(Uint16 *)p = pixel; break; case 3: if(SDL_BYTEORDER == SDL_BIG_ENDIAN) { p[0] = (pixel >> 16) & 0xff; p[1] = (pixel >> 8) & 0xff; p[2] = pixel & 0xff; } else { p[0] = pixel & 0xff; p[1] = (pixel >> 8) & 0xff; p[2] = (pixel >> 16) & 0xff; } break; case 4: *(Uint32 *)p = pixel; break; } } } }}