Close the last remaining soundness hole in the tactical overlay

It is not entirely clear whether or not this is a good change, as it
makes the algorithm significantly more conservative. In situations where
the player is confident they will not be bombed (perhaps because the
opponent cannot have a stellar bomb available), it may feel
frustratingly so. But I am going to give it a try and see if it feels
okay or not in practice, and I can change it later if it proves
annoying.
This commit is contained in:
Alexis King 2022-12-13 16:14:08 -06:00
parent b628a24ca0
commit ef83deb8fd
3 changed files with 22 additions and 3 deletions

View File

@ -1,8 +1,12 @@
## 0.0.7 (not yet released)
* Systems that are threatened by a neighboring hostile force are now overlaid with orange cross-hatching instead of yellow cross-hatching. Yellow cross-hatching is now used exclusively for systems at risk of collapse due to insufficient garrison.
* Several improvements have been made to the tactical overlay:
* The bright yellow cross-hatching used to indicate systems at risk of immediate collapse is now applied more consistently and accurately. Previously, some systems could be shaded with faded yellow cross-hatching even though they were at risk of immediate collapse, but now dim yellow cross-hatching is only applied to systems at risk of collapse due to a chain reaction.
* Systems that are threatened by a neighboring hostile force are now overlaid with orange hatching instead of yellow hatching. Yellow hatching is now used exclusively for systems at risk of collapse due to insufficient garrison.
* The bright yellow hatching used to indicate systems at risk of immediate collapse is now applied more consistently and accurately. Previously, some systems could be shaded with faded yellow hatching even though they were at risk of immediate collapse, but now dim yellow hatching is only applied to systems at risk of collapse due to a chain reaction.
* Fleet movements out of systems that are at risk of being stellar bombed no longer count towards the worst-case garrison calculation and therefore will not eliminate yellow or red hatching on their destination system. With this change, the absence of any hatching on a system provides a true guarantee that the system will not be lost.
* While placing a terraforming project, resources that are currently in surplus are colored green in the production panel, and systems that only provide a single unit of that resource (and provide no other resources) are highlighted green on the map.

View File

@ -43,3 +43,5 @@ One important property that follows from the above is that there is almost alway
### The tactical overlay and stellar bombs
Because stellar bombs prevent all fleet movements out of the target system for a turn, deploying a stellar bomb can affect the tactical overlay. Most significantly, if a system you control is only bordered by one hostile system, deploying a stellar bomb on that system will eliminate the **orange** hatching on the adjacent system! This is in fact the *only* way to remove such hatching, so although it may be counterintuitive, the most valuable way to use a stellar bomb may be defensive rather than offensive.
Note, however, that this ability cuts both ways: fleet movements out of any system at risk of being stellar bombed may be canceled. Therefore, such fleet movements do not count towards the worst-case garrison calculation and will not eliminate hatching on their destination system. This can be somewhat counterintuitive, but erring on the side of caution ensures that the absence of any hatching on a system is a true guarantee that the system will not be lost.

View File

@ -24,6 +24,12 @@ public final class TacticalAnalysis {
*/
private final boolean[] systemThreatened;
/**
* {@code true} for systems that could be the target of a stellar bomb on
* this turn.
*/
private final boolean[] systemBombable;
/**
* {@code true} for systems that the local player is <i>guaranteed</i> to own
* after this turn. Implies {@link #systemCanOwn}.
@ -80,6 +86,7 @@ public final class TacticalAnalysis {
public TacticalAnalysis(final int systemCount) {
this.systemThreatened = new boolean[systemCount];
this.systemBombable = new boolean[systemCount];
this.systemCanOwn = new boolean[systemCount];
this.systemWillOwn = new boolean[systemCount];
this.guaranteedCollapseWave = new int[systemCount];
@ -128,11 +135,17 @@ public final class TacticalAnalysis {
this.minGarrisonAtTurnEnd[system.index] = 0;
}
this.systemBombable[system.index] = Arrays.stream(system.neighbors)
.anyMatch(neighbor -> neighbor.owner != null
&& system.owner != neighbor.owner
&& (system.owner == null || !neighbor.owner.allies[system.owner.index]));
for (final MoveFleetsOrder incomingOrder : system.incomingOrders) {
if (incomingOrder.player == localPlayer) {
this.maxGarrisonAtTurnEnd[system.index] += incomingOrder.quantity;
this.systemCanOwn[system.index] = true;
if (incomingOrder.target.owner == localPlayer || incomingOrder.target.garrison == 0) {
if ((incomingOrder.target.owner == localPlayer || incomingOrder.target.garrison == 0)
&& !this.systemBombable[incomingOrder.source.index]) {
this.minGarrisonAtTurnEnd[system.index] += incomingOrder.quantity;
this.systemWillOwn[system.index] = true;
}