上一篇已完成隨機矩陣的生成,接下來要解決的核心問題是:如何根據玩家輸入移動數字,並即時更新畫面。
遊戲主迴圈持續運行直到矩陣排序完成(issort 返回真)。每輪迴圈執行以下步驟:
findnum 定位該數字在一維陣列中的索引 t。findmax 找出空格(以最大值代表)的索引 max。isleft、isright)。swap 交換。// 判斷矩陣是否已排序完成(遞增)
int issort(int a[], int c) {
for (int b = 0; b < c - 1; b++) {
if (a[b] >= a[b + 1]) return 0;
}
return 1;
}
// 找出指定數字在陣列中的索引
int findnum(int a, int b[], int c) {
for (int k = 0; k < c * c; k++) {
if (b[k] == a) return k;
}
return printf("沒這個數!\n");
}
// 找出空格(最大值)的索引
int findmax(int a[], int b) {
int max = 0;
for (int i = 1; i < b * b; i++) {
if (a[max] < a[i]) max = i;
}
return max;
}
// 判斷空格是否在最左欄
int isleft(int max, int f) {
for (int i = 0; i < f - 1; i++) {
if (max == (i + 1) * f) return 1;
}
return 0;
}
// 判斷空格是否在最右欄
int isright(int max, int f) {
for (int i = 0; i < f - 1; i++) {
if (max == (i + 1) * f - 1) return 1;
}
return 0;
}
while (!issort(square, f * f)) {
printf("請輸入要移動的數字:");
int m; scanf("%d", &m);
int t = findnum(m, square, f);
int max = findmax(square, f);
// 中間區塊:四向皆可移動
if ((!isleft(max, f)) && (!isright(max, f)) &&
(t == max + 1 || t == max - 1 || t == max + f || t == max - f)) {
swap(&square[max], &square[t]);
}
// 左邊欄:不可向左移動
else if (isleft(max, f) && (t == max + 1 || t == max + f || t == max - f)) {
swap(&square[max], &square[t]);
}
// 右邊欄:不可向右移動
else if (isright(max, f) && (t == max - 1 || t == max + f || t == max - f)) {
swap(&square[max], &square[t]);
} else {
printf("不能移動!\n");
}
// 以矩陣形式輸出
for (int i = 0, k = 0; i < f * f; i += f) {
for (int j = 0; j < f; j++) {
if (ismax(&square[0], f * f, k)) printf("%2c ", '_');
else printf("%2d ", square[k]);
k++;
}
printf("\n");
}
}
目前每次輸入都會重新印出整個矩陣,導致畫面閃爍。嘗試使用 fflush 或 ANSI 轉義碼(如 \033[H\033[J 清屏並移動游標到左上角)可實現「就地更新」效果,避免產生大量輸出歷史紀錄。在 Windows 控制台可搭配 system("cls"),但在跨平台考量下,建議使用標準輸出控制序列。