
目錄
- 前言
- 一、三子棋游戲規則
- 二、基本流程
- 二、步驟
- 1.選單界面
- 2、創建棋盤
- 3、棋盤初始化
- 4、列印棋盤
- 5、玩家落子
- 6、電腦落子
- 7、判斷勝負
- 五、多檔案形式
- game.h
- game.c
- test.c
- 總結
前言
提示:是黑白棋的一種,三子棋是一種民間傳統游戲,又叫九宮棋、圈圈叉叉、一條龍、井字棋等,將正方形對角線連起來,相對兩邊依次擺上三個雙方棋子,只要將自己的三個棋子走成一條線,對方就算輸了,但是,有很多時候會出現和棋的情況,

一、三子棋游戲規則
子棋也叫做OOXX棋,井字棋等,用“井”字分出3×3的格子,雙方輪流下棋子(可以用O或者X來區別),只要將自己的三個棋子走成一條線,就算獲勝,
二、基本流程
二、基本流程
在實作三子棋代碼之前,我們來看看實作這個游戲的邏輯:
1、建立一個游戲選單,
2、創建和初始化棋盤,
3、列印棋盤,
4、玩家落子并列印棋盤(通過坐標)用 'o’表示玩家落子,
5、判斷勝負(判斷玩家是否獲勝?獲勝則直接游戲結束否則繼續進行),
6、電腦落子并列印棋盤(隨機落子)用 ‘x’表示電腦落子,
7、判斷勝負(電腦是否獲勝?獲勝則直接游戲結束否則繼續進行),
8、若和棋則回到 步驟2 繼續執行,
二、步驟

1.選單界面
1、開始游戲 0、退出:
main.c是程式的主體框架
void menu()
{
printf("****************************\n");
printf("********** 1、play *********\n");
printf("********** 0、exit *********\n");
printf("****************************\n");
}
int main()
{
int input = 0;
srand((unsigned int)time(NULL));
char arr[ROW][COL];
menu();
do
{
printf("請輸入選擇;>\n");
scanf("%d", &input);
switch (input)
{
case 1:
game(arr,ROW,COL);
break;
case 0:
break;
default:
printf("輸入錯誤重新輸入\n");
break;
}
} while (input);
return 0;
}
在列印選單中,我們用do…while回圈可以使得選單至少列印一次
下方就是列印出的選單界面

2、創建棋盤
我們列印出選單界面后,就可以開始進行游戲了,要進行游戲,我們首先要創建一個棋盤,
棋盤:使用3行3列的二維陣列來表示,元素型別是char,
#define COL 3
#define ROW 3
**使用宏定義的原因:
1.推高代碼可讀性,后續代碼中遇到3,方便理解含義,
2.提高擴展性,如果將來要修改棋盤尺寸,代碼修改會很方便,
**
3、棋盤初始化
在我們下棋的時候,我們首先要保證棋盤上面是空的,所以我們用空格來初始化棋盤,
void InitBoard(char arr[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
arr[i][j] = ' ';
}
}
}
4、列印棋盤
當我們初始化棋盤后,我們列印出來看看棋盤是怎樣的,看下列代碼和輸出:

void diaplayBoard(char arr[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
printf(" %c ",arr[i][j]);
if(j < col - 1)
printf("|");
}
printf("\n");
if(i < col - 1)
for (j = 0; j < col; j++)
{
printf("---");
if (j < col - 1)
printf("|");
}
printf("\n");
}
}
5、玩家落子
玩家輸入行列坐標表示落子,使用’*’表示玩家落子,
玩家落子時注意事項:
1.玩家落子需要在棋盤范圍內,
2.玩家要在棋盤上空的地方落子,
3.如果輸入的坐標不滿足要重新輸入,
void playmove(char arr[ROW][COL], int row, int col)
{
do
{
int x = 0, y = 0;
int i = 0, j = 0;
printf("請輸入坐標:>");
scanf("%d%d", &x, &y);
if ((x > 0 && x <= row) && (y > 0 && y <= col))
{
if (arr[x - 1][y - 1] == ' ')
{
arr[x - 1][y - 1] = '*';
break;
}
else
{
printf("位置被占用了\n");
}
}
else
{
printf("非法坐標重新輸入\n");
}
} while (1);
}
6、電腦落子
電腦隨機落子,'X’表示電腦落子, 因為電腦是隨機落子,所以我們需要產生一個隨機坐標,所以我們需要一個隨機值,
電腦落子注意事項:
1.要在主函式中使用srand((unsigned int)time(NULL))
將時間戳作為亂數的起點(頭檔案:#include <time.h>),確保得到的行列坐標是真隨機,
2.在函式中使用rand()函式產生隨機坐標(頭檔案:#include <stdlib.h>),還要確保坐標在棋盤范圍內
3.要在棋盤上空的地方下棋,
void computermove(char arr[ROW][COL], int row, int col)
{
do
{
int x = 0, y = 0;
x = rand() % row;
y = rand() % col;
if ((x >= 0 && x <= 2) && (y >= 0 && y <= 2))
{
if (arr[x][y] == ' ')
{
arr[x][y] = '#';
break;
}
}
} while (1);
}
7、判斷勝負
利用回傳結果判斷勝負:
要回傳4種不同的狀態:
玩家獲勝—> ‘*’
電腦獲勝 —> ‘#’
平局 —> ‘Q’
繼續 —> ‘C’
1.獲勝
(1)判定所有的行(一行字符全部相同,即獲勝)
(2)判定所有的列(一列字符全部相同,即獲勝)
(3)判定兩條對角線(一條對角線字符全部相同,即獲勝)
注意:需排除空棋盤的情況(即全為空格,沒有下子)
2.平局
(1)呼叫IsFull函式,
(2)回傳1,表示棋盤滿了,回傳0,表示棋盤沒滿,
(3)如果棋盤滿了未分出勝負,平局,
(4)如果棋盤沒滿,游戲繼續
int Is_Full(char arr[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
int count = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
if (arr[i][j] != ' ')
{
count++;
}
}
}
if (count == row * col)
{
return 1;
}
return -1;
}
五、多檔案形式
我們平常寫代碼的時候,如果程式比較大,那么直接包含在一個檔案中就會顯得比較亂,就如同上方一樣,全放一個檔案中,非常容易混亂,并且不容易維護,這個時候就需要用到多檔案,使用多檔案的時候可以將整個程式拆分開來,比方說分為頭檔案、函式檔案、主函式檔案,當然如果有需要的話,還可以繼續細分,
接下來我們將上方三子棋代碼進行分塊來寫:
首先我們可以創建3個檔案:一個頭檔案game.h,兩個源檔案game.c,test.c

game.h
在game.h里可以先宣告一些變數如(ROW和COL)和頭檔案,和要定義的函式的宣告
game.h是用來各個函式的宣告,game.c是各個函式的代碼的實作,test.c是主函式檔案,負責呼叫各個三子棋所用到的函式
#define _CRT_SECURE_NO_WARNINGS
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define COL 3
#define ROW 3
void game(char arr[ROW][COL], int row, int col);
void InitBoard(char arr[ROW][COL],int row,int col);
void diaplayBoard(char arr[ROW][COL], int row, int col);
void playmove(char arr[ROW][COL], int row, int col);
void computermove(char arr[ROW][COL], int row, int col);
char IsWin(char arr[ROW][COL], int row, int col);
int Is_Full(char arr[ROW][COL], int row, int col);
game.c
在game.c里參考 #include “game.h”,參考這個后可以使用game.h里面的定義的變數和函式,
#include"game.h"
void game(char arr[ROW][COL], int row, int col)
{
char ch;
InitBoard(arr, row, col);
diaplayBoard(arr, row, col);
while (1)
{
playmove(arr, row, col);
diaplayBoard(arr, row, col);
ch = IsWin(arr, row, col);
if (ch != 'c')
{
break;
}
computermove(arr, row, col);
diaplayBoard(arr, row, col);
ch = IsWin(arr, row, col);
if (ch != 'c')
{
break;
}
}
if (ch == '*')
{
printf("玩家贏\n");
}
else if (ch == '#')
{
printf("電腦贏\n");
}
else if (ch == 'q')
{
printf("平局\n");
}
}
int Is_Full(char arr[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
int count = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
if (arr[i][j] != ' ')
{
count++;
}
}
}
if (count == row * col)
{
return 1;
}
return -1;
}
char IsWin(char arr[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
int count1 = 0;
int count2 = 0;
if (Is_Full(arr, row, col) == 1)
{
return 'q';
}
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
if (arr[i][0] == arr[i][1] && arr[i][1] == arr[i][2] && arr[i][0] != ' ')
{
return arr[i][1];
}
else if (arr[0][i] == arr[1][i] && arr[1][i] == arr[2][i] && arr[0][i] != ' ')
{
return arr[i][1];
}
else if (arr[0][0] == arr[1][1] && arr[1][1] == arr[2][2] && arr[0][0] != ' ')
{
return arr[0][0];
}
else if (arr[0][2] == arr[1][1] && arr[1][1] == arr[2][0] && arr[0][2] != ' ')
{
return arr[0][2];
}
}
}
return 'c';
}
void InitBoard(char arr[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
arr[i][j] = ' ';
}
}
}
void diaplayBoard(char arr[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
printf(" %c ",arr[i][j]);
if(j < col - 1)
printf("|");
}
printf("\n");
if(i < col - 1)
for (j = 0; j < col; j++)
{
printf("---");
if (j < col - 1)
printf("|");
}
printf("\n");
}
}
void playmove(char arr[ROW][COL], int row, int col)
{
do
{
int x = 0, y = 0;
int i = 0, j = 0;
printf("請輸入坐標:>");
scanf("%d%d", &x, &y);
if ((x > 0 && x <= row) && (y > 0 && y <= col))
{
if (arr[x - 1][y - 1] == ' ')
{
arr[x - 1][y - 1] = '*';
break;
}
else
{
printf("位置被占用了\n");
}
}
else
{
printf("非法坐標重新輸入\n");
}
} while (1);
}
void computermove(char arr[ROW][COL], int row, int col)
{
do
{
int x = 0, y = 0;
x = rand() % row;
y = rand() % col;
if ((x >= 0 && x <= 2) && (y >= 0 && y <= 2))
{
if (arr[x][y] == ' ')
{
arr[x][y] = '#';
break;
}
}
} while (1);
}
test.c
然后在test.c主函式檔案里參考 #include “game.h”,參考這個后可以使用game.h里面的定義的變數和函式,
#include"game.h"
void menu()
{
printf("****************************\n");
printf("********** 1、play *********\n");
printf("********** 0、exit *********\n");
printf("****************************\n");
}
int main()
{
int input = 0;
srand((unsigned int)time(NULL));
char arr[ROW][COL];
menu();
do
{
printf("請輸入選擇;>\n");
scanf("%d", &input);
switch (input)
{
case 1:
game(arr,ROW,COL);
break;
case 0:
break;
default:
printf("輸入錯誤重新輸入\n");
break;
}
} while (input);
return 0;
}
謝謝大家以上就是博主根據自己的理解組織的代碼跟表述形式,希望對大家有幫助

總結
多檔案編程利于維護和開發,希望各位盡早養成這種良好習慣
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/290972.html
標籤:其他
上一篇:C語言小游戲:掃雷實作
