#include #include #include #include #include "pieces.h" void printmap(char** map, int nrow, int ncol) { printf(" "); for (int c = 0; c < ncol; c++) { printf("-"); } printf("\n"); for (int r = 0; r < nrow; r++) { printf("|"); for (int c = 0; c < ncol; c++) { printf("%c", map[r][c]); } printf("|\n"); } printf(" "); for (int c = 0; c < ncol; c++) { printf("-"); } printf("\n"); } void printpieces(struct piece** hand, int nhand) { for (int i = 0; i < nhand; i++) { if (hand[i] == NULL) continue; printf("Piece %d\n", i); struct piece* pc = hand[i]; for (int r = 0; r < pc->h; r++) { for (int c = 0; c < pc->w; c++) { printf("%c", pc->blocks[r * pc->w + c]); } printf("\n"); } printf("\n"); } } void clearmap(char** map, int nrow, int ncol) { for (int r = 0; r < nrow; r++) { for (int c = 0; c < ncol; c++) { map[r][c] = ' '; } } } bool placeable(char** map, struct piece* pc, int row, int col, int mapH, int mapW) { // boundary check if (row < 0 || row + (pc->h) > mapH || col < 0 || col + (pc->w) > mapW) return false; // check if blocks to be taken by `pc` are vacant for (int r = 0; r < pc->h; r++) { for (int c = 0; c < pc->w; c++) { if (map[row + r][col + c] == '+' && pc->blocks[r * pc->w + c] == '+') return false; } } return true; } void place(char** map, struct piece* pc, int row, int col) { for (int r = 0; r < pc->h; r++) { for (int c = 0; c < pc->w; c++) { if (pc->blocks[r * (pc->w) + c] == '+') map[row + r][col + c] = '+'; } } } void freepiece(struct piece* pc) { free(pc->blocks); free(pc); } void refillpieces(struct piece** hand, int nhand) { // randomly select `no` pieces from `pool` to `hand` // capacities of `hand` and `pool` are `nhand` and `npool` resp. for (int i = 0; i < nhand; i++) { hand[i] = randpiece(); } } void sirtet() { const int H = 8; // canvas height const int W = 8; // canvas width const int P = 3; // maximum # of pieces at hand // init memory and game state char** map = malloc(H * sizeof(char*)); for (int r = 0; r < H; r++) { map[r] = malloc(W * sizeof(char)); } struct piece** hand = malloc(P * sizeof(struct piece*)); srand(time(NULL)); clearmap(map, H, W); bool over = false; refillpieces(hand, P); // begin game loop while (!over) { printmap(map, H, W); printpieces(hand, P); // await user input int pc_idx; int row; int col; printf("Input [piece #] [row #] [col #]: "); scanf("%d %d %d", &pc_idx, &row, &col); while ( pc_idx < 0 || pc_idx >= P || hand[pc_idx] == NULL || !placeable(map, hand[pc_idx], row, col, H, W) ) { printf("You cannot do that. Try again: "); scanf("%d %d %d", &pc_idx, &row, &col); } place(map, hand[pc_idx], row, col); freepiece(hand[pc_idx]); hand[pc_idx] = NULL; // if player has no piece left, refill bool pieces_left = false; for (int i = 0; i < P; i++) { if (hand[i] != NULL) { pieces_left = true; break; } } if (!pieces_left) refillpieces(hand, P); // game over if none of the pieces are placeable bool has_placeable = false; for (int i = 0; i < P; i++) { if (hand[i] == NULL) continue; for (int r = 0; r <= H - hand[i]->h; r++) { for (int c = 0; c <= W - hand[i]->w; c++) { if (placeable(map, hand[i], r, c, H, W)) has_placeable = true; } } } if (!has_placeable) { // game over printf("Game over\n"); over = true; } } // free memory for (int r = 0; r < H; r++) { free(map[r]); } free(map); for (int i = 0; i < P; i++) { if (hand[i] != NULL) freepiece(hand[i]); } free(hand); } int main(int argc, char *argv[]) { sirtet(); return 0; }