我先說一下,之所以說一學(xué)就會是因為想法很簡單,只要你會寫三子棋,我這個五子棋你就一定會寫!因為我這個五子棋是按照我寫三子棋的模板復(fù)刻的,到最后我會總結(jié)我是怎么復(fù)刻的!
創(chuàng)新互聯(lián)建站是一家專注于網(wǎng)站設(shè)計制作、成都網(wǎng)站建設(shè)與策劃設(shè)計,營山網(wǎng)站建設(shè)哪家好?創(chuàng)新互聯(lián)建站做網(wǎng)站,專注于網(wǎng)站建設(shè)10多年,網(wǎng)設(shè)計領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:營山等地區(qū)。營山做網(wǎng)站價格咨詢:13518219792能力有限,做的不是很好,如果有什么地方可以優(yōu)化可以告訴我,感謝你們~!
重要的地方我會仔細講解,有的一看就會的地方我就用幾句話描述了,而且代碼里也有我寫的標(biāo)識,很容易看懂的?。?!
好!??!現(xiàn)在開始教學(xué)?。?!
int main()
{
int input = 0;
srand((unsigned int)time(NULL));//設(shè)置隨機生成數(shù)
do
{
menu();//菜單
printf("請輸入:>");
scanf("%d", &input);
switch (input)
{
case 1:
game();//游戲
break;
case 0:
printf("已成功退出!\n");
break;
default:
printf("輸入錯誤,請重新輸入!\n");
break;
}
} while (input);
return 0;
}
void menu()
{
printf("\n");
printf("********** 菜單 *************\n");
printf("********************************\n");
printf("****** 1.play 0.exit ******\n");
printf("********************************\n");
printf("\n");
}
這里的定義的ROW和COL是棋盤是幾行幾列,看你們的需求可以隨意改變。
當(dāng)然我還要說一下,這里我設(shè)計的是玩家和電腦下棋,這里如果把電腦下棋的那一步換為玩家下棋你們就可以和自己的好朋友一起玩耍了,當(dāng)然有人可能會說,有現(xiàn)成的為什么要玩自己寫的,那就大漏特漏了?。?!
? 當(dāng)你寫出來后你玩著都開心,自己寫的代碼,那能不開心么,我下面自己設(shè)置的棋盤不是很好看,你如果用心,可以把棋盤設(shè)置的超級好看,那不比玩現(xiàn)成的要香么?。?!
? 那么接下來我們就要開始了?。?!
#pragma once
#include#include#include#define ROW 15//行
#define COL 15//列
void Init_Board(char board[ROW][COL], int row, int col);//初始化棋盤
void Display_Board(char board[ROW][COL], int row, int col);//打印棋盤
//下棋
void Player_Move(char board[ROW][COL], int row, int col);//玩家下
void Computer_Move(char boar[ROW][COL], int row, int col);//電腦下
int Is_Win(char board[ROW][COL], int row, int col);//是否贏
首先我們要先用數(shù)組對棋盤進行初始化,
然后打印棋盤,
然后再循環(huán)跟電腦下棋,而且每次下完棋后要再次打印棋盤,這樣才叫下棋嘛~
在下棋的過程中進行對對局的判斷輸贏。
(寫完這里大概輪廓就已經(jīng)出來了!接下來該對其進行“填色”啦?。?/em>
void game()
{
int ret = 0;
char board[ROW][COL] = { 0 };
//初始化棋盤
Init_Board(board, ROW, COL);
//打印棋盤
Display_Board(board, ROW, COL);
//下棋
while (1)
{
Player_Move(board, ROW, COL);
ret = Is_Win(board, ROW, COL);
if (ret != 'C')
{
break;
}
Display_Board(board, ROW, COL);
Computer_Move(board, ROW, COL);
ret = Is_Win(board, ROW, COL);
if (ret != 'C')
{
break;
}
Display_Board(board, ROW, COL);
}
//判斷
if (ret == '*')
{
printf("\n");
printf("玩家勝利!\n");
}
else if (ret == '#')
{
printf("\n");
printf("電腦勝利!\n");
}
else
{
printf("\n");
printf("平局!\n");
}
Display_Board(board, ROW, COL);
}
這里就是對棋盤進行初始化了,因為開始的棋盤是空的,所以可以將棋盤都初始化為“空格”,這樣看著棋盤就是空空的啦!
void Init_Board(char board[ROW][COL], int row, int col)
{
int i = 0;
for (i = 0; i< ROW; i++)
{
int j = 0;
for (j = 0; j< COL; j++)
{
board[i][j] = ' ';
}
}
}
?
這里要打印棋盤的樣子還要打印每行每列對應(yīng)的數(shù)字,
? 首先我先用三子棋的棋盤分析一下如何打印棋盤,五子棋的棋盤只不過是下圖所示多打印幾行罷了~!
這就是我設(shè)計的棋盤,有點簡陋,如果你想設(shè)計的好看,自己可以重新設(shè)置哦~!
void Display_Board(char board[ROW][COL], int row, int col)
{
int i = 0;
//給棋盤每一列填寫數(shù)字到下面為止!??!
if (ROW >= 10)
{
for (i = 1; i< 10; i++)
{
printf(" %d ", i);
}
for (i = 10; i<= ROW; i++)
{
printf(" %d ", i);
}
printf("\n");
}
else
{
for (i = 1; i< ROW; i++)
{
printf(" %d ", i);
}
printf("\n");
}
//從上面開始到這里將每一列的數(shù)字填寫完畢?。?!
for (i = 0; i< row; i++)
{
int j = 0;
for (j = 0; j< col; j++)
{
printf(" ---");
}
printf("\n");
for (j = 0; j< col; j++)
{
printf("| %c ", board[i][j]);
}
if (j == col)
printf("| %d", i + 1);//打印每一行的數(shù)字
printf("\n");
}
if (i == row)
{
int x = 0;
for (x = 0; x< row; x++)
{
printf(" ---");
}
}
printf("\n");
}
? 這里就是寫玩家下棋和電腦下棋的過程了,玩家和電腦下棋的時候,肯定是在不是空格的地方下棋,要是這地方有自己的棋,再下一遍那不是比電腦少下一步么,要是下的電腦上面把電腦的棋覆蓋了,那不是耍賴嘛。
? 所以我們再下之前要對那個位置進行判斷是不是空格!
? 當(dāng)然電腦下棋的時候就是隨機下棋了,找一個空著的地方就可以下(如果你有時間可以對電腦進行優(yōu)化哦~讓他思想,我之所以沒寫絕對不是因為我想贏電腦,絕對不是!)
? (下面感覺有點難度的代碼我寫上解釋了,保證每個人都可以看懂?。?/p>
void Player_Move(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
printf("玩家下棋:>\n");
while (1)
{
printf("請輸入坐標(biāo):>");
scanf("%d %d", &x, &y);
if (x >= 1 && y >= 1 && x<= ROW && y<= COL)
{
if (board[x - 1][y - 1] == ' ')
{
board[x - 1][y - 1] = '*';
break;
}
else
{
printf("坐標(biāo)已被占用,不能下棋,請下在其他位置\n");
}
}
else
{
printf("坐標(biāo)非法,請重新輸入\n");
}
}
}
void Computer_Move(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
printf("電腦下棋:>\n");
while (1)
{
x = rand() % ROW + 1;//隨機生成坐標(biāo),因為%棋盤的行列數(shù)得到的是比行列數(shù)少1;
y = rand() % COL + 1;//所以加1就是讓它和棋盤的行列數(shù)相同了;
if (board[x - 1][y - 1] == ' ')
{
board[x - 1][y - 1] = '#';
break;
}
}
}
? 平局好說,先說平局吧,當(dāng)棋盤上沒有位置下棋了,而你們也沒有五個子連在一起,那么肯定就是平局啦~!
? 然后就是判斷輸贏,我這里完全按照三子棋判斷輸贏的方法寫的!可能你看著很多,但是你仔細看是不是寫起來很簡單很簡單,就只是代碼看著多僅此而已?。?!
? 判斷輸贏就是一行五個連續(xù)的在一起,或者一列五個連續(xù)的在一起,或者從左上到右下五個連在一起,或者右上到左下連在一起,就這么四種情況?。?!
? 如果有五個相同的就返回判斷的那個點就行,返回去就是下棋用的符號,到時候只要判斷返回去的是玩家的符號還是電腦的符號就可以判斷輸贏了~
? 這里重要的就是那個推移,其實就是先判斷5×5時贏的情況,根據(jù)自己用ROW和COL設(shè)置的行列進行推移就可以了,
? 我就用一行五子舉例子,比方說:你下的是(1,1)(1,2)(1,3)(1,4)(1,5)這樣已經(jīng)算贏了吧,然后+1推移后得到(1,2)(1,3)(1,4)(1,5)(1,6),以此類推,這就是這個五子棋唯一有點難的點,但是其實還是很好想到的,就是運行起來復(fù)雜,每次下完棋判斷的時候要這樣判斷很多很多次,這也是我的方法不好的地方,如果你們在寫的時候發(fā)現(xiàn)好的方法一定要告訴我!!!
? 最后就是如果有人贏的話就返回玩家或者電腦的棋子,如果平局就返回‘D’(draw),如果沒人贏也沒平局,那么就繼續(xù),返回‘C’(continue)。
int Is_Full(char board[ROW][COL], int row, int col)
{
int i = 0;
for (i = 0; i< row; i++)
{
int j = 0;
for (j = 0; j< col; j++)
{
if (board[i][j] == ' ')//有位置
{
return 0;
}
}
}
return 1;//沒位置
}
int Is_Win(char board[ROW][COL], int row, int col)
{
int R = 0;//行推移
int C = 0;//列推移
//int RC = 0;//行列一起推移
//行是否 有三子
int i = 0;
for (i = 0; i< ROW; i++)
{
for (R = 0; R< ROW - 2; R++)//推移
{
if (board[i][R] == board[i][R + 1] &&
board[i][R] == board[i][R + 2] &&
board[i][R] == board[i][R + 3] &&
board[i][R] == board[i][R + 4] &&
board[i][R] != ' ')
{
return board[i][R];
}
}
}
//列是否 有三子
int j = 0;
for (j = 0; j< COL; j++)
{
for (C = 0; C< COL - 2; C++)//推移
{
if (board[C][j] == board[C + 1][j] &&
board[C][j] == board[C + 2][j] &&
board[C][j] == board[C + 3][j] &&
board[C][j] == board[C + 4][j] &&
board[C][j] != ' ')
{
return board[C][j];
}
}
}
//倆對角是否 有三子
for (C = 0, R = 0; C< COL - 2; C++, R++)
{
if (board[R][C] == board[R + 1][C + 1] &&
board[R][C] == board[R + 2][C + 2] &&
board[R][C] == board[R + 3][C + 3] &&
board[R][C] == board[R + 4][C + 4] &&
board[R][C] != ' ')
{
return board[R][C];
}
if (board[R][C + 4] == board[R + 1][C + 3] &&
board[R][C + 4] == board[R + 2][C + 2] &&
board[R][C + 4] == board[R + 3][C + 1] &&
board[R][C + 4] == board[R + 4][C] &&
board[R][C + 4] != ' ')
{
return board[R][C + 4];
}
}
if (Is_Full(board, row, col))
{
return 'D';
}
return 'C';
}
如果你看到這里,說明你已經(jīng)會了我這個愚笨但是簡單的五子棋了,
? 還記不記得我要總結(jié)我是怎么復(fù)刻的,其實你現(xiàn)在已經(jīng)知道是怎么復(fù)刻的了,就是打印行列圖形的時候用for循環(huán)帶上ROW和COL就可以在你改ROW和COL的時候,打印的圖形就跟著改變,還有就是判斷輸贏的時候用我上面說的推移的方法,本來三子棋不需要推移,因為它很簡易,但是五子棋的話就要棋盤大點,所以同樣用到ROW和COL。
? 這樣就是我說的復(fù)刻啦,很簡單吧。
? 創(chuàng)作不易,如果看懂了蠻煩您發(fā)財?shù)男∈贮c個贊吧,這樣我就更有動力出其他的詳細解析了?。。≈x謝你們~!
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧