也算是真正自己写的第一个C++图形化程序
使用Qt4.7开发
参考 《qt4精彩实例分析》 《C++ GUI Qt4编程》以及Qt优秀的帮助文档。
想法来源于对算法的慢慢感兴趣,Unix编程的感兴趣,以及对Qt编程的感兴趣。就想着做个东西试试。
ver1.0 为单机版
只能一个人自己跟自己下(我知道很傻, 不过作为自己写的第一个图形化程序还是很值得以后回味的)。
使用了三个类:Board,Gobang, Mainwindow
Board
Board就是中间的棋盘。实现方式特别傻:就是19*19的Labels。然后设置上不同的图片。
重写了QWidget的pressMouseEvent,当鼠标点击时计算对应的label的位置,根据顺序更新label上的图片。
计算完成的算法就是从有效棋的坐标向各个方向判断是否有连续的五个同色棋子。
结束时,emit hasFinished(const QString& );,然后无法点击。
Gobang
gobang是包含着Board的QWidget
一个水平布局,左边是Board,右边是垂直布局。
主要起了承上启下的作用。接受Board或者Mainindow的一些信号,然后转发,或者自己处理
MainWindow
MainWidget为Gobang,有一个statusBar。当游戏结束时会有消息提示。
抽时间写的,总体算来,编写用了一天左右。不过学到一些东西,尤其是对Qt的熟悉,QtCreator的熟悉,文档的使用,布局之类的。
后来加入了联网功能,加入了一些类,部分代码进行了重构。
成为ver2.0
由于有Unix 网络编程的基础,理解Qt的网络包比较容易。抓着实例上的网络编程看了半个小时,背着敲了些代码,就基本上会用了。
意识到了学习应该踏实,抓住经典,很多都是触类旁通的。
网络版Board类与单机版不能完全一样,主界面当然也不能完全一样,再加上需要聊天室、网络通信的功能。增加了一些类。
HEADERS += /
board.h /
gobang.h /
mainwindow.h /
netgobang.h /
chatroom.h /
client.h /
peer.h /
server.h /
netboard.h
NetBoard
和Board类的mousePressEvent的实现不同,需要判断是否该自己下棋。同时需要发送信号,告诉NetGobang下的位置,来进行发送到对方主机。
考虑过是否要和Board提出一个AbstractBoard。感觉不用,因为只有这两个棋盘的打算,不会扩展,没必要增加麻烦。
Server 和 Client
参考了一下例子,就是基本的server client模型,不写了。
说一下自己设计的功能。
有一个sengMessage()函数,格式透明,server和client都直接发送信息。
接受时执行检验,有两种信息:聊天信息;下棋位置。
下棋位置格式为 /行坐标x/列坐标y
聊天信息不能以/开头
接受到的信息如果解析为坐标就发送 void putAChess(int , int ); 信号
接受到的信息如果解析为信息就发送void TextReceived(const QString&); 信号
后期考虑重构,发现Server和Client用的时候有很多共同接口和实现,就抽象出了Peer类。
Peer
#ifndef PEER_H
#define PEER_H
#include <QObject>
class Peer : public QObject
{
Q_OBJECT
public:
explicit Peer(QObject *parent = 0, quint16 portNum=8012);
virtual ~Peer();
signals:
void connectedToPeer(const QString&);
void disConnectedFromPeer(const QString&);
void putAChess(int , int );
void TextReceived(const QString&);
public slots:
virtual void sendMessage(const QString&) =0;
virtual void sendMessage(int,int) =0;
protected slots:
virtual void connected()=0;
virtual void disConnected()=0;
virtual void dataReceived() =0;
protected:
typedef unsigned short quint16;
quint16 port;
};
#endif // PEER_H
记得以前看 more effectuve c++说,Peer中的非虚函数在子类中都不应该重写,要是有个java中的final就好了。
Chatroom
一个TextEdit,一个LineEdit,一个Button
唯一注意的是,发送信息时需要检验不能以/开头。
NetGobang
布局就是上Netoard,下Chatroom。
继续承上启下。
MainWindow
增加了菜单栏,可以选择3中模式:本地,成为主机,连接主机
MainWidget是一个WidgetStack,里边有Gobang和NetGobang。根据选择切换。
同时,向NetGobang添加Peer时,用类似于Java的方式setPeer(new 一个Server或者Client)。
虽然注意防止内存泄漏,但知道C++中使用这种方法好像不好。不过觉着这样还是挺方便的。
升级到ver2.0大约花了两天的时间。
深刻得体回到了,开发软件难的不是语法,是设计。。。
虽然做的时候注意了规范,但做完还是感觉乱七八糟。
刻骨铭心的第一次。。。
然后,奔向算法吧。