1 /*
2 SPDX-FileCopyrightText: 2007 Paolo Capriotti <p.capriotti@gmail.com>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
7 #include "sea.h"
8 #include "battlefield.h"
9
Sea(QObject * parent,const BattleShipsConfiguration & battleShipsConfiguration)10 Sea::Sea(QObject* parent, const BattleShipsConfiguration& battleShipsConfiguration)
11 : QObject(parent)
12 , m_size(Coord(battleShipsConfiguration.boardWidth(), battleShipsConfiguration.boardHeight()))
13 , m_turn(PLAYER_A)
14 , m_status(PLACING_SHIPS)
15 , m_battle_ships_configuration(battleShipsConfiguration)
16 {
17 m_fields[0] = new BattleField(this, m_size, battleShipsConfiguration.isAllowedAdjacentShips());
18 m_fields[1] = new BattleField(this, m_size, battleShipsConfiguration.isAllowedAdjacentShips());
19 }
20
~Sea()21 Sea::~Sea()
22 {
23 m_enemyShips.clear();
24 m_myShips.clear();
25
26 delete m_fields[0];
27 delete m_fields[1];
28 }
29
canAddShip(Player p,const Coord & pos,int size,Ship::Direction direction) const30 bool Sea::canAddShip(Player p, const Coord& pos, int size, Ship::Direction direction) const
31 {
32 if (m_status != PLACING_SHIPS) {
33 return false;
34 }
35 return m_fields[p]->canAddShip(pos, size, direction);
36 }
37
canAddShipOfSize(Player p,int size) const38 bool Sea::canAddShipOfSize(Player p, int size) const
39 {
40 if (m_status != PLACING_SHIPS) {
41 return false;
42 }
43 return m_fields[p]->canAddShipOfSize(size);
44 }
45
clear(Sea::Player p)46 void Sea::clear(Sea::Player p)
47 {
48 if (m_status == PLACING_SHIPS) {
49 m_fields[p]->clear();
50 if(p == PLAYER_B) {
51 m_enemyShips.clear();
52 }
53 else {
54 m_myShips.clear();
55 }
56 }
57 m_status = PLACING_SHIPS;
58 }
59
add(Player p,Ship * ship)60 void Sea::add(Player p, Ship* ship)
61 {
62 if(p == PLAYER_B) {
63 m_enemyShips.append(ship);
64 }
65 else {
66 m_myShips.append(ship);
67 }
68
69 m_fields[p]->add(ship);
70 }
71
add(Player p,int n)72 void Sea::add(Player p, int n)
73 {
74 m_fields[p]->add(n);
75 }
76
addBorder(Player p,const Coord & pos)77 void Sea::addBorder(Player p, const Coord& pos)
78 {
79 m_fields[p]->addBorder(pos);
80 }
81
canHit(Player p,const Coord & pos) const82 bool Sea::canHit(Player p, const Coord& pos) const
83 {
84 if (m_status != PLAYING || m_turn != p) {
85 return false;
86 }
87 if (!otherField()->valid(pos)) {
88 return false;
89 }
90 Element& e = otherField()->get(pos);
91 return e.free();
92 }
93
hit(const Coord & pos)94 HitInfo Sea::hit(const Coord& pos)
95 {
96 HitInfo res = otherField()->hit(pos);
97 checkGameOver();
98 return res;
99 }
100
forceHit(const Coord & pos,const HitInfo & info)101 void Sea::forceHit(const Coord& pos, const HitInfo& info)
102 {
103 otherField()->forceHit(pos, info);
104 checkGameOver();
105 }
106
checkGameOver()107 void Sea::checkGameOver()
108 {
109 if (otherField()->ships() <= 0) {
110 m_status = m_turn == PLAYER_A ? A_WINS : B_WINS;
111 }
112 else {
113 switchTurn();
114 }
115 }
116
allowAdjacentShips(const bool allow_adjacent_ships)117 void Sea::allowAdjacentShips(const bool allow_adjacent_ships)
118 {
119 m_battle_ships_configuration.setAllowAdjacentShips(allow_adjacent_ships);
120 m_fields[0]->setAllowAdjacentShips(allow_adjacent_ships);
121 m_fields[1]->setAllowAdjacentShips(allow_adjacent_ships);
122 }
123
at(Sea::Player player,const Coord & c) const124 const Element& Sea::at(Sea::Player player, const Coord& c) const
125 {
126 return m_fields[player]->at(c);
127 }
128
valid(Sea::Player player,const Coord & pos) const129 bool Sea::valid(Sea::Player player, const Coord& pos) const
130 {
131 return m_fields[player]->valid(pos);
132 }
133
134 // Coord Sea::find(Player p, Ship* ship) const
135 // {
136 // return m_fields[p]->find(ship);
137 // }
138
switchTurn()139 void Sea::switchTurn()
140 {
141 m_turn = opponent(m_turn);
142 }
143
opponent(Player p)144 Sea::Player Sea::opponent(Player p)
145 {
146 return p == PLAYER_A ? PLAYER_B : PLAYER_A;
147 }
148
startPlaying()149 void Sea::startPlaying()
150 {
151 Q_ASSERT(m_status == PLACING_SHIPS);
152 m_status = PLAYING;
153 }
154
abort(Player p)155 void Sea::abort(Player p)
156 {
157 if (p == PLAYER_A) {
158 m_status = A_WINS;
159 }
160 else {
161 m_status = B_WINS;
162 }
163 }
164
isNearShip(Sea::Player p,const Coord & pos) const165 bool Sea::isNearShip(Sea::Player p, const Coord& pos) const
166 {
167 return m_fields[p]->isNearShip(pos);
168 }
169
enemyShips() const170 const QList<Ship *> Sea::enemyShips() const
171 {
172 return m_enemyShips;
173 }
174
myShips() const175 const QList<Ship *> Sea::myShips() const
176 {
177 return m_myShips;
178 }
179
setBattleShipsConfiguration(const BattleShipsConfiguration & configuration)180 void Sea::setBattleShipsConfiguration(const BattleShipsConfiguration& configuration)
181 {
182 m_battle_ships_configuration=configuration;
183 m_fields[0]->setAllowAdjacentShips(configuration.isAllowedAdjacentShips());
184 m_fields[1]->setAllowAdjacentShips(configuration.isAllowedAdjacentShips());
185 }
186
187
188
189
190