C++應(yīng)用實(shí)現(xiàn)簡易五子棋游戲
本文實(shí)例為大家分享了C++實(shí)現(xiàn)簡易五子棋游戲位的具體代碼,供大家參考,具體內(nèi)容如下
在實(shí)現(xiàn)五子棋小游戲時(shí),首先應(yīng)該分為棋盤和玩家,我們先定義兩個(gè)類:chessboard、player。分別提供棋盤的構(gòu)造和玩家及游戲規(guī)則的確定。下面我們看下代碼:
chessboard.h: 對棋盤chessboard類型進(jìn)行定義
#ifndef _CHESSBOARD_H_ #define _CHESSBOARD_H_ #include <iostream> using namespace std; class ChessBoard ? ?//棋盤 { ? ? public: ? ? ? ? enum{ROW = 31, COL = 31}; ? ?//整個(gè)棋盤所占的行數(shù)和列數(shù) ? ? char cSquare[ROW+1][COL+1]; ? ? ?//定義一個(gè)字符數(shù)組,用來打印棋盤 ? ? public: ? ? ? ? ChessBoard(); ? ? ? ? ? ? ? ?//棋盤構(gòu)造函數(shù) ? ? ? ? void show(); ? ? ? ? ? ? ? ? //棋盤的顯示 ? ? ? ? ~ChessBoard(){} ? ? ? ? ? ? ?//析構(gòu)函數(shù) }; #endif
chessboard.cpp
#include <iostream> #include <cstdlib> #include "chessboard.h" using namespace std; //構(gòu)造函數(shù) ChessBoard::ChessBoard() { ? ? for(int i = 1; i <= ROW - 2; i += 2){ ? ? //將棋盤隔行放入‘-'. ? ? ? ? for(int j = 1; j <= COL - 2; j += 2){ ? ? ? ? ? ? cSquare[i][j] = ' '; ? ? ? ? ? ? cSquare[i][j+1] = '|'; ? ? ? ? ? ? cSquare[i+1][j] = '-'; ? ? ? ? ? ? cSquare[i+1][j+1] = '-'; ? ? ? ? } ? ? } ? ? //圍出棋盤的四周 ? ? for(int j = 0; j < COL; j ++) ? ? ? ? ? ? cSquare[0][j] = cSquare[ROW-1][j] = '-'; ? ? for(int i = 0; i < ROW; i ++) ? ? ? ? cSquare[i][0] = cSquare[i][COL-1] = '|'; ? ? //空處棋盤落子空間 ? ? cSquare[ROW][0] = ' '; ? ? cSquare[0][COL] = ' '; ? ? //在最后以行打印出行、列下標(biāo)0,1,2 ... A,B,C ... ? ? for(int i = 1; i < 20; i += 2){ ? ? ? ? cSquare[i][COL] = i / 2 + 48; ? ? ? ? cSquare[i+1][COL] = ' '; ? ? ? ? cSquare[ROW][i] = i / 2 + 48; ? ? ? ? cSquare[ROW][i+1] = ' '; ? ? } ? ? for(int j = 21; j < COL; j += 2){ ? ? ? ? cSquare[ROW][j] = j / 2 + 55; ? ? ? ? cSquare[ROW][j+1] = ' '; ? ? } ? ? for(int j = 21; j < ROW; j += 2){ ? ? ? ? cSquare[j][COL] = j / 2 + 55; ? ? ? ? cSquare[j+1][COL] = ' '; ? ? } } void ChessBoard::show() { ? ? system("clear"); ? ? ? //清除緩存區(qū)數(shù)據(jù) ? ? //顯示棋盤 ? ? for(int i = 0; i <= ROW; ++i){ ? ? ? ? for(int j = 0; j <= COL; ++j) ? ? ? ? ? ? cout << cSquare[i][j] << ' '; ? ? ? ? cout << endl; ? ? } }
player.h:定義player類
#ifndef _PLAYER_H_ #define _PLAYER_H_ #include <iostream> #include <string> #include "chessboard.h" using namespace std; class Player { ? ? private: ? ? ? ? string m_name; ? ? ? ? char m_ChessType; ? ? ? ? int m_x; ? ? ? ? int m_y; ? ? ? ? ChessBoard * m_ptBoard; ? ? public: ? ? ? ? enum{ROW = 31, COL = 31}; ? ? ? ? Player():m_name("no_name"),m_ChessType('?'),m_x(0),m_y(0),m_ptBoard(NULL){} ? ? ? ? void attachToBoard(ChessBoard* ptBoard){m_ptBoard = ptBoard;} ? ? ? ? bool isInChessBoard(int x, int y) const; ?//棋子是否羅在棋盤內(nèi) ? ? ? ? bool HisLine(int x, int y) const; ? //判斷水平方向是否連夠5個(gè)棋子 ? ? ? ? bool VisLine(int x, int y) const; ? //判斷豎直方向是否連夠5個(gè)棋子 ? ? ? ? bool LtoBottomisLine(int x, int y) const; ?//判斷自左上角到右下角是否連夠5個(gè)棋子 ? ? ? ? bool LtoTopisLine(int x, int y) const; ? ? //判斷子右上角到左下角是否連夠5個(gè)棋子 ? ? ? ? bool isWin() const; ? ? ? ? ? ? ? ?//是否贏 ? ? ? ? string WinName() const{return m_name;} ? ? //贏者姓名 ? ? ? ? void SetInfo(int no); ? ?? ? ? ? ? void SetChess(); ? ? ? ? ? ? ?//把玩家所選的符號(hào)放進(jìn)所選為值 ? ? ? ? ~Player(){} }; #endif
player.cpp:
#include <iostream> #include <cstdlib> #include "player.h" using namespace std; bool Player::isInChessBoard(int x, int y) const { ? ? if(x < ROW - 1 && x > 0 && y < COL - 1 && y > 0) ? ? ? ? return true; ? ? else ? ? ? ? return false; } void Player::SetInfo(int no) { ? ? cout << "Please No." << no <<" input your name(q to quit): \n"; ? ? getline(cin, m_name); ? ? if("q" == m_name){ ? ? ? ? cout << "Bye Bye!" << endl; ? ? ? ? exit(-1); ? ? } ? ? //如果鍵盤輸入有錯(cuò)誤,清楚錯(cuò)誤標(biāo)志和環(huán)中去,重新輸入用戶名稱 ? ? while(!cin){ ? ? ? ? cin.clear(); ? ? ? ? cin.ignore(2048, '\n'); ?//1024清除緩存區(qū)數(shù)據(jù) ? ? ? ? cout << "Please No." << no << " input your name agin(q to quit): " << endl; ? ? ? ? getline(cin, m_name); ? ? ? ? if("q" == m_name){cout << "Bye Bye!" << endl; exit(-1);} ? ? } ? ? cout << "Hello! " << this->m_name << ": Please Choose Your Chess Type '*' or '#': " << endl; ? ? cin >> m_ChessType; ? ? cin.get(); ? ? //如果用戶輸入q,則退出程序 ? ? if('q' == m_ChessType){cout << "Bye Bye" << endl; exit(-1);} ? ? //如果鍵盤輸入有誤,或者用戶輸入的棋子團(tuán)不屬于預(yù)其設(shè)的*或#,則要求用戶重新輸入 ? ? while(!cin || (m_ChessType != '*' && m_ChessType != '#')){ ? ? ? ? cin.clear(); ? ? ? ? cin.sync(); ? ? ? ? cout << "Hello! " << this->m_name << ": Please Choose YOur Chess Type '*' or '#'(q to quit): \n"; ? ? ? ? cin >> m_ChessType; ? ? ? ? cin.get(); ? ? ? ? if('q' == m_ChessType){cout << "Bye Bye!" << endl; exit(-1);} ? ? } } //提示用戶輸入落子的坐標(biāo),并判斷是否坐標(biāo)在棋盤上,并把當(dāng)前玩家選擇的棋子圖案字符,填充進(jìn)當(dāng)前輸入的坐標(biāo) void Player::SetChess() { ? ? char x; ? ? char y; ? ? cout << this->m_name << ": Please input Position (x, y) of your Chess. (-, -) to quit" << endl; ? ? cin >> x >> y; ? ? if('-' == x && '-' == y){ ? ? ? ? cout << "Bye Bye!" << endl; ? ? ? ? exit(-1); ? ? } ? ? #if 1 ? ? if(x >= '0' && x <= '9'){ ? ? ? ? m_x = (int) x - 48; ? ? }else if(isupper(x)){ ? ? ? ? m_x = (int) x - 55; ? ? }else if(islower(x)){ ? ? ? ? x = toupper(x); ? ? ? ? m_x = (int) x - 55; ? ? } ? ? ? if(y >= '0' && y <= '9'){ ? ? ? ? m_y = (int) y - 48; ? ? }else if(isupper(y)){ ? ? ? ? m_y = (int) y - 55; ? ? }else if(islower(y)){ ? ? ? ? y = toupper(y); ? ? ? ? m_y = (int) y - 55; ? ? } ? ? ? m_x = m_x + (1 * m_x + 1); ? ? m_y = m_y + (1 * m_y + 1); ? ? #endif ? ? //如果鍵盤數(shù)據(jù)有錯(cuò)誤或者輸入的坐標(biāo)已經(jīng)存在其他棋子 ? ? while(!cin || m_ptBoard->cSquare[m_x][m_y] != ' '){ ? ? ? ? cin.clear(); ? ? ? ? cin.ignore(1024, '\n'); ? ? ? ? cout << this->m_name << ": Please Input Position (x, y) of Your Chess.(-, -) to quit" << endl;? ? ? ? ? cin >> x >> y; ? ? ? ? //根據(jù)所輸入進(jìn)來的行、列角標(biāo)找出相應(yīng)的落子位置,并將操作玩家所對應(yīng)的棋子符號(hào)填充到該位置(不區(qū)分大小寫) ? ? ? ? if('-' == x && '-' == y){ ? ? ? ? ? ? cout << "Bye Bye!" << endl; ? ? ? ? ? ? exit(-1); ? ? ? ? } ? ? ? ? if(x >= '0' && x <= '9'){ ? ? ? ? ? ? m_x = (int) x - 48; ? ? ? ? ?? ? ? ? ? }else if(isupper(x)){ ? ? ? ? ? ? m_x = (int) x - 55; ? ? ? ? }else if(islower(x)){ ? ? ? ? ? ? x = toupper(x); ? ? ? ? ? ? m_x = (int) x - 55; ? ? ? ? } ? ? ? ? ? if(y >= '0' && y <= '9'){ ? ? ? ? ? ? m_y = (int) y - 48; ? ? ? ? }else if(isupper(y)){ ? ? ? ? ? ? //cout << "m_y" << m_y << endl; ? ? ? ? ? ? m_y = (int) y - 55; ? ? ? ? ? ? //cout << "m_y" << m_y << endl; ? ? ? ? }else if(islower(y)){ ? ? ? ? ? ? y = toupper(y); ? ? ? ? ? ? m_y = (int) y - 55; ? ? ? ? } ? ? ? ? ? m_x = m_x + (1 * m_x + 1); ? ? ? ? m_y = m_y + (1 * m_y + 1); ? ? } ? ? //填充進(jìn)當(dāng)前輸入的坐標(biāo)對應(yīng)的棋盤的二維數(shù)組單元中 ? ? if(isInChessBoard(m_x, m_y)){ ? ? ? ? m_ptBoard->cSquare[m_x][m_y] = m_ChessType; ? ? }? } //判斷是否在水平方向上形成5子連線 bool Player::HisLine(int x, int y) const { ? ? int num = 0; ? ? for(int i = -8; i <= 8; i+=2){ ? ? ? ? if(isInChessBoard(x, y+i) && m_ptBoard->cSquare[x][y+i] == m_ChessType){ ? ? ? ? ? ?num++; ? ? ? ? ? ? if(num == 5) ? ? ? ? ? ? ? ? return true; ? ? ? ? } ?? ? ? ? ? else? ? ? ? ? ? ? num = 0; ? ? } ? ? return false; } //判斷是否在垂直方向上滿足5子連線 bool Player::VisLine(int x, int y) const { ? ? int num = 0; ? ? for(int i = -8; i <= 8; i+=2){ ? ? ? ? //如果當(dāng)前坐標(biāo)統(tǒng)一行的其他坐標(biāo)在棋盤上,且其他坐標(biāo)的圖案和當(dāng)前玩家的棋子圖案相同,計(jì)數(shù)器雷家 ? ? ? ? if(isInChessBoard(x+i, y) && m_ptBoard->cSquare[x+i][y] == m_ChessType){ ? ? ? ? ? ? num++; ? ? ? ? ? ? //連續(xù)同一行有5個(gè)坐標(biāo)點(diǎn)的圖案相同時(shí),滿足贏棋的條件 ? ? ? ? ? ? if(num == 5) ? ? ? ? ? ? ? ? return true; ? ? ? ? } ? ? ? ? else? ? ? ? ? ? ? num = 0; ? ? } ? ? return false; } //判斷是否在自左上角到右下角的方向上滿足5子連線 bool Player::LtoBottomisLine(int x, int y) const { ? ? int num = 0; ? ? for(int i = -8; i <= 8; i+=2){ ? ? ? ? //如果當(dāng)前坐標(biāo)沿自左上角到右下角的對角線方向的其他 ? ? ? ? if(isInChessBoard(x+i, y+i) && m_ptBoard->cSquare[x+i][y+i] == m_ChessType){ ? ? ? ? ? ? num++; ? ? ? ? ? ? if(num == 5) ? ? ? ? ? ? ? ? return true; ? ? ? ? } ? ? ? ? else ? ? ? ? ? ? num = 0; ? ? } ? ? return false; } //判斷是否在自左下角到右上角的方向上滿足5子連線 bool Player::LtoTopisLine(int x, int y) const { ? ? int num = 0; ? ? for(int i = -8; i <= 8; i+=2){ ? ? ? ? if(isInChessBoard(x-i, y+i) && m_ptBoard->cSquare[x-i][y+i] == m_ChessType){ ? ? ? ? ? ? num++; ? ? ? ? ? ? if(num == 5) ? ? ? ? ? ? ? ? return true; ? ? ? ? } ? ? ? ? else? ? ? ? ? ? ? num = 0; ? ? } ? ? return false; } bool Player::isWin()const { ? ? return (HisLine(m_x, m_y) || VisLine(m_x, m_y) || LtoBottomisLine(m_x, m_y) || LtoTopisLine(m_x, m_y)) ? true : false; }
game.cpp:
#include <iostream> #include "player.h" #include "chessboard.h" using namespace std; int main() { ? ? ChessBoard board; ? ? Player playerA; ? ? playerA.SetInfo(1); ? ? playerA.attachToBoard(&board); ? ? Player playerB; ? ? playerB.SetInfo(2); ? ? playerB.attachToBoard(&board); ? ? board.show(); ? ? while(1){ ? ? ? ? //玩家1放下一粒棋子 ? ? ? ? playerA.SetChess(); ? ? ? ? if(playerA.isWin()){ ? ? ? ? ? ? //board.show(); ? ? ? ? ? ? cout<<playerA.WinName()<<" Winner! Game Over!!\n"; ? ? ? ? ? ? break; ? ? ? ? } ? ? ? ? //顯示當(dāng)前棋盤中所有棋子的位置。 ? ? ? ? board.show(); ? ? ? ? //玩家2放下一粒棋子 ? ? ? ? playerB.SetChess(); ? ? ? ? if(playerB.isWin()){ ? ? ? ? ? ? cout << playerB.WinName() << " Winner! Game Over!!\n"; ? ? ? ? ? ? break; ? ? ? ? } ? ? ? ? board.show(); ? ? } ? ? //運(yùn)行出錯(cuò) ? ? return 1; }
下面給出一些運(yùn)行結(jié)果:
最后一個(gè)插進(jìn)去滿5個(gè)后顯示贏,結(jié)束程序:
上面代碼只實(shí)現(xiàn)了簡單功能,圖形畫界面看起來并不是很好,還有很大改進(jìn)空間。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C++?實(shí)現(xiàn)單鏈表創(chuàng)建、插入和刪除
這篇文章主要介紹了C++?實(shí)現(xiàn)單鏈表創(chuàng)建、插入和刪除方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07一文帶你快速了解C/C++標(biāo)準(zhǔn)庫中的ptrdiff_t
ptrdiff_t是C/C++標(biāo)準(zhǔn)庫中定義的一個(gè)與機(jī)器相關(guān)的數(shù)據(jù)類型,ptrdiff_t類型變量通常用來保存兩個(gè)指針減法操作的結(jié)果,下面這篇文章主要給大家介紹了關(guān)于C/C++標(biāo)準(zhǔn)庫中ptrdiff_t的相關(guān)資料,需要的朋友可以參考下2022-11-11基于C++浮點(diǎn)數(shù)(float、double)類型數(shù)據(jù)比較與轉(zhuǎn)換的詳解
本篇文章是對C++中浮點(diǎn)數(shù)(float、double)類型數(shù)據(jù)比較與轉(zhuǎn)換進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05C++實(shí)現(xiàn)教職工管理系統(tǒng)課程設(shè)計(jì)
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)教職工管理系統(tǒng)課程設(shè)計(jì),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03