use of mage.players.Player in project mage by magefree.
the class HumanPlayer method chooseTargetAmount.
@Override
public boolean chooseTargetAmount(Outcome outcome, TargetAmount target, Ability source, Game game) {
// human can choose or un-choose MULTIPLE targets at once
if (gameInCheckPlayableState(game)) {
return true;
}
UUID abilityControllerId = playerId;
if (target.getAbilityController() != null) {
abilityControllerId = target.getAbilityController();
}
int amountTotal = target.getAmountTotal(game, source);
// 1. Select targets
while (canRespond()) {
Set<UUID> possibleTargets = target.possibleTargets(source == null ? null : source.getSourceId(), abilityControllerId, game);
boolean required = target.isRequired(source != null ? source.getSourceId() : null, game);
if (possibleTargets.isEmpty() || target.getSize() >= target.getNumberOfTargets()) {
required = false;
}
// selected
Map<String, Serializable> options = getOptions(target, null);
java.util.List<UUID> chosen = target.getTargets();
options.put("chosen", (Serializable) chosen);
// selectable
java.util.List<UUID> choosable = new ArrayList<>();
for (UUID targetId : possibleTargets) {
if (target.canTarget(abilityControllerId, targetId, source, game)) {
choosable.add(targetId);
}
}
if (!choosable.isEmpty()) {
options.put("choosable", (Serializable) choosable);
}
// if nothing to choose then show dialog (user must see non selectable items and click on any of them)
if (required && choosable.isEmpty()) {
required = false;
}
updateGameStatePriority("chooseTargetAmount", game);
prepareForResponse(game);
if (!isExecutingMacro()) {
// target amount uses for damage only, if you see another use case then message must be changed here and on getMultiAmount call
String message = String.format("Select targets to distribute %d damage (selected %d)", amountTotal, target.getTargets().size());
game.fireSelectTargetEvent(playerId, new MessageToClient(message, getRelatedObjectName(source, game)), possibleTargets, required, options);
}
waitForResponse(game);
UUID responseId = getFixedResponseUUID(game);
if (responseId != null) {
if (target.contains(responseId)) {
// unselect
target.remove(responseId);
} else if (possibleTargets.contains(responseId) && target.canTarget(abilityControllerId, responseId, source, game)) {
// select
target.addTarget(responseId, source, game);
}
} else if (!required) {
break;
}
}
// no targets to choose or disconnected
List<UUID> targets = target.getTargets();
if (targets.isEmpty()) {
return false;
}
// 2. Distribute amount between selected targets
// prepare targets list with p/t or life stats (cause that's dialog used for damage distribute)
List<String> targetNames = new ArrayList<>();
for (UUID targetId : targets) {
MageObject targetObject = game.getObject(targetId);
if (targetObject != null) {
targetNames.add(String.format("%s, P/T: %d/%d", targetObject.getIdName(), targetObject.getPower().getValue(), targetObject.getToughness().getValue()));
} else {
Player player = game.getPlayer(targetId);
if (player != null) {
targetNames.add(String.format("%s, life: %d", player.getName(), player.getLife()));
} else {
targetNames.add("ERROR, unknown target " + targetId.toString());
}
}
}
// ask and assign new amount
List<Integer> targetValues = getMultiAmount(outcome, targetNames, 1, amountTotal, MultiAmountType.DAMAGE, game);
for (int i = 0; i < targetValues.size(); i++) {
int newAmount = targetValues.get(i);
UUID targetId = targets.get(i);
if (newAmount <= 0) {
// remove target
target.remove(targetId);
} else {
// set amount
target.setTargetAmount(targetId, newAmount, source, game);
}
}
return true;
}
use of mage.players.Player in project mage by magefree.
the class ComputerPlayerMCTS method logLife.
protected void logLife(Game game) {
StringBuilder sb = new StringBuilder();
sb.append(game.getTurn().getValue(game.getTurnNum()));
for (Player player : game.getPlayers().values()) {
sb.append("[player ").append(player.getName()).append(':').append(player.getLife()).append(']');
}
logger.info(sb.toString());
}
use of mage.players.Player in project mage by magefree.
the class MCTSNode method createSimulation.
/**
* Copies game and replaces all players in copy with simulated players
* Shuffles each players library so that there is no knowledge of its order
*
* @param game
* @return a new game object with simulated players
*/
protected Game createSimulation(Game game, UUID playerId) {
Game sim = game.copy();
for (Player oldPlayer : sim.getState().getPlayers().values()) {
Player origPlayer = game.getState().getPlayers().get(oldPlayer.getId()).copy();
SimulatedPlayerMCTS newPlayer = new SimulatedPlayerMCTS(oldPlayer, true);
newPlayer.restore(origPlayer);
sim.getState().getPlayers().put(oldPlayer.getId(), newPlayer);
}
randomizePlayers(sim, playerId);
sim.setSimulation(true);
return sim;
}
use of mage.players.Player in project mage by magefree.
the class MCTSNode method randomizePlayers.
/*
* Shuffles each players library so that there is no knowledge of its order
* Swaps all other players hands with random cards from the library so that
* there is no knowledge of what cards are in opponents hands
*/
protected void randomizePlayers(Game game, UUID playerId) {
for (Player player : game.getState().getPlayers().values()) {
if (!player.getId().equals(playerId)) {
int handSize = player.getHand().size();
player.getLibrary().addAll(player.getHand().getCards(game), game);
player.getHand().clear();
player.getLibrary().shuffle();
for (int i = 0; i < handSize; i++) {
Card card = player.getLibrary().removeFromTop(game);
card.setZone(Zone.HAND, game);
player.getHand().add(card);
}
} else {
player.getLibrary().shuffle();
}
}
}
use of mage.players.Player in project mage by magefree.
the class SimulatedPlayerMCTS method assignDamage.
@Override
public void assignDamage(int damage, List<UUID> targets, String singleTargetName, UUID attackerId, Ability source, Game game) {
if (this.isHuman()) {
int remainingDamage = damage;
UUID targetId;
int amount;
while (remainingDamage > 0) {
if (targets.size() == 1) {
targetId = targets.get(0);
amount = remainingDamage;
} else {
targetId = targets.get(RandomUtil.nextInt(targets.size()));
amount = RandomUtil.nextInt(damage + 1);
}
Permanent permanent = game.getPermanent(targetId);
if (permanent != null) {
permanent.damage(amount, attackerId, source, game, false, true);
remainingDamage -= amount;
} else {
Player player = game.getPlayer(targetId);
if (player != null) {
player.damage(amount, attackerId, source, game);
remainingDamage -= amount;
}
}
targets.remove(targetId);
}
} else {
super.assignDamage(damage, targets, singleTargetName, attackerId, source, game);
}
}
Aggregations