C語言開發實現井字棋及電腦落子優化示例詳解
總體思路
井字棋棋盤我們總體可以當成一個二維數組來操作,我們分別需要實現初始化二維數組,打印棋盤,玩傢下棋,電腦下棋,判斷輸贏等代碼
項目的創建
我們創建瞭頭文件用於放函數的聲明,game.c文件放置函數的實現,test.c文件用於測試。
測試結果
電腦獲勝
玩傢獲勝
平局
各函數代碼的實現
我們在game.c文件中實現函數功能的代碼
初始化二維數組
void InitBoard(char Board[ROW][COL], int row, int col) { for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { Board[i][j] = ' '; } } }
打印棋盤
void DisplayBoard(char Board[ROW][COL], int row, int col) { for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { printf(" %c ", Board[i][j]); if (j < col - 1) printf("|"); } printf("\n"); if (i < row - 1) { for (int j = 0; j < col; j++) { printf("---"); if (j < col - 1) printf("|"); } } printf("\n"); } }
這裡的棋盤我們隻打印瞭井字的形狀,如果為瞭美觀,還可以進行封邊,這裡就留給朋友們自行實現啦。
玩傢下棋
void PlayMove(char Board[ROW][COL], int row, int col) { while (1) { int x = 0, y = 0; printf("請輸入坐標:\n"); scanf("%d%d", &x, &y); if (x >= 1 && x <= row && y >= 1 && y <= col) { if (Board[x - 1][y - 1] == ' ') { Board[x - 1][y - 1] = '#'; break; } else printf("該位置已被占,請重新輸入:\n"); } else { printf("輸入錯誤,請重新輸入:\n"); } } }
電腦下棋
在電腦落子之前,先檢測有沒有下一步可以直接贏的,若有,則落子在此處,電腦獲勝,若沒有,再檢測玩傢下一步是否有機會獲勝,若玩傢下一步可以直接獲勝,那麼電腦將搶占這一步。
如果上述兩種情況均不存在,當發現(1,1)位置是空時,電腦先下這一步。
其他情況均隨意落子。
void ComputerMove(char Board[ROW][COL], int row, int col) { int x = 0, y = 0; while (1) { if (JudgeComputer(Board, ROW, COL)) { for (int i = 0; i < row; i++) { if (Board[i][0] == Board[i][1] && Board[i][0] == '*' && Board[i][2] == ' ') { Board[i][2] = '*'; return; } else if (Board[i][0] == Board[i][2] && Board[i][0] == '*' && Board[i][1] == ' ') { Board[i][1] = '*'; return; } else if (Board[i][1] == Board[i][2] && Board[i][1] == '*' && Board[i][0] == ' ') { Board[i][0] = '*'; return; } } for (int j = 0; j < col; j++) { if (Board[0][j] == Board[1][j] && Board[0][j] == '*' && Board[2][j] == ' ') { Board[2][j] = '*'; return; } else if (Board[0][j] == Board[2][j] && Board[0][j] == '*' && Board[1][j] == ' ') { Board[1][j] = '*'; return; } else if (Board[1][j] == Board[2][j] && Board[1][j] == '*' && Board[0][j] == ' ') { Board[0][j] = '*'; return; } } if (Board[0][0] == Board[1][1] && Board[0][0] == '*' && Board[2][2] == ' ') { Board[2][2] = '*'; return; } else if (Board[0][0] == Board[2][2] && Board[0][0] == '*' && Board[1][1] == ' ') { Board[1][1] = '*'; return; } else if (Board[1][1] == Board[2][2] && Board[1][1] == '*' && Board[0][0] == ' ') { Board[0][0] = '*'; return; } else if (Board[0][2] == Board[1][1] && Board[0][2] == '*' && Board[2][0] == ' ') { Board[2][0] = '*'; return; } else if (Board[0][2] == Board[2][0] && Board[0][2] == '*' && Board[1][1] == ' ') { Board[1][1] = '*'; return; } else if (Board[2][0] == Board[1][1] && Board[2][0] == '*' && Board[0][2] == ' ') { Board[0][2] = '*'; return; } } else if (JudgePlayer(Board, ROW, COL)) { for (int i = 0; i < row; i++) { if (Board[i][0] == Board[i][1] && Board[i][0] == '#' && Board[i][2] == ' ') { Board[i][2] = '*'; return; } else if (Board[i][0] == Board[i][2] && Board[i][0] == '#' && Board[i][1] == ' ') { Board[i][1] = '*'; return; } else if (Board[i][1] == Board[i][2] && Board[i][1] == '#' && Board[i][0] == ' ') { Board[i][0] = '*'; return; } } for (int j = 0; j < col; j++) { if (Board[0][j] == Board[1][j] && Board[0][j] == '#' && Board[2][j] == ' ') { Board[2][j] = '*'; return; } else if (Board[0][j] == Board[2][j] && Board[0][j] == '#' && Board[1][j] == ' ') { Board[1][j] = '*'; return; } else if (Board[1][j] == Board[2][j] && Board[1][j] == '#' && Board[0][j] == ' ') { Board[0][j] = '*'; return; } } if (Board[0][0] == Board[1][1] && Board[0][0] == '#' && Board[2][2] == ' ') { Board[2][2] = '*'; return; } else if (Board[0][0] == Board[2][2] && Board[0][0] == '#' && Board[1][1] == ' ') { Board[1][1] = '*'; return; } else if (Board[1][1] == Board[2][2] && Board[1][1] == '#' && Board[0][0] == ' ') { Board[0][0] = '*'; return; } else if (Board[0][2] == Board[1][1] && Board[0][2] == '#' && Board[2][0] == ' ') { Board[2][0] = '*'; return; } else if (Board[0][2] == Board[2][0] && Board[0][2] == '#' && Board[1][1] == ' ') { Board[1][1] = '*'; return; } else if (Board[2][0] == Board[1][1] && Board[2][0] == '#' && Board[0][2] == ' ') { Board[0][2] = '*'; return; } } else { if (Board[1][1] == ' ') { Board[1][1] = '*'; return; } else { x = rand() % row; y = rand() % col; if (Board[x][y] == ' ') { Board[x][y] = '*'; break; } } } } }
判斷電腦是否有位置可以獲勝
static int JudgeComputer(char Board[ROW][COL], int row, int col) { for (int i = 0; i < row; i++) { if (Board[i][0] == Board[i][1] && Board[i][0] == '*' && Board[i][2] == ' ') return 1; else if (Board[i][0] == Board[i][2] && Board[i][0] == '*' && Board[i][1] == ' ') return 1; else if (Board[i][1] == Board[i][2] && Board[i][1] == '*' && Board[i][0] == ' ') return 1; } for (int j = 0; j < col; j++) { if (Board[0][j] == Board[1][j] && Board[0][j] == '*' && Board[2][j] == ' ') return 1; else if (Board[0][j] == Board[2][j] && Board[0][j] == '*' && Board[1][j] == ' ') return 1; else if (Board[1][j] == Board[2][j] && Board[1][j] == '*' && Board[0][j] == ' ') return 1; } if (Board[0][0] == Board[1][1] && Board[0][0] == '*' && Board[2][2] == ' ') return 1; else if (Board[0][0] == Board[2][2] && Board[0][0] == '*' && Board[1][1] == ' ') return 1; else if (Board[1][1] == Board[2][2] && Board[1][1] == '*' && Board[0][0] == ' ') return 1; else if (Board[0][2] == Board[1][1] && Board[0][2] == '*' && Board[2][0] == ' ') return 1; else if (Board[0][2] == Board[2][0] && Board[0][2] == '*' && Board[1][1] == ' ') return 1; else if (Board[2][0] == Board[1][1] && Board[2][0] == '*' && Board[0][2] == ' ') return 1; else return 0; }
判斷玩傢是否有位置獲勝
static int JudgePlayer(char Board[ROW][COL], int row, int col) { for (int i = 0; i < row; i++) { if (Board[i][0] == Board[i][1] && Board[i][0] == '#' && Board[i][2] == ' ') return 1; else if (Board[i][0] == Board[i][2] && Board[i][0] == '#' && Board[i][1] == ' ') return 1; else if (Board[i][1] == Board[i][2] && Board[i][1] == '#' && Board[i][0] == ' ') return 1; } for (int j = 0; j < col; j++) { if (Board[0][j] == Board[1][j] && Board[0][j] == '#' && Board[2][j] == ' ') return 1; else if (Board[0][j] == Board[2][j] && Board[0][j] == '#' && Board[1][j] == ' ') return 1; else if (Board[1][j] == Board[2][j] && Board[1][j] == '#' && Board[0][j] == ' ') return 1; } if (Board[0][0] == Board[1][1] && Board[0][0] == '#' && Board[2][2] == ' ') return 1; else if (Board[0][0] == Board[2][2] && Board[0][0] == '#' && Board[1][1] == ' ') return 1; else if (Board[1][1] == Board[2][2] && Board[1][1] == '#' && Board[0][0] == ' ') return 1; else if (Board[0][2] == Board[1][1] && Board[0][2] == '#' && Board[2][0] == ' ') return 1; else if (Board[0][2] == Board[2][0] && Board[0][2] == '#' && Board[1][1] == ' ') return 1; else if (Board[2][0] == Board[1][1] && Board[2][0] == '#' && Board[0][2] == ' ') return 1; else return 0; }
判斷輸贏
char IsWin(char Board[ROW][COL], int row, int col) for (int i = 0; i < row; i++) { if (Board[i][0] == Board[i][1] && Board[i][2] == Board[i][1] && Board[i][1] != ' ') { return Board[i][0]; } } for (int j = 0; j < col; j++) { if (Board[0][j] == Board[1][j] && Board[1][j] == Board[2][j] && Board[j][1] != ' ') { return Board[0][j]; } } if (Board[0][0] == Board[1][1] && Board[2][2] == Board[1][1] && Board[2][2] != ' ') return Board[0][0]; if (Board[0][2] == Board[1][1] && Board[2][0] == Board[1][1] && Board[1][1] != ' ') return Board[1][1]; if (IsFull(Board, ROW, COL)) { return 'o'; } return 'C'; }
判斷和棋
static int IsFull(char Board[ROW][COL], int row, int col) { for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { if (Board[i][j] == ' ') return 0; } } return 1; }
聲明代碼
我們在game.h頭文件中進行函數的聲明。
void meun(); #define ROW 3 #define COL 3 //遊戲主函數 void game(); //初始化二維數組 void InitBoard(char Board[ROW][COL], int row, int col); //打印棋盤 void DisplayBoard(char Board[ROW][COL], int row, int col); //玩傢下棋 void PlayMove(char Board[ROW][COL], int row, int col); //電腦下棋 void ComputerMove(char Board[ROW][COL], int row, int col); //判斷贏否 char IsWin(char Board[ROW][COL], int row, int col); //判斷棋盤滿瞭嗎 //int IsFull(char Board[ROW][COL], int row, int col); //判斷電腦下一部是否可以直接贏 //int JudgeComputer(char Board[ROW][COL], int row, int col); //判斷玩傢下一步是否會贏 //int JudgePlayer(char Board[ROW][COL], int row, int col);
測試代碼
我們在test.c文件中測試該遊戲。
#include "game.h" void game() { char ret = 0; char Board[ROW][COL] = { 0 }; //初始化數組 InitBoard(Board, ROW, COL); //打印棋盤 printf("棋盤如下:\n"); DisplayBoard(Board, ROW, COL); while (1) { //玩傢下棋 printf("玩傢落子:\n"); PlayMove(Board, ROW, COL); //每下一步打印一次棋盤 DisplayBoard(Board, ROW, COL); //每下一步判斷一次勝負 ret = IsWin(Board, ROW, COL); if (ret != 'C') { break; } //電腦下棋 printf("電腦落子:\n"); ComputerMove(Board, ROW, COL); //每下一步打印一次棋盤 DisplayBoard(Board, ROW, COL); ret = IsWin(Board, ROW, COL); if (ret != 'C') { break; } } if (ret == '#') printf("玩傢獲勝\n"); else if (ret == '*') printf("電腦獲勝\n"); else if (ret == 'o') printf("臥龍鳳雛\n"); } void test() { int input = 0; srand((size_t)time(NULL)); do { meun(); printf("請選擇:>"); scanf("%d", &input); switch (input) { case 1: game(); break; case 0: printf("遊戲結束\n"); break; default: printf("輸入錯誤,請重新輸入:\n"); break; } } while (input); } int main() { test(); return 0; }
總結
此次代碼的實現總體來說雖然能夠實現井字棋功能,但是不得不承認代碼確實不夠精簡,還有我們可以思考是否可以使電腦更加聰明,落子的每一步都有自己的‘想法’,這裡也是博主需要不斷思考的問題,博主也要不斷的學習看能否實現該功能,如果朋友們有好的想法,歡迎與我進行交流,不勝感激,希望大傢以後多多支持WalkonNet!