All pastes #1750354 Raw Edit

autosnake

public c v1 · immutable
#1750354 ·published 2010-01-13 23:29 UTC
rendered paste body
#include "SDL/SDL.h"#include <stdlib.h>#include <limits.h>#include <stdio.h>#include <time.h>#include <math.h>#define manhattan(fx, fy, tx, ty) (abs((fx)-(tx)) + abs((fy)-(ty)))char insnake(unsigned int* snakepos, int snakelen, int x, int y);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("autosnake", "autosnake");		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 */		while(1)		{	/* Pathfind */			int costu, costr, costd, costl;			costu = (snakepos[0] >= 0 && snakepos[0] < field_w && snakepos[1]-1 >= 0 && snakepos[1]-1 < field_h && insnake(snakepos, snakelen, snakepos[0], snakepos[1]-1) == 0) ? manhattan(snakepos[0], snakepos[1]-1, applepos[0], applepos[1]) : INT_MAX;			costr = (snakepos[0]+1 >= 0 && snakepos[0]+1 < field_w && snakepos[1] >= 0 && snakepos[1] < field_h && insnake(snakepos, snakelen, snakepos[0]+1, snakepos[1]) == 0) ? manhattan(snakepos[0]+1, snakepos[1], applepos[0], applepos[1]) : INT_MAX;			costd = (snakepos[0] >= 0 && snakepos[0] < field_w && snakepos[1]+1 >= 0 && snakepos[1]+1 < field_h && insnake(snakepos, snakelen, snakepos[0], snakepos[1]+1) == 0) ? manhattan(snakepos[0], snakepos[1]+1, applepos[0], applepos[1]) : INT_MAX;			costl = (snakepos[0]-1 >= 0 && snakepos[0]-1 < field_w && snakepos[1] >= 0 && snakepos[1] < field_h && insnake(snakepos, snakelen, snakepos[0]-1, snakepos[1]) == 0) ? manhattan(snakepos[0]-1, snakepos[1], applepos[0], applepos[1]) : INT_MAX;			if(snakedir != DIR_DOWN  && costu < costr && costu <= costd && costu < costl) snakedir = DIR_UP;			if(snakedir != DIR_LEFT  && costr < costd && costr <= costl && costr < costu) snakedir = DIR_RIGHT;			if(snakedir != DIR_UP    && costd < costl && costd <= costu && costd < costr) snakedir = DIR_DOWN;			if(snakedir != DIR_RIGHT && costl < costu && costl <= costr && costl < costd) snakedir = DIR_LEFT;	/* Input */			SDL_Event event;			while(SDL_PollEvent(&event))			{				if(event.type == SDL_QUIT)				{					printf("Final score: %d\n", score);					return score;				}				if(event.type == SDL_KEYDOWN)				{					switch(event.key.keysym.sym)					{						case SDLK_ESCAPE:						printf("Final score: %d\n", score);						return score;						break;					}				}			}	/* 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];			}			if(snakepos[0] < 0 || snakepos[0] >= field_w || snakepos[1] < 0 || snakepos[1] >= field_h || insnake(snakepos, snakelen, snakepos[0], snakepos[1]))			{		/* 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^ */	}   	char insnake(unsigned int* snakepos, int snakelen, int x, int y)	{		int i;		for(i=2; i<2*snakelen; i+=2)		{			if(snakepos[i] == x && snakepos[i+1] == y) return 1;		}   		return 0;	}	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;					}				}			}		}	}