Advertisement
Guest User

JonCaldwell

a guest
Jun 22nd, 2009
139
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.27 KB | None | 0 0
  1. // vim: ts=4:sw=4
  2. //gcc -lSDL nego.c
  3. #include "SDL/SDL.h"
  4. #define BLOCK(X,Y,T) r.x = (X) * size + margin; r.y = (Y) * size + margin; \
  5.         r.w = r.h = size - 2 * margin; SDL_FillRect(screen, &r, color(T));
  6. #define BTYPE(N,S)((b.type & N) >> S)&White?White:Black
  7. #define S2X2(X,Y)board[X][Y]& board[X+1][Y]& board[X][Y-1]& board[X+1][Y-1]
  8. #define MARK(X,Y)board[X][Y]=board[X+1][Y]=board[X][Y-1]=board[X+1][Y-1]|=4
  9. #define MAX(A,B)(A>B)?A:B
  10. #define MIN(A,B)(A>B)?B:A
  11.  
  12. enum Type {White=1, Black=2, Dead=4};
  13. typedef struct {
  14.     char x, y;
  15.     unsigned int type;
  16. } Block;
  17.  
  18. Block b;
  19. SDL_Event tick, quit;
  20. SDL_Rect r;
  21. SDL_Surface *screen;
  22. SDL_TimerID gameplay;
  23. int light, dark, games, flags, bg = -1;
  24. unsigned char **board, reset, height = 20, width = 20, size = 20, margin = 2;
  25. char timer = -127;
  26.  
  27. void background (void){
  28.     switch (bg){
  29.         case 0:
  30.             SDL_FillRect(screen, NULL, 0x000000);
  31.             r.x = timer*width*size/127; r.y = 0;
  32.             r.w = width*size; r.h = height*size;
  33.             SDL_FillRect(screen, &r, 0xffffff);
  34.             break;
  35.         case -1:
  36.             SDL_FillRect(screen, NULL, MAX(0x777777 - dark*0x010101, 0x000000));
  37.             r.x = timer*width*size/127; r.y = 0;
  38.             r.w = width*size; r.h = height*size;
  39.             SDL_FillRect(screen, &r, MIN(0x888888 + light*0x010101, 0xffffff));
  40.             break;
  41.         default:
  42.             SDL_FillRect(screen, NULL, bg);
  43.             r.x = timer*width*size/127; r.y = 0;
  44.             r.w = width*size; r.h = height*size;
  45.             SDL_FillRect(screen, &r, bg>0x808080?bg-0x222222:bg+0x222222);
  46.             break;
  47.     }
  48. }
  49.  
  50. Uint32 callback (Uint32 speed, void * param){
  51.     SDL_PushEvent(&tick);
  52.     return (speed);
  53. }
  54.  
  55. int color (char type){
  56.     switch (type&~Dead){
  57.         case White: return 0xffffff;
  58.         case Black: return 0x000000;
  59.     }
  60. }
  61.  
  62. void count (void){
  63.     printf ("Game %d: \nWhite Clear: %d\nBlack Clear: %d\nTotal Clear: %d\n",
  64.             ++games, dark, light, dark+light);
  65. }
  66.  
  67. void block (void){
  68.     BLOCK(b.x, b.y, BTYPE(0xff, 0))
  69.     BLOCK(b.x+1, b.y, BTYPE(0xff00, 8))
  70.     BLOCK(b.x+1, b.y+1, BTYPE(0xff0000, 16))
  71.     BLOCK(b.x, b.y+1, BTYPE(0xff000000, 24))
  72. }
  73.  
  74. void draw (void){
  75.     background();
  76.     block();
  77.     int i, j;
  78.     for (i = 0; i < width; i++)
  79.         for (j = height - 1; j > -1; j--)
  80.             if (board[i][j]){
  81.                 BLOCK(i, j, board[i][j]);
  82.             }
  83.     SDL_UpdateRect(screen, 0, 0, 0, 0);
  84. }
  85.  
  86. void fullscreen (void){
  87.     screen = SDL_SetVideoMode(width*size, height*size, 32, flags);
  88.     SDL_ShowCursor(flags & SDL_FULLSCREEN?SDL_DISABLE:SDL_ENABLE);
  89. }
  90.  
  91. void generate (void){
  92.     if (b.x == width/2-1 && b.y == 0){
  93.         SDL_RemoveTimer(gameplay);
  94.         draw();
  95.         gameplay = NULL;
  96.         count();
  97.         light = dark = 0;
  98.         draw();
  99.         reset = 1;
  100.     }
  101.     b.type = rand();
  102.     b.x = width/2-1; b.y = 0;
  103. }
  104.  
  105. void haft (void){
  106.     if (board[b.x][b.y+2]||board[b.x+1][b.y+2]||b.y > height-3){
  107.         board[b.x][b.y] = BTYPE(0xff, 0);
  108.         board[b.x+1][b.y] = BTYPE(0xff00, 8);
  109.         board[b.x+1][b.y+1] = BTYPE(0xff0000, 16);
  110.         board[b.x][b.y+1] = BTYPE(0xff000000, 24);
  111.         generate();
  112.     } else
  113.         b.y++;
  114. }
  115.  
  116. void iterate (){
  117.     background();
  118.     block();
  119.     int i, j;
  120.     for (i = 0; i < width; i++)
  121.         for (j = height - 1; j > -1; j--){
  122.             if (board[i][j]){
  123.                 if (timer == 0 && board[i][j]&White && board[i][j]&Dead){
  124.                     board[i][j] = 0;
  125.                     dark++;
  126.                 } else if (timer == -127 && board[i][j]&Black &&
  127.                         board[i][j]&Dead){
  128.                     board[i][j] = 0;
  129.                     light++;
  130.                 } else if (board[i][j+1] || j == height - 1){
  131.                     if (i < width - 1 && j > 0){
  132.                         r.x = i*size+margin; r.y = (j-1)*size+margin;
  133.                         r.w = r.h = 2*(size-margin);
  134.                         if (S2X2(i,j) & 1){
  135.                             SDL_FillRect(screen, &r, 0xffffff);
  136.                             MARK(i,j);
  137.                         } else if (S2X2(i,j) & 2){
  138.                             SDL_FillRect(screen, &r, 0x000000);
  139.                             MARK(i,j);
  140.                         }
  141.                     }
  142.                     BLOCK(i, j, board[i][j]);
  143.                 } else {
  144.                     board[i][j+1] = board[i][j];
  145.                     board[i][j] = 0;
  146.                     BLOCK(i, j+1, board[i][j+1]);
  147.                 }
  148.             }
  149.         }
  150.     if (++timer % 10 == 0) haft();
  151.     SDL_UpdateRect(screen, 0, 0, 0, 0);
  152. }
  153.  
  154. void keys (SDL_Event event){
  155.     switch (event.key.keysym.sym){
  156.         case SDLK_LEFT:
  157.         case SDLK_h:
  158.         case SDLK_a:
  159.             if (b.x > 0 && !(board[b.x-1][b.y]
  160.                     ||board[b.x-1][b.y+1]))
  161.                 b.x--;
  162.             break;
  163.         case SDLK_DOWN:
  164.         case SDLK_j:
  165.         case SDLK_s:
  166.             haft();
  167.             break;
  168.         case SDLK_UP:
  169.         case SDLK_k:
  170.         case SDLK_w:
  171.             b.type = (b.type & 0xff) << 24 | b.type >> 8;
  172.             break;
  173.         case SDLK_RIGHT:
  174.         case SDLK_l:
  175.         case SDLK_d:
  176.             if (b.x < width-2 && !(board[b.x+2][b.y]
  177.                     ||board[b.x+2][b.y+1]))
  178.                 b.x++;
  179.             break;
  180.     }
  181. }
  182.  
  183. int main (int argc, char *argv[]){
  184.     unsigned char i;
  185.     if (argc > 1){
  186.         for (i = 1; i < argc; i++){
  187.             switch (argv[i][1]){
  188.                 case 'b':
  189.                     i++;
  190.                     if (atoi(argv[i]) > 0)
  191.                         bg = rand();
  192.                     else
  193.                         bg = atoi(argv[i]);
  194.                     break;
  195.                 case 'f':
  196.                     flags |= SDL_FULLSCREEN;
  197.                     break;
  198.                 case 'h':
  199.                     i++;
  200.                     height = MAX(atoi(argv[i]) % 255,4);
  201.                     break;
  202.                 case 'm':
  203.                     margin = atoi(argv[++i]) % 255;
  204.                     break;
  205.                 case 's':
  206.                     size = atoi(argv[++i]) % 255;
  207.                     break;
  208.                 case 'w':
  209.                     i++;
  210.                     width = MAX(atoi(argv[i]) % 255,4);
  211.                     break;
  212.             }
  213.             margin = MIN(MAX(0,(size-1)/2), margin);
  214.         }
  215.     }
  216.  
  217.     board = (unsigned char **)malloc(width * sizeof(char *));
  218.         for(i = 0; i < width; i++)
  219.             board[i] = (unsigned char *)malloc(height * sizeof(char));
  220.     SDL_Event event;
  221.     generate();
  222.     tick.type=SDL_USEREVENT;
  223.     quit.type=SDL_QUIT;
  224.     SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER);
  225.     SDL_EnableKeyRepeat(60, 60);
  226.     fullscreen();
  227.     gameplay = SDL_AddTimer(60, callback, NULL);
  228.  
  229.     while ( SDL_WaitEvent(&event) ) {
  230.         switch (event.type) {
  231.             case SDL_KEYUP:
  232.                 switch (event.key.keysym.sym){
  233.                     case SDLK_SPACE:
  234.                         if (gameplay == NULL){
  235.                             gameplay = SDL_AddTimer(60, callback, NULL);
  236.                             if (reset){
  237.                                 for(i = 0; i < width; i++)
  238.                                     memset(board[i], 0, height*sizeof (char));
  239.                                 reset--;
  240.                             }
  241.                         } else {
  242.                             SDL_RemoveTimer(gameplay);
  243.                             gameplay = NULL;
  244.                         }
  245.                         break;
  246.                     case SDLK_RETURN:
  247.                         flags ^= SDL_FULLSCREEN;
  248.                         fullscreen();
  249.                         draw();
  250.                         break;
  251.                     case SDLK_q:
  252.                     case SDLK_ESCAPE:
  253.                         SDL_PushEvent(&quit);
  254.                         break;
  255.                 }
  256.                 break;
  257.             case SDL_KEYDOWN:
  258.                 if (gameplay)
  259.                     keys(event);
  260.                 break;
  261.             case SDL_USEREVENT:
  262.                 iterate();
  263.                 break;
  264.             case SDL_QUIT:
  265.                 if (!reset)
  266.                     count();
  267.                 SDL_Quit();
  268.         }
  269.     }
  270.     return 0;
  271. }
  272.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement