From 843702bd86210fb1b51ea65614563bfbf2ccc2de Mon Sep 17 00:00:00 2001 From: brodee Date: Fri, 26 Oct 2018 22:17:57 -0700 Subject: [PATCH 1/4] draftbots and afk autopicks will more aggressivly take rares two draft quality of life improvements for situations when real players quit or go afk. 1. made the draftbot lean on rarity for card ratings. this helps make the draftbots behave and not just pass bombs to the human players. 2. changed the draft autopick that happens when the timer runs out and the player hasn't selected anything. I changed it to pick the last card in the pack, which should be the rarest, so basically it raredrafts. again making it so AFK players aren't just feeding real live human players the best cards. --- .../java/mage/player/ai/utils/RateCard.java | 23 ++++++++++++++++++- .../main/java/mage/game/draft/DraftImpl.java | 3 ++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/utils/RateCard.java b/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/utils/RateCard.java index 5197c335365..e737122a958 100644 --- a/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/utils/RateCard.java +++ b/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/utils/RateCard.java @@ -13,6 +13,7 @@ import org.apache.log4j.Logger; import java.io.InputStream; import java.util.*; +import mage.constants.Rarity; import mage.constants.SubType; /** @@ -71,7 +72,7 @@ public final class RateCard { type = 6; } int score = 10 * getCardRating(card) + 2 * type + getManaCostScore(card, allowedColors) - + 40 * isRemoval(card); + + 40 * isRemoval(card) + getRarityScore(card); if (allowedColors == null) rated.put(card.getName(), score); return score; @@ -218,6 +219,26 @@ public final class RateCard { return 2 * converted + 3 * (10 - SINGLE_PENALTY[maxSingleCount]/*-DOUBLE_PENALTY[doubleCount]*/); } + /** + * Get rarity score. + * nowadays, cards that are more rare are more powerful, lets + * trust that and play the shiny cards. + * + * @param card + * @return integer rating value + */ + private static int getRarityScore(Card card) { + Rarity r = card.getRarity(); + if (Rarity.MYTHIC == r){ + return 80; + }else if (Rarity.RARE == r){ + return 50; + }else if (Rarity.UNCOMMON == r){ + return 25; + }else{ + return 1; + } + } /** * Determines whether mana symbol is color. * diff --git a/Mage/src/main/java/mage/game/draft/DraftImpl.java b/Mage/src/main/java/mage/game/draft/DraftImpl.java index 35efc144316..5ef5a2330ea 100644 --- a/Mage/src/main/java/mage/game/draft/DraftImpl.java +++ b/Mage/src/main/java/mage/game/draft/DraftImpl.java @@ -147,7 +147,8 @@ public abstract class DraftImpl implements Draft { @Override public void autoPick(UUID playerId) { - this.addPick(playerId, players.get(playerId).getBooster().get(0).getId(), null); + List booster = players.get(playerId).getBooster(); + this.addPick(playerId, booster.get(booster.size()-1).getId(), null); } protected void passLeft() { From 04457558b39f957a95444a187d10fe31b1fa491c Mon Sep 17 00:00:00 2001 From: brodee Date: Sat, 27 Oct 2018 11:50:59 -0700 Subject: [PATCH 2/4] ai tweaks: improve rating for multicolor cards and reduce effect of rarity multicolor cards are the payoffs for playing those colors so they should be better reduced the effect of rarity increasing the rating --- .../java/mage/player/ai/utils/RateCard.java | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/utils/RateCard.java b/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/utils/RateCard.java index e737122a958..877bb466314 100644 --- a/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/utils/RateCard.java +++ b/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/utils/RateCard.java @@ -169,11 +169,13 @@ public final class RateCard { } private static final int SINGLE_PENALTY[] = {0, 1, 1, 3, 6, 9}; + private static final int MULTICOLOR_BONUS = 15; /** * Get manacost score. * Depends on chosen colors. Returns negative score for those cards that doesn't fit allowed colors. * If allowed colors are not chosen, then score based on converted cost is returned with penalty for heavy colored cards. + * gives bonus to multicolor cards that fit within allowed colors and if allowed colors is <5 * * * @param card @@ -216,7 +218,12 @@ public final class RateCard { } if (maxSingleCount > 5) maxSingleCount = 5; - return 2 * converted + 3 * (10 - SINGLE_PENALTY[maxSingleCount]/*-DOUBLE_PENALTY[doubleCount]*/); + + int rate = 2 * converted + 3 * (10 - SINGLE_PENALTY[maxSingleCount]); + if( singleCount.size() > 1 && singleCount.size() < 5){ + rate += MULTICOLOR_BONUS; + } + return rate; } /** @@ -230,13 +237,13 @@ public final class RateCard { private static int getRarityScore(Card card) { Rarity r = card.getRarity(); if (Rarity.MYTHIC == r){ - return 80; + return 60; }else if (Rarity.RARE == r){ - return 50; + return 40; }else if (Rarity.UNCOMMON == r){ - return 25; + return 20; }else{ - return 1; + return 0; } } /** From 1f31323f47b5d8f7fbabafc05b6e52300ff96e59 Mon Sep 17 00:00:00 2001 From: brodee Date: Sat, 27 Oct 2018 11:53:05 -0700 Subject: [PATCH 3/4] fixed bug in test that skipped manual targetting addtarget was being ignored and AI was being used to determine a target. the spell has a target so I think this is not a bug with add target but rather the test itself --- .../mage/test/cards/single/soi/PrizedAmalgamTest.java | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/soi/PrizedAmalgamTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/soi/PrizedAmalgamTest.java index 0cd8182c34f..807859f205b 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/single/soi/PrizedAmalgamTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/soi/PrizedAmalgamTest.java @@ -26,8 +26,7 @@ public class PrizedAmalgamTest extends CardTestPlayerBase { addCard(Zone.GRAVEYARD, playerA, "Prized Amalgam", 1); addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1); - castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Reanimate"); - addTarget(playerA, "Bronze Sable"); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Reanimate", "Bronze Sable"); setStopAt(1, PhaseStep.END_TURN); execute(); @@ -72,8 +71,7 @@ public class PrizedAmalgamTest extends CardTestPlayerBase { addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3); addCard(Zone.GRAVEYARD, playerB, "Prized Amalgam", 1); - castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Reanimate"); - addTarget(playerA, "Hill Giant"); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Reanimate", "Hill Giant"); setStopAt(1, PhaseStep.END_TURN); execute(); @@ -95,8 +93,7 @@ public class PrizedAmalgamTest extends CardTestPlayerBase { // Whenever a creature enters the battlefield, if it entered from your graveyard or you cast it from your graveyard, return Prized Amalgam from your graveyard to the battlefield tapped at the beginning of the next end step. addCard(Zone.GRAVEYARD, playerB, "Prized Amalgam", 1); - castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Necromantic Summons"); - addTarget(playerA, "Merfolk Looter"); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Necromantic Summons", "Merfolk Looter"); setStopAt(1, PhaseStep.END_TURN); execute(); From bdf3394b848805e7375aaaaedc3962b2f495995e Mon Sep 17 00:00:00 2001 From: brodee Date: Sat, 27 Oct 2018 11:55:05 -0700 Subject: [PATCH 4/4] changed the card used in summoner's egg test this test uses ai to determine which card to imprint, with my other changes to AI, the rarity of the cards changed the relative rating of these two cards. I changed the merfolk to be a common merfolk so that part of the card rating shouldn't affect it --- .../mage/test/cards/facedown/SummonersEggTest.java | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/facedown/SummonersEggTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/facedown/SummonersEggTest.java index e9354e7a8d5..ab984d69d8b 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/facedown/SummonersEggTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/facedown/SummonersEggTest.java @@ -27,17 +27,16 @@ public class SummonersEggTest extends CardTestPlayerBase { @Test public void testSummonersEggImprint() { addCard(Zone.HAND, playerA, "Summoner's Egg"); - addCard(Zone.HAND, playerA, "Sejiri Merfolk"); + addCard(Zone.HAND, playerA, "Maritime Guard"); addCard(Zone.HAND, playerA, "Goblin Roughrider"); addCard(Zone.BATTLEFIELD, playerA, "Island", 4); - - castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Summoner's Egg"); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Summoner's Egg"); setStopAt(1, PhaseStep.BEGIN_COMBAT); execute(); - + assertHandCount(playerA, 1); - assertHandCount(playerA, "Sejiri Merfolk", 1); + assertHandCount(playerA, "Maritime Guard", 1); assertHandCount(playerA, "Goblin Roughrider", 0); assertExileCount("Goblin Roughrider", 1); @@ -53,7 +52,7 @@ public class SummonersEggTest extends CardTestPlayerBase { @Test public void testSummonersEggDies() { addCard(Zone.HAND, playerA, "Summoner's Egg"); - addCard(Zone.HAND, playerA, "Sejiri Merfolk"); + addCard(Zone.HAND, playerA, "Maritime Guard"); addCard(Zone.HAND, playerA, "Goblin Roughrider"); addCard(Zone.BATTLEFIELD, playerA, "Island", 4); addCard(Zone.HAND, playerB, "Char"); @@ -67,7 +66,7 @@ public class SummonersEggTest extends CardTestPlayerBase { execute(); assertHandCount(playerA, 1); - assertHandCount(playerA, "Sejiri Merfolk", 1); + assertHandCount(playerA, "Maritime Guard", 1); assertHandCount(playerA, "Goblin Roughrider", 0); assertGraveyardCount(playerA, "Summoner's Egg", 1);