mirror of
https://github.com/correl/mage.git
synced 2024-12-26 03:00:11 +00:00
merge
This commit is contained in:
commit
6f844e0743
6 changed files with 93 additions and 45 deletions
|
@ -56,10 +56,8 @@ import mage.players.Player;
|
||||||
import mage.target.Target;
|
import mage.target.Target;
|
||||||
import mage.target.TargetCard;
|
import mage.target.TargetCard;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.io.File;
|
||||||
import java.util.LinkedList;
|
import java.util.*;
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -81,11 +79,15 @@ public class ComputerPlayer6 extends ComputerPlayer<ComputerPlayer6> implements
|
||||||
protected int currentScore;
|
protected int currentScore;
|
||||||
protected SimulationNode2 root;
|
protected SimulationNode2 root;
|
||||||
|
|
||||||
|
private static final String FILE_WITH_INSTRUCTIONS = "config/ai.please.cast.this.txt";
|
||||||
|
private List<String> suggested = new ArrayList<String>();
|
||||||
|
|
||||||
public ComputerPlayer6(String name, RangeOfInfluence range, int skill) {
|
public ComputerPlayer6(String name, RangeOfInfluence range, int skill) {
|
||||||
super(name, range);
|
super(name, range);
|
||||||
maxDepth = skill * 2;
|
maxDepth = skill * 2;
|
||||||
maxThink = skill * 3;
|
maxThink = skill * 3;
|
||||||
maxNodes = Config2.maxNodes;
|
maxNodes = Config2.maxNodes;
|
||||||
|
getSuggestedActions();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ComputerPlayer6(final ComputerPlayer6 player) {
|
public ComputerPlayer6(final ComputerPlayer6 player) {
|
||||||
|
@ -773,7 +775,7 @@ public class ComputerPlayer6 extends ComputerPlayer<ComputerPlayer6> implements
|
||||||
|
|
||||||
for (Player copyPlayer: sim.getState().getPlayers().values()) {
|
for (Player copyPlayer: sim.getState().getPlayers().values()) {
|
||||||
Player origPlayer = game.getState().getPlayers().get(copyPlayer.getId());
|
Player origPlayer = game.getState().getPlayers().get(copyPlayer.getId());
|
||||||
SimulatedPlayer2 newPlayer = new SimulatedPlayer2(copyPlayer.getId(), copyPlayer.getId().equals(playerId));
|
SimulatedPlayer2 newPlayer = new SimulatedPlayer2(copyPlayer.getId(), copyPlayer.getId().equals(playerId), suggested);
|
||||||
newPlayer.restore(origPlayer);
|
newPlayer.restore(origPlayer);
|
||||||
sim.getState().getPlayers().put(copyPlayer.getId(), newPlayer);
|
sim.getState().getPlayers().put(copyPlayer.getId(), newPlayer);
|
||||||
}
|
}
|
||||||
|
@ -795,4 +797,26 @@ public class ComputerPlayer6 extends ComputerPlayer<ComputerPlayer6> implements
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void getSuggestedActions() {
|
||||||
|
try {
|
||||||
|
File file = new File(FILE_WITH_INSTRUCTIONS);
|
||||||
|
if (file.exists()) {
|
||||||
|
Scanner scanner = new Scanner(file);
|
||||||
|
while (scanner.hasNextLine()) {
|
||||||
|
String line = scanner.nextLine();
|
||||||
|
if (line.startsWith("cast:") || line.startsWith("play:")) {
|
||||||
|
suggested.add(line.substring(5, line.length()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.println("suggested::");
|
||||||
|
for (int i = 0; i < suggested.size(); i++) {
|
||||||
|
System.out.println(" " + suggested.get(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
// swallow
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,12 +28,8 @@
|
||||||
|
|
||||||
package mage.player.ai;
|
package mage.player.ai;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.io.File;
|
||||||
import java.util.Collections;
|
import java.util.*;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.TriggeredAbility;
|
import mage.abilities.TriggeredAbility;
|
||||||
|
@ -43,6 +39,7 @@ import mage.abilities.costs.mana.ManaCost;
|
||||||
import mage.abilities.costs.mana.ManaCosts;
|
import mage.abilities.costs.mana.ManaCosts;
|
||||||
import mage.abilities.costs.mana.VariableManaCost;
|
import mage.abilities.costs.mana.VariableManaCost;
|
||||||
import mage.abilities.mana.ManaOptions;
|
import mage.abilities.mana.ManaOptions;
|
||||||
|
import mage.cards.Card;
|
||||||
import mage.choices.Choice;
|
import mage.choices.Choice;
|
||||||
import mage.filter.FilterAbility;
|
import mage.filter.FilterAbility;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
|
@ -50,6 +47,7 @@ import mage.game.combat.Combat;
|
||||||
import mage.game.events.GameEvent;
|
import mage.game.events.GameEvent;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
import mage.game.stack.StackAbility;
|
import mage.game.stack.StackAbility;
|
||||||
|
import mage.sets.innistrad.UnholyFiend;
|
||||||
import mage.target.Target;
|
import mage.target.Target;
|
||||||
import mage.util.Logging;
|
import mage.util.Logging;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
@ -66,10 +64,13 @@ public class SimulatedPlayer2 extends ComputerPlayer<SimulatedPlayer2> {
|
||||||
private transient ConcurrentLinkedQueue<Ability> allActions;
|
private transient ConcurrentLinkedQueue<Ability> allActions;
|
||||||
private static PassAbility pass = new PassAbility();
|
private static PassAbility pass = new PassAbility();
|
||||||
|
|
||||||
public SimulatedPlayer2(UUID id, boolean isSimulatedPlayer) {
|
private List<String> suggested;
|
||||||
|
|
||||||
|
public SimulatedPlayer2(UUID id, boolean isSimulatedPlayer, List<String> suggested) {
|
||||||
super(id);
|
super(id);
|
||||||
pass.setControllerId(playerId);
|
pass.setControllerId(playerId);
|
||||||
this.isSimulatedPlayer = isSimulatedPlayer;
|
this.isSimulatedPlayer = isSimulatedPlayer;
|
||||||
|
this.suggested = suggested;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SimulatedPlayer2(final SimulatedPlayer2 player) {
|
public SimulatedPlayer2(final SimulatedPlayer2 player) {
|
||||||
|
@ -101,6 +102,7 @@ public class SimulatedPlayer2 extends ComputerPlayer<SimulatedPlayer2> {
|
||||||
ManaOptions available = getManaAvailable(game);
|
ManaOptions available = getManaAvailable(game);
|
||||||
available.addMana(manaPool.getMana());
|
available.addMana(manaPool.getMana());
|
||||||
List<Ability> playables = game.getPlayer(playerId).getPlayable(game, filter, available, isSimulatedPlayer);
|
List<Ability> playables = game.getPlayer(playerId).getPlayable(game, filter, available, isSimulatedPlayer);
|
||||||
|
playables = filterAbilities(game, playables, suggested);
|
||||||
for (Ability ability: playables) {
|
for (Ability ability: playables) {
|
||||||
List<Ability> options = game.getPlayer(playerId).getPlayableOptions(ability, game);
|
List<Ability> options = game.getPlayer(playerId).getPlayableOptions(ability, game);
|
||||||
if (options.size() == 0) {
|
if (options.size() == 0) {
|
||||||
|
@ -141,6 +143,29 @@ public class SimulatedPlayer2 extends ComputerPlayer<SimulatedPlayer2> {
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
protected List<Ability> filterAbilities(Game game, List<Ability> playables, List<String> suggested) {
|
||||||
|
if (playables.isEmpty()) {
|
||||||
|
return playables;
|
||||||
|
}
|
||||||
|
if (suggested == null || suggested.isEmpty()) {
|
||||||
|
return playables;
|
||||||
|
}
|
||||||
|
List<Ability> filtered = new ArrayList<Ability>();
|
||||||
|
for (Ability ability : playables) {
|
||||||
|
Card card = game.getCard(ability.getSourceId());
|
||||||
|
for (String s : suggested) {
|
||||||
|
if (s.equals(card.getName())) {
|
||||||
|
System.out.println("matched: " + s);
|
||||||
|
filtered.add(ability);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!filtered.isEmpty()) {
|
||||||
|
return filtered;
|
||||||
|
}
|
||||||
|
return playables;
|
||||||
|
}
|
||||||
|
|
||||||
//add a generic mana cost for each amount possible
|
//add a generic mana cost for each amount possible
|
||||||
protected void simulateVariableCosts(Ability ability, Game game) {
|
protected void simulateVariableCosts(Ability ability, Game game) {
|
||||||
int numAvailable = getAvailableManaProducers(game).size();
|
int numAvailable = getAvailableManaProducers(game).size();
|
||||||
|
@ -276,5 +301,4 @@ public class SimulatedPlayer2 extends ComputerPlayer<SimulatedPlayer2> {
|
||||||
public void priority(Game game) {
|
public void priority(Game game) {
|
||||||
//should never get here
|
//should never get here
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
2
Mage.Server/config/ai.please.cast.this.txt.example
Normal file
2
Mage.Server/config/ai.please.cast.this.txt.example
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
play:Swamp
|
||||||
|
cast:Duress
|
Binary file not shown.
|
@ -37,12 +37,15 @@ import mage.abilities.Ability;
|
||||||
import mage.abilities.common.EntersBattlefieldAbility;
|
import mage.abilities.common.EntersBattlefieldAbility;
|
||||||
import mage.abilities.common.SimpleActivatedAbility;
|
import mage.abilities.common.SimpleActivatedAbility;
|
||||||
import mage.abilities.common.SimpleStaticAbility;
|
import mage.abilities.common.SimpleStaticAbility;
|
||||||
|
import mage.abilities.condition.common.CastFromHandCondition;
|
||||||
import mage.abilities.condition.common.HasCounterCondition;
|
import mage.abilities.condition.common.HasCounterCondition;
|
||||||
import mage.abilities.costs.common.RemoveCountersSourceCost;
|
import mage.abilities.costs.common.RemoveCountersSourceCost;
|
||||||
import mage.abilities.decorator.ConditionalContinousEffect;
|
import mage.abilities.decorator.ConditionalContinousEffect;
|
||||||
|
import mage.abilities.decorator.ConditionalOneShotEffect;
|
||||||
import mage.abilities.effects.OneShotEffect;
|
import mage.abilities.effects.OneShotEffect;
|
||||||
import mage.abilities.effects.common.DestroyAllEffect;
|
import mage.abilities.effects.common.DestroyAllEffect;
|
||||||
import mage.abilities.effects.common.continious.GainAbilitySourceEffect;
|
import mage.abilities.effects.common.continious.GainAbilitySourceEffect;
|
||||||
|
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
|
||||||
import mage.abilities.keyword.IndestructibleAbility;
|
import mage.abilities.keyword.IndestructibleAbility;
|
||||||
import mage.cards.Card;
|
import mage.cards.Card;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
|
@ -54,7 +57,6 @@ import mage.watchers.Watcher;
|
||||||
import mage.watchers.common.CastFromHandWatcher;
|
import mage.watchers.common.CastFromHandWatcher;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author Loki
|
* @author Loki
|
||||||
*/
|
*/
|
||||||
public class MyojinOfCleansingFire extends CardImpl<MyojinOfCleansingFire> {
|
public class MyojinOfCleansingFire extends CardImpl<MyojinOfCleansingFire> {
|
||||||
|
@ -77,7 +79,7 @@ public class MyojinOfCleansingFire extends CardImpl<MyojinOfCleansingFire> {
|
||||||
this.addWatcher(new CastFromHandWatcher());
|
this.addWatcher(new CastFromHandWatcher());
|
||||||
|
|
||||||
// Myojin of Cleansing Fire enters the battlefield with a divinity counter on it if you cast it from your hand.
|
// Myojin of Cleansing Fire enters the battlefield with a divinity counter on it if you cast it from your hand.
|
||||||
this.addAbility(new EntersBattlefieldAbility(new MyojinOfCleansingFireEntersBattlefieldEffect(), "{this} enters the battlefield with a divinity counter on it if you cast it from your hand"));
|
this.addAbility(new EntersBattlefieldAbility(new ConditionalOneShotEffect(new AddCountersSourceEffect(CounterType.DIVINITY.createInstance()), new CastFromHandCondition(), ""), "{this} enters the battlefield with a divinity counter on it if you cast it from your hand"));
|
||||||
// Myojin of Cleansing Fire is indestructible as long as it has a divinity counter on it.
|
// Myojin of Cleansing Fire is indestructible as long as it has a divinity counter on it.
|
||||||
this.addAbility(new SimpleStaticAbility(Constants.Zone.BATTLEFIELD, new ConditionalContinousEffect(new GainAbilitySourceEffect(IndestructibleAbility.getInstance(), Constants.Duration.WhileOnBattlefield),
|
this.addAbility(new SimpleStaticAbility(Constants.Zone.BATTLEFIELD, new ConditionalContinousEffect(new GainAbilitySourceEffect(IndestructibleAbility.getInstance(), Constants.Duration.WhileOnBattlefield),
|
||||||
new HasCounterCondition(CounterType.DIVINITY), "{this} is indestructible as long as it has a divinity counter on it")));
|
new HasCounterCondition(CounterType.DIVINITY), "{this} is indestructible as long as it has a divinity counter on it")));
|
||||||
|
@ -94,33 +96,3 @@ public class MyojinOfCleansingFire extends CardImpl<MyojinOfCleansingFire> {
|
||||||
return new MyojinOfCleansingFire(this);
|
return new MyojinOfCleansingFire(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class MyojinOfCleansingFireEntersBattlefieldEffect extends OneShotEffect<MyojinOfCleansingFireEntersBattlefieldEffect> {
|
|
||||||
MyojinOfCleansingFireEntersBattlefieldEffect() {
|
|
||||||
super(Constants.Outcome.Benefit);
|
|
||||||
}
|
|
||||||
|
|
||||||
MyojinOfCleansingFireEntersBattlefieldEffect(final MyojinOfCleansingFireEntersBattlefieldEffect effect) {
|
|
||||||
super(effect);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean apply(Game game, Ability source) {
|
|
||||||
Permanent p = game.getPermanent(source.getSourceId());
|
|
||||||
if (p != null) {
|
|
||||||
Watcher watcher = game.getState().getWatchers().get("CastFromHand", source.getSourceId());
|
|
||||||
if (watcher != null && watcher.conditionMet()) {
|
|
||||||
p.addCounters(CounterType.DIVINITY.createInstance(), game);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public MyojinOfCleansingFireEntersBattlefieldEffect copy() {
|
|
||||||
return new MyojinOfCleansingFireEntersBattlefieldEffect(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
package mage.abilities.condition.common;
|
||||||
|
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.condition.Condition;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.game.permanent.Permanent;
|
||||||
|
import mage.watchers.Watcher;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Warning: CastFromHandWatcher must be installed to card for proper working.
|
||||||
|
*
|
||||||
|
* @author Loki
|
||||||
|
*/
|
||||||
|
public class CastFromHandCondition implements Condition {
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, Ability source) {
|
||||||
|
Permanent p = game.getPermanent(source.getSourceId());
|
||||||
|
if (p != null) {
|
||||||
|
Watcher watcher = game.getState().getWatchers().get("CastFromHand", source.getSourceId());
|
||||||
|
if (watcher != null && watcher.conditionMet()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue