今天帶大家用C語(yǔ)言來(lái)實(shí)現(xiàn)我們的一個(gè)小游戲—— 三子棋
也是用我們之前所學(xué)的知識(shí)學(xué)實(shí)現(xiàn)一些有價(jià)值的東西。
在開(kāi)始之前要跟大家聲明一下我們這個(gè)項(xiàng)目需要三個(gè)文件:
- game.h —— 主要來(lái)聲明和游戲相關(guān)的函數(shù)
- game.c —— 主要來(lái)實(shí)現(xiàn)和游戲相關(guān)的函數(shù)
- test.c —— 主函數(shù)所在的文件,游戲的入口
游戲的整體框架
我們平常在玩游戲的時(shí)候,玩完一把還想玩,還可以接著玩,我們?nèi)悠逡惨粯?,所以根?jù)我們的邏輯,我們可以想到用do…while循環(huán)來(lái)實(shí)現(xiàn),我們還需要一個(gè)菜單來(lái)提示我們的玩家,所以我們應(yīng)該需要一個(gè)菜單函數(shù),我們就可以在main函數(shù)中先把大體的框架搭建起來(lái)。
void menu()
{
printf("********************************\n");
printf("********* 1. play **********\n");
printf("********* 0. exit **********\n");
printf("**** 玩家為 * 電腦為 # *****\n");
printf("********************************\n");
}
void game();
int main()
{
int input = 0;
do
{
menu();
printf("請(qǐng)輸入你的選擇:>");
scanf("%d", &input);
switch (input)
{
case 1: game();
break;
case 0: printf("退出游戲。");
break;
default: printf("輸入錯(cuò)誤,請(qǐng)重新選擇。");
break;
}
} while (input);
return 0;
}
在這里玩家如果想繼續(xù)游戲機(jī)會(huì)選擇 1 ,如果想退出的話,就會(huì)選擇 0 ,綜合考慮我們將 玩家輸入的值作為do …while循環(huán)進(jìn)行下去的條件是會(huì)比較合適。在循環(huán)里面,我們根據(jù)用戶的選擇,來(lái)進(jìn)行操作,我們就可以使用switch語(yǔ)句?,F(xiàn)在我們整體的框架就已經(jīng)寫(xiě)好了,就剩下一個(gè)游戲的具體邏輯的實(shí)現(xiàn)了。
游戲函數(shù)的具體實(shí)現(xiàn)(這里的函數(shù)聲明都放到game.h中,函數(shù)的實(shí)現(xiàn)在game.c中)
大家都知道三子棋是一個(gè)3×3的一個(gè)格子,只要有三個(gè)相同的連起來(lái)就會(huì)獲得勝利。
我們?cè)谶@里棋盤(pán)可以用一個(gè)3×3的一個(gè)二維字符數(shù)組來(lái)表示,但是如果以后有人想修改的話,我們棋盤(pán)每一個(gè)地方都要修改,所以我們不妨定義2個(gè)宏來(lái)表示 我們棋盤(pán)的行數(shù)和列數(shù),如下:
#define ROW 3
#define COL 3
我們的棋盤(pán)就為
char board[ROW][COL]
我們下棋的時(shí)候剛開(kāi)始棋盤(pán)什么都沒(méi)有,我們要將棋盤(pán)打印在屏幕上什么都沒(méi)有,所以剛開(kāi)始我們的字符數(shù)組中的元素應(yīng)該都初始化為空格。
這是我們需要一個(gè)函數(shù)來(lái)初始化棋盤(pán)。初始化是我們需要這個(gè)數(shù)組,以及這個(gè)數(shù)組的行數(shù)和列數(shù),所以我們需要有三個(gè)參數(shù)。
初始化棋盤(pán)函數(shù)
void Initboard(char board[ROW][COL], int row, int col);
void InitBoard(char board[ROW][COL], int row, int col)
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
board[i][j] = ' ';
}
}
}
我們初始化棋盤(pán)以后,我們需要打印棋盤(pán),讓玩家知道要下到那個(gè)位置去,所以我們需要一個(gè)打印函數(shù),但是我們不能值打印棋盤(pán)的內(nèi)容,這樣玩家什么也看不見(jiàn),我們需要打印分割線就和上圖一樣,我們要打印這樣一個(gè)棋盤(pán):
void Displayboard(char board[ROW][COL], int row, int col);
void DisplayBoard(char board[ROW][COL], int row, int col)
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
printf(" %c ", board[i][j]);
if (j < col - 1)
{
printf("|");
}
}
printf("\n");
if (i < row - 1)
{
for (int j = 0; j < col; j++)
{
printf("---");
if (j < col-1)
{
printf("|");
}
}
printf("\n");
}
}
}
當(dāng)我們可以打印棋盤(pán)以后,我們就可以開(kāi)始下棋了。這是我們就需要來(lái)控制玩家下棋,所以我們可以在封裝一個(gè)函數(shù);來(lái)控制玩家下棋。我們玩家下棋的內(nèi)容要存放在字符數(shù)組中,這樣打印棋盤(pán)的時(shí)候就會(huì)把我們玩家下的棋也打印出來(lái),這里假設(shè)我們玩家下的為‘*’;
玩家下棋
void PlayerMove(char board[ROW][COL], int row, int col);
void PlayerMove(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
printf("玩家下棋:>\n");
while (1)
{
printf("請(qǐng)你輸入想要下的坐標(biāo)(用空格隔開(kāi)):>");
scanf("%d %d", &x, &y);
x--;
y--;
if (x >= 0 && x < row && y >= 0 && y < col//判斷是否越界
{
if (board[x][y] == ' ') // 判斷下的位置是否有棋子
{
board[x][y] = '*';
break;
}
else
{
printf("坐標(biāo)被占用!請(qǐng)重新輸入??!\n");
}
}
else
{
printf("坐標(biāo)非法!重新輸入??!\n");
}
}
}
當(dāng)我們?cè)O(shè)計(jì)好玩家走后,我們也要讓電腦走一步。
我們需要再封裝一個(gè)函數(shù)來(lái)實(shí)現(xiàn)電腦下棋。
電腦下棋
void ComputerMove(char board[ROW][COL], int row, int col) ;
void ComputerMove(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
printf("電腦下棋:>\n");
while (1)
{
x = rand() % row; //rand為隨機(jī)值函數(shù),需要頭文件stdlib.h
y = rand() % col;
if (board[x][y] == ' ')
{
board[x][y] = '#';
break;
}
}
}
當(dāng)電腦下棋也設(shè)計(jì)好以后我們還差一個(gè)判斷輸贏平局的函數(shù)
這是我們?cè)O(shè)計(jì)
玩家贏 —— 返回 字符* *;
電腦贏 —— 返回字符 #;
平局 —— 返回字符Q;
游戲繼續(xù) —— 返回字符C;
判斷輸贏
char Is_win(char board[ROW][COL], int row, int col);
char Is_win(char board[ROW][COL], int row, int col)
{
// 贏
//判斷行
for (int i = 0; i < row; i++)
{
if (board[i][0] == board[i][1] && board[i][2] == board[i][1] && board[i][0] != ' ')
return board[i][0];
}
//判斷列
for (int i = 0; i < row; i++)
{
if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
return board[0][i];
}
//判斷對(duì)角線
if(board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
{
return board[1][1];
}
if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
{
return board[1][1];
}
// 平局
if (is_full(board, row, col) == 1) //is_full()函數(shù)判斷棋盤(pán)是否滿了
return 'Q';
// 繼續(xù)
return 'C';
}
這里我們還需要一個(gè)判斷棋盤(pán)是否滿了的函數(shù):
判斷棋盤(pán)是否滿了
滿了返回 1 否則 返回 0。
int is_full(char board[ROW][COL],int row,int col)
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
if (board[i][j] == ' ') return 0;
}
}
return 1;
}
我們游戲相關(guān)的函數(shù)基本上已經(jīng)全部實(shí)現(xiàn)了
接下來(lái)實(shí)現(xiàn)我們游戲的邏輯
游戲的邏輯及game()的實(shí)現(xiàn)
我們剛開(kāi)始一定需要一個(gè)棋盤(pán),然后就是將它初始化,初始化以后我們要打印一下,讓玩家看到棋盤(pán),接下來(lái)就是下棋了,下棋肯定是一個(gè)重復(fù)的過(guò)程,一人下一次,因此下棋的邏輯肯定要用循環(huán)來(lái)表示,每一次下棋以后都要判斷是否有人贏,以及棋盤(pán)是否滿了,如果都不滿足,游戲才繼續(xù),等游戲結(jié)束后我們要打印誰(shuí)贏了還是平局,所以這里我們可以用ret 來(lái)當(dāng)做一個(gè)標(biāo)識(shí)。代碼如下:
void game()
{
char board[ROW][COL];
//初始化棋盤(pán)
InitBoard(board, ROW, COL);
//打印棋盤(pán)
DisplayBoard(board, ROW, COL);
// ret 來(lái)標(biāo)識(shí)
char ret = 0;
while (1)
{
//玩家下棋
PlayerMove(board, ROW, COL);
//每次下完以后打印棋盤(pán)
DisplayBoard(board, ROW, COL);
//判斷輸贏
ret = Is_win(board, ROW, COL);
if (ret != 'C')
break;
//電腦下棋
ComputerMove(board, ROW, COL);
//打印棋盤(pán)
DisplayBoard(board, ROW, COL);
ret = Is_win(board, ROW, COL);
if (ret != 'C')
break;
}
if (ret == '*')
{
printf("玩家贏\n");
}
else
{
if (ret == '#')
{
printf("電腦贏\n");
}
else
{
printf("平局\n");
}
}
}
到這里我們整個(gè)游戲的邏輯就清晰了:
接下來(lái)把三個(gè)文件的完整代碼分享給大家:文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-503744.html
game.h
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define ROW 3
#define COL 3
//初始化棋盤(pán)
void InitBoard(char board[ROW][COL], int row, int col);
//打印棋盤(pán)
void DisplayBoard(char board[ROW][COL], int row, int col);
//玩家走
void PlayerMove(char board[ROW][COL], int row, int col);
// 電腦走
void ComputerMove(char board[ROW][COL], int row, int col);
// 判斷輸贏
char Is_win(char board[ROW][COL], int row, int col);
game.c
#include "game.h"
//初始化棋盤(pán)
void InitBoard(char board[ROW][COL], int row, int col)
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
board[i][j] = ' ';
}
}
}
//打印棋盤(pán)
void DisplayBoard(char board[ROW][COL], int row, int col)
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
printf(" %c ", board[i][j]);
if (j < col - 1)
{
printf("|");
}
}
printf("\n");
if (i < row - 1)
{
for (int j = 0; j < col; j++)
{
printf("---");
if (j < col-1)
{
printf("|");
}
}
printf("\n");
}
}
}
//玩家走
void PlayerMove(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
printf("玩家下棋:>\n");
while (1)
{
printf("請(qǐng)你輸入想要下的坐標(biāo)(用空格隔開(kāi)):>");
scanf("%d %d", &x, &y);
x--;
y--;
if (x >= 0 && x < row && y >= 0 && y < col)
{
if (board[x][y] == ' ')
{
board[x][y] = '*';
break;
}
else
{
printf("坐標(biāo)被占用!請(qǐng)重新輸入!!\n");
}
}
else
{
printf("坐標(biāo)非法!重新輸入??!\n");
}
}
}
//電腦走
void ComputerMove(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
printf("電腦下棋:>\n");
while (1)
{
x = rand() % row;
y = rand() % col;
if (board[x][y] == ' ')
{
board[x][y] = '#';
break;
}
}
}
//判斷棋盤(pán)是否滿了
int is_full(char board[ROW][COL],int row,int col)
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
if (board[i][j] == ' ') return 0;
}
}
return 1;
}
// 玩家贏 — '*'
// 電腦贏 — '#'
// 平 局 — 'Q'
// 繼續(xù) — 'C'
char Is_win(char board[ROW][COL], int row, int col)
{
// 贏
for (int i = 0; i < row; i++)
{
if (board[i][0] == board[i][1] && board[i][2] == board[i][1] && board[i][0] != ' ')
return board[i][0];
}
for (int i = 0; i < row; i++)
{
if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
return board[0][i];
}
if(board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
{
return board[1][1];
}
if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
{
return board[1][1];
}
// 平局
if (is_full(board, row, col) == 1)
return 'Q';
// 繼續(xù)
return 'C';
}
test.c
#include"game.h"
void menu()
{
printf("********************************\n");
printf("********* 1. play **********\n");
printf("********* 0. exit **********\n");
printf("**** 玩家為 * 電腦為 # *****\n");
printf("********************************\n");
}
void game()
{
char board[ROW][COL];
InitBoard(board, ROW, COL);
DisplayBoard(board, ROW, COL);
char ret = 0;
while (1)
{
PlayerMove(board, ROW, COL);
DisplayBoard(board, ROW, COL);
ret = Is_win(board, ROW, COL);
if (ret != 'C')
break;
ComputerMove(board, ROW, COL);
DisplayBoard(board, ROW, COL);
ret = Is_win(board, ROW, COL);
if (ret != 'C')
break;
}
if (ret == '*')
{
printf("玩家贏\n");
}
else
{
if (ret == '#')
{
printf("電腦贏\n");
}
else
{
printf("平局\n");
}
}
}
int main()
{
int input = 0;
srand((unsigned int)time(NULL));// 設(shè)置隨機(jī)值的起點(diǎn)
do
{
menu();
printf("請(qǐng)輸入你的選擇:>");
scanf("%d", &input);
switch (input)
{
case 1: game();
break;
case 0: printf("退出游戲。");
break;
default: printf("輸入錯(cuò)誤,請(qǐng)重新選擇。");
break;
}
} while (input);
return 0;
}
那么今天的分享就到這里了,希望能幫助到大家,感謝大家的關(guān)注和支持??!文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-503744.html
到了這里,關(guān)于【C】C語(yǔ)言實(shí)現(xiàn)三子棋小游戲的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!