Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AI Attack & getSpellAbilityToPlay Timeout #6577

Open
wants to merge 50 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 43 commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
e2c37d1
AI Attack Timeout
kevlahnota Nov 14, 2024
8dbb648
add user setting for AI Timeout
kevlahnota Nov 14, 2024
66c08ab
try to fix unsupportedoperation
kevlahnota Nov 14, 2024
37eed29
try this multimap for manapool
kevlahnota Nov 15, 2024
a988261
check for stack only
kevlahnota Nov 15, 2024
8a1d25e
fix failing test
kevlahnota Nov 15, 2024
fc85623
better to use a linkedqueue
kevlahnota Nov 15, 2024
4936fd3
remove comment, seems it works fine. need to test on android.
kevlahnota Nov 15, 2024
a094149
remove redundant check for can cast timing
kevlahnota Nov 15, 2024
b9a56f0
revert multimap, needs better implementation for this
kevlahnota Nov 15, 2024
d9c4c81
Merge branch 'master' into AI_ATTACK_TIMEOUT
kevlahnota Nov 15, 2024
f52b7ab
create ConcurrentMultiMap, remove unused map
kevlahnota Nov 15, 2024
5c46048
removed unused import
kevlahnota Nov 15, 2024
7c35968
try to fix ConcurrentModificationException on FCollection -> addAll
kevlahnota Nov 15, 2024
548f97a
dumb check for AI
kevlahnota Nov 15, 2024
acfde12
Merge branch 'master' into AI_ATTACK_TIMEOUT
kevlahnota Nov 16, 2024
0247acb
Merge branch 'master' into AI_ATTACK_TIMEOUT
kevlahnota Nov 16, 2024
cb64567
Merge branch 'master' into AI_ATTACK_TIMEOUT
kevlahnota Nov 16, 2024
54266e8
Merge branch 'master' into AI_ATTACK_TIMEOUT
kevlahnota Nov 16, 2024
1261332
Update PlayEffect.java
kevlahnota Nov 16, 2024
f72ab6f
use removeall
kevlahnota Nov 16, 2024
6c847e0
refactor AiCardMemory
kevlahnota Nov 16, 2024
f6d2d42
use anymatch
kevlahnota Nov 16, 2024
5dc84a6
remove threadsafeIterable
kevlahnota Nov 17, 2024
619130b
remove unused import
kevlahnota Nov 17, 2024
39fc141
Merge branch 'master' into AI_ATTACK_TIMEOUT
kevlahnota Nov 18, 2024
0854fbb
update FCollection
kevlahnota Nov 19, 2024
065f6b9
Merge remote-tracking branch 'origin/AI_ATTACK_TIMEOUT' into AI_ATTAC…
kevlahnota Nov 19, 2024
12ae996
Merge branch 'master' into AI_ATTACK_TIMEOUT
kevlahnota Nov 19, 2024
8177776
add ManaPoolTest
kevlahnota Nov 20, 2024
e23b3b9
Merge remote-tracking branch 'origin/AI_ATTACK_TIMEOUT' into AI_ATTAC…
kevlahnota Nov 20, 2024
27740be
Merge branch 'master' into AI_ATTACK_TIMEOUT
kevlahnota Nov 21, 2024
dda5afe
refactor ManaPool
kevlahnota Nov 21, 2024
259247c
update ManaMultiMap clear
kevlahnota Nov 21, 2024
3d42da9
add persistentmana check
kevlahnota Nov 21, 2024
f01d03e
Merge branch 'master' into AI_ATTACK_TIMEOUT
kevlahnota Nov 21, 2024
afb062e
revert ManaPool
kevlahnota Nov 22, 2024
f918ae5
Merge branch 'master' into AI_ATTACK_TIMEOUT
kevlahnota Nov 22, 2024
7c3354c
Merge remote-tracking branch 'origin/AI_ATTACK_TIMEOUT' into AI_ATTAC…
kevlahnota Nov 22, 2024
69fef79
refactor timeout
kevlahnota Nov 22, 2024
8486dbb
Merge branch 'master' into AI_ATTACK_TIMEOUT
kevlahnota Nov 22, 2024
78e587b
handle exception
kevlahnota Nov 22, 2024
0b9fb9f
Merge remote-tracking branch 'origin/AI_ATTACK_TIMEOUT' into AI_ATTAC…
kevlahnota Nov 22, 2024
b041142
use Executor, update MatchScreen
kevlahnota Nov 23, 2024
8fa95a0
update arrows
kevlahnota Nov 23, 2024
08bab22
refactor lazy initialization
kevlahnota Nov 25, 2024
8fa1ce1
Merge branch 'master' into AI_ATTACK_TIMEOUT
kevlahnota Nov 25, 2024
e1d7c4a
use Guava memoize
kevlahnota Nov 25, 2024
c317d1f
Merge remote-tracking branch 'origin/AI_ATTACK_TIMEOUT' into AI_ATTAC…
kevlahnota Nov 25, 2024
486e8d3
Merge branch 'master' into AI_ATTACK_TIMEOUT
kevlahnota Nov 28, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
293 changes: 155 additions & 138 deletions forge-ai/src/main/java/forge/ai/AiAttackController.java

Large diffs are not rendered by default.

154 changes: 30 additions & 124 deletions forge-ai/src/main/java/forge/ai/AiCardMemory.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@

package forge.ai;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import forge.game.card.Card;
import forge.game.player.Player;

Expand Down Expand Up @@ -62,75 +64,26 @@ public enum MemorySet {
REVEALED_CARDS // These cards were recently revealed to the AI by a call to PlayerControllerAi.reveal
}

private final Set<Card> memMandatoryAttackers;
private final Set<Card> memTrickAttackers;
private final Set<Card> memHeldManaSources;
private final Set<Card> memHeldManaSourcesForCombat;
private final Set<Card> memHeldManaSourcesForEnemyCombat;
private final Set<Card> memHeldManaSourcesForNextSpell;
private final Set<Card> memAttachedThisTurn;
private final Set<Card> memAnimatedThisTurn;
private final Set<Card> memBouncedThisTurn;
private final Set<Card> memActivatedThisTurn;
private final Set<Card> memChosenFogEffect;
private final Set<Card> memMarkedToAvoidReentry;
private final Set<Card> memPaysTapCost;
private final Set<Card> memPaysSacCost;
private final Set<Card> memRevealedCards;
private Map<MemorySet, Set<Card>> _memoryMap;
private Map<MemorySet, Set<Card>> memoryMap() {
Map<MemorySet, Set<Card>> result = _memoryMap;
if (result == null) {
synchronized (this) {
result = _memoryMap;
if (result == null) {
result = Maps.newConcurrentMap();
_memoryMap = result;
}
}
}
return _memoryMap;
}

public AiCardMemory() {
Hanmac marked this conversation as resolved.
Show resolved Hide resolved
this.memMandatoryAttackers = new HashSet<>();
this.memHeldManaSources = new HashSet<>();
this.memHeldManaSourcesForCombat = new HashSet<>();
this.memHeldManaSourcesForEnemyCombat = new HashSet<>();
this.memAttachedThisTurn = new HashSet<>();
this.memAnimatedThisTurn = new HashSet<>();
this.memBouncedThisTurn = new HashSet<>();
this.memActivatedThisTurn = new HashSet<>();
this.memTrickAttackers = new HashSet<>();
this.memChosenFogEffect = new HashSet<>();
this.memMarkedToAvoidReentry = new HashSet<>();
this.memHeldManaSourcesForNextSpell = new HashSet<>();
this.memPaysTapCost = new HashSet<>();
this.memPaysSacCost = new HashSet<>();
this.memRevealedCards = new HashSet<>();
}

private Set<Card> getMemorySet(MemorySet set) {
switch (set) {
case MANDATORY_ATTACKERS:
return memMandatoryAttackers;
case TRICK_ATTACKERS:
return memTrickAttackers;
case HELD_MANA_SOURCES_FOR_MAIN2:
return memHeldManaSources;
case HELD_MANA_SOURCES_FOR_DECLBLK:
return memHeldManaSourcesForCombat;
case HELD_MANA_SOURCES_FOR_ENEMY_DECLBLK:
return memHeldManaSourcesForEnemyCombat;
case HELD_MANA_SOURCES_FOR_NEXT_SPELL:
return memHeldManaSourcesForNextSpell;
case ATTACHED_THIS_TURN:
return memAttachedThisTurn;
case ANIMATED_THIS_TURN:
return memAnimatedThisTurn;
case BOUNCED_THIS_TURN:
return memBouncedThisTurn;
case ACTIVATED_THIS_TURN:
return memActivatedThisTurn;
case CHOSEN_FOG_EFFECT:
return memChosenFogEffect;
case MARKED_TO_AVOID_REENTRY:
return memMarkedToAvoidReentry;
case PAYS_TAP_COST:
return memPaysTapCost;
case PAYS_SAC_COST:
return memPaysSacCost;
case REVEALED_CARDS:
return memRevealedCards;
default:
return null;
}
return memoryMap().computeIfAbsent(set, value -> Sets.newConcurrentHashSet());
}

/**
Expand All @@ -145,10 +98,7 @@ public boolean isRememberedCard(Card c, MemorySet set) {
if (c == null) {
return false;
}

Set<Card> memorySet = getMemorySet(set);

return memorySet != null && memorySet.contains(c);
return getMemorySet(set).contains(c);
}

/**
Expand All @@ -160,17 +110,7 @@ public boolean isRememberedCard(Card c, MemorySet set) {
* @return true, if at least one card with the given name is remembered in the given memory set
*/
public boolean isRememberedCardByName(String cardName, MemorySet set) {
Set<Card> memorySet = getMemorySet(set);

if (memorySet != null) {
for (Card c : memorySet) {
if (c.getName().equals(cardName)) {
return true;
}
}
}

return false;
return getMemorySet(set).stream().anyMatch(c -> c.getName().equals(cardName));
}

/**
Expand All @@ -184,17 +124,7 @@ public boolean isRememberedCardByName(String cardName, MemorySet set) {
* @return true, if at least one card with the given name is remembered in the given memory set
*/
public boolean isRememberedCardByName(String cardName, MemorySet set, Player owner) {
Set<Card> memorySet = getMemorySet(set);

if (memorySet != null) {
for (Card c : memorySet) {
if (c.getName().equals(cardName) && c.getOwner().equals(owner)) {
return true;
}
}
}

return false;
return getMemorySet(set).stream().anyMatch(c -> c.getName().equals(cardName) && c.getOwner().equals(owner));
}

/**
Expand All @@ -207,14 +137,7 @@ public boolean isRememberedCardByName(String cardName, MemorySet set, Player own
public boolean rememberCard(Card c, MemorySet set) {
if (c == null)
return false;

Set<Card> memorySet = getMemorySet(set);

if (memorySet != null) {
memorySet.add(c);
}

return true;
return getMemorySet(set).add(c);
}

/**
Expand All @@ -231,14 +154,7 @@ public boolean forgetCard(Card c, MemorySet set) {
if (!isRememberedCard(c, set)) {
return false;
}

Set<Card> memorySet = getMemorySet(set);

if (memorySet != null) {
memorySet.remove(c);
}

return true;
return getMemorySet(set).remove(c);
}

/**
Expand All @@ -249,16 +165,11 @@ public boolean forgetCard(Card c, MemorySet set) {
* @return true, if at least one card with the given name was previously remembered in the given memory set and was successfully forgotten
*/
public boolean forgetAnyCardWithName(String cardName, MemorySet set) {
Set<Card> memorySet = getMemorySet(set);

if (memorySet != null) {
for (Card c : memorySet) {
if (c.getName().equals(cardName)) {
return forgetCard(c, set);
}
for (Card c : getMemorySet(set)) {
if (c.getName().equals(cardName)) {
return forgetCard(c, set);
}
}

return false;
}

Expand All @@ -271,16 +182,11 @@ public boolean forgetAnyCardWithName(String cardName, MemorySet set) {
* @return true, if at least one card with the given name was previously remembered in the given memory set and was successfully forgotten
*/
public boolean forgetAnyCardWithName(String cardName, MemorySet set, Player owner) {
Set<Card> memorySet = getMemorySet(set);

if (memorySet != null) {
for (Card c : memorySet) {
if (c.getName().equals(cardName) && c.getOwner().equals(owner)) {
return forgetCard(c, set);
}
for (Card c : getMemorySet(set)) {
if (c.getName().equals(cardName) && c.getOwner().equals(owner)) {
return forgetCard(c, set);
}
}

return false;
}

Expand Down Expand Up @@ -374,4 +280,4 @@ public static boolean isMemorySetEmpty(Player ai, MemorySet set) {
public static boolean isMemorySetEmpty(AiController aic, MemorySet set) {
return aic.getCardMemory().isMemorySetEmpty(set);
}
}
}
Loading
Loading