File indexing completed on 2024-04-28 07:52:37

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 BATTLEFIELD_H
0008 #define BATTLEFIELD_H
0009 
0010 #include "ship.h"
0011 #include "hitinfo.h"
0012 #include "grid.h"
0013 #include <QObject>
0014 
0015 class Sea;
0016 
0017 class BattleField : public QObject
0018 {
0019 Q_OBJECT
0020     typedef Grid<Element> Board;
0021     Coord m_size;
0022     Board m_board;
0023     // Using a second board to annotate the real space used by the ships
0024     // Another solution would be to annotate the borders along with the ships,
0025     // and then send a signal to clean the borders when the shooting is going to start.
0026     Grid<bool> m_secondary_board;
0027     bool m_allow_adjacent_ships;
0028     unsigned int m_ships;
0029 
0030     inline int convert(const Coord& c) const { return c.x + m_size.x * c.y; }
0031     void setUpSecondaryBoard();
0032     void addSecondaryBoard(Ship* ship);
0033     void addBorderSecondaryBoard(Ship *ship);
0034     bool canAddShipOfSizeInHorizontal(unsigned int size) const;
0035     bool canAddShipOfSizeInVertical(unsigned int size) const;
0036 public:
0037     BattleField(Sea* parent, const Coord& size, const bool allow_adjacent_ships);
0038     ~BattleField() override;
0039 
0040     bool valid(const Coord& pos) const;
0041     Element& get(const Coord& pos);
0042     const Element& get(const Coord& pos) const;
0043     void set(const Coord& pos, const Element& e);
0044 
0045     void add(Ship* ship);
0046     void add(int n);
0047     void addBorder(const Coord& pos);
0048     bool canAddShip(const Coord& pos, unsigned int size, Ship::Direction direction) const;
0049     bool canAddShipOfSize(unsigned int size) const;
0050     HitInfo hit(const Coord& pos);
0051     void forceHit(const Coord& pos, const HitInfo& info);
0052     const Element& at(const Coord& c) const;
0053     Coord find(Ship* ship) const;
0054     bool isNearShip(const Coord& c) const;
0055     void setAllowAdjacentShips(const bool adjacent) { m_allow_adjacent_ships = adjacent; };
0056     void clear(); // to start placing the ships again in a clean BattleField
0057     inline unsigned int ships() const { return m_ships; }
0058 Q_SIGNALS:
0059     void shipDestroyed(Ship*);
0060 };
0061 
0062 #endif // BATTLEFIELD_H
0063