Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*==========================================================*
- * Snake v1.0 *
- *----------------------------------------------------------*
- * Amos_MHF *
- * 01/12/2010 *
- * Linguaggio: C *
- *==========================================================*/
- /* Inclusione header */
- #include <stdio.h>
- #include <time.h>
- #include <conio.h>
- #include <windows.h>
- /* Direttive define */
- #define FIELD_X 32
- #define FIELD_Y 12
- #define START_LEN 1
- #define MAX_LEN 149
- #define HEAD_X snake.x[0]
- #define HEAD_Y snake.y[0]
- #define SNAKE_CH 'o'
- #define FOOD_CH '*'
- #define ASCII_LEFT 97
- #define ASCII_UP 119
- #define ASCII_RIGHT 100
- #define ASCII_DOWN 115
- #define EASY_MS 60
- #define MEDIUM_MS 50
- #define HARD_MS 40
- /* Prototipi funzioni */
- void food_gen(int *x, int *y);
- int move(int x[], int y[], int *len, int dir, int *food_x, int *food_y, int *points, int *game_over);
- int crash(int x[], int y[], int dir, int len);
- int opp_dir(int dir);
- void refresh(int x[], int y[], int *len, int *food_x, int *food_y, int points);
- void clear_screen();
- /* Definizione struct */
- struct snake
- {
- int x[MAX_LEN];
- int y[MAX_LEN];
- int len;
- int dir;
- };
- struct food
- {
- int x;
- int y;
- };
- /* Main */
- main()
- {
- /* Dichiarazione variabili e strutture */
- struct snake snake;
- struct food food = {0, 0}; /* Inizializz. con coordinate 0, 0 */
- int points = 0;
- int game_over = 0;
- int i;
- int snake_opp; /* Direzione opposta a quella attuale */
- int diff; /* Livello di difficoltà */
- int wait; /* Attesa tra i refresh dello schermo (dipende da diff) */
- int c;
- /* Inizializzazione variabili snake */
- HEAD_X = (FIELD_X-2)/2;
- HEAD_Y = (FIELD_Y-2)/2;
- snake.len = START_LEN;
- snake.dir = ASCII_UP;
- /* Rende non visibili (coordinate = 0) i pezzi dello snake dal secondo all'ultimo */
- for(i=1; i<MAX_LEN; i++)
- snake.x[i] = snake.y[i] = 0;
- food_gen(&food.x, &food.y); /* Genera il primo cibo */
- printf("\n\tSnake v1.0\n");
- printf("\nSelezione difficolta\':"
- "\n1. Facile"
- "\n2. Medio"
- "\n3. Difficile"
- "\n0. Esci\n\n"
- " Scelta: ");
- do
- {
- scanf("%d", &diff);
- switch(diff) /* In base alla difficoltà, assegna valore a wait */
- {
- case 1:
- {
- wait = EASY_MS;
- break;
- }
- case 2:
- {
- wait = MEDIUM_MS;
- break;
- }
- case 3:
- {
- wait = HARD_MS;
- break;
- }
- default: /* Se diff non appartiene a {1, 2, 3} */
- {
- if(diff) /* Se diff!=0 (cioè se non è stato scelto Esci */
- {
- wait = 0;
- printf("Inserire una scelta valida.\n");
- }
- break;
- }
- }
- }while(wait==0 && diff!= 0); /* Esegui ciclo finché l'input è invalido */
- if(diff) /* Se è stata scelta una difficoltà (non è stato scelto esci) */
- {
- do
- {
- refresh(snake.x, snake.y, &snake.len, &food.x, &food.y, points); /* Disegna */
- if(kbhit()) /* Se almeno un carattere è presente nel buffer della tastiera */
- {
- do{
- snake_opp = opp_dir(snake.dir); /* Individua la direzione opposta a quella attuale */
- if((snake.dir = getch()) == snake_opp) /* Se è stata scelta la direzione opposta, mantiene quella attuale */
- snake.dir = opp_dir(snake.dir);
- /* Ripete l'input finché non corrisponde ad una direzione */
- }while(snake.dir != ASCII_UP && snake.dir != ASCII_LEFT && snake.dir != ASCII_DOWN && snake.dir != ASCII_RIGHT);
- }
- if(move(snake.x, snake.y, &snake.len, snake.dir, &food.x, &food.y, &points, &game_over)) /* Se nel movimento lo snake mangia */
- food_gen(&food.x, &food.y); /* Genera cibo */
- Sleep(wait); /* Attendi per il prossimo refresh */
- }while(!game_over); /* Ripete il ciclo finché non avviene il game over */
- printf("\n\tG A M E O V E R");
- while((c = getchar()) != '\n' && c != EOF)
- ;
- while(getchar() != '\n')
- ;
- }
- }
- void food_gen(int *x, int *y)
- {
- srand((unsigned int)time(NULL)); /* Prepara il random utilizzando l'orario del SO */
- *x = (1 + (rand() % (FIELD_X - 3))); /* *x diventa un valore nel range [1, 31] */
- srand((unsigned int)time(NULL));
- *y = (1 + (rand() % (FIELD_Y - 3))); /* *y diventa un valore nel range [1, 11] */
- }
- int move(int x[], int y[], int *len, int dir, int *food_x, int *food_y, int *points, int *game_over)
- {
- int eaten = 0; /* Snake non ha ancora mangiato nulla */
- int i;
- if((x[0] == *food_x) && (y[0] == *food_y) && (*len < (MAX_LEN - 1))) /* Se snake mangia (coord. testa == coord.cibo) e può allungarsi */
- {
- *points += 1; /* Aumenta punti */
- *len += 1; /* Aumenta lunghezza */
- eaten = 1; /* Snake ha mangiato */
- /* Posiziona la nuova parte di snake sopra quella appena precedente */
- x[*len-1] = x[*len-2];
- y[*len-1] = y[*len-2];
- food_gen(&food_x, &food_y); /* Genera cibo */
- }
- for(i=*len-1; i>0; i--) /* Per tutte le parti di snake tranne la testa */
- {
- /* Ogni parte prende le coordinate di quella precedente */
- x[i] = x[i-1];
- y[i] = y[i-1];
- }
- switch(dir) /* In base alla direzione, sposta la testa */
- {
- case ASCII_LEFT:
- {
- if(x[0] == 1) /* Se snake è al lim sinistro */
- x[0] = FIELD_X - 3;
- else
- x[0] -= 1;
- break;
- }
- case ASCII_UP:
- {
- if(y[0] == 1) /* Se snake è al lim superiore */
- y[0] = FIELD_Y - 3;
- else
- y[0] -= 1;
- break;
- }
- case ASCII_RIGHT:
- {
- if(x[0] == FIELD_X - 3) /* Se snake è al lim destro */
- x[0] = 1;
- else
- x[0] += 1;
- break;
- }
- case ASCII_DOWN:
- {
- if(y[0] == FIELD_Y - 3) /* Se snake è al lim inferiore */
- y[0] = 1;
- else
- y[0] += 1;
- break;
- }
- }
- if(*len > 1) /* Se la lunghezza è maggiore di uno, controlla che non vi siano collisioni */
- *game_over = crash(x, y, dir, *len);
- return eaten; /* Ritorna eaten (il serpente ha mangiato?) */
- }
- int opp_dir(int dir)
- {
- switch(dir) /* Data in input la direzione, ritorna il valore di quella opposta */
- {
- case ASCII_DOWN:
- {
- return ASCII_UP;
- }
- case ASCII_RIGHT:
- {
- return ASCII_LEFT;
- }
- case ASCII_UP:
- {
- return ASCII_DOWN;
- }
- case ASCII_LEFT:
- {
- return ASCII_RIGHT;
- }
- }
- return 0; /* Se direzione invalida, ritorna 0 (debug) */
- }
- int crash(int x[], int y[], int dir, int len)
- {
- int i;
- /* Controlla se la testa vada in collisione con qualsiasi altra parte di snake.
- In tal caso, ritorna 1. */
- for(i=1; i<len; i++)
- {
- if((x[0] == x[i]) && (y[0] == y[i]))
- return 1;
- }
- return 0; /* Ritorna 0 in assenza di collisioni */
- }
- void refresh(int x[], int y[], int *len, int *food_x, int *food_y, int points)
- {
- int i, j, k;
- int found;
- clear_screen();
- /* Riga 1 */
- putchar('/');
- for(i=1; i<FIELD_X-2; i++)
- putchar('-');
- putchar('\\');
- printf("Punti: %05d", points);
- putchar('\n');
- /* Righe 2..(n-1) */
- for(j=1; j<FIELD_Y-2; j++)
- {
- for(i=0; i<FIELD_X-1; i++)
- {
- switch(i)
- {
- case 0:
- {
- putchar('|');
- break;
- }
- case FIELD_X-2:
- {
- putchar('|');
- break;
- }
- default:
- {
- found = 0;
- for(k=0; k<*len; k++)
- {
- if(i==x[k] && j==y[k])
- {
- putchar(SNAKE_CH);
- k = *len;
- found = 1;
- break;
- }
- }
- if(!found)
- {
- if(*food_x==i && *food_y==j)
- putchar(FOOD_CH);
- else
- {
- putchar(' ');
- break;
- }
- }
- }
- }
- }
- putchar('\n');
- }
- /* Riga n */
- putchar('\\');
- for(i=1; i<FIELD_X-2; i++)
- putchar('-');
- putchar('/');
- }
- void clear_screen()
- {
- system("cls");
- }
Advertisement
Add Comment
Please, Sign In to add comment