File indexing completed on 2024-04-21 04:03:16

0001 /*
0002     SPDX-FileCopyrightText: 2007 Paolo Capriotti <p.capriotti@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #ifndef MESSAGE_H
0008 #define MESSAGE_H
0009 
0010 #include <QExplicitlySharedDataPointer>
0011 
0012 #include "ship.h"
0013 #include "ships.h"
0014 
0015 class MessageVisitor;
0016 
0017 class Message : public QSharedData
0018 {
0019 public:
0020     virtual ~Message() { }
0021     virtual void accept(MessageVisitor& visitor) const = 0;
0022 };
0023 
0024 typedef QExplicitlySharedDataPointer<Message> MessagePtr;
0025 
0026 class HeaderMessage : public Message
0027 {
0028     QString m_protocol_version;
0029     QString m_client_name;
0030     QString m_client_version;
0031     QString m_client_description;
0032 public:
0033     static const int MSGTYPE = 0;
0034     HeaderMessage(const QString& protocolVersion,
0035                  const QString& clientName,
0036                  const QString& clientVersion,
0037                  const QString& clientDescription);
0038     HeaderMessage();
0039     void accept(MessageVisitor& visitor) const override;
0040     static QString messageType() { return QStringLiteral("Header"); }
0041     
0042     const QString& protocolVersion() const { return m_protocol_version; }
0043     const QString& clientName() const { return m_client_name; }
0044     const QString& clientVersion() const { return m_client_version; }
0045     const QString& clientDescription() const { return m_client_description; }
0046 };
0047 
0048 class RejectMessage : public Message
0049 {
0050     bool m_version_mismatch;
0051     QString m_reason;
0052 public:
0053     static const int MSGTYPE = 1;
0054     RejectMessage(bool versionMismatch, const QString& reason);
0055     void accept(MessageVisitor& visitor) const override;
0056     static QString messageType() { return QStringLiteral("Reject"); }
0057 };
0058 
0059 class NickMessage : public Message
0060 {
0061     QString m_nickname;
0062 public:
0063     static const int MSGTYPE = 2;
0064     explicit NickMessage(const QString& nickname);
0065     void accept(MessageVisitor& visitor) const override;
0066     
0067     const QString& nickname() const { return m_nickname; }
0068     static QString messageType() { return QStringLiteral("Nick"); }
0069 };
0070 
0071 class BeginMessage : public Message
0072 {
0073 public:
0074     static const int MSGTYPE = 3;
0075     void accept(MessageVisitor& visitor) const override;
0076     static QString messageType() { return QStringLiteral("Begin"); }
0077 };
0078 
0079 class MoveMessage : public Message
0080 {
0081     Coord m_move;
0082 public:
0083     static const int MSGTYPE = 4;
0084     explicit MoveMessage(const Coord& move);
0085     void accept(MessageVisitor& visitor) const override;
0086     
0087     const Coord& move() const { return m_move; }
0088     static QString messageType() { return QStringLiteral("Move"); }
0089 };
0090 
0091 class NotificationMessage : public Message
0092 {
0093     Coord m_move;
0094     bool m_hit;
0095     bool m_death;
0096     Coord m_start;
0097     Coord m_stop;
0098 public:
0099     static const int MSGTYPE = 5;
0100     NotificationMessage(const Coord& m_move, bool hit, bool death,
0101         const Coord& start = Coord::invalid(), const Coord& stop = Coord::invalid());
0102     void accept(MessageVisitor& visitor) const override;
0103     static QString messageType() { return QStringLiteral("Notification"); }
0104     
0105     const Coord& move() const { return m_move; }
0106     bool hit() const { return m_hit; }
0107     bool death() const { return m_death; }
0108     const Coord& start() const { return m_start; }
0109     const Coord& stop() const { return m_stop; }
0110 };
0111 
0112 class GameOverMessage : public Message
0113 {
0114 public:
0115     struct ShipInfo
0116     {
0117         Coord pos;
0118         int size;
0119         Ship::Direction direction;
0120 
0121         ShipInfo(const Coord& pos, int size, Ship::Direction direction)
0122         : pos(pos)
0123         , size(size)
0124         , direction(direction)
0125         {
0126         }
0127     };
0128 private:
0129     QList<ShipInfo> m_ships;
0130 public:
0131     static const int MSGTYPE = 6;
0132     GameOverMessage();
0133 
0134     void addShip(const Coord& pos, int size, Ship::Direction direction);
0135     void accept(MessageVisitor& visitor) const override;
0136     static QString messageType() { return QStringLiteral("GameOver"); }
0137 
0138     const QList<ShipInfo>& ships() const { return m_ships; }
0139 };
0140 
0141 class RestartMessage : public Message
0142 {
0143 public:
0144     static const int MSGTYPE = 7;
0145     void accept(MessageVisitor& visitor) const override;
0146     static QString messageType() { return QStringLiteral("Restart"); }
0147 };
0148 
0149 class ChatMessage : public Message
0150 {
0151     QString m_nickname;
0152     QString m_chat;
0153 public:
0154     static const int MSGTYPE = 8;
0155     explicit ChatMessage(const QString& nick, const QString& chat);
0156     void accept(MessageVisitor& visitor) const override;
0157     static QString messageType() { return QStringLiteral("Chat"); }
0158 
0159     const QString& chat() const { return m_chat; }
0160     const QString& nickname() const { return m_nickname; }
0161 };
0162 
0163 
0164 class GameOptionsMessage : public Message
0165 {
0166 private:
0167     QString m_enabledAdjacentShipsString;
0168     QString m_oneOrSeveralShipsString;
0169     const BattleShipsConfiguration* m_battleShipsConfiguration;
0170 public:
0171     static const int MSGTYPE = 9;
0172     GameOptionsMessage(const QString& enableAdjacentShips, const QString& oneOrSeveralShips,
0173         const BattleShipsConfiguration* configuration);
0174     GameOptionsMessage(const bool enableAdjacentShips, const bool oneOrSeveralShips,
0175         const BattleShipsConfiguration &configuration);
0176 
0177     const QString & enabledAdjacentShips() const { return m_enabledAdjacentShipsString; }
0178     const QString & oneOrSeveralShips() const { return m_oneOrSeveralShipsString; }
0179     unsigned int gridWidth() const { return m_battleShipsConfiguration->boardWidth(); }
0180     unsigned int gridHeight() const { return m_battleShipsConfiguration->boardHeight(); }
0181     const BattleShipsConfiguration* shipsConfiguration() const { return m_battleShipsConfiguration; }
0182     void accept(MessageVisitor& visitor) const override;
0183     static QString messageType() { return QStringLiteral("GameOptions"); }
0184 };
0185 
0186 
0187 class MessageVisitor
0188 {
0189 public:
0190     virtual ~MessageVisitor() { }
0191     virtual void visit(const HeaderMessage& msg) = 0;
0192     virtual void visit(const RejectMessage& msg) = 0;
0193     virtual void visit(const NickMessage& msg) = 0;
0194     virtual void visit(const BeginMessage& msg) = 0;
0195     virtual void visit(const MoveMessage& msg) = 0;
0196     virtual void visit(const NotificationMessage& msg) = 0;
0197     virtual void visit(const GameOverMessage& msg) = 0;
0198     virtual void visit(const RestartMessage& msg) = 0;
0199     virtual void visit(const ChatMessage& msg) = 0;
0200     virtual void visit(const GameOptionsMessage& msg) = 0;
0201 };
0202 
0203 #endif // MESSAGE_H
0204