使用Qt开发中国象棋(五):走棋
来源:互联网 发布:linux ioctl 编辑:程序博客网 时间:2024/04/29 21:50
在整个游戏中,走棋是最复杂的部分,也是最麻烦的。开发这个程序,大概花了三分之一的时间在这个上面。在这个游戏中,走棋是通过鼠标点击事件来完成的,当然也可以通过拖动鼠标事件来弄。假设我们自己先走,整个走棋的逻辑如下:
(1)点击鼠标。
(2)ChessBoard类调用mousePressEvent并激发doMove信号。在该事件处理函数中,我们只处理鼠标左键单击事件。
void ChessBoard::mousePressEvent(QMouseEvent *event){ if (event->button() == Qt::LeftButton) { int row = 0; int column = 0; getPixmapIndex(event->pos().x(), event->pos().y(), row, column); int sq = getChessmanIndex(row, column, fliped); emit doMove(sq); }}
(3)调用MainWindow的doMove槽。如果该局未结束,则可以走棋。此外还会根据游戏的模式和走棋方进行判断。
void MainWindow::doMove(int index){ if (chessHandler->getCurrentTurn() == g_gameSettings.getCompetitorSide() && g_gameSettings.getGameType() != COMPITITOR_HUMAN) { return; } if (chessHandler->getGameResult() == -1) { chessHandler->doMove(index); }}
(4)调用逻辑层ChessHandle的doMove方法。该方法包括死棋检测,重复局面检测,走法合理性判断,生成走棋字符串,更新zobrist值等等。激发refreshGame信号。里面的更多细节,限于篇幅,就不列举了,后面会介绍个中细节。
void ChessHandler::doMove(int index){ assert(index >= 0x33 && index <= 0xcb); int fromPos = SRC(currentMoveInfo.move); int toPos = DST(currentMoveInfo.move); if (fromPos == index || toPos == index) { return; } bool legal = false; if (currentTurn == RED) { legal = redDoMove(index); } else { legal = blackDoMove(index); } if (legal) { if (SRC(currentMoveInfo.move) > 0 && DST(currentMoveInfo.move) > 0) { applyMove(); if (g_gameSettings.getGameType() == COMPITITOR_MACHINE) { //电脑走棋 computerMove(); } } else { //发送网络消息 if (g_gameSettings.getGameType() == COMPITITOR_NETWORK) { sendMoveInfoMsg(); } emit refreshGame(EVENT_UPDATE_MOVE); } } else { if (currentMoveInfo.movingChessman > 0) { emit refreshGame(EVENT_ILLEGAL_MOVE); } }}
(5)MainWindow中调用ProcessEvent,根据不同的参数进行不同的处理。如走棋合法会调用processUpdateMoveEvent,在该方法中会更新着法列表,显示走棋的路迹,更新某些按钮的状态。否则会调用processIllegalMoveEvent,播放提示音。
void MainWindow::processUpdateMoveEvent(){ MoveInfo info = chessHandler->getCurrentMoveInfo(); int gameResult = chessHandler->getGameResult(); //如果移动了完整的一步,则需要先更新整个棋盘 if (SRC(info.move) > 0 && DST(info.move) > 0) { chessBoard->loadPixmap(chessHandler->getChessman()); addToStepList(info); if (gameResult == -1 && g_gameSettings.getStepTime() > 0) { stepOverCond.wakeAll(); } } if (isSameSide(lastMoveInfo.movingChessman, info.movingChessman)) { chessBoard->showMoveRoute(lastMoveInfo.movingChessman, lastMoveInfo.move, false); } chessBoard->showMoveRoute(info.movingChessman, info.move, true); chessBoard->update(); playTipSound(info, gameResult); if (gameResult != -1) { if (gameResult != 0) { updateGeneralDisplay(gameResult); } showResult(gameResult); } lastMoveInfo = info; gameOver = gameResult != -1; ui->actionUndo->setEnabled(chessHandler->getLstMoveInfo().size() > 0);}void MainWindow::processIllegalMoveEvent(){ QSound::play(AUDIO_ILLEGAL);}整个走棋基本就是这个逻辑,也不是很复杂。中国象棋真正复杂的地方是机器走棋的算法,在这个游戏中,没有涉及到这么复杂的算法。曾经以为自己坚持不下来,毕竟要花两百多个小时的时间,还是很需要耐心的。心情浮躁的话,很可能坚持不下来。当我硬着头皮做完走棋的功能,发现已经完成了一半,如果半途而废的话,前面的努力就全白费了。想到这里,便一鼓作气的完成了剩下的工作。虽说做这个东西没什么用,但至少也算是考验一下自己的意志和耐性吧。个人感觉这个东西太需要耐心了,不能太浮躁。
0 0
- 使用Qt开发中国象棋(五):走棋
- 使用Qt开发中国象棋(三):走棋着法列表
- Cocos2d-X开发中国象棋《八》走棋
- Cocos2d-X开发中国象棋《九》走棋规则
- 使用Qt开发中国象棋(一):概述
- 中国象棋游戏Chess(2) - 走棋
- Unity中国象棋(二)——走棋
- 使用Qt开发中国象棋(二):棋盘绘制
- 使用Qt开发中国象棋(四):步时控制
- 使用Qt开发中国象棋(六):将军和死棋检测
- 使用Qt开发中国象棋(七):网络对战
- 中国象棋游戏Chess(3) - 实现走棋规则
- Cocos2d-X开发中国象棋《五》摆棋
- Qt中国象棋
- QT项目三:中国象棋
- 手机软件开发入门 - 中国象棋(1)090308
- 手机软件开发入门 - 中国象棋(2)090311
- (一)QT实现中国象棋(棋盘实现)
- mysql一些函数常见的用法(group by、order by、....)(1)
- inux下SonarQube安装方法
- Maven和开发JAX-RS Web应用的基本示例
- Day6.16 C语言简单递归调用:用递归法求N的阶乘
- 基于C语言的字符串函数
- 使用Qt开发中国象棋(五):走棋
- UIWebView加载PDF时出现的问题
- iOS使用自定义字体
- 解决本地启用XAMPP – MySQL shutdown unexpectedly问题
- Android 架构
- [知其然不知其所以然-8] linux cpufreq的sysfs文件详细解释
- GestureDetector类的用法
- java集合类详解二
- 全球有多少 C/C++ 程序员?Java 和 Python 又有多少?