@Nippolo
Il codice mi è piaciuto, è ben strutturato, ci si mette bene le mani.
Ho messo la testa che si orienta, in velocità ho usato un'orribile variabile pubblica, ma si può integrare nelle chiamate con le altre, oppure una struct con tutte le caratteristiche del serpente...
Scusa mauronew, il tuo codice non l'ho ancora guardato.
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <time.h>
#include <windows.h>
#define R 15
#define C 29
#define DIM (R - 2) * (C - 2)
#define START_LENGTH 3 // min 2 max 7
#define DIM_OBSTACLE 31
#define BITE 3
#define SOUND 7
#define BLOCK_BODY 79
#define BLOCK_BODY_U 30
#define BLOCK_BODY_L 17
#define BLOCK_BODY_R 16
#define BLOCK_BODY_D 31
#define UL 201
#define UR 187
#define DL 200
#define DR 188
#define HOR 205
#define VER 186
#define CROSS 206
#define UL_THROUGH 218
#define UR_THROUGH 191
#define DL_THROUGH 192
#define DR_THROUGH 217
#define HOR_THROUGH 196
#define VER_THROUGH 179
#define UP 72
#define DOWN 80
#define LEFT 75
#define RIGHT 77
int head_direction = BLOCK_BODY_R;
COORD coord_obstacle[DIM_OBSTACLE] = {{ 3, R / 2}, { 4, R / 2}, { 5, R / 2}, { 6, R / 2}, { 7, R / 2}, { 8, R / 2}, { 9, R / 2},
{10, R / 2}, {11, R / 2}, {12, R / 2}, {13, R / 2}, {15, R / 2}, {16, R / 2}, {17, R / 2},
{18, R / 2}, {19, R / 2}, {20, R / 2}, {21, R / 2}, {22, R / 2}, {23, R / 2}, {24, R / 2},
{25, R / 2}, {C / 2, 3}, {C / 2, 4}, {C / 2, 5}, {C / 2, 6}, {C / 2, 8}, {C / 2, 9},
{C / 2, 10}, {C / 2, 11}, {C / 2, R / 2}};
int char_obstacle[DIM_OBSTACLE] = {HOR, HOR, HOR, HOR, HOR, HOR, HOR, HOR, HOR, HOR, HOR, HOR, HOR, HOR, HOR, HOR, HOR, HOR,
HOR, HOR, HOR, HOR, VER, VER, VER, VER, VER, VER, VER, VER, CROSS};
void set_position(const COORD xy)
{
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), xy);
}
void delay(const int ms)
{
clock_t goal = ms * CLOCKS_PER_SEC / 1000 + clock();
while(goal > clock());
}
int get_input(const int direction)
{
return getch() == 224 ? getch() : direction;
}
void choose_settings(int *through, int *obstacle)
{
char c;
do
{
printf("THROUGH MODE (y/n) --> ");
scanf(" %c", &c);
}
while(c != 'y' && c != 'n');
*through = c == 'y';
do
{
printf("OBSTACLES (y/n) --> ");
scanf(" %c", &c);
}
while(c != 'y' && c != 'n');
*obstacle = c == 'y';
system("CLS");
}
void initialize_grid(int grid[R][C])
{
for(unsigned int i = 1; i < R - 1; ++i)
{
for(unsigned int j = 1; j < C - 1; grid[i][j++] = 1);
}
}
void print_and_apply_border(int grid [R][C], const int through)
{
printf("%c", through ? UL_THROUGH : UL);
for(unsigned int i = 0; i < C - 2; ++i)
{
printf("%c", through ? HOR_THROUGH : HOR);
}
printf("%c\n", through ? UR_THROUGH : UR);
for(unsigned int i = 0; i < R - 2; ++i)
{
printf("%c", through ? VER_THROUGH : VER);
set_position((COORD){C - 1, i + 1});
printf("%c\n", through ? VER_THROUGH : VER);
}
printf("%c", through ? DL_THROUGH : DL);
for(unsigned int i = 0; i < C - 2; ++i)
{
printf("%c", through ? HOR_THROUGH : HOR);
}
printf("%c\n", through ? DR_THROUGH : DR);
if(!through)
{
for(unsigned int j = 0; j < C; ++j)
{
grid[0][j] = grid[R - 1][j] = 0;
}
for(unsigned int i = 1; i < R - 1; ++i)
{
grid[i][0] = grid[i][C - 1] = 0;
}
}
}
void print_and_apply_snake(int grid[R][C], const COORD *snake)
{
for(unsigned int i = 0; i < START_LENGTH-1; ++i)
{
set_position(snake[i]);
printf("%c", BLOCK_BODY);
grid[snake[i].Y][snake[i].X] = 0;
}
set_position(snake[START_LENGTH-1]);
printf("%c", head_direction);
grid[snake[START_LENGTH-1].Y][snake[START_LENGTH-1].X] = 0;
}
void print_and_apply_obstacle(int grid[R][C])
{
for(unsigned int i = 0; i < DIM_OBSTACLE; ++i)
{
set_position(coord_obstacle[i]);
printf("%c", char_obstacle[i]);
grid[coord_obstacle[i].Y][coord_obstacle[i].X] = 0;
}
}
void print_score(const unsigned int score)
{
set_position((COORD){C + 3, 1});
printf("SCORE: %u", score);
}
void generate_bite(int grid[R][C], const unsigned int score, const int obstacle)
{
unsigned int r = rand() % (DIM - score / 10 - START_LENGTH - obstacle * DIM_OBSTACLE) + 1;
for(unsigned int i = 1; i < R - 1; ++i)
{
for(unsigned int j = 1; j < C - 1; ++j)
{
if(!(r -= grid[i][j] == 1))
{
grid[i][j] = 2;
set_position((COORD){j, i});
printf("%c", BITE);
return;
}
}
}
}
void define_direction(int *direction, const int input)
{
if((*direction == UP || *direction == DOWN) && (input == LEFT || input == RIGHT) || (*direction == LEFT || *direction == RIGHT) && (input == UP || input == DOWN))
{
*direction = input;
}
}
void define_new_head(COORD *snake, COORD **head, const int direction, const int through)
{
COORD new_head = **head;
if(direction == UP)
{
head_direction = BLOCK_BODY_U;
new_head.Y = through && new_head.Y == 1 ? R - 2 : new_head.Y - 1;
}
else if(direction == DOWN)
{
head_direction = BLOCK_BODY_D;
new_head.Y = through && new_head.Y == R - 2 ? 1 : new_head.Y + 1;
}
else if(direction == LEFT)
{
head_direction = BLOCK_BODY_L;
new_head.X = through && new_head.X == 1 ? C - 2 : new_head.X - 1;
}
else
{
head_direction = BLOCK_BODY_R;
new_head.X = through && new_head.X == C - 2 ? 1 : new_head.X + 1;
}
*head = *head == snake + DIM - 1 ? snake : *head + 1;
**head = new_head;
}
int snake_update(int grid[R][C], COORD *snake, COORD **tail, COORD *new_head, unsigned int *score, const int obstacle, COORD *old_head)
{
if(grid[new_head->Y][new_head->X])
{
if(grid[new_head->Y][new_head->X] == 1)
{
grid[(*tail)->Y][(*tail)->X] = 1;
set_position(**tail);
printf(" ");
*tail = *tail == snake + DIM - 1 ? snake : *tail + 1;
}
else
{
*score += 10;
printf("%c", SOUND);
print_score(*score);
generate_bite(grid, *score, obstacle);
}
grid[new_head->Y][new_head->X] = 0;
set_position(*old_head);
printf("%c", BLOCK_BODY);
set_position(*new_head);
printf("%c", head_direction);
return 1;
}
return 0;
}
int main()
{
srand(time(0));
int grid[R][C];
int through;
int obstacle;
int direction = RIGHT;
unsigned int score = 0;
COORD snake[DIM] = {{2, R / 4}, {3, R / 4}, {4, R / 4}, {5, R / 4}, {6, R / 4}, {7, R / 4}, {8, R / 4}};
COORD *tail = snake;
COORD *head = snake + START_LENGTH - 1;
COORD *old = head;
choose_settings(&through, &obstacle);
initialize_grid(grid);
print_and_apply_border(grid, through);
print_and_apply_snake(grid, snake);
print_score(score);
if(obstacle)
{
print_and_apply_obstacle(grid);
}
generate_bite(grid, score, obstacle);
set_position((COORD){0, R + 1});
printf("Press any key to start.\n");
define_direction(&direction, get_input(direction));
set_position((COORD){0, R + 1});
printf(" ");
do
{
delay(200);
if(kbhit())
{
define_direction(&direction, get_input(direction));
}
old=head;
define_new_head(snake, &head, direction, through);
}
while(snake_update(grid, snake, &tail, head, &score, obstacle, old));
set_position((COORD){0, R + 1});
printf("GAME OVER!\n");
return 0;
}
Qui il mio Snake (Nibblerer_2), con schemi personalizzabili e scorrimento fluido del serpente, in VB.Net:
http://www.pierotofy.it/pages/sorgenti/dettagli/19600-Nibblerer2/