井字棋是一個經典的雙人遊戲,雙方輪流在 3x3 的棋盤上放置棋子,率先連成一直線(橫、直、斜)者獲勝。本文將示範如何使用 C 語言實作一個完整的井字棋遊戲,包含棋盤繪製、玩家輸入、電腦隨機下棋、勝負判斷等核心功能。
程式主要包含以下模組:
char a[3][3] = {0};
int size = 9;
void qipan() {
int i, j;
printf(" | | \n");
for (i = 0; i < 3; i++) {
printf("_%c_|_%c_|_%c_\n", a[i][0], a[i][1], a[i][2]);
if (i < 2) printf(" | | \n");
}
}
棋盤以字元陣列儲存,空位為空白字元 `' '`,玩家棋子為 `'@'`,電腦棋子為 `'#'`。`qipan()` 以格式化輸出呈現 3x3 格狀棋盤。
void wjxq() {
int m, n;
printf("玩家棋子為 @: ");
scanf("%d %d", &m, &n);
if (m < 1 || m > 3 || n < 1 || n > 3 || a[m-1][n-1] != ' ') {
printf("座標不合法!請重新輸入。\n");
wjxq(); // 遞迴重新輸入
} else {
a[m-1][n-1] = '@';
size--;
}
}
輸入座標採 1-based 索引,轉為 0-based 存取陣列。若座標越界或該位已有棋子,會遞迴要求重新輸入。
void dn() {
int m, n;
printf("電腦棋子 #:\n");
srand(time(NULL));
do {
m = rand() % 3;
n = rand() % 3;
} while (a[m][n] != ' ');
a[m][n] = '#';
size--;
}
使用 `rand()` 產生 0~2 的亂數,直到找到空位為止。注意 `srand(time(NULL))` 建議只在 `main()` 呼叫一次,避免短時間內重複種子導致相同亂數序列。
int winner() {
// 檢查 8 條連線:3 橫、3 直、2 斜
// 玩家 '@' 獲勝回傳 1
// 電腦 '#' 獲勝回傳 0
// 平手回傳 -1
// 遊戲繼續回傳 2
}
函式以硬編碼方式檢查所有可能的連線組合。雖然程式碼較長,但邏輯直觀,適合初學者理解。進階版可改用迴圈或位元運算優化。
int main() {
// 初始化棋盤為空白
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
a[i][j] = ' ';
while (1) {
qipan();
if (winner() != 2) break; // 遊戲結束
wjxq(); // 玩家回合
qipan();
if (winner() != 2) break;
dn(); // 電腦回合
}
// 顯示最終結果
switch (winner()) {
case 1: printf("玩家獲勝!\n"); break;
case 0: printf("玩家輸了!\n"); break;
default: printf("平局\n");
}
system("pause");
return 0;
}
本範例展示了 C 語言實作井字棋的完整流程,涵蓋陣列操作、使用者互動、亂數應用與條件判斷等基礎觀念。透過逐步建構,初學者可清楚掌握遊戲程式的核心架構,並以此為基礎延伸更複雜的專案。