All pastes #1750341 Raw Edit

snake

public c v1 · immutable
#1750341 ·published 2010-01-13 23:25 UTC
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;		    }	       }	  }     }}