五子棋是一款經(jīng)典小游戲,今天我們就用c++實(shí)現(xiàn)簡單的五子棋小游戲
目錄
用到的算法:
思路分析
定義變量?
開始寫代碼
?
完整代碼?
結(jié)果圖:
用到的算法:
合法移動的判斷:
isValidMove
函數(shù)通過檢查指定位置是否在棋盤范圍內(nèi),并且該位置是否為空位來確定是否為合法的移動。獲勝條件的檢查:
checkWin
函數(shù)通過遍歷四個方向(水平、垂直、兩個對角線)來檢查是否存在連續(xù)的五個相同類型的棋子。它使用兩個 while 循環(huán),一個向一個方向移動,另一個向相反方向移動,以統(tǒng)計(jì)橫向、縱向和對角線上相同類型棋子的數(shù)量。棋盤狀態(tài)的打印:
printBoard
函數(shù)使用嵌套的 for 循環(huán)來遍歷棋盤的每個位置,并輸出相應(yīng)的符號來表示該位置的狀態(tài)。棋盤是否已滿的檢查:
isBoardFull
函數(shù)使用嵌套的 for 循環(huán)來遍歷棋盤的每個位置,檢查是否存在空位。如果不存在空位,則棋盤已滿
思路分析
-
初始化:創(chuàng)建一個空的棋盤,大小為15x15,用二維向量表示。初始時所有位置都是空位。
-
循環(huán)游戲:進(jìn)入一個無限循環(huán),在每一輪中依次執(zhí)行以下步驟:
- 打印當(dāng)前棋盤狀態(tài);
- 根據(jù)當(dāng)前輪到的玩家,提示玩家輸入下子位置;
- 檢查輸入的下子位置是否合法,即在棋盤范圍內(nèi)且為空位,如果不合法則提示重新輸入;
- 在棋盤上下子,并判斷是否獲勝或棋盤已滿;
- 如果獲勝或棋盤已滿,根據(jù)情況打印相應(yīng)的信息,并結(jié)束游戲。
-
判斷獲勝和棋盤是否已滿:
- 每次下子后,調(diào)用?
checkWin
?函數(shù)來檢查當(dāng)前位置是否連成五子,如果是則返回獲勝; - 如果沒有獲勝,則調(diào)用?
isBoardFull
?函數(shù)來判斷棋盤是否已滿,如果棋盤已滿則返回平局。
- 每次下子后,調(diào)用?
-
輸出棋盤狀態(tài):
-
printBoard
?函數(shù)使用嵌套的 for 循環(huán)遍歷棋盤的每個位置,根據(jù)該位置的狀態(tài)輸出相應(yīng)的符號,用于展示當(dāng)前棋盤狀態(tài)
-
定義變量?
-
BOARD_SIZE
?定義了棋盤的大小,這里設(shè)置為15x15。 -
EMPTY
、BLACK
?和?WHITE
?定義了棋盤上的三種狀態(tài):空位、黑棋和白棋。 -
board
?是一個二維向量,表示棋盤,初始時所有位置都是空位。 -
isValidMove
?函數(shù)用于判斷某個位置是否可以下子。合法的位置必須在棋盤范圍內(nèi),并且為空位。 -
checkWin
?函數(shù)用于判斷某個位置下子后是否獲勝。它檢查當(dāng)前位置在四個方向上(水平、垂直、兩個對角線)是否有連續(xù)的連續(xù)的五個相同類型棋子。如果有則返回 true,否則返回 false。 -
printBoard
?函數(shù)用于打印當(dāng)前棋盤的狀態(tài)。 -
isBoardFull
?函數(shù)用于判斷棋盤是否已經(jīng)滿了(即沒有空位),如果棋盤已滿,則返回 true,否則返回 false。 -
main
?函數(shù)是程序的入口。它使用一個無限循環(huán),每次循環(huán)輪流讓玩家下子,然后判斷是否游戲結(jié)束。如果有一方獲勝或者棋盤已滿,則打印相應(yīng)的信息,并結(jié)束游戲。
開始寫代碼
void printBoard() {
for (int i = 0; i < BOARD_SIZE; i++) {
for (int j = 0; j < BOARD_SIZE; j++) {
cout << board[i][j] << " ";
}
cout << endl;
}
cout << endl;
}
?
這段代碼為打印棋盤狀態(tài)的函數(shù)
printBoard()
,使用了嵌套的循環(huán)來遍歷棋盤,并輸出每個位置的狀態(tài)。具體的實(shí)現(xiàn)邏輯如下:
- 外層循環(huán)
for (int i = 0; i < BOARD_SIZE; i++)
遍歷棋盤的行數(shù),從第一行開始到最后一行。- 內(nèi)層循環(huán)
for (int j = 0; j < BOARD_SIZE; j++)
遍歷棋盤的列數(shù),從第一列開始到最后一列。- 在內(nèi)層循環(huán)中,通過
board[i][j]
獲取當(dāng)前位置的狀態(tài)值,并使用cout
輸出該狀態(tài)值。- 輸出一個空格,以分隔不同位置的狀態(tài)值。
- 內(nèi)層循環(huán)結(jié)束后,通過
cout << endl;
輸出換行符,以換行顯示下一行的棋盤狀態(tài)。- 外層循環(huán)結(jié)束后,通過
cout << endl;
再次輸出一個換行符,以在棋盤狀態(tài)的輸出之間添加空行。這樣,調(diào)用
printBoard()
函數(shù)可以按照指定格式輸出當(dāng)前棋盤的狀態(tài)。每個位置上的狀態(tài)值可以是空格、X或O等字符,表示空位、玩家1和玩家2的棋子。通過這個函數(shù),可以直觀地展示游戲棋盤的狀態(tài)給玩家。
bool isValidMove(int row, int col) {
return (row >= 0 && row < BOARD_SIZE && col >= 0 && col < BOARD_SIZE && board[row][col] == EMPTY);
}
?
這段代碼是用于判斷玩家落子是否合法的函數(shù)
isValidMove(row, col)
,其中row
和col
分別表示玩家輸入的坐標(biāo)值。具體的實(shí)現(xiàn)邏輯如下:
- 首先,通過
row >= 0 && row < BOARD_SIZE && col >= 0 && col < BOARD_SIZE
判斷玩家輸入的坐標(biāo)值是否在棋盤范圍內(nèi)。如果超出了棋盤范圍,則此次落子不合法。- 否則,通過
board[row][col] == EMPTY
判斷該位置是否已有棋子(即狀態(tài)值是否為EMPTY)。如果該位置上沒有棋子,則此次落子合法,返回true
。- 如果該位置上已經(jīng)有棋子,則此次落子不合法,返回
false
。通過這個函數(shù),可以快速判斷玩家輸入的坐標(biāo)是否合法。如果不合法,則需要提示玩家重新輸入坐標(biāo);如果合法,則可以繼續(xù)進(jìn)行游戲。
?
bool checkWin(int row, int col, char player) {
int directions[4][2] = {{1, 0}, {0, 1}, {1, 1}, {-1, 1}};
for (int i = 0; i < 4; i++) {
int count = 1;
int dx = directions[i][0], dy = directions[i][1];
int r = row + dx, c = col + dy;
while (r >= 0 && r < BOARD_SIZE && c >= 0 && c < BOARD_SIZE && board[r][c] == player) {
count++;
r += dx;
c += dy;
}
dx = -dx, dy = -dy;
r = row + dx, c = col + dy;
while (r >= 0 && r < BOARD_SIZE && c >= 0 && c < BOARD_SIZE && board[r][c] == player) {
count++;
r += dx;
c += dy;
}
if (count >= 5)
return true;
}
return false;
}
?
這段代碼是用于檢查玩家是否取得勝利的函數(shù)
checkWin(row, col, player)
,其中row
和col
表示最后一次落子的坐標(biāo),player
表示當(dāng)前玩家的符號。具體的實(shí)現(xiàn)邏輯如下:
- 首先,定義一個二維數(shù)組
directions[4][2]
來表示四個方向,分別為向下、向右、右下、左下。每個方向由兩個元素組成,分別表示在行方向和列方向上的增量。- 使用一個循環(huán)遍歷四個方向。
- 在循環(huán)內(nèi)部,初始化一個計(jì)數(shù)器
count
為1,表示已經(jīng)有一顆當(dāng)前玩家的棋子。- 根據(jù)當(dāng)前方向的增量
(dx, dy)
,計(jì)算下一個檢查的位置(r, c)
,并檢查該位置是否在棋盤范圍內(nèi)且值等于當(dāng)前玩家的符號。- 如果滿足條件,將計(jì)數(shù)器
count
加1,并更新下一個位置(r, c)
為當(dāng)前位置加上增量(dx, dy)
。- 重復(fù)步驟4和步驟5,直到碰到越界或者不是當(dāng)前玩家的棋子。
- 然后,將增量
(dx, dy)
取相反數(shù),即改變方向。- 再次計(jì)算下一個檢查的位置
(r, c)
,并檢查該位置是否在棋盤范圍內(nèi)且值等于當(dāng)前玩家的符號。- 如果滿足條件,將計(jì)數(shù)器
count
加1,并更新下一個位置(r, c)
為當(dāng)前位置加上增量(dx, dy)
。- 重復(fù)步驟8和步驟9,直到碰到越界或者不是當(dāng)前玩家的棋子。
- 檢查計(jì)數(shù)器
count
是否大于等于5,如果是,則表示當(dāng)前玩家在其中一個方向上取得了勝利,返回true
。- 如果四個方向都遍歷完畢,仍未滿足取勝條件,則返回
false
。通過這個函數(shù),可以判斷當(dāng)前玩家是否在最后一次落子后取得了勝利。根據(jù)游戲規(guī)則,只有當(dāng)任意一方在橫、豎、斜對角線方向上連續(xù)五個棋子時才算獲勝。
完整代碼?
#include <iostream>
#include <vector>
using namespace std;
const int BOARD_SIZE = 15;
const char EMPTY = '-';
const char BLACK = 'X';
const char WHITE = 'O';
vector<vector<char> > board(BOARD_SIZE, vector<char>(BOARD_SIZE, EMPTY));
bool isValidMove(int row, int col) {
return (row >= 0 && row < BOARD_SIZE && col >= 0 && col < BOARD_SIZE && board[row][col] == EMPTY);
}
bool checkWin(int row, int col, char player) {
int directions[4][2] = {{1, 0}, {0, 1}, {1, 1}, {-1, 1}};
for (int i = 0; i < 4; i++) {
int count = 1;
int dx = directions[i][0], dy = directions[i][1];
int r = row + dx, c = col + dy;
while (r >= 0 && r < BOARD_SIZE && c >= 0 && c < BOARD_SIZE && board[r][c] == player) {
count++;
r += dx;
c += dy;
}
dx = -dx, dy = -dy;
r = row + dx, c = col + dy;
while (r >= 0 && r < BOARD_SIZE && c >= 0 && c < BOARD_SIZE && board[r][c] == player) {
count++;
r += dx;
c += dy;
}
if (count >= 5)
return true;
}
return false;
}
void printBoard() {
for (int i = 0; i < BOARD_SIZE; i++) {
for (int j = 0; j < BOARD_SIZE; j++) {
cout << board[i][j] << " ";
}
cout << endl;
}
cout << endl;
}
bool isBoardFull() {
for (int i = 0; i < BOARD_SIZE; i++) {
for (int j = 0; j < BOARD_SIZE; j++) {
if (board[i][j] == EMPTY)
return false;
}
}
return true;
}
int main() {
int row, col;
char currentPlayer = BLACK;
while (true) {
printBoard();
cout << "Player " << currentPlayer << ", enter your move (row col): ";
cin >> row >> col;
if (!isValidMove(row, col)) {
cout << "Invalid move! Try again." << endl;
continue;
}
board[row][col] = currentPlayer;
if (checkWin(row, col, currentPlayer)) {
cout << "Player " << currentPlayer << " wins!" << endl;
break;
} else if (isBoardFull()) {
cout << "It's a draw!" << endl;
break;
}
currentPlayer = (currentPlayer == BLACK) ? WHITE : BLACK;
}
printBoard();
return 0;
}
?
在這個五子棋游戲代碼中,可以通過以下方式進(jìn)行輸入和輸出:
輸入:
- 玩家輸入下子位置:可以通過命令行提示玩家輸入坐標(biāo),例如,要求玩家輸入行和列的數(shù)字,表示下子位置的坐標(biāo)。
- 其他玩家操作:例如,要求玩家輸入指令來選擇重新開始游戲或退出游戲。
輸出:
- 打印當(dāng)前棋盤狀態(tài):使用嵌套的循環(huán)遍歷棋盤,根據(jù)棋盤上每個位置的狀態(tài)輸出相應(yīng)的符號,可以使用空格、X和O等字符來表示空位、玩家1和玩家2的棋子。
- 提示玩家操作:例如,提示玩家輸入坐標(biāo)來下子,或者提示玩家輸入指令以進(jìn)行其他操作。
- 游戲結(jié)果輸出:當(dāng)游戲結(jié)束時,根據(jù)游戲結(jié)果輸出勝利者或者平局信息。
- 錯誤提示:如果玩家輸入了無效的指令或下子位置,可以輸出錯誤提示信息,要求玩家重新輸入。
在代碼中,可以使用適當(dāng)?shù)妮斎牒瘮?shù),如input()
來接收玩家輸入,并使用適當(dāng)?shù)妮敵龊瘮?shù),如print()
來輸出信息到控制臺。通過合理地組織輸入和輸出,可以實(shí)現(xiàn)與玩家的有效交互,并提供友好的游戲體驗(yàn)。
結(jié)果圖:
文章來源:http://www.zghlxwxcb.cn/news/detail-733239.html
如果想要更加華麗美觀的代碼,關(guān)注博主贊賞2元回復(fù)“五子棋華麗代碼”即可。文章來源地址http://www.zghlxwxcb.cn/news/detail-733239.html
到了這里,關(guān)于用c++實(shí)現(xiàn)五子棋小游戲的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!