Guest User

[C] Snake, Amos_MHF

a guest
Dec 4th, 2010
129
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 9.25 KB | None | 0 0
  1. /*==========================================================*
  2.  * Snake v1.0                                               *
  3.  *----------------------------------------------------------*
  4.  * Amos_MHF                                                 *
  5.  * 01/12/2010                                               *
  6.  * Linguaggio: C                                            *
  7.  *==========================================================*/
  8.  
  9. /* Inclusione header */
  10. #include <stdio.h>
  11. #include <time.h>
  12. #include <conio.h>
  13. #include <windows.h>
  14.  
  15. /* Direttive define */
  16. #define FIELD_X 32
  17. #define FIELD_Y 12
  18. #define START_LEN 1
  19. #define MAX_LEN 149
  20. #define HEAD_X snake.x[0]
  21. #define HEAD_Y snake.y[0]
  22. #define SNAKE_CH 'o'
  23. #define FOOD_CH '*'
  24. #define ASCII_LEFT 97
  25. #define ASCII_UP 119
  26. #define ASCII_RIGHT 100
  27. #define ASCII_DOWN 115
  28. #define EASY_MS 60
  29. #define MEDIUM_MS 50
  30. #define HARD_MS 40
  31.  
  32. /* Prototipi funzioni */
  33. void food_gen(int *x, int *y);
  34. int move(int x[], int y[], int *len, int dir, int *food_x, int *food_y, int *points, int *game_over);
  35. int crash(int x[], int y[], int dir, int len);
  36. int opp_dir(int dir);
  37. void refresh(int x[], int y[], int *len, int *food_x, int *food_y, int points);
  38. void clear_screen();
  39.  
  40. /* Definizione struct */
  41. struct snake
  42. {
  43.     int x[MAX_LEN];
  44.     int y[MAX_LEN];
  45.     int len;
  46.     int dir;
  47. };
  48.  
  49. struct food
  50. {
  51.     int x;
  52.     int y;
  53. };
  54.  
  55. /* Main */
  56. main()
  57. {
  58.     /* Dichiarazione variabili e strutture */
  59.     struct snake snake;
  60.     struct food food = {0, 0}; /* Inizializz. con coordinate 0, 0 */
  61.     int points = 0;
  62.     int game_over = 0;
  63.     int i;
  64.     int snake_opp; /* Direzione opposta a quella attuale */
  65.     int diff; /* Livello di difficoltà */
  66.     int wait; /* Attesa tra i refresh dello schermo (dipende da diff) */
  67.     int c;
  68.  
  69.     /* Inizializzazione variabili snake */
  70.     HEAD_X = (FIELD_X-2)/2;
  71.     HEAD_Y = (FIELD_Y-2)/2;
  72.     snake.len = START_LEN;
  73.     snake.dir = ASCII_UP;
  74.  
  75.     /* Rende non visibili (coordinate = 0) i pezzi dello snake dal secondo all'ultimo */
  76.     for(i=1; i<MAX_LEN; i++)
  77.         snake.x[i] = snake.y[i] = 0;
  78.  
  79.     food_gen(&food.x, &food.y); /* Genera il primo cibo */
  80.  
  81.     printf("\n\tSnake v1.0\n");
  82.     printf("\nSelezione difficolta\':"
  83.            "\n1. Facile"
  84.            "\n2. Medio"
  85.            "\n3. Difficile"
  86.            "\n0. Esci\n\n"
  87.            "  Scelta: ");
  88.     do
  89.     {
  90.         scanf("%d", &diff);
  91.         switch(diff) /* In base alla difficoltà, assegna valore a wait */
  92.         {
  93.             case 1:
  94.             {
  95.                 wait = EASY_MS;
  96.                 break;
  97.             }
  98.             case 2:
  99.             {
  100.                 wait = MEDIUM_MS;
  101.                 break;
  102.             }
  103.             case 3:
  104.             {
  105.                 wait = HARD_MS;
  106.                 break;
  107.             }
  108.             default: /* Se diff non appartiene a {1, 2, 3} */
  109.             {
  110.                 if(diff) /* Se diff!=0 (cioè se non è stato scelto Esci */
  111.                 {
  112.                     wait = 0;
  113.                     printf("Inserire una scelta valida.\n");
  114.                 }
  115.                 break;
  116.             }
  117.         }
  118.     }while(wait==0 && diff!= 0); /* Esegui ciclo finché l'input è invalido */
  119.  
  120.     if(diff) /* Se è stata scelta una difficoltà (non è stato scelto esci) */
  121.     {
  122.         do
  123.         {
  124.             refresh(snake.x, snake.y, &snake.len, &food.x, &food.y, points); /* Disegna */
  125.             if(kbhit()) /* Se almeno un carattere è presente nel buffer della tastiera */
  126.             {
  127.                 do{
  128.                     snake_opp = opp_dir(snake.dir); /* Individua la direzione opposta a quella attuale */
  129.                     if((snake.dir = getch()) == snake_opp) /* Se è stata scelta la direzione opposta, mantiene quella attuale */
  130.                         snake.dir = opp_dir(snake.dir);
  131.                 /* Ripete l'input finché non corrisponde ad una direzione */
  132.                 }while(snake.dir != ASCII_UP && snake.dir != ASCII_LEFT && snake.dir != ASCII_DOWN && snake.dir != ASCII_RIGHT);
  133.             }
  134.             if(move(snake.x, snake.y, &snake.len, snake.dir, &food.x, &food.y, &points, &game_over)) /* Se nel movimento lo snake mangia */
  135.                 food_gen(&food.x, &food.y); /* Genera cibo */
  136.             Sleep(wait); /* Attendi per il prossimo refresh */
  137.         }while(!game_over); /* Ripete il ciclo finché non avviene il game over */
  138.         printf("\n\tG A M E   O V E R");
  139.         while((c = getchar()) != '\n' && c != EOF)
  140.                  ;
  141.         while(getchar() != '\n')
  142.                         ;
  143.     }
  144. }
  145.  
  146. void food_gen(int *x, int *y)
  147. {
  148.     srand((unsigned int)time(NULL)); /* Prepara il random utilizzando l'orario del SO */
  149.     *x = (1 + (rand() % (FIELD_X - 3))); /* *x diventa un valore nel range [1, 31] */
  150.     srand((unsigned int)time(NULL));
  151.     *y = (1 + (rand() % (FIELD_Y - 3))); /* *y diventa un valore nel range [1, 11] */
  152. }
  153.  
  154. int move(int x[], int y[], int *len, int dir, int *food_x, int *food_y, int *points, int *game_over)
  155. {
  156.     int eaten = 0; /* Snake non ha ancora mangiato nulla */
  157.     int i;
  158.     if((x[0] == *food_x) && (y[0] == *food_y) && (*len < (MAX_LEN - 1))) /* Se snake mangia (coord. testa == coord.cibo) e può allungarsi */
  159.     {
  160.         *points += 1; /* Aumenta punti */
  161.         *len += 1; /* Aumenta lunghezza */
  162.         eaten = 1; /* Snake ha mangiato */
  163.  
  164.         /* Posiziona la nuova parte di snake sopra quella appena precedente */
  165.         x[*len-1] = x[*len-2];
  166.         y[*len-1] = y[*len-2];
  167.         food_gen(&food_x, &food_y); /* Genera cibo */
  168.     }
  169.     for(i=*len-1; i>0; i--) /* Per tutte le parti di snake tranne la testa */
  170.     {
  171.         /* Ogni parte prende le coordinate di quella precedente */
  172.         x[i] = x[i-1];
  173.         y[i] = y[i-1];
  174.     }
  175.     switch(dir) /* In base alla direzione, sposta la testa */
  176.     {
  177.         case ASCII_LEFT:
  178.         {
  179.             if(x[0] == 1) /* Se snake è al lim sinistro */
  180.                 x[0] = FIELD_X - 3;
  181.             else
  182.                 x[0] -= 1;
  183.             break;
  184.         }
  185.         case ASCII_UP:
  186.         {
  187.             if(y[0] == 1) /* Se snake è al lim superiore */
  188.                 y[0] = FIELD_Y - 3;
  189.             else
  190.                 y[0] -= 1;
  191.             break;
  192.         }
  193.         case ASCII_RIGHT:
  194.         {
  195.             if(x[0] == FIELD_X - 3) /* Se snake è al lim destro */
  196.                 x[0] = 1;
  197.             else
  198.                 x[0] += 1;
  199.             break;
  200.         }
  201.         case ASCII_DOWN:
  202.         {
  203.             if(y[0] == FIELD_Y - 3) /* Se snake è al lim inferiore */
  204.                 y[0] = 1;
  205.             else
  206.                 y[0] += 1;
  207.             break;
  208.         }
  209.     }
  210.     if(*len > 1) /* Se la lunghezza è maggiore di uno, controlla che non vi siano collisioni */
  211.         *game_over = crash(x, y, dir, *len);
  212.     return eaten; /* Ritorna eaten (il serpente ha mangiato?) */
  213. }
  214.  
  215. int opp_dir(int dir)
  216. {
  217.     switch(dir) /* Data in input la direzione, ritorna il valore di quella opposta */
  218.     {
  219.         case ASCII_DOWN:
  220.         {
  221.             return ASCII_UP;
  222.         }
  223.         case ASCII_RIGHT:
  224.         {
  225.             return ASCII_LEFT;
  226.         }
  227.         case ASCII_UP:
  228.         {
  229.             return ASCII_DOWN;
  230.         }
  231.         case ASCII_LEFT:
  232.         {
  233.             return ASCII_RIGHT;
  234.         }
  235.     }
  236.     return 0; /* Se direzione invalida, ritorna 0 (debug) */
  237. }
  238.  
  239. int crash(int x[], int y[], int dir, int len)
  240. {
  241.     int i;
  242.     /* Controlla se la testa vada in collisione con qualsiasi altra parte di snake.
  243.        In tal caso, ritorna 1. */
  244.     for(i=1; i<len; i++)
  245.     {
  246.         if((x[0] == x[i]) && (y[0] == y[i]))
  247.            return 1;
  248.     }
  249.     return 0; /* Ritorna 0 in assenza di collisioni */
  250. }
  251.  
  252. void refresh(int x[], int y[], int *len, int *food_x, int *food_y, int points)
  253. {
  254.     int i, j, k;
  255.     int found;
  256.     clear_screen();
  257.  
  258.     /* Riga 1 */
  259.     putchar('/');
  260.     for(i=1; i<FIELD_X-2; i++)
  261.         putchar('-');
  262.     putchar('\\');
  263.     printf("Punti: %05d", points);
  264.     putchar('\n');
  265.  
  266.     /* Righe 2..(n-1) */
  267.     for(j=1; j<FIELD_Y-2; j++)
  268.     {
  269.         for(i=0; i<FIELD_X-1; i++)
  270.         {
  271.             switch(i)
  272.             {
  273.                 case 0:
  274.                 {
  275.                     putchar('|');
  276.                     break;
  277.                 }
  278.                 case FIELD_X-2:
  279.                 {
  280.                     putchar('|');
  281.                     break;
  282.                 }
  283.                 default:
  284.                 {
  285.                     found = 0;
  286.                     for(k=0; k<*len; k++)
  287.                     {
  288.                         if(i==x[k] && j==y[k])
  289.                         {
  290.                             putchar(SNAKE_CH);
  291.                             k = *len;
  292.                             found = 1;
  293.                             break;
  294.                         }
  295.                     }
  296.                     if(!found)
  297.                     {
  298.                         if(*food_x==i && *food_y==j)
  299.                             putchar(FOOD_CH);
  300.                         else
  301.                         {
  302.                             putchar(' ');
  303.                             break;
  304.                         }
  305.                     }
  306.                 }
  307.             }
  308.         }
  309.         putchar('\n');
  310.     }
  311.  
  312.     /* Riga n */
  313.     putchar('\\');
  314.     for(i=1; i<FIELD_X-2; i++)
  315.         putchar('-');
  316.     putchar('/');
  317. }
  318.  
  319. void clear_screen()
  320. {
  321.     system("cls");
  322. }
Advertisement
Add Comment
Please, Sign In to add comment