2 Copyright Russell Steffen <rsteffen@bayarea.net>
3 Copyright Stephan Zehetner <s.zehetner@nevox.org>
4 Copyright Dmitry Suzdalev <dimsuz@gmail.com>
5 Copyright Inge Wallin <inge@lysator.liu.se>
6 Copyright Pierre Ducroquet <pinaraf@gmail.com>
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 #include "gamelogic.h"
30 #include "gamelogic.moc"
32 /*********************************************************************
34 *********************************************************************/
36 GameLogic::GameLogic( QObject
*parent
)
39 m_map
= new Map(16, 16);
40 m_neutralPlayer
= Player::createNeutralPlayer(m_map
);
46 GameLogic::~GameLogic()
52 //************************************************************************
53 // To the end turn processing (resolve combat, etc.)
54 //************************************************************************
57 // FIXME: Rename into resolveTurn(), and create a new newTurn() method.
62 // Resolve things from last turn.
63 resolveShipsInFlight();
65 // See if any players are left.
68 // advance to first living player
69 while( (*m_currentPlayer
) && !(*m_currentPlayer
)->isInPlay() ) {
73 // advance turn counter
74 // FIXME: Emit a newTurn() signal.
78 foreach (Planet
*planet
, m_planets
) {
84 //************************************************************************
85 // Determine the fate of the ships in transit
86 //************************************************************************
90 GameLogic::resolveShipsInFlight()
92 AttackFleetList arrivingShips
;
94 foreach (Player
*player
, m_players
) {
95 player
->attackList() += player
->newAttacks();
96 player
->statFleetsLaunched( player
->newAttacks().size() );
97 player
->newAttacks().clear();
98 foreach (AttackFleet
*fleet
, player
->attackList()) {
99 if( m_turnNumber
== fleet
->arrivalTurn
) {
100 doFleetArrival( fleet
);
101 player
->attackList().removeAll( fleet
);
110 GameLogic::findWinner()
114 foreach (Player
*player
, m_players
) {
115 if (player
->isInPlay()) {
116 // If there are more than one player alive, then there is
121 // Tentatively set this player as winner.
124 else if (player
->attackList().count() != 0)
125 // There is still a fleet attacking, so wait for its arrival...
134 //************************************************************************
135 // check to see any players have been eliminated
136 //************************************************************************
140 GameLogic::scanForSurvivors()
142 QList
<Player
*> activePlayers
;
143 QList
<Player
*> inactivePlayers
;
145 // Insert all of the active players into a special list,
146 // then deactivate them
148 foreach (player
, m_players
) {
149 if( player
->isInPlay() ) {
150 activePlayers
.append( player
);
151 player
->setInPlay( false );
153 inactivePlayers
.append( player
);
158 // iterate through the list of planets and
159 // mark their owners in play
160 foreach (Planet
*planet
, m_planets
) {
161 planet
->player()->setInPlay( true );
164 foreach (player
, activePlayers
) {
165 if( !player
->isInPlay() ) {
166 // Player has bitten the dust
167 emit
gameMsg(ki18n("The once mighty empire of %1 has fallen in ruins."), player
);
171 foreach (player
, inactivePlayers
) {
172 if( player
->isInPlay() ) {
173 // Player has bitten the dust
174 emit
gameMsg(ki18n("The fallen empire of %1 has staggered back to life."), player
);
180 //************************************************************************
181 // handle the arrival of a fleet at a planet
182 //************************************************************************
186 GameLogic::doFleetArrival( AttackFleet
*arrivingFleet
)
188 // Check to see of (fleet owner) == (planet owner)
189 // if the planet and fleet owner are the same, then merge the fleets
192 if( *arrivingFleet
->owner
== *arrivingFleet
->destination
->player() ) {
193 arrivingFleet
->destination
->fleet().absorb(arrivingFleet
);
194 if ( !arrivingFleet
->owner
->isAiPlayer() )
195 emit
gameMsg(ki18np("Reinforcements (1 ship) have arrived for planet %2.",
196 "Reinforcements (%1 ships) have arrived for planet %2.")
197 .subs(arrivingFleet
->shipCount()),
198 0, arrivingFleet
->destination
);
201 // let's get ready to rumble...
204 AttackFleet
&attacker
= *arrivingFleet
;
205 Planet
&attackerPlanet
= *(attacker
.source
);
206 Planet
&defenderPlanet
= *(attacker
.destination
);
207 DefenseFleet
&defender
= defenderPlanet
.fleet();
209 bool haveVictor
= false;
210 bool planetHolds
= true;
212 while( !haveVictor
) {
213 double attackerRoll
= cl
.roll();
214 double defenderRoll
= cl
.roll();
216 if( defenderRoll
< defenderPlanet
.killPercentage() ) {
217 attacker
.removeShips( 1 );
218 defenderPlanet
.player()->statEnemyShipsDestroyed( 1 );
221 if( attacker
.shipCount() <= 0 ) {
227 if( attackerRoll
< attackerPlanet
.killPercentage() ) {
228 defender
.removeShips( 1 );
229 attacker
.owner
->statEnemyShipsDestroyed( 1 );
232 if( defender
.shipCount() <= 0 ) {
239 defenderPlanet
.player()->statEnemyFleetsDestroyed(1);
240 emit
gameMsg(ki18n("Planet %2 has held against an attack from %1."),
241 attacker
.owner
, &defenderPlanet
);
243 Player
*defender
= defenderPlanet
.player();
244 attacker
.owner
->statEnemyFleetsDestroyed( 1 );
246 defenderPlanet
.conquer( &attacker
);
248 emit
gameMsg(ki18n("Planet %2 has fallen to %1."),
249 attacker
.owner
, &defenderPlanet
, defender
);
255 //************************************************************************
256 // Set up the game board for a new game
257 //************************************************************************
261 GameLogic::startNewGame()
263 // Setup for a new game to start playing.
264 m_currentPlayer
= m_players
.begin();
269 //************************************************************************
270 // Shut down the current game
271 //************************************************************************
274 GameLogic::cleanupGame()
283 // The current player has done its orders, and it's the next players
288 GameLogic::nextPlayer()
290 foreach (Planet
*planet
, m_planets
) {
291 if(planet
->player() == *m_currentPlayer
) {
292 planet
->showOldShips();
295 // End turn and advance to next player.
298 } while ( m_currentPlayer
!= m_players
.end()
299 && !(*m_currentPlayer
)->isInPlay() );
301 if( m_currentPlayer
== m_players
.end() ) {
304 // end of player list, new turn
305 m_currentPlayer
= m_players
.begin();