From 606deb8813068c04d1f413caab45cfbc7390381a Mon Sep 17 00:00:00 2001 From: WCSumpton Date: Fri, 29 Sep 2023 13:04:00 -0400 Subject: [PATCH] isAI to check AI controlled players. (#11979) isAI added to RulesAttachment to allow for checking of AI controlled players. isAI values: true/false, check if the player is AI controlled. Can be used with the players option. --- .../triplea/attachments/RulesAttachment.java | 37 ++++++++ .../attachments/RulesAttachmentTest.java | 86 +++++++++++++++++++ 2 files changed, 123 insertions(+) create mode 100644 game-app/game-core/src/test/java/games/strategy/triplea/attachments/RulesAttachmentTest.java diff --git a/game-app/game-core/src/main/java/games/strategy/triplea/attachments/RulesAttachment.java b/game-app/game-core/src/main/java/games/strategy/triplea/attachments/RulesAttachment.java index 1908d9db9cc..7fa82e707ba 100644 --- a/game-app/game-core/src/main/java/games/strategy/triplea/attachments/RulesAttachment.java +++ b/game-app/game-core/src/main/java/games/strategy/triplea/attachments/RulesAttachment.java @@ -37,6 +37,7 @@ import java.util.Set; import java.util.function.Predicate; import javax.annotation.Nullable; +import org.jetbrains.annotations.VisibleForTesting; import org.triplea.java.Interruptibles; import org.triplea.java.collections.CollectionUtils; import org.triplea.java.collections.IntegerMap; @@ -55,6 +56,8 @@ public class RulesAttachment extends AbstractPlayerRulesAttachment { private int techCount = -1; // condition for having specific relationships private @Nullable List relationship = null; + // condition for checking AI player + private @Nullable Boolean isAI = null; // condition for being at war private @Nullable Set atWarPlayers = null; private int atWarCount = -1; @@ -489,6 +492,23 @@ private void resetUnitPresence() { unitPresence = null; } + @VisibleForTesting + public void setIsAI(final String s) { + isAI = (s == null) ? null : getBool(s); + } + + private void setIsAI(final Boolean s) { + isAI = s; + } + + public Boolean getIsAI() { + return isAI; + } + + private void resetIsAI() { + isAI = null; + } + private int getAtWarCount() { return atWarCount; } @@ -735,11 +755,17 @@ public boolean isSatisfied( } objectiveMet = checkDirectOwnership(listedTerritories, players); } + // check for AI controlled player + if (objectiveMet && getIsAI() != null) { + objectiveMet = checkIsAI(players); + } // get attached to player final GamePlayer playerAttachedTo = (GamePlayer) getAttachedTo(); + // check for players at war if (objectiveMet && !getAtWarPlayers().isEmpty()) { objectiveMet = checkAtWar(playerAttachedTo, getAtWarPlayers(), getAtWarCount()); } + // check for techs if (objectiveMet && !getTechs().isEmpty()) { objectiveMet = checkTechs(playerAttachedTo, data.getTechnologyFrontier()); } @@ -1001,6 +1027,15 @@ private boolean matchTerritories( return numberMet >= getTerritoryCount(); } + @VisibleForTesting + public boolean checkIsAI(final List players) { + boolean bcheck = true; + for (GamePlayer player : players) { + bcheck = (bcheck && (getIsAI() == player.isAi())); + } + return bcheck; + } + private boolean checkAtWar( final GamePlayer player, final Set enemies, final int count) { int found = CollectionUtils.countMatches(enemies, player::isAtWar); @@ -1057,6 +1092,8 @@ public MutableProperty getPropertyOrNull(String propertyName) { this::setRelationship, this::getRelationship, this::resetRelationship); + case "isAI": + return MutableProperty.of(this::setIsAI, this::setIsAI, this::getIsAI, this::resetIsAI); case "atWarPlayers": return MutableProperty.of( this::setAtWarPlayers, diff --git a/game-app/game-core/src/test/java/games/strategy/triplea/attachments/RulesAttachmentTest.java b/game-app/game-core/src/test/java/games/strategy/triplea/attachments/RulesAttachmentTest.java new file mode 100644 index 00000000000..23bd588cc55 --- /dev/null +++ b/game-app/game-core/src/test/java/games/strategy/triplea/attachments/RulesAttachmentTest.java @@ -0,0 +1,86 @@ +package games.strategy.triplea.attachments; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.lenient; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import games.strategy.engine.data.GameData; +import games.strategy.engine.data.GamePlayer; +import games.strategy.engine.data.PlayerList; +import java.util.List; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +class RulesAttachmentTest { + + @Mock private PlayerList playerList; + + private final GameData gameData = mock(GameData.class); + + private final RulesAttachment attachment = new RulesAttachment("Test attachment", null, gameData); + + @Mock private GamePlayer player1; + @Mock private GamePlayer player2; + @Mock private GamePlayer player3; + @Mock private GamePlayer player4; + + @BeforeEach + void setUp() { + when(gameData.getPlayerList()).thenReturn(playerList); + } + + /* Testing stored getIsAI values with setIsAI */ + @Test + void isAITest() { + attachment.setIsAI("true"); + assertTrue(attachment.getIsAI()); + attachment.setIsAI("false"); + assertFalse(attachment.getIsAI()); + } + + /* Testing returned values for checkGetIsAI */ + @Test + void checkGetIsAITest() { + lenient().when(player1.isAi()).thenReturn(false); + lenient().when(player2.isAi()).thenReturn(true); + lenient().when(player3.isAi()).thenReturn(true); + lenient().when(player4.isAi()).thenReturn(false); + + /* Testing with 1 non AI player */ + final List players1 = List.of(player1); + attachment.setIsAI("true"); + assertFalse(attachment.checkIsAI(players1)); + attachment.setIsAI("false"); + assertTrue(attachment.checkIsAI(players1)); + /* Testing with 1 AI player */ + final List players2 = List.of(player2); + attachment.setIsAI("true"); + assertTrue(attachment.checkIsAI(players2)); + attachment.setIsAI("false"); + assertFalse(attachment.checkIsAI(players2)); + /* Testing with 1 non AI player and 1 AI player */ + final List players12 = List.of(player1, player2); + attachment.setIsAI("true"); + assertFalse(attachment.checkIsAI(players12)); + attachment.setIsAI("false"); + assertFalse(attachment.checkIsAI(players12)); + /* Testing with 2 AI players */ + final List players23 = List.of(player2, player3); + attachment.setIsAI("true"); + assertTrue(attachment.checkIsAI(players23)); + attachment.setIsAI("false"); + assertFalse(attachment.checkIsAI(players23)); + /* Testing with 2 non AI players */ + final List players14 = List.of(player1, player4); + attachment.setIsAI("true"); + assertFalse(attachment.checkIsAI(players14)); + attachment.setIsAI("false"); + assertTrue(attachment.checkIsAI(players14)); + } +}