C++應(yīng)用實現(xiàn)簡易五子棋游戲
本文實例為大家分享了C++實現(xiàn)簡易五子棋游戲位的具體代碼,供大家參考,具體內(nèi)容如下
在實現(xiàn)五子棋小游戲時,首先應(yīng)該分為棋盤和玩家,我們先定義兩個類:chessboard、player。分別提供棋盤的構(gòu)造和玩家及游戲規(guī)則的確定。下面我們看下代碼:
chessboard.h: 對棋盤chessboard類型進行定義
#ifndef _CHESSBOARD_H_
#define _CHESSBOARD_H_
#include <iostream>
using namespace std;
class ChessBoard ? ?//棋盤
{
? ? public:
? ? ? ? enum{ROW = 31, COL = 31}; ? ?//整個棋盤所占的行數(shù)和列數(shù)
? ? char cSquare[ROW+1][COL+1]; ? ? ?//定義一個字符數(shù)組,用來打印棋盤
? ? public:
? ? ? ? ChessBoard(); ? ? ? ? ? ? ? ?//棋盤構(gòu)造函數(shù)
? ? ? ? void show(); ? ? ? ? ? ? ? ? //棋盤的顯示
? ? ? ? ~ChessBoard(){} ? ? ? ? ? ? ?//析構(gòu)函數(shù)
};
#endifchessboard.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個棋子
? ? ? ? bool VisLine(int x, int y) const; ? //判斷豎直方向是否連夠5個棋子
? ? ? ? bool LtoBottomisLine(int x, int y) const; ?//判斷自左上角到右下角是否連夠5個棋子
? ? ? ? bool LtoTopisLine(int x, int y) const; ? ? //判斷子右上角到左下角是否連夠5個棋子
? ? ? ? bool isWin() const; ? ? ? ? ? ? ? ?//是否贏
? ? ? ? string WinName() const{return m_name;} ? ? //贏者姓名
? ? ? ? void SetInfo(int no); ? ??
? ? ? ? void SetChess(); ? ? ? ? ? ? ?//把玩家所選的符號放進所選為值
? ? ? ? ~Player(){}
};
#endifplayer.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);
? ? }
? ? //如果鍵盤輸入有錯誤,清楚錯誤標(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);}
? ? //如果鍵盤輸入有誤,或者用戶輸入的棋子團不屬于預(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)前玩家選擇的棋子圖案字符,填充進當(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ù)有錯誤或者輸入的坐標(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ù)所輸入進來的行、列角標(biāo)找出相應(yīng)的落子位置,并將操作玩家所對應(yīng)的棋子符號填充到該位置(不區(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);
? ? }
? ? //填充進當(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)前玩家的棋子圖案相同,計數(shù)器雷家
? ? ? ? if(isInChessBoard(x+i, y) && m_ptBoard->cSquare[x+i][y] == m_ChessType){
? ? ? ? ? ? num++;
? ? ? ? ? ? //連續(xù)同一行有5個坐標(biāo)點的圖案相同時,滿足贏棋的條件
? ? ? ? ? ? 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();
? ? }
? ? //運行出錯
? ? return 1;
}下面給出一些運行結(jié)果:




最后一個插進去滿5個后顯示贏,結(jié)束程序:

上面代碼只實現(xiàn)了簡單功能,圖形畫界面看起來并不是很好,還有很大改進空間。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C語言字符函數(shù)isalnum()和iscntrl()詳解
大家好,本篇文章主要講的是C語言字符函數(shù)isalnum()和iscntrl()詳解,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下2022-02-02
基于Matlab實現(xiàn)BP神經(jīng)網(wǎng)絡(luò)交通標(biāo)志識別
道路交通標(biāo)志用以禁止、警告、指示和限制道路使用者有秩序地使用道路,?保障出行安全.若能自動識別道路交通標(biāo)志,?則將極大減少道路交通事故的發(fā)生。本文將介紹基于Matlab實現(xiàn)BP神經(jīng)網(wǎng)絡(luò)交通標(biāo)志識別,感興趣的可以學(xué)習(xí)一下2022-01-01
C語言單鏈表實現(xiàn)學(xué)生管理系統(tǒng)
這篇文章主要為大家詳細介紹了C語言單鏈表實現(xiàn)學(xué)生管理系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2020-12-12
C++中的while循環(huán)和for循環(huán)語句學(xué)習(xí)教程
這篇文章主要介紹了C++中的while循環(huán)和for循環(huán)語句學(xué)習(xí)教程,是C++入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下2015-09-09

