/** * Implements Speed special movement/attack model. * * @param board * @param mtkn * @return */ public List<Vector2D> powerMovementSystemSpeed(Board board, MovablePlayerToken mtkn) { List<Vector2D> movements = new ArrayList<Vector2D>(); List<Vector2D> extraMovements = new ArrayList<Vector2D>(); // Make consecutive movements: int x = mtkn.getCol(); int y = mtkn.getRow(); movements.add(new Vector2D(y - 1, x)); movements.add(new Vector2D(y + 1, x)); movements.add(new Vector2D(y, x - 1)); movements.add(new Vector2D(y, x + 1)); movements = validInBoard(movements); movements = validInPlayer(board, movements); for (int k = 0; k < movements.size(); k++) { if (board.getToken(movements.get(k).y, movements.get(k).x).getOwn() != this.getTurn().otherSide()) { extraMovements.add(new Vector2D(movements.get(k).y - 1, movements.get(k).x)); extraMovements.add(new Vector2D(movements.get(k).y + 1, movements.get(k).x)); extraMovements.add(new Vector2D(movements.get(k).y, movements.get(k).x - 1)); extraMovements.add(new Vector2D(movements.get(k).y, movements.get(k).x + 1)); } } extraMovements = validInBoard(extraMovements); extraMovements = validInPlayer(board, extraMovements); movements.addAll(extraMovements); return movements; }
/** * Valid classic (cross-like) attack positions for each position in input list, that enemy Token * exists. * * @param board * @param loc * @return */ public List<Vector2D> validForAttack(Board board, List<Vector2D> loc) { for (int i = loc.size() - 1; i >= 0; i--) { if (!(board.getToken(loc.get(i).y, loc.get(i).x).getOwn() == this.getTurn().otherSide())) { loc.remove(i); } } return loc; }
/** * Converts the input PlayerToken to the other side. The particular token can not be converted * back, till the end of the game. * * @param board * @param tkn PlayerToken to be converted. */ public void convertToken(Board board, PlayerToken tkn) { // Check if PlayerToken is converted previously: boolean isconverted = board.isConverted(tkn); if (!isconverted) { // Come to the dark side, we have cookies.. tkn.setOwn(this.getTurn().side()); this.getTurn().side().tokens.add(tkn); board.convertedTokens.add(tkn); } }
/** * Filter valid movements in order to not conflict with same player Tokens. * * @param board * @param loc * @return */ public List<Vector2D> validInPlayer(Board board, List<Vector2D> loc) { // remove locations if they fall on same player tokens: for (int i = loc.size() - 1; i >= 0; i--) { // Smarter way to check: // Not valid location if same player token overlap. if (board.getToken(loc.get(i).y, loc.get(i).x).getOwn() == this.getTurn().side()) { loc.remove(i); } } return loc; }
/** * Saves the lost (input) Token and places it back to the board in the first empty position. If no * empty position Token is not saved. * * @param board * @param tkn * @return */ public boolean saveToken(Board board, MovablePlayerToken tkn) { // Check if input Token is indeed killed; if (tkn.getCol() >= 0) { return false; } // Move the selected Token into the board (if possible!): if (getTurn().side().pname.equals("Fire")) { // find the first empty spot: for (int k = 0; k < 30; k++) { int r = k / 10 + 5; int c = k % 10; if (board.getToken(r, c) instanceof Grass) { this.insertToken2Board(board, tkn, r, c); return true; } } } return false; }
/** * Checks if input position has valid attack options: * * @param loc query position. * @return List with possible attack options. */ public List<Vector2D> positionsAttackOptions(Board board, Vector2D pos) { List<Vector2D> attackPositions = new ArrayList<Vector2D>(); int y = pos.y; int x = pos.x; // Add the clasic attack positions: attackPositions.add(new Vector2D(y - 1, x)); attackPositions.add(new Vector2D(y + 1, x)); attackPositions.add(new Vector2D(y, x - 1)); attackPositions.add(new Vector2D(y, x + 1)); attackPositions = validInBoard(attackPositions); for (int k = 0; k < attackPositions.size(); k++) { if (!(board.getToken(attackPositions.get(k).y, attackPositions.get(k).x).getOwn() == this.getTurn().otherSide())) { attackPositions.remove(k); } } return attackPositions; }
/** * Implements Dragon moving/attack model. * * @param board * @param drg * @return */ public List<Vector2D> powerMovementSystemFlight(Board board, Dragon drg) { List<Vector2D> drgMovements = new ArrayList<Vector2D>(); // move in each direction skipping first obstacle: int x = drg.getCol(); int y = drg.getRow(); boolean mustLand = false; boolean obstacle = false; List<Vector2D> safeLanding = new ArrayList<Vector2D>(); List<Vector2D> riskyLanding = new ArrayList<Vector2D>(); List<Vector2D> attackAfterLanding = new ArrayList<Vector2D>(); // Negative Y: int ny = y; while (!mustLand) { ny--; if (isInsideBoard(new Vector2D(ny, x))) { Token bt = board.getToken(ny, x); /*if(!isInsideBoard(new Vector2D(ny,x))){ mustLand = true; }else */ if (hitsRock(new Vector2D(ny, x))) { riskyLanding.add(new Vector2D(ny, x)); obstacle = true; } else if (bt instanceof PlayerToken) { riskyLanding.add(new Vector2D(ny, x)); obstacle = true; } else if (obstacle) { riskyLanding.add(new Vector2D(ny, x)); safeLanding.addAll(riskyLanding); mustLand = true; } else { // If no better position is found, glide down with pride (like a true dragon): safeLanding.add(new Vector2D(ny, x)); } } else { // Hit the end of the board: mustLand = true; } } mustLand = false; obstacle = false; riskyLanding = new ArrayList<Vector2D>(); // Positive Y: ny = y; while (!mustLand) { ny++; if (isInsideBoard(new Vector2D(ny, x))) { Token bt = board.getToken(ny, x); if (hitsRock(new Vector2D(ny, x))) { riskyLanding.add(new Vector2D(ny, x)); obstacle = true; } else if (bt instanceof PlayerToken) { riskyLanding.add(new Vector2D(ny, x)); obstacle = true; } else if (obstacle) { riskyLanding.add(new Vector2D(ny, x)); safeLanding.addAll(riskyLanding); mustLand = true; } else { safeLanding.add(new Vector2D(ny, x)); } } else { // Hit the end of the board: mustLand = true; } } mustLand = false; obstacle = false; riskyLanding = new ArrayList<Vector2D>(); // Negative X: int nx = x; while (!mustLand) { nx--; if (isInsideBoard(new Vector2D(y, nx))) { Token bt = board.getToken(y, nx); if (hitsRock(new Vector2D(y, nx))) { riskyLanding.add(new Vector2D(y, nx)); obstacle = true; } else if (bt instanceof PlayerToken) { riskyLanding.add(new Vector2D(y, nx)); obstacle = true; } else if (obstacle) { riskyLanding.add(new Vector2D(y, nx)); safeLanding.addAll(riskyLanding); mustLand = true; } else { safeLanding.add(new Vector2D(y, nx)); } } else { // Hit the end of the board: mustLand = true; } } mustLand = false; obstacle = false; riskyLanding = new ArrayList<Vector2D>(); // Positive X: nx = x; while (!mustLand) { nx++; if (isInsideBoard(new Vector2D(y, nx))) { Token bt = board.getToken(y, nx); if (hitsRock(new Vector2D(y, nx))) { riskyLanding.add(new Vector2D(y, nx)); obstacle = true; } else if (bt instanceof PlayerToken) { riskyLanding.add(new Vector2D(y, nx)); obstacle = true; } else if (obstacle) { riskyLanding.add(new Vector2D(y, nx)); safeLanding.addAll(riskyLanding); mustLand = true; } else { safeLanding.add(new Vector2D(y, nx)); } } else { // Hit the end of the board: mustLand = true; } } // Define additional attack options for each landing position: for (int k = 0; k < safeLanding.size(); k++) { attackAfterLanding.addAll( positionsAttackOptions(board, new Vector2D(safeLanding.get(k).y, safeLanding.get(k).x))); } drgMovements.addAll(safeLanding); drgMovements.addAll(attackAfterLanding); return drgMovements; }
/** * Implements Scout moving model. * * @param board * @param sct * @return */ public List<Vector2D> movementSystemScout(Board board, Scout sct) { List<Vector2D> sctMovements = new ArrayList<Vector2D>(); // move in each direction until hitting something: int x = sct.getCol(); int y = sct.getRow(); // Blocked by: // 1.rock (non-inclusive) // 2.same player token (non-inclusive) // 3.other player token (inclusive) // 4.Board boundaries (non-inclusive) boolean blocked = false; // Negative Y: int ny = y; while (!blocked) { ny--; if (isInsideBoard(new Vector2D(ny, x))) { Token bt = board.getToken(ny, x); if (hitsRock(new Vector2D(ny, x))) { blocked = true; } else if (bt.getOwn() == this.getTurn().side()) { blocked = true; } else if (bt.getOwn() == this.getTurn().otherSide()) { sctMovements.add(new Vector2D(ny, x)); blocked = true; } else { sctMovements.add(new Vector2D(ny, x)); } } else { blocked = true; } } blocked = false; // Positive Y: ny = y; while (!blocked) { ny++; if (isInsideBoard(new Vector2D(ny, x))) { Token bt = board.getToken(ny, x); if (hitsRock(new Vector2D(ny, x))) { blocked = true; } else if (bt.getOwn() == this.getTurn().side()) { blocked = true; } else if (bt.getOwn() == this.getTurn().otherSide()) { sctMovements.add(new Vector2D(ny, x)); blocked = true; } else { sctMovements.add(new Vector2D(ny, x)); } } else { blocked = true; } } blocked = false; // Negative X: int nx = x; while (!blocked) { nx--; if (isInsideBoard(new Vector2D(y, nx))) { Token bt = board.getToken(y, nx); if (hitsRock(new Vector2D(y, nx))) { blocked = true; } else if (bt.getOwn() == this.getTurn().side()) { blocked = true; } else if (bt.getOwn() == this.getTurn().otherSide()) { sctMovements.add(new Vector2D(y, nx)); blocked = true; } else { sctMovements.add(new Vector2D(y, nx)); } } else { blocked = true; } } blocked = false; // Positive X: nx = x; while (!blocked) { nx++; if (isInsideBoard(new Vector2D(y, nx))) { Token bt = board.getToken(y, nx); if (hitsRock(new Vector2D(y, nx))) { blocked = true; } else if (bt.getOwn() == this.getTurn().side()) { blocked = true; } else if (bt.getOwn() == this.getTurn().otherSide()) { sctMovements.add(new Vector2D(y, nx)); blocked = true; } else { sctMovements.add(new Vector2D(y, nx)); } } else { blocked = true; } } return sctMovements; }