QT项目:中国象棋
項目簡介:
????????開發(fā)語言:C++
? ? ? ? 開發(fā)軟件:Qt Creator 4.6.2?
? ? ? ? 實現(xiàn)功能:目前所能實現(xiàn)的功能比較單一,只支持人人對戰(zhàn),也就是兩個人在一臺電腦上實現(xiàn)對戰(zhàn)。
項目思路:
????????1、繪制棋盤
????????2、繪制棋子
????????3、放置棋子于棋盤之上
????????4、倒計時
????????5、象棋輪流下
????????6、制定象棋的具體規(guī)則
項目主要組成:
1、總的文件(其中chessmovelaw文件是自定義文件,res是資源文件,包括棋盤、棋子、應(yīng)用程序logo等圖片)
?2、主要代碼
????????mainwindow.h
#ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QMainWindow>namespace Ui { class MainWindow; }enum ChessPieces //棋子 {NullChess,Ju_R,Ma_R,Xiang_R,Shi_R,Jiang_R,Pao_R,Bing_R,Ju_B,Ma_B,Xiang_B,Shi_B,Jiang_B,Pao_B,Bing_B };class MainWindow : public QMainWindow {Q_OBJECTpublic:explicit MainWindow(QWidget *parent = 0);~MainWindow();void paintEvent(QPaintEvent *e); //繪畫事件void mousePressEvent(QMouseEvent * event); //鼠標(biāo)按下事件bool CanMove(int tarRow,int tarCol); //被選中棋子,能否從選中位置移動到當(dāng)前位置bool IsRedChess(ChessPieces chesspieces);void IsDead();void timerEvent(QTimerEvent *event);int eventID1;int d = 60;void InitChess(); //初始化所有棋子的位置void DrawChess(QPainter*p,int row,int col,ChessPieces pieces);private slots:void on_pushButton_2_clicked();private:Ui::MainWindow *ui;QPoint stPos,edPos;int W,H;ChessPieces chesspieces[10][9];int pressRow,pressCol;bool turn; //turn=0為紅,turn=1為黑 };#endif // MAINWINDOW_H????????mainwindow.cpp
#include "mainwindow.h" #include "ui_mainwindow.h" #include <QIcon> #include <QPainter> #include <QRect> #include <QDebug> #include <QPushButton> #include <QPoint> #include <QMouseEvent> #include <QPen> #include <QFont> #include <QBrush> #include <QColor> #include <QImage> #include "chessmovelaw.h"MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow) {ui->setupUi(this);setWindowIcon(QIcon(":/image/logo.png"));setWindowTitle("中國象棋");stPos = QPoint(30,30);edPos = QPoint(570,630);W = (edPos.x()-stPos.x())/8;H = (edPos.y()-stPos.y())/9;InitChess(); //未選中棋子pressRow = -1;pressCol = -1;turn = false;//定時器eventID1 = startTimer(1000); //可自定義切換快慢 }MainWindow::~MainWindow() {delete ui; }void MainWindow::timerEvent(QTimerEvent *event) {//設(shè)置字體大小QFont font;font.setPointSize(20);ui->label->setFont(font);//設(shè)置定時器(倒計時)if(event->timerId() == eventID1){d--;ui->label->move(700,20);ui->label->resize(200,60);QString aa = "倒計時";QString bb = QString::number(d);ui->label->setText(aa+bb);} } void MainWindow::paintEvent(QPaintEvent *e) {QPainter painter(this);QRect rect;rect = QRect(0,0,600,660);painter.drawPixmap(rect,QPixmap(":/image/chessboard2.png"));if(pressRow>=0 && pressCol>=0){QRect r(stPos.x()+pressCol*W-0.5*W,stPos.y()+pressRow*H-0.5*H,W,H);painter.drawPixmap(r,QPixmap(":/image/4.jpg"));}for(int i=0;i<10;i++){for(int j=0;j<9;j++){if(chesspieces[i][j] != NullChess)DrawChess(&painter,i,j,chesspieces[i][j]);}} }void MainWindow::mousePressEvent(QMouseEvent * event) {event->pos();if(event->button() == Qt::LeftButton){int row=(event->y()-stPos.y()+0.5*H)/H;int col=(event->x()-stPos.x()+0.5*W)/W;//選中到行和列在棋盤內(nèi)的時候if(row>=0 && row<=9 && col>=0 && col<=8){//之前選中到棋子為空if(pressRow>=0 && pressCol>=0){//如果滿足象棋移動規(guī)則,移動棋子if(CanMove(row,col)){d=61;chesspieces[row][col] = chesspieces[pressRow][pressCol];chesspieces[pressRow][pressCol] = NullChess;pressRow = -1;pressCol = -1;turn =! turn;IsDead();repaint();return;}}//當(dāng)前選中棋子為空if(chesspieces[row][col] != NullChess){//如果是紅棋走且選中的是紅棋,或如果是黑棋走且選中的是黑棋,把棋子選中if((turn==false &&IsRedChess(chesspieces[row][col]))||(turn==true && !IsRedChess(chesspieces[row][col]))){pressRow = row;pressCol = col;}repaint();}}} }void MainWindow::InitChess() {for(int i=0;i<10;i++){for(int j=0;j<9;j++){chesspieces[i][j] = NullChess;}}chesspieces[0][0] = Ju_R;chesspieces[0][1] = Ma_R;chesspieces[0][2] = Xiang_R;chesspieces[0][3] = Shi_R;chesspieces[0][4] = Jiang_R;chesspieces[9][0] = Ju_B;chesspieces[9][1] = Ma_B;chesspieces[9][2] = Xiang_B;chesspieces[9][3] = Shi_B;chesspieces[9][4] = Jiang_B;for(int i=0;i<4;i++){chesspieces[0][8-i] = chesspieces[0][i];chesspieces[9][8-i] = chesspieces[9][i];}chesspieces[2][1]=Pao_R;chesspieces[2][7]=Pao_R;chesspieces[7][1]=Pao_B;chesspieces[7][7]=Pao_B;chesspieces[3][0]=Bing_R;chesspieces[3][2]=Bing_R;chesspieces[3][4]=Bing_R;chesspieces[3][6]=Bing_R;chesspieces[3][8]=Bing_R;chesspieces[6][0]=Bing_B;chesspieces[6][2]=Bing_B;chesspieces[6][4]=Bing_B;chesspieces[6][6]=Bing_B;chesspieces[6][8]=Bing_B; }void MainWindow::DrawChess(QPainter *p,int row,int col,ChessPieces pieces) {QPixmap pix;switch (pieces){case Ju_R:pix = QPixmap(":/image/Ju_r.png");break;case Ma_R:pix = QPixmap(":/image/Ma_r.png");break;case Xiang_R:pix = QPixmap(":/image/Xiang_r.png");break;case Shi_R:pix = QPixmap(":/image/Shi_r.png");break;case Jiang_R:pix = QPixmap(":/image/Shuai_b.png");break;case Pao_R:pix = QPixmap(":/image/Pao_r.png");break;case Bing_R:pix = QPixmap(":/image/Bing_r.png");break;case Ju_B:pix = QPixmap(":/image/Ju_b.png");break;case Ma_B:pix = QPixmap(":/image/Ma_b.png");break;case Xiang_B:pix = QPixmap(":/image/Xiang_b.png");break;case Shi_B:pix = QPixmap(":/image/Shi_b.png");break;case Jiang_B:pix = QPixmap(":/image/Jiang_b.png");break;case Pao_B:pix = QPixmap(":/image/Pao_b.png");break;case Bing_B:pix = QPixmap(":/image/Zu_b.png");break;default:break;}QRect r(stPos.x()+col*W-0.5*W,stPos.y()+row*H-0.5*H,W,H);p->drawPixmap(r,pix); }bool MainWindow::CanMove(int tarRow,int tarCol) {if(pressRow>=0 && pressCol>=0){return ChessMoveLaw::ChessCanMove(chesspieces,pressRow,pressCol,tarRow,tarCol);}return false; }bool MainWindow::IsRedChess(ChessPieces chesspieces) {if(chesspieces==Ju_R || chesspieces==Ma_R || chesspieces==Xiang_R || chesspieces==Shi_R || chesspieces==Pao_R || chesspieces==Jiang_R || chesspieces==Bing_R )return true;elsereturn false; }void MainWindow::IsDead() {int red=0;int black=0;for(int i=0;i<10;i++){for(int j=0;j<9;j++){if(chesspieces[i][j]==Jiang_R)red++;else if(chesspieces[i][j]==Jiang_B)black++;}}if(red==0){QFont font;font.setPointSize(20);ui->label_2->setFont(font);ui->label_2->resize(200,60);QString w = "黑方獲勝!!";ui->label_2->move(700,80);ui->label_2->setText(w);}else if(black==0){QFont font;font.setPointSize(20);ui->label_2->setFont(font);ui->label_2->resize(200,60);QString w = "紅方獲勝!!";ui->label_2->move(700,80);ui->label_2->setText(w);}elsereturn; }chessmovelaw.h
#ifndef CHESSMOVELAW_H #define CHESSMOVELAW_H#include "mainwindow.h"class ChessMoveLaw { public:static bool ChessCanMove(ChessPieces chesspieces[10][9],int sourceRow,int sourceCol,int destRow,int destCol);protected:static bool MaLaw(ChessPieces chesspieces[10][9],int sourceRow,int sourceCol,int destRow,int destCol);static bool XiangLaw(ChessPieces chesspieces[10][9],int sourceRow,int sourceCol,int destRow,int destCol);static bool ShiLaw(ChessPieces chesspieces[10][9],int sourceRow,int sourceCol,int destRow,int destCol);static bool JiangLaw(ChessPieces chesspieces[10][9],int sourceRow,int sourceCol,int destRow,int destCol);static bool JuLaw(ChessPieces chesspieces[10][9],int sourceRow,int sourceCol,int destRow,int destCol);static bool PaoLaw(ChessPieces chesspieces[10][9],int sourceRow,int sourceCol,int destRow,int destCol);static bool BingLaw(ChessPieces chesspieces[10][9],int sourceRow,int sourceCol,int destRow,int destCol);static bool IsSameColor(ChessPieces chesspieces[10][9],int sourceRow,int sourceCol,int destRow,int destCol);static bool IsRedChess(ChessPieces chesspieces); };#endif // CHESSMOVELAW_Hchessmovelaw.cpp
#include "chessmovelaw.h"#include <cmath> #include <QDebug>bool ChessMoveLaw::ChessCanMove(ChessPieces chesspieces[10][9],int sourceRow,int sourceCol,int destRow,int destCol) {//如果目標(biāo)棋子不為空且顏色相同if(chesspieces[destRow][destCol]!=NullChess && IsSameColor(chesspieces, sourceRow, sourceCol, destRow, destCol))return false;//馬-規(guī)則if(chesspieces[sourceRow][sourceCol]==Ma_R || chesspieces[sourceRow][sourceCol]==Ma_B){return MaLaw(chesspieces, sourceRow, sourceCol, destRow, destCol);}//象-規(guī)則if(chesspieces[sourceRow][sourceCol]==Xiang_R || chesspieces[sourceRow][sourceCol]==Xiang_B){return XiangLaw(chesspieces, sourceRow, sourceCol, destRow, destCol);}//士-規(guī)則if(chesspieces[sourceRow][sourceCol]==Shi_R || chesspieces[sourceRow][sourceCol]==Shi_B){return ShiLaw(chesspieces, sourceRow, sourceCol, destRow, destCol);}//將-規(guī)則if(chesspieces[sourceRow][sourceCol]==Jiang_R || chesspieces[sourceRow][sourceCol]==Jiang_B){return JiangLaw(chesspieces, sourceRow, sourceCol, destRow, destCol);}//車-規(guī)則if(chesspieces[sourceRow][sourceCol]==Ju_R || chesspieces[sourceRow][sourceCol]==Ju_B){return JuLaw(chesspieces, sourceRow, sourceCol, destRow, destCol);}//炮-規(guī)則if(chesspieces[sourceRow][sourceCol]==Pao_R || chesspieces[sourceRow][sourceCol]==Pao_B){return PaoLaw(chesspieces, sourceRow, sourceCol, destRow, destCol);}//兵-規(guī)則if(chesspieces[sourceRow][sourceCol]==Bing_R || chesspieces[sourceRow][sourceCol]==Bing_B){return BingLaw(chesspieces, sourceRow, sourceCol, destRow, destCol);}return true; }bool ChessMoveLaw::IsRedChess(ChessPieces chesspieces) {if(chesspieces==Ju_R || chesspieces==Ma_R || chesspieces==Xiang_R || chesspieces==Shi_R || chesspieces==Pao_R || chesspieces==Jiang_R || chesspieces==Bing_R )return true;elsereturn false; } bool ChessMoveLaw::IsSameColor(ChessPieces chesspieces[10][9],int sourceRow,int sourceCol,int destRow,int destCol) {if(chesspieces[destRow][destCol]==NullChess)return false;return IsRedChess(chesspieces[sourceRow][sourceCol])==IsRedChess(chesspieces[destRow][destCol]); }//馬的走法 bool ChessMoveLaw::MaLaw(ChessPieces chesspieces[10][9],int sourceRow,int sourceCol,int destRow,int destCol) {if(abs(sourceRow-destRow) == 1){if(abs(sourceCol-destCol) != 2)return false;else if(chesspieces[sourceRow][(sourceCol+destCol)/2] != NullChess)return false;elsereturn true;}else if(abs(sourceRow-destRow) == 2){if(abs(sourceCol-destCol) != 1)return false;else if(chesspieces[(sourceRow+destRow)/2][sourceCol] != NullChess)return false;elsereturn true;}else{return false;} }//象的走法 bool ChessMoveLaw::XiangLaw(ChessPieces chesspieces[10][9],int sourceRow,int sourceCol,int destRow,int destCol) {//是否過河了if(IsRedChess(chesspieces[sourceRow][sourceCol])){if(sourceRow<=4 && destRow<=4){if(abs(sourceRow-destRow) == 2){if(abs(sourceCol-destCol) != 2)return false;else{if(chesspieces[(sourceRow+destRow)/2][(sourceCol+destCol)/2] == NullChess)return true;elsereturn false;}}else{return false;}}}else{if(sourceRow>=5 && destRow>=5){if(abs(sourceRow-destRow) == 2){if(abs(sourceCol-destCol) != 2)return false;else{if(chesspieces[(sourceRow+destRow)/2][(sourceCol+destCol)/2] == NullChess)return true;elsereturn false;}}else{return false;}}} }//士的走法 bool ChessMoveLaw::ShiLaw(ChessPieces chesspieces[10][9],int sourceRow,int sourceCol,int destRow,int destCol) {//是否在田字格內(nèi)if(IsRedChess(chesspieces[sourceRow][sourceCol])){if(sourceRow>=0 && sourceRow<=2 && sourceCol>=3 && sourceCol<=5 && destRow>=0 && destRow<=2 && destCol>=3 && destCol<=5 ){//斜線走if(abs(sourceRow-destRow)==1 && abs(sourceCol-destCol)==1)return true;elsereturn false;}return false;}else{if(sourceRow>=7 && sourceRow<=9 && sourceCol>=3 && sourceCol<=5 && destRow>=7 && destRow<=9 && destCol>=3 && destCol<=5 ){if(abs(sourceRow-destRow)==1 && abs(sourceCol-destCol)==1)return true;elsereturn false;}return false;} }//將的走法 bool ChessMoveLaw::JiangLaw(ChessPieces chesspieces[10][9],int sourceRow,int sourceCol,int destRow,int destCol) {//是否在田字格內(nèi)if(IsRedChess(chesspieces[sourceRow][sourceCol])){if(sourceRow>=0 && sourceRow<=2 && sourceCol>=3 && sourceCol<=5 && destRow>=0 && destRow<=2 && destCol>=3 && destCol<=5 ){//上下左右走if(((abs(sourceRow-destRow)==1 && abs(sourceCol-destCol)==0))||((abs(sourceRow-destRow)==0 && abs(sourceCol-destCol)==1)))return true;elsereturn false;}return false;}else{if(sourceRow>=7 && sourceRow<=9 && sourceCol>=3 && sourceCol<=5 && destRow>=7 && destRow<=9 && destCol>=3 && destCol<=5 ){if(((abs(sourceRow-destRow)==1 && abs(sourceCol-destCol)==0))||((abs(sourceRow-destRow)==0 && abs(sourceCol-destCol)==1)))return true;elsereturn false;}return false;}if(chesspieces[sourceRow][sourceCol] == Jiang_R){int r,c;int m=0;for(int i=0;i<10;i++)for(int j=0;j<9;j++){if(chesspieces[i][j] == Jiang_B){r=i;c=j;}}if(destCol == c){for(int a=destRow;a<r;a++){if(chesspieces[a][c] != NullChess){m++;}}if(m == 0)qDebug() << "黑棋獲勝!";}}else if(chesspieces[sourceRow][sourceCol] == Jiang_B){int r,c;int m=0;for(int i=0;i<10;i++)for(int j=0;j<9;j++){if(chesspieces[i][j] == Jiang_R){r=i;c=j;}}if(destCol == c){for(int a=r;a<destRow;a++){if(chesspieces[a][c] != NullChess){m++;}}if(m == 0)qDebug() << "紅棋獲勝!";}}}//車的走法 bool ChessMoveLaw::JuLaw(ChessPieces chesspieces[10][9],int sourceRow,int sourceCol,int destRow,int destCol) { int m=0;if(sourceRow == destRow){if(sourceCol < destCol){for(int i=sourceCol+1;i<destCol;i++)if(chesspieces[sourceRow][i] != NullChess)m++;if(m == 0)return true;elsereturn false;}if(sourceCol > destCol){for(int i=destCol+1;i<sourceCol;i++)if(chesspieces[sourceRow][i] != NullChess)m++;if(m == 0)return true;elsereturn false;}}if(sourceCol == destCol){if(sourceRow<destRow){for(int i=sourceRow+1;i<destRow;i++)if(chesspieces[i][sourceCol] != NullChess)m++;if(m == 0)return true;elsereturn false;}if(sourceRow>destRow){for(int i=destRow+1;i<sourceRow;i++)if(chesspieces[i][sourceCol] != NullChess)m++;if(m == 0)return true;elsereturn false;}} }//炮的走法 bool ChessMoveLaw::PaoLaw(ChessPieces chesspieces[10][9],int sourceRow,int sourceCol,int destRow,int destCol) {int m = 0;if(sourceRow == destRow && abs(sourceCol-destCol) <= 9){if(sourceCol < destCol){//是否隔山打牛for(int i=sourceCol+1;i<destCol-1;i++)if(chesspieces[sourceRow][i] != NullChess)m++;if(m==0 && chesspieces[destRow][destCol]==NullChess)return true;else if(m==1 && chesspieces[destRow][destCol]!=NullChess){if(IsRedChess(chesspieces[sourceRow][sourceCol]) != IsRedChess(chesspieces[destRow][destCol]))return true;return false;}elsereturn false;}if(sourceCol > destCol){for(int i=destCol+1;i<sourceCol;i++)if(chesspieces[sourceRow][i] != NullChess)m++;if(m==0 && chesspieces[destRow][destCol]==NullChess)return true;else if(m==1 && chesspieces[destRow][destCol]!=NullChess){if(IsRedChess(chesspieces[sourceRow][sourceCol]) != IsRedChess(chesspieces[destRow][destCol]))return true;return false;}elsereturn false;}}if(sourceCol == destCol && abs(sourceRow-destRow) <= 8){if(sourceRow < destRow){for(int i=sourceRow+1;i<destRow;i++)if(chesspieces[i][sourceCol] != NullChess)m++;if(m==0 && chesspieces[destRow][destCol] == NullChess)return true;else if(m==1 && chesspieces[destRow][destCol] != NullChess){if(IsRedChess(chesspieces[sourceRow][sourceCol]) != IsRedChess(chesspieces[destRow][destCol]))return true;return false;}elsereturn false;}if(sourceRow > destRow){for(int i=destRow+1;i<sourceRow;i++)if(chesspieces[i][sourceCol] != NullChess)m++;if(m==0 && chesspieces[destRow][destCol] == NullChess)return true;else if(m==1 && chesspieces[destRow][destCol] != NullChess){if(IsRedChess(chesspieces[sourceRow][sourceCol]) != IsRedChess(chesspieces[destRow][destCol]))return true;return false;}elsereturn false;}} }//兵的走法 bool ChessMoveLaw::BingLaw(ChessPieces chesspieces[10][9],int sourceRow,int sourceCol,int destRow,int destCol) {//是否過河了if(IsRedChess(chesspieces[sourceRow][sourceCol])){//沒有過河if(sourceRow <= 4){if(destRow-sourceRow==1 && sourceCol==destCol)return true;elsereturn false;}//過河了else{if(destRow-sourceRow == 1 && destCol==sourceCol){return true;}else if(sourceRow==destRow && abs(sourceCol-destCol)==1)return true;elsereturn false;}}else{if(sourceRow >= 5){if(sourceRow-destRow==1 && sourceCol==destCol){return true;}elsereturn false;}else{if(sourceRow-destRow == 1 && destCol==sourceCol){return true;}else if(sourceRow==destRow && abs(sourceCol-destCol)==1){return true;}elsereturn false;}} }????????main.cpp
#include "mainwindow.h" #include <QApplication>int main(int argc, char *argv[]) {QApplication a(argc, argv);MainWindow w;w.show();return a.exec(); }3、最終效果圖
?
?
總結(jié)
- 上一篇: 随机排列与八卦太极的联系
- 下一篇: weui.js slider的使用笔记