package mage.utils.testers; import mage.abilities.Ability; import mage.constants.MultiAmountType; import mage.constants.Outcome; import mage.game.Game; import mage.players.Player; import mage.util.DebugUtil; import mage.util.MultiAmountMessage; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; import java.util.stream.IntStream; /** * Part of testable game dialogs *

* Its simple dialog to get distributed value between multiple options (example: part of combat damage distributing) *

* Supported methods: * - player.getMultiAmountWithIndividualConstraints() * - player.getMultiAmount() - simple version of constraints * * @author JayDi85 */ class GetMultiAmountTestableDialog extends BaseTestableDialog { boolean isYou; // who choose - you or opponent int totalMin; int totalMax; List amountOptions = new ArrayList<>(); /** * @param options min, max, default */ public GetMultiAmountTestableDialog(boolean isYou, String info, int totalMin, int totalMax, List> options) { super(String.format("player.getMultiAmount(%s)", isYou ? "you" : "AI"), String.format("%s, %d options from [%d-%d]", info, options.size(), totalMin, totalMax), "", new MultiAmountTestableResult() ); this.isYou = isYou; this.totalMin = totalMin; this.totalMax = totalMax; int optionNumber = 0; for (List single : options) { optionNumber++; String mes = "option " + optionNumber + " with html"; this.amountOptions.add(new MultiAmountMessage(mes, single.get(0), single.get(1), single.get(2))); } } private GetMultiAmountTestableDialog aiMustChoose(Integer... needValues) { // TODO: AI use default distribution (min possible values), improve someday MultiAmountTestableResult res = ((MultiAmountTestableResult) this.getResult()); res.aiAssertEnabled = true; res.aiAssertValues = Arrays.stream(needValues).collect(Collectors.toList()); return this; } private GetMultiAmountTestableDialog aiMustChooseMany(Integer options, Integer perOption) { List need = new ArrayList<>(); IntStream.rangeClosed(1, options).forEach(x -> { need.add(perOption); }); MultiAmountTestableResult res = ((MultiAmountTestableResult) this.getResult()); res.aiAssertEnabled = true; res.aiAssertValues = need; return this; } @Override public void showDialog(Player player, Ability source, Game game, Player opponent) { Player choosingPlayer = this.isYou ? player : opponent; //String message = "message with html"; List options = this.amountOptions.stream().map(MultiAmountMessage::copy).collect(Collectors.toList()); String chooseDebugSource = DebugUtil.getMethodNameWithSource(0, "class"); List chooseRes = choosingPlayer.getMultiAmountWithIndividualConstraints( Outcome.Benefit, options, this.totalMin, this.totalMax, MultiAmountType.DAMAGE, game ); List res = new ArrayList<>(); res.add(getGroup() + " - " + this.getName()); int selectedIndex = -1; int selectedTotal = 0; for (Integer selectedValue : chooseRes) { selectedIndex++; selectedTotal += selectedValue; MultiAmountMessage option = this.amountOptions.get(selectedIndex); res.add(String.format("%d from [%d-%d, def %d]", selectedValue, option.min, option.max, option.defaultValue )); } res.add("total selected: " + selectedTotal); ((MultiAmountTestableResult) this.getResult()).onFinish(chooseDebugSource, true, res, chooseRes); } static public void register(TestableDialogsRunner runner) { List isYous = Arrays.asList(false, true); for (boolean isYou : isYous) { // make sure default values are valid due min/max settings // TODO: add bad effect for AI (must test default distribution) // single target runner.registerDialog(new GetMultiAmountTestableDialog(isYou, "one, 0 def", 0, 1, genSameOptions(1, 0, 1, 0)).aiMustChoose(1)); runner.registerDialog(new GetMultiAmountTestableDialog(isYou, "one, 0 def", 0, 3, genSameOptions(1, 0, 3, 0)).aiMustChoose(3)); runner.registerDialog(new GetMultiAmountTestableDialog(isYou, "one, 1 def", 1, 1, genSameOptions(1, 1, 1, 1)).aiMustChoose(1)); runner.registerDialog(new GetMultiAmountTestableDialog(isYou, "one, 1 def", 1, 3, genSameOptions(1, 1, 3, 1)).aiMustChoose(3)); runner.registerDialog(new GetMultiAmountTestableDialog(isYou, "one, 5 def", 0, 10, genSameOptions(1, 0, 10, 5)).aiMustChoose(10)); runner.registerDialog(new GetMultiAmountTestableDialog(isYou, "one, 10 def", 10, 10, genSameOptions(1, 0, 10, 10)).aiMustChoose(10)); // multiple targets runner.registerDialog(new GetMultiAmountTestableDialog(isYou, "many, 0 def", 0, 5, genSameOptions(3, 0, 3, 0)).aiMustChoose(2, 2, 1)); runner.registerDialog(new GetMultiAmountTestableDialog(isYou, "many, 1 def", 1, 5, genSameOptions(3, 1, 3, 1)).aiMustChoose(2, 2, 1)); runner.registerDialog(new GetMultiAmountTestableDialog(isYou, "many, 20 def", 0, 60, genSameOptions(3, 0, 60, 20)).aiMustChoose(20, 20, 20)); runner.registerDialog(new GetMultiAmountTestableDialog(isYou, "many, 20 def", 60, 60, genSameOptions(3, 0, 60, 20)).aiMustChoose(20, 20, 20)); // big lists runner.registerDialog(new GetMultiAmountTestableDialog(isYou, "big list", 0, 100, genSameOptions(20, 0, 100, 0)).aiMustChooseMany(20, 5)); runner.registerDialog(new GetMultiAmountTestableDialog(isYou, "big list", 0, 100, genSameOptions(100, 0, 100, 0)).aiMustChooseMany(100, 1)); } } private static List> genSameOptions(int options, int min, int max, int def) { List> res = new ArrayList<>(); for (int i = 0; i < options; i++) { // min, max, default res.add(Arrays.asList(min, max, def)); } return res; } }