Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // vim: ts=4:sw=4
- //gcc -lSDL nego.c
- #include "SDL/SDL.h"
- #define BLOCK(X,Y,T) r.x = (X) * size + margin; r.y = (Y) * size + margin; \
- r.w = r.h = size - 2 * margin; SDL_FillRect(screen, &r, color(T));
- #define BTYPE(N,S)((b.type & N) >> S)&White?White:Black
- #define S2X2(X,Y)board[X][Y]& board[X+1][Y]& board[X][Y-1]& board[X+1][Y-1]
- #define MARK(X,Y)board[X][Y]=board[X+1][Y]=board[X][Y-1]=board[X+1][Y-1]|=4
- #define MAX(A,B)(A>B)?A:B
- #define MIN(A,B)(A>B)?B:A
- enum Type {White=1, Black=2, Dead=4};
- typedef struct {
- char x, y;
- unsigned int type;
- } Block;
- Block b;
- SDL_Event tick, quit;
- SDL_Rect r;
- SDL_Surface *screen;
- SDL_TimerID gameplay;
- int light, dark, games, flags, bg = -1;
- unsigned char **board, reset, height = 20, width = 20, size = 20, margin = 2;
- char timer = -127;
- void background (void){
- switch (bg){
- case 0:
- SDL_FillRect(screen, NULL, 0x000000);
- r.x = timer*width*size/127; r.y = 0;
- r.w = width*size; r.h = height*size;
- SDL_FillRect(screen, &r, 0xffffff);
- break;
- case -1:
- SDL_FillRect(screen, NULL, MAX(0x777777 - dark*0x010101, 0x000000));
- r.x = timer*width*size/127; r.y = 0;
- r.w = width*size; r.h = height*size;
- SDL_FillRect(screen, &r, MIN(0x888888 + light*0x010101, 0xffffff));
- break;
- default:
- SDL_FillRect(screen, NULL, bg);
- r.x = timer*width*size/127; r.y = 0;
- r.w = width*size; r.h = height*size;
- SDL_FillRect(screen, &r, bg>0x808080?bg-0x222222:bg+0x222222);
- break;
- }
- }
- Uint32 callback (Uint32 speed, void * param){
- SDL_PushEvent(&tick);
- return (speed);
- }
- int color (char type){
- switch (type&~Dead){
- case White: return 0xffffff;
- case Black: return 0x000000;
- }
- }
- void count (void){
- printf ("Game %d: \nWhite Clear: %d\nBlack Clear: %d\nTotal Clear: %d\n",
- ++games, dark, light, dark+light);
- }
- void block (void){
- BLOCK(b.x, b.y, BTYPE(0xff, 0))
- BLOCK(b.x+1, b.y, BTYPE(0xff00, 8))
- BLOCK(b.x+1, b.y+1, BTYPE(0xff0000, 16))
- BLOCK(b.x, b.y+1, BTYPE(0xff000000, 24))
- }
- void draw (void){
- background();
- block();
- int i, j;
- for (i = 0; i < width; i++)
- for (j = height - 1; j > -1; j--)
- if (board[i][j]){
- BLOCK(i, j, board[i][j]);
- }
- SDL_UpdateRect(screen, 0, 0, 0, 0);
- }
- void fullscreen (void){
- screen = SDL_SetVideoMode(width*size, height*size, 32, flags);
- SDL_ShowCursor(flags & SDL_FULLSCREEN?SDL_DISABLE:SDL_ENABLE);
- }
- void generate (void){
- if (b.x == width/2-1 && b.y == 0){
- SDL_RemoveTimer(gameplay);
- draw();
- gameplay = NULL;
- count();
- light = dark = 0;
- draw();
- reset = 1;
- }
- b.type = rand();
- b.x = width/2-1; b.y = 0;
- }
- void haft (void){
- if (board[b.x][b.y+2]||board[b.x+1][b.y+2]||b.y > height-3){
- board[b.x][b.y] = BTYPE(0xff, 0);
- board[b.x+1][b.y] = BTYPE(0xff00, 8);
- board[b.x+1][b.y+1] = BTYPE(0xff0000, 16);
- board[b.x][b.y+1] = BTYPE(0xff000000, 24);
- generate();
- } else
- b.y++;
- }
- void iterate (){
- background();
- block();
- int i, j;
- for (i = 0; i < width; i++)
- for (j = height - 1; j > -1; j--){
- if (board[i][j]){
- if (timer == 0 && board[i][j]&White && board[i][j]&Dead){
- board[i][j] = 0;
- dark++;
- } else if (timer == -127 && board[i][j]&Black &&
- board[i][j]&Dead){
- board[i][j] = 0;
- light++;
- } else if (board[i][j+1] || j == height - 1){
- if (i < width - 1 && j > 0){
- r.x = i*size+margin; r.y = (j-1)*size+margin;
- r.w = r.h = 2*(size-margin);
- if (S2X2(i,j) & 1){
- SDL_FillRect(screen, &r, 0xffffff);
- MARK(i,j);
- } else if (S2X2(i,j) & 2){
- SDL_FillRect(screen, &r, 0x000000);
- MARK(i,j);
- }
- }
- BLOCK(i, j, board[i][j]);
- } else {
- board[i][j+1] = board[i][j];
- board[i][j] = 0;
- BLOCK(i, j+1, board[i][j+1]);
- }
- }
- }
- if (++timer % 10 == 0) haft();
- SDL_UpdateRect(screen, 0, 0, 0, 0);
- }
- void keys (SDL_Event event){
- switch (event.key.keysym.sym){
- case SDLK_LEFT:
- case SDLK_h:
- case SDLK_a:
- if (b.x > 0 && !(board[b.x-1][b.y]
- ||board[b.x-1][b.y+1]))
- b.x--;
- break;
- case SDLK_DOWN:
- case SDLK_j:
- case SDLK_s:
- haft();
- break;
- case SDLK_UP:
- case SDLK_k:
- case SDLK_w:
- b.type = (b.type & 0xff) << 24 | b.type >> 8;
- break;
- case SDLK_RIGHT:
- case SDLK_l:
- case SDLK_d:
- if (b.x < width-2 && !(board[b.x+2][b.y]
- ||board[b.x+2][b.y+1]))
- b.x++;
- break;
- }
- }
- int main (int argc, char *argv[]){
- unsigned char i;
- if (argc > 1){
- for (i = 1; i < argc; i++){
- switch (argv[i][1]){
- case 'b':
- i++;
- if (atoi(argv[i]) > 0)
- bg = rand();
- else
- bg = atoi(argv[i]);
- break;
- case 'f':
- flags |= SDL_FULLSCREEN;
- break;
- case 'h':
- i++;
- height = MAX(atoi(argv[i]) % 255,4);
- break;
- case 'm':
- margin = atoi(argv[++i]) % 255;
- break;
- case 's':
- size = atoi(argv[++i]) % 255;
- break;
- case 'w':
- i++;
- width = MAX(atoi(argv[i]) % 255,4);
- break;
- }
- margin = MIN(MAX(0,(size-1)/2), margin);
- }
- }
- board = (unsigned char **)malloc(width * sizeof(char *));
- for(i = 0; i < width; i++)
- board[i] = (unsigned char *)malloc(height * sizeof(char));
- SDL_Event event;
- generate();
- tick.type=SDL_USEREVENT;
- quit.type=SDL_QUIT;
- SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER);
- SDL_EnableKeyRepeat(60, 60);
- fullscreen();
- gameplay = SDL_AddTimer(60, callback, NULL);
- while ( SDL_WaitEvent(&event) ) {
- switch (event.type) {
- case SDL_KEYUP:
- switch (event.key.keysym.sym){
- case SDLK_SPACE:
- if (gameplay == NULL){
- gameplay = SDL_AddTimer(60, callback, NULL);
- if (reset){
- for(i = 0; i < width; i++)
- memset(board[i], 0, height*sizeof (char));
- reset--;
- }
- } else {
- SDL_RemoveTimer(gameplay);
- gameplay = NULL;
- }
- break;
- case SDLK_RETURN:
- flags ^= SDL_FULLSCREEN;
- fullscreen();
- draw();
- break;
- case SDLK_q:
- case SDLK_ESCAPE:
- SDL_PushEvent(&quit);
- break;
- }
- break;
- case SDL_KEYDOWN:
- if (gameplay)
- keys(event);
- break;
- case SDL_USEREVENT:
- iterate();
- break;
- case SDL_QUIT:
- if (!reset)
- count();
- SDL_Quit();
- }
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement