教你用C語(yǔ)言實(shí)現(xiàn)三子棋
三子棋
三子棋的規(guī)則是:在3x3的棋盤里,雙方輪流下子(以X和O表示),先將3個(gè)子連成一條線(橫豎斜都可以)的一方獲勝
下面是三子棋C語(yǔ)言實(shí)現(xiàn)的幾個(gè)問(wèn)題:
1.要想實(shí)現(xiàn)三子棋,我們需要一個(gè)棋盤,然后就是棋盤的內(nèi)容。
2.下棋的時(shí)候需要判斷是否該位置合法。
3.玩家和電腦的下棋邏輯不同,玩家需要手動(dòng)輸入,電腦是自己下棋
4.每下一步棋都需要判斷游戲是否結(jié)束(哪方勝利、平局還是繼續(xù)下棋)。
設(shè)計(jì)方式:
需要?jiǎng)?chuàng)建三個(gè)文件:一個(gè)頭文件,兩個(gè)源文件,頭文件里面放的是函數(shù)的聲明以及一系列預(yù)處理命令,命名為game.h
兩個(gè)源文件,一個(gè)里面放的是主函數(shù)(游戲大體的運(yùn)行順序),命名為work.c,一個(gè)里面放的是游戲內(nèi)容的實(shí)現(xiàn)邏輯(放大部分執(zhí)行函數(shù)),命名為game.c
work.c的設(shè)置
首先是進(jìn)入游戲,為了確保游戲可以重復(fù)玩,我們可以以循環(huán)的方式實(shí)現(xiàn)
//work.c里面的內(nèi)容
#include"gmae.h"http://這樣的話,在game.h里面包含的文件,在work.c里面也能使用
int main()
{
int option = 0;//在主函數(shù)里面設(shè)計(jì)循環(huán),可以保證每次游戲結(jié)束后可以選擇繼續(xù)游戲或者退出游戲
do
{
Menu();
scanf("%d", &option);
switch (option)
{
case 1:
game();//如果選擇開(kāi)始游戲,就會(huì)進(jìn)入到game()函數(shù),
/*我們需要定義game函數(shù)來(lái)存放游戲的實(shí)現(xiàn)順序*/
break;
case 0:
printf("已退出");
break;
default :
printf("錯(cuò)誤選擇,請(qǐng)重新輸入");
}
} while (option);
return 0;
}
//work.c里面的內(nèi)容
void Menu()//定義菜單函數(shù),配合主函數(shù)里面的循環(huán),可以實(shí)現(xiàn)每次游戲結(jié)束會(huì)跳到這個(gè)界面
{
printf("*****************\n");
printf("*** 1.play ****\n");
printf("*** 0.exit ****\n");
printf("*****************\n");
printf("請(qǐng)選擇");
}
然后就是游戲進(jìn)行的順序需要在game函數(shù)里面實(shí)現(xiàn)
//work.c里面的內(nèi)容
void game()
{
srand((unsigned int)time(NULL));//使用隨機(jī)數(shù),便于后面電腦下棋時(shí)是隨機(jī)出棋
char board[ROW][COL] = { 0 };//創(chuàng)建一個(gè)二維數(shù)組,用來(lái)實(shí)現(xiàn)棋盤的內(nèi)容
printf("游戲開(kāi)始:\n");
init_board(board,ROW,COL);//初始化棋盤
print_board(board, ROW, COL);//打印棋盤
while (1)
{
char ret = '0';
player_move(board, ROW, COL);//玩家下棋
print_board(board, ROW, COL);//打印棋盤
ret = is_win(board, ROW, COL);//判斷是否結(jié)束
if (ret == '*')
{
printf("玩家勝利\n");
break;
}
computer_move(board, ROW, COL);//電腦下棋
print_board(board, ROW, COL);//打印棋盤
ret = is_win(board, ROW, COL);//判斷是否結(jié)束
if (ret == '#')//
{
printf("電腦勝利\n");
break;
}//判斷電腦勝利
if (ret == 'Q')//判斷平局
{
printf("平局\n");
break;
}//判斷平局
}
}
//work.c里面的內(nèi)容
void game()
{
srand((unsigned int)time(NULL));//使用隨機(jī)數(shù),便于后面電腦下棋時(shí)是隨機(jī)出棋
char board[ROW][COL] = { 0 };//創(chuàng)建一個(gè)二維數(shù)組,用來(lái)實(shí)現(xiàn)棋盤的內(nèi)容
printf("游戲開(kāi)始:\n");
init_board(board,ROW,COL);//初始化棋盤
print_board(board, ROW, COL);//打印棋盤
while (1)
{
char ret = '0';
player_move(board, ROW, COL);//玩家下棋
print_board(board, ROW, COL);//打印棋盤
ret = is_win(board, ROW, COL);//判斷是否結(jié)束
if (ret == '*')
{
printf("玩家勝利\n");
break;
}
computer_move(board, ROW, COL);//電腦下棋
print_board(board, ROW, COL);//打印棋盤
ret = is_win(board, ROW, COL);//判斷是否結(jié)束
if (ret == '#')//
{
printf("電腦勝利\n");
break;
}//判斷電腦勝利
if (ret == 'Q')//判斷平局
{
printf("平局\n");
break;
}//判斷平局
}
}
下面是對(duì)這幾點(diǎn)問(wèn)題的解決方法:
game.h的內(nèi)容設(shè)置
#define _CRT_SECURE_NO_WARNINGS 1 #define ROW 3 #define COL 3//設(shè)置了行與列的值,可以更改 #include<stdio.h> #include<time.h>//用來(lái)實(shí)現(xiàn)時(shí)間戳 //下面是游戲?qū)崿F(xiàn)邏輯所需的函數(shù)聲明。 void init_board(char board[ROW][COL], int row, int col); void player_move(char board[ROW][COL], int row, int col); void computer_move(char board[ROW][COL], int row, int col); void print_board(char board[ROW][COL], int row, int col); char is_win(char board[ROW][COL], int row, int col);
game.c的設(shè)置
1.棋盤的內(nèi)容
我們通過(guò)創(chuàng)建一個(gè)二維數(shù)組來(lái)作為棋子,通過(guò)輸入坐標(biāo)的方式來(lái)進(jìn)行下棋的步驟
創(chuàng)建數(shù)組:
char board[ROW][COL] ;這里括號(hào)里面的值我們用提前處理過(guò)的ROW與COL來(lái)表示,
通過(guò)預(yù)處理命令,我們后期可以很方便的更改ROW與COL的值來(lái)改變棋盤的大小
2.棋盤以及棋盤的初始化
棋盤是3x3形式,所以我們可以通過(guò)循環(huán)的方式打印一個(gè)棋盤,下面是棋盤的格式
0 | 0 | 0
---|---|---
0 | 0 | 0
---|---|---
0 | 0 | 0 //而這個(gè)表里面的0就是我們的下的棋子占有的位置
/*而這個(gè)棋盤的設(shè)計(jì)是有明顯的規(guī)律的:
第一行: 空格%c空格
第二行:---|循環(huán)3遍,但是最后遍不打印“|”
然后這樣的兩行在循環(huán)中多次打印,就出現(xiàn)了這樣的三子棋表格
注意:最后一行不用再打印“---”
這里我們定義init_board()函數(shù)來(lái)初始化棋盤(即讓數(shù)組的所有元素的值都為空格)
void init_board(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
board[i][j] = ' ';//把所有元素賦值為' '
}
}
}
3.打印棋盤
void print_board(char board[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 ", board[i][j]);
if (j != col - 1)
{
printf("|");//最后一列不打印'|'
}
}
//每次進(jìn)行上一個(gè)循環(huán)時(shí),i的值在變化,打印的是不同的值
printf("\n");
if (i != row - 1)//最后一行不打印字符
{
for (j = 0; j < col; j++)
{
printf("---");
if (j != col - 1)
printf("|");
}
}
printf("\n");
}
printf("\n");
}
4.下棋步驟 玩家下棋
void player_move(char board[ROW][COL], int row, int col)
{
printf("玩家下棋:\n");
int x = 0;
int y = 0;
int i = 0;
int j = 0;
while (1)
{
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y <= col & y >= 1)
{
if (board[x-1][y-1] == ' ')
{
board[x-1][y-1] = '*';
break;
}
else
{
printf("該坐標(biāo)被占用,請(qǐng)重新輸入\n");
}
}
}
}
電腦下棋
void computer_move(char board[ROW][COL], int row, int col)
{
char x = 0;
char y = 0;
while (1)
{
x = rand() % row;
y = rand() % col;
if (board[x][y] == ' ')
{
board[x][y] = '#';
break;
}
}
}
5.判斷是否勝利
char is_full(char board[ROW][COL], int row, int col)
//判斷是否格子占滿了,格子占滿了還沒(méi)有出現(xiàn)勝利的話就會(huì)判斷平局
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
if (board[i][j] = ' ')
return 0;//用是否還有空格判斷平局
}
}
}
char is_win(char board[ROW][COL], int row, int col)//這里是判斷橫豎斜三種方式是否出現(xiàn)勝利
{
int i = 0;
int j = 0;
int count = 0;
for (i = 0; i < row; i++)
{
if ((board[i][0] == board[i][1])&&(board[i][1]==board[i][2])&&board[i][1]!=' ');
{
return board[i][0];
}
}
for (i = 0; i < row; i++)
{
if ((board[0][i] == board[1][i])&&(board[2][i]==board[1][i]) && board[1][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];
}
//一旦出現(xiàn)勝利,就返回勝利一方的棋子字符
if (is_full(board,ROW,COL))
{
return 'Q';//平局返回'Q'
}
else
return 'C';//什么情況都沒(méi)有就繼續(xù)游戲
}
總結(jié)
本篇文章就到這里了,希望能夠給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
詳解C語(yǔ)言的結(jié)構(gòu)體中成員變量偏移問(wèn)題
這篇文章主要介紹了C語(yǔ)言的結(jié)構(gòu)體中成員變量偏移問(wèn)題,以講解如何編寫宏來(lái)對(duì)成員變量進(jìn)行修改為主,需要的朋友可以參考下2016-04-04
Clion(CMake工具)中引入第三方庫(kù)的詳細(xì)方法
這篇文章主要介紹了Clion(CMake工具)中引入第三方庫(kù)的詳細(xì)方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-02-02
C++ 數(shù)據(jù)類型強(qiáng)制轉(zhuǎn)化的實(shí)現(xiàn)
這篇文章主要介紹了C++ 數(shù)據(jù)類型強(qiáng)制轉(zhuǎn)化的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-02-02
C語(yǔ)言signed關(guān)鍵字的詳細(xì)使用
這篇文章主要介紹了C語(yǔ)言signed關(guān)鍵字的詳細(xì)使用,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-06-06
的相關(guān)資料
C++ OpenCV實(shí)現(xiàn)灰度圖蒙版GrayMask的示例代碼
這篇文章主要為大家詳細(xì)介紹了如何利用C++和OpenCV實(shí)現(xiàn)灰度圖蒙版GrayMask,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)或工作有一定參考價(jià)值,需要的可以參考一下2022-05-05
C++實(shí)現(xiàn)LeetCode(116.每個(gè)節(jié)點(diǎn)的右向指針)
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(116.每個(gè)節(jié)點(diǎn)的右向指針),本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下

