這是我的第一個C語言小遊戲:三子棋。
下面分享一下我的思路:
代碼分為四個部分:utili.h是存放頭檔案;game.h是存放函數聲明;game.c是遊戲内所需要的函數的代碼編寫;gameMain.c是進行遊戲的邏輯編寫。
<1>列印菜單欄
首先我們進入遊戲肯定會看到菜單欄進行選擇玩遊戲或者退出,1就是玩遊戲,0就是退出遊戲。代碼如下:
//這裡在gameMain.c源檔案中
int select = 1;
while(select)
{
printf("********************************\n");
printf("* 簡 易 三 子 棋 *\n");
printf("********************************\n");
printf("* [1] Play *\n");
printf("* [0] Exit *\n");
printf("********************************\n");
printf("請選擇:>");
scanf("%d", &select);
if(select == 0)
break;
if(select != 1)
{
printf("輸入的選項有誤,請重新輸入......\n");
continue;
}
在這裡我把菜單放到了主函數裡,也可以單獨寫一個函數。
<2>初始化棋盤
三子棋遊戲中的棋盤我們用空格來初始化,代碼如下:
//這裡在game.c源檔案中
void InitChessBoard(char chess_board[ROW][COL])//ROW是行,COL是列,可以在檔案前做一個宏定義
{ //#define ROW 3
for(int i=0; i<ROW; ++i) //#define COL 3放到game.h頭檔案裡
{
for(int j=0; j<COL; ++j)
{
chess_board[i][j] = ' ';
}
}
}
<3>顯示棋盤
這裡列印出棋盤的樣子,代碼如下:
//utili.h頭檔案中的代碼
//預防頭檔案重複引入
#ifndef _UTILI_H_
#define _UTILI_H_
#include<stdio.h>
#include<time.h>
#include<stdbool.h>
#endif /* _UTILI_H_ */
//game.h頭檔案中的代碼
#ifndef _GAME_H_
#define _GAME_H_
#include"utili.h"
#define ROW 3
#define COL 3
//函數申明
void StartGame();
void InitChessBoard(char chess_board[ROW][COL]);
void DisplayChessBoard(char chess_board[ROW][COL]);
#endif /* _GAME_H_ */
//這裡在game.c源檔案中
void DisplayChessBoard(char chess_board[ROW][COL])
{
for(int i=0; i<ROW; ++i)
{
printf("| %c | %c | %c |\n", chess_board[i][0],
chess_board[i][1],
chess_board[i][2]);
if(i < ROW-1)
printf(" --- --- ---\n");
}
}
這裡可以自己調整成自己喜歡的樣子。
<4>玩家下棋
寫完玩家下棋函數後在頭檔案裡加入聲明。
//game.c源檔案中的代碼
void PlayerMove(char chess_board[ROW][COL])
{
int x, y;
printf("玩家下棋.\n");
printf("請輸入坐标:>");
while(1)
{
scanf("%d %d", &x, &y);
//檢查坐标的有效性
if(x<0||x>=ROW || y<0 || y>COL)
{
printf("輸入的坐标不合法,請重新輸入.....\n");
continue;
}
//檢查坐标是否被占用
if(chess_board[x][y] == ' ')
{
chess_board[x][y] = PLAYER_CHESS_SYMBAL;
break;
}
}
}
<5>電腦下棋
電腦下棋要随機下棋可以寫一個随機數函數(根據時間生成數值)
//電腦下棋
void ComputerMove(char chess_board[ROW][COL])
{
int x, y;
srand(time(0));//種一個随機數種子
while(1)
{
x = rand()%ROW;
y = rand()%COL;
if(chess_board[x][y] == ' ')
{
chess_board[x][y] = COMPUTER_CHESS_SYMBAL; //'o'
break;
}
}
}
<6>判滿
我們需要判斷勝負首先要知道棋盤是否下滿,這就要我們寫一個判滿函數。代碼如下:
bool ChessBoardFull(char chess_board[ROW][COL])
{
for (int i = 0; i < ROW; ++i)
{
for (int j = 0; j < COL; ++j)
{
if (chess_board[i][j] == ' ')
{
return false;
}
}
}
return true;
}
<7>檢查結果
有四種情況就是玩家赢,電腦赢,平局,繼續遊戲,我們可以有一個傳回值,根據傳回值來判。比如玩家赢我們就傳回'x',電腦赢我們就傳回'o',平局就傳回'h',繼續遊戲就傳回'c'。
//檢查結果
//'c': 繼續
//'x':玩家赢
//'o': 電腦赢
//'h': 和棋
char CheckResult(char chess_board[ROW][COL])
{
//1 檢查行
for (int i = 0; i < ROW; ++i)
{
if ((chess_board[i][0] != ' ') &&
(chess_board[i][0] == chess_board[i][1]) &&
(chess_board[i][0] == chess_board[i][2]))
return chess_board[i][0];
}
//2 檢查列
for (int i = 0; i < ROW; ++i)
{
if ((chess_board[0][i] != ' ') &&
(chess_board[0][i] == chess_board[1][i]) &&
(chess_board[0][i] == chess_board[2][i]))
return chess_board[0][i];
}
//3 檢查對角線
if ((chess_board[0][0] != ' ') &&
(chess_board[0][0] == chess_board[1][1]) &&
(chess_board[0][0] == chess_board[2][2]))
return chess_board[1][1];
if ((chess_board[1][1] != ' ') &&
(chess_board[1][1] == chess_board[2][0]) &&
(chess_board[1][1] == chess_board[0][2]))
return chess_board[1][1];
//4 檢查是否和棋
if (ChessBoardFull(chess_board))
return 'h';
return 'c';
}
<8>開始遊戲
将以上所有的函數進行三子棋遊戲邏輯進行組裝函數,代碼如下:
void StartGame()
{
//定義棋盤
char chess_board[ROW][COL];
//初始化棋盤
InitChessBoard(chess_board);
//進入遊戲
char winner;
while(1)
{
//顯示棋盤
DisplayChessBoard(chess_board);
//玩家下棋
PlayerMove(chess_board);
//判斷結果
winner = CheckResult(chess_board);
if(winner != 'c')
break;
//電腦下棋
ComputerMove(chess_board);
//判斷結果
winner = CheckResult(chess_board);
if (winner != 'c')
break;
}
DisplayChessBoard(chess_board);
//顯示結果
if(winner == 'x')
{
//玩家赢
printf("玩家勝利.\n");
}
else if(winner == 'o')
{
//電腦赢
printf("電腦勝利.\n");
}
else if(winner == 'h')
{
//和棋
printf("和棋.\n");
}
else
{
//程式出錯
printf("error.\n");
}
}
<9>utili.h全部代碼
//預防頭檔案重複引入
#ifndef _UTILI_H_
#define _UTILI_H_
#include<stdio.h>
#include<time.h>
#include<stdbool.h>
#endif /* _UTILI_H_ */
<10>game.h全部代碼
#ifndef _GAME_H_
#define _GAME_H_
#include"utili.h"
#define ROW 3
#define COL 3
//函數申明
void StartGame();
void InitChessBoard(char chess_board[ROW][COL]);
void DisplayChessBoard(char chess_board[ROW][COL]);
bool ChessBoardFull(char chess_board[ROW][COL]);
void PlayerMove(char chess_board[ROW][COL]);
void ComputerMove(char chess_board[ROW][COL]);
char CheckResult(char chess_board[ROW][COL]);
#endif /* _GAME_H_ */
<11>game.c全部代碼
#include"game.h"
#define PLAYER_CHESS_SYMBAL 'x'
#define COMPUTER_CHESS_SYMBAL 'o'
//初始化棋盤
void InitChessBoard(char chess_board[ROW][COL])
{
for(int i=0; i<ROW; ++i)
{
for(int j=0; j<COL; ++j)
{
chess_board[i][j] = ' ';
}
}
}
//顯示棋盤
void DisplayChessBoard(char chess_board[ROW][COL])
{
for(int i=0; i<ROW; ++i)
{
printf("| %c | %c | %c |\n", chess_board[i][0],
chess_board[i][1],
chess_board[i][2]);
if(i < ROW-1)
printf(" --- --- ---\n");
}
}
//判滿
bool ChessBoardFull(char chess_board[ROW][COL])
{
for (int i = 0; i < ROW; ++i)
{
for (int j = 0; j < COL; ++j)
{
if (chess_board[i][j] == ' ')
{
return false;
}
}
}
return true;
}
//玩家下棋
void PlayerMove(char chess_board[ROW][COL])
{
int x, y;
printf("玩家下棋.\n");
printf("請輸入坐标:>");
while(1)
{
scanf("%d %d", &x, &y);
//檢查坐标的有效性
if(x<0||x>=ROW || y<0 || y>COL)
{
printf("輸入的坐标不合法,請重新輸入.....\n");
continue;
}
//檢查坐标是否被占用
if(chess_board[x][y] == ' ')
{
chess_board[x][y] = PLAYER_CHESS_SYMBAL;
break;
}
}
}
//電腦下棋
void ComputerMove(char chess_board[ROW][COL])
{
int x, y;
srand(time(0));
while(1)
{
x = rand()%ROW;
y = rand()%COL;
if(chess_board[x][y] == ' ')
{
chess_board[x][y] = COMPUTER_CHESS_SYMBAL; //'o'
break;
}
}
}
//檢查結果
//'c': 繼續
//'x':玩家赢
//'o': 電腦赢
//'h': 和棋
char CheckResult(char chess_board[ROW][COL])
{
//1 檢查行
for (int i = 0; i < ROW; ++i)
{
if ((chess_board[i][0] != ' ') &&
(chess_board[i][0] == chess_board[i][1]) &&
(chess_board[i][0] == chess_board[i][2]))
return chess_board[i][0];
}
//2 檢查列
for (int i = 0; i < ROW; ++i)
{
if ((chess_board[0][i] != ' ') &&
(chess_board[0][i] == chess_board[1][i]) &&
(chess_board[0][i] == chess_board[2][i]))
return chess_board[0][i];
}
//3 檢查對角線
if ((chess_board[0][0] != ' ') &&
(chess_board[0][0] == chess_board[1][1]) &&
(chess_board[0][0] == chess_board[2][2]))
return chess_board[1][1];
if ((chess_board[1][1] != ' ') &&
(chess_board[1][1] == chess_board[2][0]) &&
(chess_board[1][1] == chess_board[0][2]))
return chess_board[1][1];
//4 檢查是否和棋
if (ChessBoardFull(chess_board))
return 'h';
return 'c';
}
//開始遊戲
void StartGame()
{
//定義棋盤
char chess_board[ROW][COL];
//初始化棋盤
InitChessBoard(chess_board);
//進入遊戲
char winner;
while(1)
{
//顯示棋盤
DisplayChessBoard(chess_board);
//玩家下棋
PlayerMove(chess_board);
//判斷結果
winner = CheckResult(chess_board);
if(winner != 'c')
break;
//電腦下棋
ComputerMove(chess_board);
//判斷結果
winner = CheckResult(chess_board);
if (winner != 'c')
break;
}
DisplayChessBoard(chess_board);
//顯示結果
if(winner == 'x')
{
//玩家赢
printf("玩家勝利.\n");
}
else if(winner == 'o')
{
//電腦赢
printf("電腦勝利.\n");
}
else if(winner == 'h')
{
//和棋
printf("和棋.\n");
}
else
{
//程式出錯
printf("error.\n");
}
}
<12>gameMain.c全部代碼
#include"game.h"
int main(int argc, char *argv[])
{
int select = 1;
while(select)
{
printf("********************************\n");
printf("* 簡 易 三 子 棋 *\n");
printf("********************************\n");
printf("* [1] Play *\n");
printf("* [0] Exit *\n");
printf("********************************\n");
printf("請選擇:>");
scanf("%d", &select);
if(select == 0)
break;
if(select != 1)
{
printf("輸入的選項有誤,請重新輸入......\n");
continue;
}
//開始遊戲
StartGame();
}
printf("Game Over, 拜拜......\n");
return 0;
}