作為編程新手,通過 CS50 公開課受啟發,決定親手實現一個類似華容道的滑塊拼圖遊戲。本文記錄第一階段:根據階數生成矩陣、隨機打亂、並解決「空位顯示」問題。
n,生成 n×n 矩陣n²-1 填充,剩餘一格為空位(用 _ 表示)int square[n * n];
for (int i = 0; i < n * n; i++) {
square[i] = i + 1; // 1, 2, 3, ..., n²
}
#include <stdlib.h>
#include <time.h>
srand(time(NULL)); // 以當前時間為種子,每次運行結果不同
for (int i = n * n - 1; i > 0; i--) {
int j = rand() % (i + 1); // [0, i] 隨機索引
swap(&square[i], &square[j]);
}
為什麼不用原文的 rand() % (n*n)? 那種寫法會導致某些排列概率更高,不是均勻分佈。Fisher-Yates 保證每種排列等概率。
void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
for (int i = 0; i < n * n; i += n) {
for (int j = 0; j < n; j++) {
printf("%2d ", square[i + j]);
}
printf("\n");
}
_遊戲規定最大數字 n² 代表空位,輸出時需特殊處理。
for (int i = 0; i < n * n; i++) {
if (square[i] == n * n) {
printf("%2c ", '_');
} else {
printf("%2d ", square[i]);
}
if ((i + 1) % n == 0) printf("\n");
}
// 判斷索引 c 處是否為數組最大值
int is_max(int *arr, int len, int c) {
for (int m = 0; m < len; m++) {
if (arr[c] < arr[m]) return 0;
}
return 1;
}
// 主循環中調用
if (is_max(square, n * n, k)) {
printf("%2c ", '_');
} else {
printf("%2d ", square[k]);
}
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void swap(int *a, int *b);
int is_max(int *arr, int len, int idx);
int main(int argc, char *argv[]) {
int n;
printf("請輸入階數:\n");
scanf("%d", &n);
int total = n * n;
int square[total];
// 初始化
for (int i = 0; i < total; i++) square[i] = i + 1;
// 打亂
srand(time(NULL));
for (int i = total - 1; i > 0; i--) {
int j = rand() % (i + 1);
swap(&square[i], &square[j]);
}
// 輸出
for (int i = 0; i < total; i++) {
if (is_max(square, total, i)) {
printf("%2c ", '_');
} else {
printf("%2d ", square[i]);
}
if ((i + 1) % n == 0) printf("\n");
}
return 0;
}
void swap(int *a, int *b) {
int temp = *a; *a = *b; *b = temp;
}
int is_max(int *arr, int len, int idx) {
for (int m = 0; m < len; m++) {
if (arr[idx] < arr[m]) return 0;
}
return 1;
}
動手實踐是學好編程的唯一捷徑,繼續加油!