summaryrefslogtreecommitdiff
path: root/pieces.c
blob: 95c9923147525e70b65c8623e0d226840716a550 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "pieces.h"

const int N_SHAPES = 17;
const struct piece SHAPES[] = {
    {1, 1, "+"},
    {1, 2, "++"},
    {1, 3, "+++"},
    {1, 4, "++++"},
    {1, 5, "+++++"},
    {2, 2, "+  +"},         // 2x2 diagonal
    {2, 2, "++++"},         // 2x2 square
    {2, 3, "++++  "},       // L shape
    {2, 3, "++  ++"},       // Z shape
    {2, 3, "+++ + "},       // T shape
    {2, 3, "++++++"},       // 2x3 rectangle
    {2, 4, "+++++   "},     // long L shape
    {2, 4, "++++++++"},     // 2x4 rectangle
    {3, 3, "++++  +  "},    // large L shape
    {3, 3, "+++ +  + "},    // large T shape
    {3, 3, "+   +   +"},    // 3x3 diagonal
    {3, 3, "+++++++++"},    // 3x3 square
};

void transpose(struct piece* pc) {
    // transpose blocks
    char* old = malloc(strlen(pc->blocks) + 1);
    strcpy(old, pc->blocks); // before transposition
    for (int r = 0; r < pc->h; r++) {
        for (int c = 0; c < pc->w; c++) {
            pc->blocks[c * (pc->h) + r] = old[r * (pc->w) + c];
        }
    }
    free(old);
    // swap dimensions
    int h = pc->h;
    pc->h = pc->w;
    pc->w = h;
}

void rotate(struct piece* pc) {
    // rotate `pc` ccw by 90 degrees
    // transpose blocks
    char* old = malloc(strlen(pc->blocks) + 1);
    strcpy(old, pc->blocks); // before transposition
    for (int r = 0; r < pc->h; r++) {
        for (int c = 0; c < pc->w; c++) {
            pc->blocks[(pc->w - c - 1) * (pc->h) + r] = old[r * (pc->w) + c];
        }
    }
    free(old);
    // swap dimensions
    int h = pc->h;
    pc->h = pc->w;
    pc->w = h;
}

struct piece* randpiece() {
    // select a random shape from `SHAPES`, make a copy where memory for `.blocks` is manually managed,
    // then do random transformations to the copy
    struct piece shape = SHAPES[rand() % N_SHAPES];
    char* blocks = malloc(strlen(shape.blocks) + 1);
    strcpy(blocks, shape.blocks);
    struct piece* pc = malloc(sizeof(struct piece));
    pc->h = shape.h;
    pc->w = shape.w;
    pc->blocks = blocks;
    if (rand() % 2) transpose(pc);
    for (int i = rand() % 4; i > 0; i--) // 0 to 3 times
        rotate(pc);
    return pc;
}