【C語言】專案-三子棋
阿新 • • 發佈:2018-12-22
C語言專案
三子棋
實現思想
大家都玩過五子棋,也對五子棋的遊戲規則不陌生,今天我們就仿照五子棋做一個三子棋,以函式模組為進行封裝逐步實現,並且實現一個萬能演算法,可以達到n*n的棋盤上玩n子棋(前提是螢幕夠大)。
實現具體思想很簡單,先做出選單,然後根據玩家選擇執行不同的內容函式,如果選擇遊戲則開始三子棋的遊戲主體函式,執行完成之後重新執行選單,知道玩家選擇退出遊戲!
三子棋的主體遊戲思想也很簡單,用一個數組表示棋盤,每一個回合開始前先列印棋盤,隨後讓玩家進行座標選擇要落子的地方,此時注意 要判斷玩家輸入是否合法,玩家輸入後將棋盤上的資料進行更改,並判斷是否已經分出勝負,未結束的話是由電腦隨機選擇座標進行落子(在這裡我們暫時先進行簡單的設計,讓電腦隨機落子
實現程式碼
/*! * \檔名 源.cpp * \日期 2018/11/10 13:35 * * \作者 Misaki * 聯絡方式 [email protected] * * 檔案描述: 三子棋 * */ #define _CRT_SECURE_NO_WARNINGS #define ROW 5//棋盤行 #define COL 5//棋盤列 #define WIN 5//獲勝條件 #include <stdio.h> #include <stdlib.h> #include <windows.h> #include <time.h> char g_board[ROW][COL]; /* 將棋盤進行初始化 */ void initBoard() { for (int row = 0; row < ROW; row++) { for (int col = 0; col < COL; col++) { g_board[row][col] = ' ';//空位置用' '表示 } } } /* 列印選單 */ int menu() { system("cls"); int choose = 0; printf("1、開始遊戲\n"); printf("2、遊戲說明\n"); printf("3、退出\n"); printf("請選擇:"); scanf("%d", &choose); return choose; } /* 列印棋盤 */ void printBoard() { system("cls"); for (int col = 0; col < COL; col++) { printf(" _____"); } printf(" \n"); for (int row = 0; row < ROW; row++) { printf("|"); for (int col = 0; col < COL; col++) { printf("%6c", '|'); } printf("\n|"); for (int col = 0; col < COL; col++) { printf(" %c |", g_board[row][col]); } printf("\n|"); for (int col = 0; col < COL; col++) { printf("_____|"); } printf("\n"); } printf("\n"); } /* 玩家回合 */ void playerMove(int* row, int* col) { printf("玩家回合:\n"); int rowt = 0, colt = 0, result; while (1) { printf("請輸入座標:(格式:y x)"); if (result = scanf("%d%d", &rowt, &colt) != 2) { printf("你輸的是座標麼?重來\n"); rewind(stdin); continue; } if (rowt < 0 || rowt >= ROW || colt < 0 || colt >= COL) { printf("輸入座標不合法,請重新輸入!\n"); rewind(stdin); continue; } if (g_board[rowt][colt] != ' ') { printf("這個位置已經有子了!\n"); rewind(stdin); continue; } g_board[rowt][colt] = 'x'; //將值返回出去 *row = rowt; *col = colt; break; } } void computerMove(int* row, int* col) { int rowt = 0; int colt = 0; while (1) { rowt = rand() % (ROW); colt = rand() % (COL); if (g_board[rowt][colt] == ' ') { break; } } g_board[rowt][colt] = 'o'; //將值返回出去 *row = rowt; *col = colt; } /* 判斷是否平局 */ int isdraw() { int num = 0; for (int i = 0; i < ROW; i++) { for (int j = 0; j < COL; j++) { if (g_board[i][j] == ' ') { num++; } } } if (num == 0)//平局了,棋盤滿了 { return 1; } else//還能打 { return 0; } } /* 判斷是否三子相連 引數:當前下子位置 返回值:誰獲得勝利 */ char judge(int row, int col) { int num =1;//計數相連棋子個數 int i = 1;//判斷周圍第i個棋子是否相同 //從左到右的判斷 for (i = 1; i < WIN; i++) { if ((col + i) > (COL - 1) || g_board[row][col] != g_board[row][col + i]) { break; } num++; } //從右到左的判斷 for (i = 1; i < WIN; i++) { if ((col - i) < 0 || g_board[row][col] != g_board[row][col - i]) { break; } num++; } if (num >= WIN) { return g_board[row][col]; } num = 1; //從上到下的判斷 for (i = 1; i < WIN; i++) { if ((row + i) > (ROW - 1) || g_board[row][col] != g_board[row + i][col]) { break; } num++; } //從下到上的判斷 for (i = 1; i < WIN; i++) { if ((row - i) < 0 || g_board[row][col] != g_board[row - i][col]) { break; } num++; } if (num >= WIN) { return g_board[row][col]; } num = 1; //從左上到右下的判斷 for (i = 1; i < WIN; i++) { if ((row + i) > (ROW - 1) || (col + i) > (COL - 1) || g_board[row][col] != g_board[row + i][col + i]) { break; } num++; } //從右下到左上的判斷 for (i = 1; i < WIN; i++) { if ((row - i) < 0 || (col - i) < 0 || g_board[row][col] != g_board[row - i][col - i]) { break; } num++; } if (num >= WIN) { return g_board[row][col]; } num = 1; //從右上到左下的判斷 for (i = 1; i < WIN; i++) { if ((row + i) > (ROW - 1) || (col - i) < 0 || g_board[row][col] != g_board[row + i][col - i]) { break; } num++; } //從左下到右上的判斷 for (i = 1; i < WIN; i++) { if ((row - i) < 0 || (col + i) > (COL - 1) || g_board[row][col] != g_board[row - i][col + i]) { break; } num++; } if (num >= WIN) { return g_board[row][col]; } if (isdraw())//平局了 { return 'd'; } else { return ' '; } } /* 遊戲是否結束 */ int isOver(int row, int col) { char c = judge(row, col); if (c == ' ') { return 0; } if (c == 'x') { printf("恭喜你贏了!\n"); system("pause"); return 1; } if (c == 'o') { printf("不走運,你輸了!\n"); system("pause"); return 1; } else { printf("平局!\n"); system("pause"); return 1; } } /* 遊戲主體 */ void mainGame() { int row = 0; int col = 0; //初始化棋盤 initBoard(); //列印棋盤 printBoard(); //迴圈控制遊戲程序 while (1) { //玩家開始下 playerMove(&row, &col); //列印棋盤 printBoard(); //判定是否遊戲結束 if (isOver(row, col)) { break; } //電腦下 computerMove(&row, &col); //列印棋盤 printBoard(); printf("計算機回合↑\n"); //判定是否遊戲結束 if (isOver(row, col)) { break; } } } void gameExplain() { system("cls"); printf("五子棋你會玩,三子棋你不會玩?\n"); printf("什麼你五子棋都不會玩,你不會百度,搜狗,goole啊!\n"); system("pause"); } int main() { srand(time(NULL)); while (1) { int choose = menu(); if (choose == 1) { mainGame(); continue; } if (choose == 2) { gameExplain(); continue; } if (choose == 3) { break; } else { printf("別瞎比選!\n"); rewind(stdin); system("pause"); continue; } } printBoard(); return 0; }
在這裡值得一提的是我用來判斷是否獲勝的演算法,演算法可總結為以落子為中心,向橫縱正斜和反斜四個方向分別計數,以達到統計是否已經連子獲勝的目的。
歡迎來我的部落格閒逛:https://misakifx.github.io/