C++實(shí)現(xiàn)簡單五子棋游戲
五子棋是世界智力運(yùn)動(dòng)會(huì)競技項(xiàng)目之一,是一種兩人對(duì)弈的純策略型棋類游戲,是世界智力運(yùn)動(dòng)會(huì)競技項(xiàng)目之一,通常雙方分別使用黑白兩色的棋子,下在棋盤直線與橫線的交叉點(diǎn)上,先形成5子連線者獲勝。
規(guī)則
(1)對(duì)局雙方各執(zhí)一色棋子。
(2)空棋盤開局。
(3)黑先、白后,交替下子,每次只能下一子。
(4)棋子下在棋盤的空白點(diǎn)上,棋子下定后,不得向其它點(diǎn)移動(dòng),不得從棋盤上拿掉或拿起另落別處。
(5)黑方的第一枚棋子可下在棋盤任意交叉點(diǎn)上。
(6)輪流下子是雙方的權(quán)利,但允許任何一方放棄下子權(quán)(即:PASS權(quán))
五子棋對(duì)局,執(zhí)行黑方指定開局、三手可交換、五手兩打的規(guī)定。整個(gè)對(duì)局過程中黑方有禁手,白方無禁手。黑方禁手有三三禁手、四四禁手和長連禁手三種。
實(shí)現(xiàn)方案
通過縮小棋盤來抑制五子棋先行的優(yōu)勢,在這里使用15路棋盤。
(1)提供3個(gè)選擇模式
(2)輸入坐標(biāo)(注意橫縱坐標(biāo)之間需要空格)
(3)輸入非法坐標(biāo)
(4)判斷輸贏
- 判斷行是否滿足條件
- 判斷列是否滿足條件
- 判斷主對(duì)角線是否滿足條件
- 判斷副對(duì)角線是否滿足條件
之后可選擇yes再來一局,也可以選擇no退出游戲。
源代碼如下:
#define _CRT_SECURE_NO_WARNINGS 1 #include <iostream> #include <stdio.h> #include <stdlib.h> #include <time.h> #include <string.h> using namespace std; const int N = 15; //15*15的棋盤 const char ChessBoard = ' '; //棋盤標(biāo)志 const char flag1 = 'o'; //玩家1或電腦標(biāo)志 const char flag2 = 'x'; //玩家2標(biāo)志 typedef struct Position{ //坐標(biāo) int row; //行 int col; //列 }Position; class GoBang{ //五子棋類 public: GoBang(){ InitChessBoard(); //初始化棋盤 } void Play(){ //下棋 Position Play1; //玩家1或電腦 Position Play2; //玩家2 while (1){ int mode = ChoiceMode(); while (1){ if (mode == 1){ //電腦VS玩家 ComputerChess(Play1, flag1); //電腦走 if (GetVictory(Play1, 0, flag1)){ //0代表電腦,為真則表示電腦獲勝 break; } PlayChess(Play2, 2, flag2); //玩家2走 if (GetVictory(Play2, 2, flag2)){ //2代表玩家2 break; } } else{ //玩家1VS玩家2 PlayChess(Play1, 1, flag1); //玩家1走 if (GetVictory(Play1, 1, flag1)){ //玩家1贏 break; } PlayChess(Play2, 2, flag2); //玩家2走 if (GetVictory(Play2, 2, flag2)){ //玩家2贏 break; } } } cout << "======再來一局=======" << endl; cout << "yes or no :"; char s[] = "yes"; cin >> s; if (strcmp(s, "no") == 0){ break; } } } protected: void InitChessBoard(){ //初始化棋盤 for (int i = 0; i < N + 1; ++i){ for (int j = 0; j < N + 1; ++j){ _ChessBoard[i][j] = ChessBoard; } } } int ChoiceMode(){ //選擇模式 system("cls"); //系統(tǒng)調(diào)用,清屏 InitChessBoard(); //重新初始化棋盤 cout << "*************************************************" << endl; cout << "******************0、退出************************" << endl; cout << "******************1、電腦VS玩家******************" << endl; cout << "******************2、玩家VS玩家******************" << endl; cout << "*************************************************" << endl; while (1){ int i = 0; cout << "請(qǐng)選擇模式:"; cin >> i; if (i == 0){ //退出 exit(1); } if (i == 1 || i == 2){ return i; } else{ cout << "非法輸入,請(qǐng)重新輸入!" << endl; } } } void PrintChessBoard(){ //打印棋盤 printf(" 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15\n"); printf(" |---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|\n"); for (int i = 1; i < N + 1; ++i) { printf("%2d ", i); printf("| %c | %c | %c | %c | %c | %c | %c | %c | %c | %c | %c | %c | %c | %c | %c |\n", _ChessBoard[i][1], _ChessBoard[i][2], _ChessBoard[i][3], _ChessBoard[i][4], _ChessBoard[i][5], _ChessBoard[i][6], _ChessBoard[i][7], _ChessBoard[i][8], _ChessBoard[i][9], _ChessBoard[i][10], _ChessBoard[i][11], _ChessBoard[i][12], _ChessBoard[i][13], _ChessBoard[i][14], _ChessBoard[i][15]); printf(" |---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|\n"); } cout << endl; } void ComputerChess(Position& pos, char flag){ //電腦走 //PrintChessBoard(); //打印棋盤 int x = 0; int y = 0; while (1){ //循環(huán)查找空位置 x = (rand() % N) + 1; //產(chǎn)生從1~N的隨機(jī)數(shù) srand((unsigned int)time(NULL)); y = (rand() % N) + 1; //產(chǎn)生從1~N的隨機(jī)數(shù) srand((unsigned int)time(NULL)); if (_ChessBoard[x][y] == ChessBoard){ //如果這個(gè)位置為空(沒有棋子),跳出循環(huán),下棋 break; } } pos.row = x; pos.col = y; _ChessBoard[pos.row][pos.col] = flag; } void PlayChess(Position& pos, int player, char flag){ PrintChessBoard(); //打印棋盤 while (1){ printf("請(qǐng)玩家%d輸入坐標(biāo):", player); cin >> pos.row >> pos.col; if (JudgeValue(pos) == 1){ //判斷坐標(biāo)是否合法 break; } cout << "坐標(biāo)不合法,請(qǐng)重新輸入:" << endl; } _ChessBoard[pos.row][pos.col] = flag; } int JudgeValue(const Position& pos){ //判斷坐標(biāo)的合法性 //1.在棋盤上 if (pos.row > 0 && pos.row <= N && pos.col > 0 && pos.col <= N){ //2.所在位置為空(沒有棋子) if (_ChessBoard[pos.row][pos.col] == ChessBoard){ return 1; //合法 } } return 0; //非法 } int JudgeVictory(Position pos, char flag){ //判斷是否有玩家獲勝(底層判斷) int begin = 0; int end = 0; //1.判斷行是否滿足條件 (pos.col - 4) > 0 ? begin = (pos.col - 4) : begin = 1; (pos.col + 4) > N ? end = N : end = (pos.col + 4); for (int i = pos.row, j = begin; j + 4 <= end; ++j){ if (_ChessBoard[i][j] == flag && _ChessBoard[i][j + 1] == flag && _ChessBoard[i][j + 2] == flag && _ChessBoard[i][j + 3] == flag && _ChessBoard[i][j + 4] == flag) return 1; } //2.判斷列是否滿足條件 (pos.row - 4) > 0 ? begin = (pos.row - 4) : begin = 1; (pos.row + 4) > N ? end = N : end = (pos.row + 4); for (int j = pos.col, i = begin ; i + 4 <= end; ++i){ if (_ChessBoard[i][j] == flag && _ChessBoard[i + 1][j] == flag && _ChessBoard[i + 2][j] == flag && _ChessBoard[i + 3][j] == flag && _ChessBoard[i + 4][j] == flag) return 1; } //3.判斷主對(duì)角線是否滿足條件 int len = 0; //相對(duì)長度 int start = 0; int finish = 0; pos.row > pos.col ? len = pos.col - 1 : len = pos.row - 1; if (len > 4){ len = 4; } begin = pos.row - len; //橫坐標(biāo)起始位置 start = pos.col - len; //縱坐標(biāo)起始位置 pos.row > pos.col ? len = N - pos.row : len = N - pos.col; if (len > 4){ len = 4; } end = pos.row + len; //橫坐標(biāo)結(jié)束位置 finish = pos.col + len; //縱坐標(biāo)結(jié)束位置 for (int i = begin, j = start; (i + 4 <= end) && (j + 4 <= finish); ++i, ++j){ if (_ChessBoard[i][j] == flag && _ChessBoard[i + 1][j + 1] == flag && _ChessBoard[i + 2][j + 2] == flag && _ChessBoard[i + 3][j + 3] == flag && _ChessBoard[i + 4][j + 4] == flag) return 1; } //4.判斷副對(duì)角線是否滿足條件 (pos.row - 1) > (N - pos.col) ? len = N - pos.col : len = pos.row - 1; if (len > 4){ len = 4; } begin = pos.row - len; //橫坐標(biāo)起始位置 start = pos.col + len; //縱坐標(biāo)起始位置 (N - pos.row) > (pos.col - 1) ? len = pos.col - 1 : len = N - pos.row; if (len > 4){ len = 4; } end = pos.row + len; //橫坐標(biāo)結(jié)束位置 finish = pos.col - len; //縱坐標(biāo)結(jié)束位置 for (int i = begin, j = start; (i + 4 <= end) && (j - 4 >= finish); ++i, --j){ if (_ChessBoard[i][j] == flag && _ChessBoard[i + 1][j - 1] == flag && _ChessBoard[i + 2][j - 2] == flag && _ChessBoard[i + 3][j - 3] == flag && _ChessBoard[i + 4][j - 4] == flag) return 1; } //該位置并未下棋 for (int x = 1; x < N + 1; ++x){ for (int y = 1; y < N + 1; ++y){ if (_ChessBoard[x][y] == ChessBoard){ return 0; //未下棋 } } } return -1; //和局 } bool GetVictory(Position& pos, int player, char flag){ //判斷具體哪位玩家贏 if (JudgeVictory(pos, flag) != 0){ //判斷有無人獲勝 if (JudgeVictory(pos, flag) == 1){ //判斷是否有人獲勝,1表示獲勝 PrintChessBoard(); //打印棋盤 if (player == 0){ cout << "電腦獲勝!" << endl; } else{ printf("恭喜玩家%d獲勝!\n", player); } } else{ printf("和局!\n"); } return true; //有人獲勝 } return false; //沒人獲勝 } private: char _ChessBoard[N + 1][N + 1]; //棋盤 }; int main(){ GoBang g; g.Play(); system("pause"); return 0; }
更多有趣的經(jīng)典小游戲?qū)崿F(xiàn)專題,分享給大家:
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C語言植物大戰(zhàn)數(shù)據(jù)結(jié)構(gòu)快速排序圖文示例
這篇文章主要為大家介紹了C語言植物大戰(zhàn)數(shù)據(jù)結(jié)構(gòu)快速排序圖文示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05C語言數(shù)據(jù)結(jié)構(gòu)之Hash散列表
這篇文章主要介紹了C語言數(shù)據(jù)結(jié)構(gòu)之Hash散列表,散列表(哈希表)其思想主要是基于數(shù)組支持按照下標(biāo)隨機(jī)訪問數(shù)據(jù),時(shí)間復(fù)雜度為O(1)的特性,可以說是數(shù)組的一種拓展,需要的朋友可以參考下2023-08-08C++實(shí)現(xiàn)LeetCode(48.旋轉(zhuǎn)圖像)
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(48.旋轉(zhuǎn)圖像),本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07