一、三子棋的規則
三子棋是一個很古老的民間傳統游戲,玩起來也非常便捷,三子棋也叫做OOXX棋,井字棋等,用“井”字分出3×3的格子,雙方輪流下棋子(可以用O或者X來區別),只要將自己的棋子連成直線就贏了,

二、三子棋的具體實作思路(基本流程)
- 建立一個游戲選單
- 創建一個棋盤并將其初始化
- 將初始化后的棋盤進行列印
- 玩家落子并列印棋盤(玩家輸入行列坐標的方式來落子)
- 判定勝負關系(玩家是否獲勝?有則直接游戲結束無則繼續進行)
- 電腦落子并列印棋盤(隨機位置落子)
- 判定勝負關系(電腦是否獲勝?有則直接游戲結束無則繼續進行)
- 若無勝負關系則回到 2 繼續交替下棋直至出現勝負或和棋,
三、游戲的具體實作程序(源代碼)
1.代碼總覽
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<windows.h>
#include<time.h>
//三子棋游戲
#define MAX_ROW 3//宏定義行數,列數,方便后續進行修改
#define MAX_COL 3
//一·創建一個游戲選單
//選單函式
int menu(){
printf("========================\n");
printf(" 1. 開始游戲\n");
printf(" 0. 結束游戲\n");
printf("========================\n");
printf(" 請輸入您的選擇: ");
int num = -1;
scanf("%d", &num);;//利用鍵盤輸入選項
return num;//將選項值回傳到主函式中進行判斷
}
//二·游戲內容
//棋盤初始化
void init(char chessBoard[MAX_ROW][MAX_COL]) {
// 把陣列中的每個元素都設為 “空格”
for (int row = 0; row < MAX_ROW; row++) {
for (int col = 0; col < MAX_COL; col++) {
chessBoard[row][col] = ' ';
}
}
}
//列印棋盤
void printChessBoard(char chessBoard[MAX_ROW][MAX_COL]){
printf("+---+---+---+\n");
for (int row = 0; row < MAX_ROW; row++){
printf("| %c | %c | %c |\n", chessBoard[row][0],
chessBoard[row][1], chessBoard[row][2]);
printf("+---+---+---+\n");
}
}
//玩家落子“x”
void playerMove(char chessBoard[MAX_ROW][MAX_COL]) {
while (1){
printf("請輸入你要下棋的坐標(ROW COL)");
int row = 0;
int col = 0;
scanf("%d %d", &row, &col);
//對落子進行判斷
if (row < 0 || row >= MAX_ROW || col < 0 || col >= MAX_COL) {
// 輸入越界讓玩家重新輸入.
printf("您的坐標不在合法范圍內 [0, 2]\n");
continue;
}
// 校驗玩家落子位置是否已經有子了.
if (chessBoard[row][col] != ' ') {
printf("您的坐標位置已經有子了!\n");
continue;
}
//最終落子
chessBoard[row][col] = 'x';
break;
}
}
//電腦落子“o”
void computerMove(char chessBoard[MAX_ROW][MAX_COL]) {
while (1){
int row = rand() % MAX_ROW;//設定亂數讓棋子落在棋盤內
int col = rand() % MAX_COL;
//對落子進行判斷
// 校驗玩家落子位置是否已經有子了.
if (chessBoard[row][col] != ' ') {
continue;
}
//最終落子
chessBoard[row][col] = 'o';
break;
}
}
//判斷棋盤是否有剩余空間
int isFull(char chessBoard[MAX_ROW][MAX_COL]) {
// 找空格?如果找不到就是滿了回傳1:找到了則說明未滿回傳0
for (int row = 0; row < MAX_ROW; row++) {
for (int col = 0; col < MAX_COL; col++) {
if (chessBoard[row][col] == ' ') {
// 找到了
return 0;
}
}
}
//未找到
return 1;
}
//判斷是否勝利
char isWin(char chessBoard[MAX_ROW][MAX_COL]) {
// 'x' 表示玩家獲勝
// 'o' 表示電腦獲勝
// ' ' 表示勝負未分
// 'q' 表示和棋
// 判定是否行相等
for (int row = 0; row < MAX_ROW; row++) {
if (chessBoard[row][0] != ' '//行不都等于“ ”
&& chessBoard[row][0] == chessBoard[row][1]
&& chessBoard[row][0] == chessBoard[row][2]) {
return chessBoard[row][0];
}
}
// 判定是否列相等
for (int col = 0; col < MAX_COL; col++) {
if (chessBoard[0][col] != ' '
&& chessBoard[0][col] == chessBoard[1][col]
&& chessBoard[0][col] == chessBoard[2][col]) {
return chessBoard[0][col];
}
}
// 判定兩個對角線是否相等
if (chessBoard[0][0] != ' '
&& chessBoard[0][0] == chessBoard[1][1]
&& chessBoard[0][0] == chessBoard[2][2]) {
return chessBoard[0][0];//主對角線相等
}
if (chessBoard[2][0] != ' '
&& chessBoard[2][0] == chessBoard[1][1]
&& chessBoard[2][0] == chessBoard[0][2]) {
return chessBoard[2][0];//副對角線相等
}
// 判定是否和棋看棋盤中是否有剩余空間?有剩余繼續:無剩余則為和棋
if (isFull(chessBoard)) {
return 'q';
}
//若游戲未結束則繼續游戲
return ' ';
}
//游戲函式
void game(){
//1創建一個3x3的棋盤
int chessBoard[MAX_ROW][MAX_COL] = { 0 };
//2初始化棋盤
init(chessBoard);
char winner = ' ';
while (1){
//3將棋盤進行列印
printChessBoard(chessBoard);
//4玩家落子
playerMove(chessBoard);
//5判斷是否勝利
winner = isWin(chessBoard);
//如果未結束則繼續游戲
if (winner != ' ') {
break;
}
//7電腦落子
computerMove(chessBoard);
//8判斷是否勝利
winner = isWin(chessBoard);
//如果未結束則繼續游戲
if (winner != ' ') {
break;
}
//回圈操作3直至游戲結束
}
printChessBoard(chessBoard);
//勝利條件判斷
if (winner == 'x') {
printf("恭喜您, 您贏了!\n");
}
else if (winner == 'o') {
printf("很遺憾, 您連人機下不過!\n");
}
else {
printf("很遺憾, 您和人機五五開!\n");
}
}
int main(){
srand((unsigned int)time(0));//用時間設定一個隨機種子,將時間從 time_t 轉成 unsigned int
while (1){
//一·創建一個游戲選單
int choice = menu();//選單函式
if (choice == 1){
game();//游戲函式
}
else if (choice == 0) {
printf("goodbye!\n");
break;
}
else{
printf("您輸入的有誤請重新輸入\n");
}
}
system("pause");
return 0;
}
2.代碼分部剖析
(1)主函式書寫
main(){
while (1){
int choice = menu();//呼叫選單函式進行游戲選擇
if (choice == 1){//輸入1時進入游戲
game();//游戲函式
}
else if (choice == 0) {//輸入0時退出程式
printf("goodbye!\n");
break;
}
else{//輸入其他字符進行錯誤提示并使其再次輸入
printf("您輸入的有誤請重新輸入\n");
}
}
system("pause");
return 0;
}
(2)選單函式書寫
//選單函式
int menu(){
printf("========================\n");
printf(" 1. 開始游戲\n");
printf(" 0. 結束游戲\n");
printf("========================\n");
printf(" 請輸入您的選擇: ");
int num = -1;
scanf("%d", &num);//利用鍵盤輸入選項
return num;//將選項值回傳到主函式中進行判斷
}
(3)游戲函式書寫
1初始化棋盤
//棋盤初始化
void init(char chessBoard[MAX_ROW][MAX_COL]) {
// 把陣列中的每個元素都設為 “空格”
for (int row = 0; row < MAX_ROW; row++) {
for (int col = 0; col < MAX_COL; col++) {
chessBoard[row][col] = ' ';
}
}
}
2列印棋盤
//列印棋盤
void printchessBoard(char chessBoard[MAX_ROW][MAX_COL]){
printf("+---+---+---+\n");
for (int row = 0; row < MAX_ROW; row++){
printf("| %c | %c | %c |\n", chessBoard[row][0],
chessBoard[row][1], chessBoard[row][2]);
printf("+---+---+---+\n");
}
};
列印棋盤效果圖:

3.玩家落子:
//玩家落子“x”
void playerMove(char chessBoard[MAX_ROW][MAX_COL]) {
while (1){
printf("請輸入你要下棋的坐標(ROW COL)");
int row = 0;
int col = 0;
scanf("%d %d", row, col);
//對落子進行判斷
if (row < 0 || row >= MAX_ROW || col < 0 || col >= MAX_COL) {
// 輸入越界讓玩家重新輸入.
printf("您的坐標不在合法范圍內 [0, 2]\n");
continue;
}
// 校驗玩家落子位置是否已經有子了.
if (chessBoard[row][col] != ' ') {
printf("您的坐標位置已經有子了!\n");
continue;
}
//最終落子
chessBoard[row][col] = 'x';
break;
}
};
4.電腦落子:
//電腦落子“o”
void playerMove(char chessBoard[MAX_ROW][MAX_COL]) {
while (1){
int row = rand() % MAX_ROW;//設定亂數讓棋子落在棋盤內
int col = rand() % MAX_COL;
//對落子進行判斷
// 校驗玩家落子位置是否已經有子了.
if (chessBoard[row][col] != ' ') {
continue;
}
//最終落子
chessBoard[row][col] = 'o';
break;
}
};
注意:
使用亂數需要設定隨機種子,否則rand()是一個偽亂數!
// 此處使用強制型別轉換, 把 time_t 轉成 unsigned int
srand((unsigned int)time(0));
5判斷勝負:
//判斷是否勝利
char isWin(char chessBoard[MAX_ROW][MAX_COL]) {
// 'x' 表示玩家獲勝
// 'o' 表示電腦獲勝
// ' ' 表示勝負未分
// 'q' 表示和棋
// 判定是否行相等
for (int row = 0; row < MAX_ROW; row++) {
if (chessBoard[row][0] != ' '//行不都等于“ ”
&& chessBoard[row][0] == chessBoard[row][1]
&& chessBoard[row][0] == chessBoard[row][2]) {
return chessBoard[row][0];
}
}
// 判定是否列相等
for (int col = 0; col < MAX_COL; col++) {
if (chessBoard[0][col] != ' '
&& chessBoard[0][col] == chessBoard[1][col]
&& chessBoard[0][col] == chessBoard[2][col]) {
return chessBoard[0][col];
}
}
// 判定兩個對角線是否相等
if (chessBoard[0][0] != ' '
&& chessBoard[0][0] == chessBoard[1][1]
&& chessBoard[0][0] == chessBoard[2][2]) {
return chessBoard[0][0];//主對角線相等
}
if (chessBoard[2][0] != ' '
&& chessBoard[2][0] == chessBoard[1][1]
&& chessBoard[2][0] == chessBoard[0][2]) {
return chessBoard[2][0];//副對角線相等
}
// 判定是否和棋看棋盤中是否有剩余空間?有剩余繼續:無剩余則為和棋
if (isFull(chessBoard)) {
return 'q';
}
//若游戲未結束則繼續游戲
return ' ';
}
6判斷棋盤是否為空
//判斷棋盤是否有剩余空間
int isFull(char chessBoard[MAX_ROW][MAX_COL]) {
// 找空格?如果找不到就是滿了回傳1:找到了則說明未滿回傳0
for (int row = 0; row < MAX_ROW; row++) {
for (int col = 0; col < MAX_COL; col++) {
if (chessBoard[row][col] == ' ') {
// 找到了
return 0;
}
}
}
//未找到
return 1;
}
7進行勝利判斷
//勝利條件判斷
if (winner == 'x') {
printf("恭喜您, 您贏了!\n");
}
else if (winner == 'o') {
printf("很遺憾, 您連人機下不過!\n");
}
else {
printf("很遺憾, 您和人機五五開!\n");
}
}
3.運行圖例


4.小結
此游戲實作利用了二維陣列,亂數,函式等知識進行實作
基本能實作三子棋游戲,講解內容略顯累贅,有不足之處望指教!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/204191.html
標籤:其他
