版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
第C語言實現(xiàn)五子棋功能全解析目錄1、game.h2、test.c3、game.c4、游戲功能詳解(1)、棋盤初始化(2)、棋盤的打印(3)、玩家下棋(4)、電腦下棋(5)、判斷游戲輸贏(6)、判斷棋盤是否滿了5、AI算法下棋(1)、判斷自己是否會贏(CheckComputer)(2)、對玩家進行攔截(CheckPlayer)(3)、加入AI算法后game.c的改動
1、game.h
game.h:自定義頭文件,用于:
庫函數(shù)頭文件的包含符號與結構的聲明函數(shù)的定義
//防止頭文件被重復包含
#pragmaonce
//頭文件的包含
#includestdio.h
#includestdlib.h
#includetime.h
//符號的定義:使棋盤的大小可以跟著row和col的改變而改變
#defineROW5
#defineCOL5
//函數(shù)的聲明
//棋盤初始化
voidBoardInit(chararr[ROW][COL],introw,intcol);
//打印棋盤
voidBoardPrint(chararr[ROW][COL],introw,intcol);
//玩家下棋
voidPlayerMove(chararr[ROW][COL],introw,intcol);
//電腦下棋
voidComputerMove(chararr[ROW][COL],introw,intcol);
//判斷輸贏
charIsWin(chararr[ROW][COL],introw,intcol);
//判斷棋盤是否滿了
intIsFull(charboard[ROW][COL],introw,intcol);
2、test.c
test.c:用于游戲邏輯的測試
#define_CRT_SECURE_NO_WARNINGS1
//自定義頭文件的包含
#include"game.h"
voidmenu()
printf("================================\n");
printf("=========1.play==========\n");
printf("=========0.exit==========\n");
printf("================================\n");
//游戲邏輯的實現(xiàn)
voidgame()
//定義一個二維數(shù)組來存儲下棋的數(shù)據(jù)
chararr[ROW][COL]={0};
//棋盤初始化
BoardInit(arr,ROW,COL);
//打印棋盤
BoardPrint(arr,ROW,COL);
charch=0;
while(1)
//玩家下棋
PlayerMove(arr,ROW,COL);
//打印棋盤
BoardPrint(arr,ROW,COL);
//判斷輸贏
ch=IsWin(arr,ROW,COL);
if(ch!='C')
break;
//電腦下棋
ComputerMove(arr,ROW,COL);
//打印棋盤
BoardPrint(arr,ROW,COL);
//判斷輸贏
ch=IsWin(arr,ROW,COL);
if(ch!='C')
break;
if(ch=='*')
printf("直接拿下!\n");
elseif(ch=='#')
printf("你竟然打不過人機!\n");
else
printf("平局,得加油啊!\n");
intmain()
intinput=0;
//設置隨機數(shù)種子
srand((unsignedint)time(NULL));
do{
//菜單
menu();
printf("請選擇:
scanf("%d",input);
switch(input){
case1:
//玩游戲
game();
break;
case0:
printf("退出游戲\n");
break;
default:
printf("輸入錯誤,請重新輸入!\n");
break;
}while(input);
return0;
}
3、game.c
game.c:游戲功能的實現(xiàn)
#define_CRT_SECURE_NO_WARNINGS1
//自定義頭文件的包含
#include"game.h"
//函數(shù)的定義
//棋盤初始化
voidBoardInit(chararr[ROW][COL],introw,intcol)
inti=0;
intj=0;
for(i=0;irow;i++)
for(j=0;jcol;j++)
arr[i][j]='';
//打印棋盤
voidBoardPrint(chararr[ROW][COL],introw,intcol)
inti=0;
intj=0;
for(i=0;irow;i++)
//打印分割豎向分割
for(j=0;jcol;j++)
printf("%c",arr[i][j]);
if(jcol-1)
printf("|");
//一行完畢之后打印分隔符
printf("\n");
//打印橫向分割
if(irow-1)//最后一行不打印橫線分隔符
for(j=0;jcol;j++)
printf("---");
if(jcol-1)
printf("|");
//一行完畢之后打印分隔符
printf("\n");
//玩家下棋
voidPlayerMove(chararr[ROW][COL],introw,intcol)
//獲取玩家坐標
intx=0;
inty=0;
printf("玩家下棋\n");
while(1)
printf("請輸入坐標:
scanf("%d%d",x,
//判斷坐標合法性
if((x=1x=row)(y=1y=col))
//把玩家坐標對應數(shù)組下標
x-=1;
y-=1;
//判斷坐標是否被占用
if(arr[x][y]=='')
arr[x][y]='*';//假設玩家為*號
break;
else
printf("該坐標已被占用\n");
else
printf("坐標非法\n");
//電腦下棋
voidComputerMove(chararr[ROW][COL],introw,intcol)
printf("電腦下棋\n");
while(1)
//在主函數(shù)生成種子srand
//隨機生成范圍內(nèi)的坐標
intx=rand()%row;
inty=rand()%col;
//判斷坐標是否被占用
if(arr[x][y]=='')
arr[x][y]='#';//假設電腦為#號
break;
//判斷輸贏
charIsWin(charboard[ROW][COL],introw,intcol)
*約定返回*代表玩家贏
*返回#代表電腦贏
*返回D代表平局
*返回C代表繼續(xù)
inti=0;
intj=0;
//判斷行
for(i=0;irow;i++)
intcount=0;//標記相同棋子的個數(shù)
for(j=0;jcol-1;j++)
if(board[i][j]==board[i][j+1]board[i][j]!='')
count++;
if(count==col-1)//一次判斷有兩個棋子
returnboard[i][j];
//判斷列
for(i=0;icol;i++)
intcount=0;
for(j=0;jrow-1;j++)
if(board[j][i]==board[j+1][i]board[j][i]!='')
count++;
if(count==row-1)
returnboard[j][i];
//判斷兩條斜邊
//第一條
intcount=0;
for(i=0,j=0;irow-1jcol-1;i++,j++)
if(board[i][j]==board[i+1][j+1]board[i][j]!='')
count++;
if(count==row-1)
returnboard[i][j];
//第二條
count=0;//把count重新置為0(易錯)
//注意:這里i+1,j-1,所以i小于row-1,j0,而不是irow,j=0(易錯)
for(i=0,j=col-1;irow-1ji++,j--)
if(board[i][j]==board[i+1][j-1]board[i][j]!='')
count++;
if(count==row-1)
returnboard[i][j];
//判斷棋盤是否滿了
if(IsFull(board,row,col))
return'D';
//如果上述情況都沒有返回,游戲繼續(xù)
return'C';
//判斷棋盤是否滿了
if(IsFull(board,row,col))
return'D';
//如果上述情況都沒有返回,游戲繼續(xù)
return'C';
//判斷棋盤是否滿了
intIsFull(charboard[ROW][COL],introw,intcol)
inti=0;
intj=0;
for(i=0;irow;i++)
for(j=0;jcol;j++)
if(board[i][j]=='')
return0;//有空格就返回0
return1;
}
4、游戲功能詳解
(1)、棋盤初始化
voidBoardInit(chararr[ROW][COL],introw,intcol)
inti=0;
intj=0;
for(i=0;irow;i++)
for(j=0;jcol;j++)
arr[i][j]='';
(2)、棋盤的打印
voidBoardPrint(chararr[ROW][COL],introw,intcol)
inti=0;
intj=0;
for(i=0;irow;i++)
//打印分割豎向分割
for(j=0;jcol;j++)
printf("%c",arr[i][j]);
if(jcol-1)
printf("|");
//一行完畢之后打印分隔符
printf("\n");
//打印橫向分割
if(irow-1)//最后一行不打印橫線分隔符
for(j=0;jcol;j++)
printf("---");
if(jcol-1)
printf("|");
//一行完畢之后打印分隔符
printf("\n");
(3)、玩家下棋
voidPlayerMove(chararr[ROW][COL],introw,intcol)
//獲取玩家坐標
intx=0;
inty=0;
printf("玩家下棋\n");
while(1)
printf("請輸入坐標:
scanf("%d%d",x,
//判斷坐標合法性
if((x=1x=row)(y=1y=col))
//把玩家坐標對應數(shù)組下標
x-=1;
y-=1;
//判斷坐標是否被占用
if(arr[x][y]=='')
arr[x][y]='*';//假設玩家為*號
break;
else
printf("該坐標已被占用\n");
else
printf("坐標非法\n");
(4)、電腦下棋
voidComputerMove(chararr[ROW][COL],introw,intcol)
printf("電腦下棋\n");
while(1)
//在主函數(shù)生成種子srand
//隨機生成范圍內(nèi)的坐標
intx=rand()%row;
inty=rand()%col;
//判斷坐標是否被占用
if(arr[x][y]=='')
arr[x][y]='#';//假設電腦為#號
break;
(5)、判斷游戲輸贏
charIsWin(charboard[ROW][COL],introw,intcol)
*約定返回*代表玩家贏
*返回#代表電腦贏
*返回D代表平局
*返回C代表繼續(xù)
inti=0;
intj=0;
//判斷行
for(i=0;irow;i++)
intcount=0;//標記相同棋子的個數(shù)
for(j=0;jcol-1;j++)
if(board[i][j]==board[i][j+1]board[i][j]!='')
count++;
if(count==col-1)//一次判斷有兩個棋子
returnboard[i][j];
//判斷列
for(i=0;icol;i++)
intcount=0;
for(j=0;jrow-1;j++)
if(board[j][i]==board[j+1][i]board[j][i]!='')
count++;
if(count==row-1)
returnboard[j][i];
//判斷兩條斜邊
//第一條
intcount=0;
for(i=0,j=0;irow-1jcol-1;i++,j++)
if(board[i][j]==board[i+1][j+1]board[i][j]!='')
count++;
if(count==row-1)
returnboard[i][j];
//第二條
count=0;//把count重新置為0(易錯)
//注意:這里i+1,j-1,所以i小于row-1,j0,而不是irow,j=0(易錯)
for(i=0,j=col-1;irow-1ji++,j--)
if(board[i][j]==board[i+1][j-1]board[i][j]!='')
count++;
if(count==row-1)
returnboard[i][j];
//判斷棋盤是否滿了
if(IsFull(board,row,col))
return'D';
//如果上述情況都沒有返回,游戲繼續(xù)
return'C';
//判斷棋盤是否滿了
if(IsFull(board,row,col))
return'D';
//如果上述情況都沒有返回,游戲繼續(xù)
return'C';
}
(6)、判斷棋盤是否滿了
intIsFull(charboard[ROW][COL],introw,intcol)
inti=0;
intj=0;
for(i=0;irow;i++)
for(j=0;jcol;j++)
if(board[i][j]=='')
return0;//有空格就返回0
return1;
}
5、AI算法下棋
大家可以發(fā)現(xiàn),在上面的代碼中,電腦下棋是非常笨拙的,因為電腦產(chǎn)生的坐標是隨機的,即不會攔截玩家,也不會判斷自己,所以這里我們可以設計一個小小的算法來讓電腦變得聰明起來,讓它擁有攔截和判斷功能。具體思路和代碼如下:
(1)、判斷自己是否會贏(CheckComputer)
//電腦檢查自己是否會贏
//約定如果在函數(shù)內(nèi)部成功判斷就返回1
//判斷失敗則返回0
intCheckComputer(charboard[ROW][COL],introw,intcol)
inti=0;
intj=0;
//判斷每一行是否有兩個相連的棋子,如果有,且第三個棋格為空,則落棋
for(i=0;irow;i++)
if(board[i][0]==board[i][1]board[i][0]=='#'board[i][2]=='')
board[i][2]='#';
return1;//成功判斷,返回1
if(board[i][0]==board[i][2]board[i][0]=='#'board[i][1]=='')
board[i][1]='#';
return1;
if(board[i][1]==board[i][2]board[i][1]=='#'board[i][0]=='')
board[i][0]='#';
return1;
//判斷每一列是否有兩個相連的棋子,如果有,且第三個棋格為空,則落棋
for(j=0;jcol;j++)
if(board[0][j]==board[1][j]board[0][j]=='#'board[2][j]=='')
board[2][j]='#';
return1;
if(board[0][j]==board[2][j]board[0][j]=='#'board[1][j]=='')
board[1][j]='#';
return1;
}if(board[1][j]==board[2][j]board[1][j]=='#'board[0][j]=='')
board[0][j]='#';
return1;
//判斷兩條對角線是否有兩個相連的棋子,如果有,且第三個棋格為空,則落棋
//第一條
if(board[0][0]==board[1][1]board[0][0]=='#'board[2][2]=='')
board[2][2]='#';
return1;
if(board[0][0]==board[2][2]board[0][0]=='#'board[1][1]=='')
board[1][1]='#';
return1;
if(board[1][1]==board[2][2]board[1][1]=='#'board[0][0]=='')
board[0][0]='#';
return1;
//第二條
if(board[0][2]==board[1][1]board[0][2]=='#'board[2][0]=='')
board[2][0]='#';
return1;
if(board[0][2]==board[2][0]board[0][2]=='#'board[1][1]=='')
board[1][1]='#';
return1;
if(board[1][1]==board[2][0]board[1][1]=='#'board[0][2]=='')
board[0][2]='#';
return1;
//如果上面都沒返回,說明不符合贏的條件,返回0
return0;
}
(2)、對玩家進行攔截(CheckPlayer)
//電腦檢查玩家是否會贏(邏輯和CheckComputer完全相同)
//約定成功攔截返回1
//無需攔截或者攔截不了返回0
intCheckPlayer(charboard[ROW][COL],introw,intcol)
inti=0;
intj=0;
//判斷每一行是否有兩個相連的棋子,如果有,且第三個棋格為空,則攔截
for(i=0;irow;i++)
if(board[i][0]==board[i][1]board[i][0]=='*'board[i][2]=='')
board[i][2]='#';
return1;//成功攔截,返回1
if(board[i][0]==board[i][2]board[i][0]=='*'board[i][1]=='')
board[i][1]='#';
return1;
if(board[i][1]==board[i][2]board[i][1]=='*'board[i][0]=='')
board[i][0]='#';
return1;
//判斷每一列是否有兩個相連的棋子,如果有,且第三個棋格為空,則攔截
for(j=0;jcol;j++)
if(board[0][j]==board[1][j]board[0][j]=='*'board[2][j]=='')
board[2][j]='#';
return1;
if(board[0][j]==board[2][j]board[0][j]=='*'board[1][j]=='')
board[1][j]='#';
return1;
}if(board[1][j]==board[2][j]board[1][j]=='*'board[0][j]=='')
board[0][j]='#';
return1;
//判斷兩條對角線是否有兩個相連的棋子,如果有,且第三個棋格為空,則攔截
//第一條
if(board[0][0]==board[1][1]board[0][0]=='*'board[2][2]=='')
board[2][2]='#';
return1;
if(board[0][0]==board[2][2]board[0][0]=='*'board[1][1]=='')
board[1][1]='#';
return1;
if(board[1][1]==board[2][2]board[1][1]=='*'board[0][0]=='')
board[0][0]='#';
return1;
//第二條
if(board[0][2]==board[1][1
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2026江蘇省常州市體育運動學校招聘排球教練1人備考題庫及一套完整答案詳解
- 江蘇省東臺市三倉中學2026屆高一上數(shù)學期末質量跟蹤監(jiān)視模擬試題含解析
- 罕見腫瘤的個體化治療治療策略優(yōu)化經(jīng)驗與案例
- 罕見腫瘤的個體化治療療效預測模型構建與個體化路徑
- 2025貴州興義市人民醫(yī)院引進高層次、急需緊缺人才100人備考題庫及一套答案詳解
- 電商會計財務制度
- 生產(chǎn)經(jīng)營類企業(yè)財務制度
- 石油公司財務制度
- 2026江蘇南京大學招聘備考題庫XZ2025-428醫(yī)學院專業(yè)、技術人員備考題庫有完整答案詳解
- 學校社團章程財務制度
- 途虎養(yǎng)車安全培訓課件
- 衛(wèi)生管理研究論文
- 2025-2026學年人教版(新教材)小學數(shù)學二年級下冊(全冊)教學設計(附教材目錄P161)
- 委托市場調研合同范本
- 畜牧安全培訓資料課件
- 2025年度黨支部書記述職報告
- 2026四川省引大濟岷水資源開發(fā)限公司公開招聘易考易錯模擬試題(共500題)試卷后附參考答案
- 2026年安徽糧食工程職業(yè)學院高職單招職業(yè)適應性考試備考試題及答案詳解
- 內(nèi)科學總論小兒遺傳代謝病課件
- 雨課堂學堂在線學堂云《中國電影經(jīng)典影片鑒賞(北京師范大學)》單元測試考核答案
- 核電站防地震應急方案
評論
0/150
提交評論