[C]專案--三子棋遊戲
阿新 • • 發佈:2018-12-22
三子棋
- 楔子:
三子棋是我們小時候經常玩的遊戲,那麼我們今天嘗試用C語言實現一下這個小遊戲.需要用到的主要知識就是函式封裝和陣列.
以下為程式主體:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
//定義棋盤為 3 * 3
#define ROW 3
#define COL 3
char g_board[ROW][COL];
//對於全域性變數,沒顯式初始化,就會預設初始化為 0
void menu() {
while (1) {
printf(" 三子棋\n");
printf("-----------------------\n");
printf("1.開始遊戲 0.退出遊戲\n");
printf("-----------------------\n");
int a = 0;
scanf("%d", &a);//接受玩家選擇指令
if (a == 1) {
break;
}
else {
printf("\n輸入有誤,請根據選項數字重新輸入!\n");
printf("\n");
continue ;
}
}
}
//1.進行棋盤的初始化
void Init() {
srand((unsigned int)time(0));//設定隨機種子
for (int row = 0; row < ROW; ++row) {
for (int col = 0; col < COL; ++col) {
g_board[row][col] = ' ';//未下子用空格表示
}
}
}
//列印棋盤
void Print() {
printf("|---|---|---|\n");
for (int row = 0; row < ROW; ++row) {
printf ("| %c | %c | %c |\n", g_board[row][0],
g_board[row][1], g_board[row][2]);
printf(" ---|---|--- \n");
}
}
//玩家落子回合
void PlayerMove() {
printf("請玩家落子!\n");
while (1) {
printf("請輸入座標(row col):\n");
int row, col;
scanf("%d %d", &row, &col);
//判斷輸入引數是否合法
if (row < 0 || row >= ROW || col < 0 || col >= COL) {
printf("輸入的座標非法,請重新輸入!\n");
continue;
}
if (g_board[row][col] != ' ') {
printf("當前位置已經有子,請重新輸入!\n");
continue;
}
g_board[row][col] = 'x';//完成元素的更迭,直觀上來看就是"落子"了
break;
}
}
//電腦落子回合
void ComputerMove() {
printf("請電腦落子!\n");
while (1) {
//電腦"隨機下"
int row = rand() % ROW;
int col = rand() % ROW;
if (g_board[row][col] != ' ') {
continue;
}
g_board[row][col] = 'o';
break;
}
}
//判斷棋盤是否全部填滿的函式
int Isfull() {
for (int row = 0; row < ROW; ++row) {
for (int col = 0; col < COL; ++col) {
if (g_board[row][col] == ' ') {
return 0;
}
}
}
return 1;
}
char CheckWinner() {
//檢查行列斜線是否可以連成三個
//行
for (int row = 0; row < ROW; ++row) {
if (g_board[row][0] == g_board[row][1] &&
g_board[row][0] == g_board[row][2] &&
g_board[row][0] != ' ') {
return g_board[row][0];
}
}
//列
for (int col = 0; col < COL; ++col) {
if (g_board[0][col] == g_board[1][col] &&
g_board[0][col] == g_board[2][col] &&
g_board[0][col] != ' ') {
return g_board[0][col];
}
}
//斜 兩條對角線
if (g_board[0][0] == g_board[1][1] &&
g_board[0][0] == g_board[2][2] &&
g_board[0][0] != ' ') {
return g_board[0][0];
}
if (g_board[0][2] == g_board[1][1] &&
g_board[0][2] == g_board[2][0] &&
g_board[0][2] != ' ') {
return g_board[0][2];
}
//判斷和棋情況
if (Isfull()) {
//如果填滿了 返回和棋
return 'q';
}
//如若沒填滿 返回 勝負未分
return ' ';
}
//遊戲邏輯主體
int main() {
menu();//1.先列印選單函式,讓玩家選擇
Init();//2.玩家選擇開始,初始化棋盤
Print();//3.列印棋盤
char winner;//4.判斷勝者
while (1) {
//winner -> x 玩家勝
//winner -> o 電腦勝
//winner -> ' '勝負未分
//winner -> q 和棋
//5.玩家落子,判定是否遊戲結束
PlayerMove();
winner = CheckWinner();
if (winner != ' ') {
//如果CheckWinner函式返回了 勝負未分 則跳出迴圈,跳出玩家落子階段
break;
}
Print();//列印更新後的棋盤
//6.電腦落子,判定是否遊戲結束
ComputerMove();
winner = CheckWinner();
if (winner != ' ') {
break;
}
Print();
}
if (winner == 'x') {
printf("玩家勝\n");
Print();
}
else if (winner == 'o') {
printf("電腦勝\n");
Print();
}
else {
printf("和棋\n");
Print();
}
system("pause");
return 0;
}
需要注意的是:
- 在程式首用define定義變數是為了程式的延展性,讓他不僅限於此程式碼,而可以擴充套件成為4 * 4或者 5 * 5的四子棋或五子棋.
- 整個遊戲邏輯必須明晰:
列印選單,讓玩家選擇.
列印棋盤 (選擇開始再列印,否則退出遊戲)
玩家落子,判定勝負
電腦落子,判定勝負
大體框架明確了,接下來就是完成拆分的具體小模組了,化整為零的解決. - 儘量不要只侷限於本專案,儘量多抽象一些引數出來,將它包裝化,讓我們可以對它進行延伸和衍生,達到一定程度上的泛型程式設計.
- 總結:
一個小遊戲的實現,讓我對所學知識的總和運用能力有了一定的提升,函式是為了主體而服務的,所以一定要確定目標邏輯,再有針對性的下筆.