The while loop is where the combat occurs. cas0 and cas9 are the casualties inflicted per round with tcas0 and tcas9 being total casualties incurred on both sides. For each ship in fleet0
if (Random(100)<= p0)
cas9++;
Roll a random 100 sided dice and if its less than or equal to the chance of a casualty (p0- which is 50-80%) one ship is destroyed. This is done for both sides. The battle ends when one or both sides has lost 50% or more of the original forces.
Casualties are removed by the function RemoveCasualties(). This walks through all fleets of the affected player at the system in question. One casualty is deducted from each fleet so if you had four fleets with twelve casualties, three would be removed from each, except for those fleets with two or less ships. If a fleet is destroyed, then its turns, numships and destination are cleared.
After the battle, the last step is deciding who won and returning 0 or 9. The survivors of the losing fleets are retreated through a call to retreat() that takes the from member of each retreating force and makes it the to. The return turns are recalculated and off it goes.
Capturing Systems
The AttackSystem(function is very similar to DoOneonOne() but has minor differences in that:
- Defenders get 10% bonus,
- The defenders must be fully wiped out to capture the system. No retreat!
If the system is captured, the attackers ships are moved into orbit as the new defenders, there's a check to see if the game is over and various messages are output. Failed attackers retreat once 50% or more casualties occur. The idea is to make it need a reasonable number of ships to capture a system.
The Message System
Tactical displays are ok but don't give a real idea of what's going on. A 15 line scrolling message system outputs messages. These are output to a 100 line ring buffer and then pumped onto the display (at the bottom, scrolling up) at the rate of one per second.
A ring buffer is a block of 100 messages each a char array[120] of type message as discussed in previous tutorials. Messages are added using the msgtail index variable and the msghead index retrieves them in the function CheckMessages(), so msghead is always behind msgtail. Once msgtail or msghead reaches line 99 they wrap round to 0. This is why it's called a ring buffer.
CheckMessages() is a little messy as it outputs spaces (the printf("%66s",spaces) for empty lines at the start so the messages are displayed from the bottom. The confusing if (msghead != msgtail) deals with the situation where msghead is ahead of msgtail because msgtail has wrapped round but msghead hasn't yet.
Game Over Man!
CheckMessages() returns a one as long as there are messages to output so after the game has ended, the scrolling display continues. If you couldn't see that the Game had finished you'd think it had crashed!
Conclusion
This concludes this tutorial and on Star Empires. The next game tutorial (#4) will be on programming the game Snake.

