@Override public PlayerModel deepCopy() { PlayerModel copiedPlayerModel = new PlayerModel( this.playerId, this.name, this.hero.deepCopy(), this.deck // TODO should be a deep copy, we're just using the index in boardmodel right // now to compensate.. // oyachai: the use of the deck position index is actually an attempt to reduce memory // usage. ); copiedPlayerModel.setMana(mana); copiedPlayerModel.setMaxMana(maxMana); copiedPlayerModel.setOverload(overload); copiedPlayerModel.deckPos = deckPos; copiedPlayerModel.fatigueDamage = fatigueDamage; copiedPlayerModel.numCardsUsed = numCardsUsed; for (Minion minion : minions) { copiedPlayerModel.minions.add((Minion) (minion).deepCopy()); } for (final Card card : hand) { Card tc = card.deepCopy(); copiedPlayerModel.placeCardHand(tc); } return copiedPlayerModel; }
@Before public void setup() throws HSException { board = new HearthTreeNode(new BoardModel()); currentPlayer = board.data_.getCurrentPlayer(); waitingPlayer = board.data_.getWaitingPlayer(); board.data_.placeMinion(PlayerSide.CURRENT_PLAYER, new RaidLeader()); board.data_.placeMinion(PlayerSide.CURRENT_PLAYER, new StormwindChampion()); board.data_.placeMinion(PlayerSide.WAITING_PLAYER, new RaidLeader()); board.data_.placeMinion(PlayerSide.WAITING_PLAYER, new BloodfenRaptor()); currentPlayer.setMana((byte) 10); waitingPlayer.setMana((byte) 10); Minion fb = new DefenderOfArgus(); currentPlayer.placeCardHand(fb); }
@Test public void test1() throws HSException { Card theCard = currentPlayer.getHand().get(0); HearthTreeNode ret = theCard.useOn(PlayerSide.CURRENT_PLAYER, CharacterIndex.MINION_1, board); assertNotNull(ret); currentPlayer = ret.data_.getCurrentPlayer(); waitingPlayer = ret.data_.getWaitingPlayer(); assertEquals(currentPlayer.getHand().size(), 0); assertEquals(currentPlayer.getNumMinions(), 3); assertEquals(waitingPlayer.getNumMinions(), 2); assertEquals(currentPlayer.getMana(), 6); assertEquals(waitingPlayer.getMana(), 10); assertEquals(currentPlayer.getHero().getHealth(), 30); assertEquals(waitingPlayer.getHero().getHealth(), 30); assertEquals(currentPlayer.getCharacter(CharacterIndex.MINION_1).getTotalHealth(), 4); assertEquals(currentPlayer.getCharacter(CharacterIndex.MINION_2).getTotalHealth(), 4); assertEquals(currentPlayer.getCharacter(CharacterIndex.MINION_3).getTotalHealth(), 7); assertEquals(waitingPlayer.getCharacter(CharacterIndex.MINION_1).getTotalHealth(), 2); assertEquals(waitingPlayer.getCharacter(CharacterIndex.MINION_2).getTotalHealth(), 2); assertEquals(currentPlayer.getCharacter(CharacterIndex.MINION_1).getTotalAttack(), 4); assertEquals(currentPlayer.getCharacter(CharacterIndex.MINION_2).getTotalAttack(), 4); assertEquals(currentPlayer.getCharacter(CharacterIndex.MINION_3).getTotalAttack(), 8); assertEquals(waitingPlayer.getCharacter(CharacterIndex.MINION_1).getTotalAttack(), 2); assertEquals(waitingPlayer.getCharacter(CharacterIndex.MINION_2).getTotalAttack(), 4); assertEquals(currentPlayer.getCharacter(CharacterIndex.MINION_1).getAuraAttack(), 1); assertEquals(currentPlayer.getCharacter(CharacterIndex.MINION_2).getAuraAttack(), 2); assertEquals(currentPlayer.getCharacter(CharacterIndex.MINION_3).getAuraAttack(), 1); assertEquals(waitingPlayer.getCharacter(CharacterIndex.MINION_1).getAuraAttack(), 0); assertEquals(waitingPlayer.getCharacter(CharacterIndex.MINION_2).getAuraAttack(), 1); assertTrue(currentPlayer.getCharacter(CharacterIndex.MINION_1).getTaunt()); assertFalse(currentPlayer.getCharacter(CharacterIndex.MINION_2).getTaunt()); assertTrue(currentPlayer.getCharacter(CharacterIndex.MINION_3).getTaunt()); }
// TODO Unused? public HearthTreeNode perform(HearthTreeNode boardState) throws HSException { HearthTreeNode toRet = boardState; PlayerModel actingPlayer = actionPerformerPlayerSide != null ? boardState.data_.modelForSide(actionPerformerPlayerSide) : null; PlayerModel targetPlayer = targetPlayerSide != null ? boardState.data_.modelForSide(targetPlayerSide) : null; switch (verb_) { case USE_CARD: { Card card = actingPlayer.getHand().get(cardOrCharacterIndex_); toRet = card.useOn(targetPlayerSide, targetCharacterIndex, toRet); } break; case HERO_ABILITY: { Hero hero = actingPlayer.getHero(); Minion target = targetPlayer.getCharacter(targetCharacterIndex); toRet = hero.useHeroAbility(targetPlayerSide, target, toRet); } break; case ATTACK: { Minion attacker = actingPlayer.getCharacter(CharacterIndex.fromInteger(cardOrCharacterIndex_)); toRet = attacker.attack(targetPlayerSide, targetCharacterIndex, toRet); } break; case UNTARGETABLE_BATTLECRY: { Minion minion = actingPlayer.getCharacter(CharacterIndex.fromInteger(cardOrCharacterIndex_)); toRet = minion.useUntargetableBattlecry(targetCharacterIndex, toRet); break; } case TARGETABLE_BATTLECRY: { Minion minion = actingPlayer.getCharacter(CharacterIndex.fromInteger(cardOrCharacterIndex_)); toRet = minion.useTargetableBattlecry(targetPlayerSide, targetCharacterIndex, toRet); break; } case START_TURN: { toRet = new HearthTreeNode(Game.beginTurn(boardState.data_.deepCopy())); break; } case END_TURN: { toRet = new HearthTreeNode(Game.endTurn(boardState.data_.deepCopy()).flipPlayers()); break; } case DO_NOT_USE_CARD: { for (Card c : actingPlayer.getHand()) { c.hasBeenUsed(true); } break; } case DO_NOT_ATTACK: { for (Minion minion : actingPlayer.getMinions()) { minion.hasAttacked(true); } actingPlayer.getHero().hasAttacked(true); break; } case DO_NOT_USE_HEROPOWER: { actingPlayer.getHero().hasBeenUsed(true); break; } case RNG: { // We need to perform the current state again if the children don't exist yet. This can // happen in certain replay scenarios. // Do not do this if the previous action was *also* RNG or we will end up in an infinite // loop. if (toRet.isLeaf() && boardState.getAction().verb_ != Verb.RNG) { boardState.data_.getCurrentPlayer().addNumCardsUsed((byte) -1); // do not double count toRet = boardState.getAction().perform(boardState); } // RNG has declared this child happened toRet = toRet.getChildren().get(cardOrCharacterIndex_); break; } case DRAW_CARDS: { // Note, this action only supports drawing cards from the deck. Cards like Ysera or // Webspinner need to be implemented using RNG children. for (int indx = 0; indx < cardOrCharacterIndex_; ++indx) { actingPlayer.drawNextCardFromDeck(); } break; } } return toRet; }