public override string ToString(Game game) { Readable_LifeTarget attacker = game.Get_ReadableSnapshot(this.attackerID); Readable_LifeTarget defender = game.Get_ReadableSnapshot(this.defenderID); return(attacker.ToString(game) + " attacks " + defender.ToString(game)); }
public Readable_GamePlayer GetValue(ID <ReadableCard> cardId, Game game, Readable_GamePlayer outputType) { ReadableCard card = game.Get_ReadableSnapshot(cardId); Readable_GamePlayer owner = game.Get_ReadableSnapshot(card.Get_OwnerID()); return(owner); }
public GameEffect ChooseBestAction(GameChoice choice, Game game) { game = game.Clone(); // Inform the game and its descendents that it is a hypothetical game, so all players use the strategy of the player doing the imagining Readable_GamePlayer chooser = game.Get_ReadableSnapshot(choice.ControllerID); game.Strategy = game.GetStrategy(chooser); IEnumerable <GameEffect> effects = choice.Options; // create the base game Analyzed_GameState rootState = new Analyzed_GameState(game, null, null, this.GameEvaluator.EstimateWinProbabilities(game)); rootState.ChoosingPlayerID = choice.ControllerID; // Put the first set of choices onto the starting gameState this.PutGameOptions(rootState, choice); // loop until we run out of time while (rootState.NumDescendents < this.NumTimeSteps) { // Find the current best path and explore it for one more time unit this.ProcessOnce(rootState); double winProbability = rootState.WinProbabilities[choice.ControllerID]; if (winProbability == 0 || winProbability == 1) { break; } } if (this.ShouldPrint) { Console.WriteLine("Plan for " + chooser.ToString()); rootState.printBestPath(); } return(rootState.FavoriteChild.SourceEffect); }
public virtual bool IsPlayable(Game game) { // check that we have enough resources to play this card Readable_GamePlayer controller = game.Get_ReadableSnapshot(this.ControllerID); return(controller.Get_CurrentResources().Minus(this.cost).IsValid); }
public double EstimateWinProbability(Game game, ID <Readable_GamePlayer> playerId) { Readable_GamePlayer player = game.Get_ReadableSnapshot(playerId); // first check for obvious things like whether one player has already lost if (game.GetWinner() != null) { if (game.GetWinner() == player) { return(1); } else { return(0); } } if (game.GetLosers().Count == game.NumPlayers) { return(0); //return 1.0 / game.NumPlayers; } // Now compute a heuristic based on how much stuff each player has double totalScore = 0; double playerScore = 0; double activePlayer = 1; foreach (Readable_GamePlayer candidate in game.Players) { // Exchange rates: // n power and n toughness is worth n mana // losing 25% of your life is worth 2 mana // 1 crystal per turn is worth 2 mana now. // n cards in hand is worth n mana (the cards often generate n mana worth of value (plus the mana spent to play them) even though they often cost 2*n to draw them) // Being the active player is worth 0.5 cards and 0.5 mana/turn, but the active player has received 1 additional card and 1 additional mana, so these must each be subtracted instead // This results in this score (equivalent amount of mana this turn): // mana+manaPerTurn*2++((power+toughness)/2)+(log(life)/log(4/3))+(activePlayer?)*-1.5+handSize /* * double score = candidate.Get_CurrentResources().ToNumber() * activePlayer / 2 + candidate.Get_ResourcesPerTurn().ToNumber() - activePlayer * 2 + * (candidate.Get_Total_MonsterDamage(game) + candidate.Get_Total_MonsterHealth(game)) / 2 + Math.Log(candidate.GetHealth()) / Math.Log(4.0 / 3.0); */ double score = candidate.Get_CurrentResources().ToNumber() * activePlayer + candidate.Get_ResourcesPerTurn().ToNumber() * 2 + (candidate.Get_Total_MonsterDamage(game) + candidate.Get_Total_MonsterHealth(game)) / 2 + Math.Log(candidate.GetHealth()) / Math.Log(4.0 / 3.0) + activePlayer * -1.5 + candidate.Get_ReadableHand().Count; if (score < 1) // can't have 0 or less probability of winning unless you've actually lost already { score = 1; } totalScore += score; if (candidate == player) { playerScore = score; } activePlayer *= 0; } return(playerScore / totalScore); }
public void Print(Game game) { Console.WriteLine("Player " + this.ID + " : " + this.Health + " health, " + this.CurrentResources.ToNumber() + "/" + this.ResourcesPerTurn.ToNumber() + " resources"); IEnumerable <ID <ReadableCard> > hand = this.hand.GetReadable(); Console.WriteLine(" Hand:(" + hand.Count() + ")"); foreach (ID <ReadableCard> cardId in this.hand.GetReadable()) { ReadableCard card = game.Get_ReadableSnapshot(cardId); Console.WriteLine(card.ToString(game)); } Console.WriteLine(" Field:"); foreach (ID <Readable_MonsterCard> cardId in this.MonsterIDsInPlay.GetReadable()) { ReadableCard card = game.Get_ReadableSnapshot(cardId); Console.WriteLine(card.ToString(game)); } }
public bool IsPlayable(Readable_MonsterCard card, Game game) { Readable_GamePlayer controller = game.Get_ReadableSnapshot(card.Get_ControllerID()); IEnumerable <ID <Readable_MonsterCard> > cardsInPlay = controller.Get_MonsterIDsInPlay(); if (cardsInPlay.Count() < 7) { return(true); } return(false); }
public int Get_Total_MonsterHealth(Game game) { int total = 0; foreach (ID <Readable_MonsterCard> monsterId in this.MonsterIDsInPlay.GetReadable()) { Readable_MonsterCard monster = game.Get_ReadableSnapshot(monsterId); total += monster.GetHealth(); } return(total); }
public override string ToString(Game game) { Readable_LifeTarget target = game.Get_ReadableSnapshot(this.TargetID); int amount = this.AmountToGain; string result = target.ToString(game); if (amount > 0) { result += " gains "; } else { result += " loses "; amount *= -1; } result += amount.ToString() + " hitpoint"; if (amount != 1) { result += "s"; } return(result); }
public override string ToString(Game game) { ReadableCard card = game.Get_ReadableSnapshot(this.cardId); return("Play " + card.ToString(game)); }
public override bool IsProcessable(Game game) { ReadableCard card = game.Get_ReadableSnapshot(this.cardId); return(card.IsPlayable(game)); }
public override void Process(Game game) { ReadableCard card = game.Get_ReadableSnapshot(this.cardId); card.Play(game); }
public List <GameEffect> Get_AvailableGameActions(Game game, Readable_GamePlayer player) { // This function only gets called when there are no effects in progress (like choosing the target of a triggered effect). List <GameEffect> options = new List <GameEffect>(); // So, a player has these types of options: 1. Play a card. 2. Attack with a monster. 3. Activate their special ability. 4. End their turn // Let the player play any card foreach (ID <ReadableCard> cardId in player.Get_ReadableHand()) { ReadableCard card = game.Get_ReadableSnapshot(cardId); if (card.IsPlayable(game)) { options.Add(new PlayCard_Effect(card.GetID((ReadableCard)null))); } } // Let the player attack with any monster IEnumerable <ID <Readable_MonsterCard> > availableAttacker_IDs = player.Get_MonsterIDsInPlay(); // first figure out which monsters can be attacked (if any monsters have Taunt, they are the only ones that may be attacked) foreach (ID <Readable_GamePlayer> playerId in game.TurnOrder) { // make sure this is a different player if (!playerId.Equals(player.GetID((Readable_GamePlayer)null))) { LinkedList <ID <Readable_LifeTarget> > requiredTarget_IDs = new LinkedList <ID <Readable_LifeTarget> >(); LinkedList <ID <Readable_LifeTarget> > allTarget_Ids = new LinkedList <ID <Readable_LifeTarget> >(); Readable_GamePlayer controller = game.Get_ReadableSnapshot(playerId); foreach (ID <Readable_MonsterCard> monsterId in controller.Get_MonsterIDsInPlay()) { Readable_MonsterCard monster = game.Get_ReadableSnapshot(monsterId); ID <Readable_LifeTarget> convertedID = monster.GetID((Readable_LifeTarget)null); allTarget_Ids.AddLast(convertedID); if (monster.Get_MustBeAttacked()) { requiredTarget_IDs.AddLast(convertedID); } } if (requiredTarget_IDs.Count != 0) { // There is a monster with taunt, so the only valid targets are the monsters with taunt allTarget_Ids = requiredTarget_IDs; } else { // There are no monsters with taunt, so the valid targets are all monsters and the opponent too allTarget_Ids.AddLast(controller.GetID((Readable_LifeTarget)null)); } // Now allow each monster to attack each available target foreach (ID <Readable_MonsterCard> attackerId in availableAttacker_IDs) { if (game.Get_ReadableSnapshot(attackerId).Get_CanAttack()) { foreach (ID <Readable_LifeTarget> targetId in allTarget_Ids) { options.Add(new AttackEffect(attackerId.AsType((Readable_LifeTarget)null), targetId)); } } } } } // Let the player end their turn options.Add(new EndTurn_Effect(player.GetID((Readable_GamePlayer)null))); return(options); }
public override string ToString(Game game) { return("End turn for " + game.Get_ReadableSnapshot(this.ControllerID)); }