# ===== CodeLab: C 小游戏⑦:记忆翻牌(控制台) =====
# 来源: https://aoerliang.dpdns.org/articles/game-c-memory
# 以下代码片段按文章出现顺序拼接, 共 3 段

# ----- 片段 1 (c) -----
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define N 16
int cards[N];          // 图案 0~7
int matched[N];        // 1=已配对
int open_a, open_b;    // 当前翻开的两张(未翻开为 -1)

void shuffle(void) {
    for (int i = N - 1; i > 0; i--) {
        int j = rand() % (i + 1);
        int t = cards[i]; cards[i] = cards[j]; cards[j] = t;
    }
}

void init(void) {
    for (int i = 0; i < N; i++) cards[i] = i / 2;
    shuffle();
    for (int i = 0; i < N; i++) matched[i] = 0;
    open_a = open_b = -1;
}

# ----- 片段 2 (c) -----
int play_round(int a, int b) {
    if (a == b) return 0;
    if (matched[a] || matched[b]) return 0;
    open_a = a; open_b = b;
    if (cards[a] == cards[b]) {
        matched[a] = matched[b] = 1;
        return 1;
    }
    return -1;
}

# ----- 片段 3 (c) -----
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define N 16
#define COLS 4
int cards[N];
int matched[N];
int open_a, open_b;
int moves = 0;

void shuffle(void) {
    for (int i = N - 1; i > 0; i--) {
        int j = rand() % (i + 1);
        int t = cards[i]; cards[i] = cards[j]; cards[j] = t;
    }
}

void init(void) {
    for (int i = 0; i < N; i++) cards[i] = i / 2;
    shuffle();
    for (int i = 0; i < N; i++) matched[i] = 0;
    open_a = open_b = -1;
    moves = 0;
}

void draw(void) {
    for (int r = 0; r < 4; r++) {
        for (int c = 0; c < 4; c++) {
            int i = r * COLS + c;
            if (matched[i]) printf("  * ");
            else if (i == open_a || i == open_b) printf(" %d ", cards[i]);
            else printf(" _ ");
        }
        printf("\n");
    }
    printf("步数: %d\n", moves);
}

int main(void) {
    srand((unsigned)time(NULL));
    init();
    while (1) {
        draw();
        int a, b;
        printf("翻开两张(0-15,空格隔开,q退出): ");
        fflush(stdout);
        char cmd[8];
        if (scanf("%7s", cmd) == 1 && cmd[0] == 'q') break;
        sscanf(cmd, "%d", &a);
        if (scanf("%d", &b) != 1) continue;
        if (a < 0 || a >= N || b < 0 || b >= N) continue;
        if (a == b || matched[a] || matched[b]) { printf("无效选择\n"); continue; }
        moves++;
        open_a = a; open_b = b;
        draw();
        if (cards[a] == cards[b]) {
            matched[a] = matched[b] = 1;
            printf("配对成功!\n");
        } else {
            printf("不匹配,记住它们~\n");
        }
        open_a = open_b = -1;
        int done = 1;
        for (int i = 0; i < N; i++) if (!matched[i]) done = 0;
        if (done) { printf("通关!用了 %d 步\n", moves); break; }
    }
    return 0;
}
