Nippolo ha scritto:
giammo ha scritto:
bel codice veramente!!! posso metterci le mani?
Certo!
Anche io continuo a metterci le mani, uso Win7, e Snake gira senza imperfezioni, ma sono abituato a controllare i codici anche su Win10, che ha una console leggermente diversa.
Nella console di Win10 il cursore viene visualizzato accanto all'ultima posizione scritta, e è brutto vedere accanto alla testa di Snake il cursore.
Ho pensato di implementare il tempo in modo da portare il cursore lontano dalla testa di Snake, ma poi il cursore non mi piaceva nenche a fianco del tempo e allora l'ho spento.
#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 TRUE 1
#define FALSE 0
#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 print_time(clock_t start)
{
set_position((COORD){C + 3, 3});
printf("TEMPO: %.1f", (float)(clock()-start)/CLK_TCK);
}
void cursor_on(const int Bool)
{
CONSOLE_CURSOR_INFO cinfo;
cinfo.bVisible=Bool;
if (Bool) cinfo.dwSize = 10; else cinfo.dwSize = 1;
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cinfo);
}
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(" ");
clock_t start = clock();
cursor_on(FALSE);
do
{
print_time(start);
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));
cursor_on(TRUE);
set_position((COORD){0, R + 1});
printf("GAME OVER!\n");
return 0;
}