19luca97 ha scritto:
Qualche soluzione, sono ancora bloccato e tra una settimana ho la scadenza per la consegna...
Mi dispiace non averti potuto aiutare, ma sono stato un po' occupato in questo periodo!
In ogni caso in un programma del genere, cmq non semplicissimo, risulta difficile isolare/correggere un problema senza sapere precisamente da quale idea si è partiti e dove si vuole arrivare.
Detto questo, ieri, dopo essermi ricordato di questo topic, ho pensato: TETRIS? Sarà divertente cercare di implementarlo!
#include <stdbool.h>
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>
#define N_PIECES 7
#define R 22
#define C 12
#define DEFAULT_COLOUR 7
#define EMPTY 127
#define BLOCK_CHARACTER 254
#define SOUND 7
#define UP 72
#define DOWN 80
#define LEFT 75
#define RIGHT 77
typedef struct _piece
{
int m[4][4][4];
int n_state;
int colour;
} piece;
piece O = {{{{0, 0, 0, 0}, {0, 1, 1, 0}, {0, 1, 1, 0}, {0, 0, 0, 0}}}, 1, 126};
piece I = {{{{0, 0, 0, 0}, {1, 1, 1, 1}, {0, 0, 0, 0}, {0, 0, 0, 0}},
{{0, 1, 0, 0}, {0, 1, 0, 0}, {0, 1, 0, 0}, {0, 1, 0, 0}}}, 2, 123};
piece S = {{{{0, 0, 0, 0}, {0, 1, 1, 0}, {1, 1, 0, 0}, {0, 0, 0, 0}},
{{1, 0, 0, 0}, {1, 1, 0, 0}, {0, 1, 0, 0}, {0, 0, 0, 0}}}, 2, 124};
piece Z = {{{{0, 0, 0, 0}, {1, 1, 0, 0}, {0, 1, 1, 0}, {0, 0, 0, 0}},
{{0, 1, 0, 0}, {1, 1, 0, 0}, {1, 0, 0, 0}, {0, 0, 0, 0}}}, 2, 122};
piece T = {{{{0, 0, 0, 0}, {1, 1, 1, 0}, {0, 1, 0, 0}, {0, 0, 0, 0}},
{{0, 1, 0, 0}, {1, 1, 0, 0}, {0, 1, 0, 0}, {0, 0, 0, 0}},
{{0, 1, 0, 0}, {1, 1, 1, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}},
{{0, 1, 0, 0}, {0, 1, 1, 0}, {0, 1, 0, 0}, {0, 0, 0, 0}}}, 4, 125};
piece J = {{{{0, 0, 0, 0}, {1, 1, 1, 0}, {0, 0, 1, 0}, {0, 0, 0, 0}},
{{0, 1, 0, 0}, {0, 1, 0, 0}, {1, 1, 0, 0}, {0, 0, 0, 0}},
{{1, 0, 0, 0}, {1, 1, 1, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}},
{{0, 1, 1, 0}, {0, 1, 0, 0}, {0, 1, 0, 0}, {0, 0, 0, 0}}}, 4, 121};
piece L = {{{{0, 0, 0, 0}, {1, 1, 1, 0}, {1, 0, 0, 0}, {0, 0, 0, 0}},
{{1, 1, 0, 0}, {0, 1, 0, 0}, {0, 1, 0, 0}, {0, 0, 0, 0}},
{{0, 0, 1, 0}, {1, 1, 1, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}},
{{0, 1, 0, 0}, {0, 1, 0, 0}, {0, 1, 1, 0}, {0, 0, 0, 0}}}, 4, 120};
piece* pieces[N_PIECES] = {&O, &I, &S, &Z, &T, &J, &L};
unsigned int points[] = {100, 400, 900, 2000};
void set_colour(int colour)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), colour);
}
void set_position(COORD coord)
{
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}
int get_input()
{
set_position((COORD){0, R - 1});
getch();
return getch();
}
void print_info()
{
set_colour(DEFAULT_COLOUR);
set_position((COORD){23, 2});
printf("NEXT:");
set_position((COORD){23, 8});
printf("SCORE:0");
}
void print_score(unsigned int score)
{
set_colour(DEFAULT_COLOUR);
set_position((COORD){29, 8});
printf("%u", score);
}
void initialize_grid(int grid[R][C])
{
for(unsigned int i = 1; i < R - 1; ++i)
{
for(unsigned int j = 1; j < C - 1; ++j)
{
grid[i][j] = EMPTY;
}
}
}
void print_grid(int grid[R][C])
{
set_colour(DEFAULT_COLOUR);
set_position((COORD){0, 0});
printf("\n");
set_colour(EMPTY);
for(unsigned int i = 1; i < R - 1; ++i)
{
printf(" ");
for(unsigned int j = 1; j < C - 1; ++j)
{
set_colour(grid[i][j]);
printf("%c ", BLOCK_CHARACTER);
}
printf("\n");
}
}
void print_piece(piece *p, unsigned int state, unsigned int i_0, unsigned int j_0, unsigned int colour)
{
set_colour(colour);
for(unsigned int i = 0; i < 4; ++i)
{
for(unsigned int j = 0; j < 4; ++j)
{
if(p->m[state][i][j])
{
set_position((COORD){(j + j_0) * 2 - 1, i + i_0});
printf("%c", BLOCK_CHARACTER);
}
}
}
}
bool check_state(int grid[R][C], piece *p, unsigned int state, unsigned int i_0, unsigned int j_0)
{
for(unsigned int i = 0; i < 4; ++i)
{
for(unsigned int j = 0; j < 4; ++j)
{
if(p->m[state][i][j] && grid[i + i_0][j + j_0] != EMPTY)
{
return false;
}
}
}
return true;
}
void to_left(int grid[R][C], piece *p, unsigned int state, unsigned int i_0, unsigned int *j_0)
{
if(check_state(grid, p, state, i_0, *j_0 - 1))
{
print_piece(p, state, i_0, *j_0, EMPTY);
--(*j_0);
print_piece(p, state, i_0, *j_0, p->colour);
}
}
void to_right(int grid[R][C], piece *p, unsigned int state, unsigned int i_0, unsigned int *j_0)
{
if(check_state(grid, p, state, i_0, *j_0 + 1))
{
print_piece(p, state, i_0, *j_0, EMPTY);
++(*j_0);
print_piece(p, state, i_0, *j_0, p->colour);
}
}
void rotate(int grid[R][C], piece *p, unsigned int *state, unsigned int i_0, unsigned int j_0)
{
if(p->n_state > 1)
{
unsigned int new_state = (*state + 1) % p->n_state;
if(check_state(grid, p, new_state, i_0, j_0))
{
print_piece(p, *state, i_0, j_0, EMPTY);
*state = new_state;
print_piece(p, *state, i_0, j_0, p->colour);
}
}
}
bool to_down(int grid[R][C], piece *p, unsigned int state, unsigned int *i_0, unsigned int j_0)
{
if(check_state(grid, p, state, *i_0 + 1, j_0))
{
print_piece(p, state, *i_0, j_0, EMPTY);
++(*i_0);
print_piece(p, state, *i_0, j_0, p->colour);
return true;
}
for(unsigned int i = 0; i < 4; ++i)
{
for(unsigned int j = 0; j < 4; ++j)
{
if(p->m[state][i][j])
{
grid[i + *i_0][j + j_0] = p->colour;
}
}
}
return false;
}
bool check_row(int grid[R][C], unsigned int r, bool flag)
{
for(unsigned int j = 1; j < C - 1; ++j)
{
if(grid[r][j] == EMPTY == flag)
{
return false;
}
}
return true;
}
void update_row(int grid[R][C], unsigned int r, unsigned int n)
{
for(unsigned int j = 1; j < C - 1; ++j)
{
if(!n)
{
grid[r][j] = EMPTY;
}
else
{
grid[r][j] = grid[r - n][j];
}
}
}
void check_rows(int grid[R][C], unsigned int i_0, unsigned int *score)
{
unsigned int v[4] = {0};
unsigned int n = 0;
for(unsigned int i = 0; i < 4; ++i)
{
if(i + i_0 > 0 && i + i_0 < R - 1 && (v[i] = check_row(grid, i + i_0, true)))
{
++n;
}
}
if(n)
{
for(unsigned int i = 1; i < 4; ++i)
{
if(!v[3 - i] && i_0 + 3 - i > 0 && i_0 + 4 - i < R)
{
unsigned int m = 0;
for(unsigned int j = 4 - i; j < 4; ++j)
{
m += v[j];
}
if(m)
{
update_row(grid, i_0 + 3 - i + m, m);
}
}
}
for(unsigned int i = i_0 + n - 1; i > 0; --i)
{
update_row(grid, i, n * (i > n));
}
*score += points[n - 1] * (1 + 9 * check_row(grid, R - 2, false));
print_score(*score);
printf("%c", SOUND);
print_grid(grid);
}
}
int main()
{
srand(time(NULL));
int grid[R][C] = {0};
unsigned int score = 0;
piece *curr = NULL;
piece *next = pieces[rand() % N_PIECES];
initialize_grid(grid);
print_grid(grid);
print_info();
while(check_state(grid, next, 0, 0, 4))
{
unsigned int state = 0;
unsigned int i_0 = 0;
unsigned int j_0 = 4;
curr = next;
next = pieces[rand() % N_PIECES];
print_piece(curr, state, i_0, j_0, curr->colour);
print_piece(next, 0, 3, 12, next->colour - 112);
while(true)
{
int input = get_input();
if(input == LEFT)
{
to_left(grid, curr, state, i_0, &j_0);
}
else if(input == RIGHT)
{
to_right(grid, curr, state, i_0, &j_0);
}
else if(input == UP)
{
rotate(grid, curr, &state, i_0, j_0);
}
else if(input == DOWN)
{
if(!to_down(grid, curr, state, &i_0, j_0))
{
check_rows(grid, i_0, &score);
break;
}
}
}
print_piece(next, 0, 3, 12, 0);
}
set_colour(DEFAULT_COLOUR);
set_position((COORD){0, R});
printf("%cGAME OVER!\n", SOUND);
return 0;
}
L'impostazione logica e il codice possono sicuramente essere migliorati, ma per il momento sembra funzionare; in ogni caso se trovate qualche bug fatemi sapere.
Non so se i colori e i caratteri utilizzati siano uguali anche su altri pc, ecco quindi uno screen di come lo vedo io:
Tengo però a precisare che il giochino non è ancora "operativo", infatti al momento gli spostamenti verso il basso sono dettati solo dall'input. A tal proposito, avete qualche consiglio su come implementare il fattore tempo al fine di simulare la caduta automatica dei pezzi?
Purtroppo con la mia limitata conoscenza di librerie/funzioni non riesco ad uscirne.
P.S.
Al momento la successione dei pezzi è completamente casuale, per caso sapete se essa, pur restando randomica, debba invece rispettare alcuni vincoli?