/** * 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; }
public void moveToken(Board board, MovablePlayerToken src, Vector2D trgloc) { // A move happens only between a movablePlayerToken and Grass token: // Swap tokens: int tmpc = src.getCol(); int tmpr = src.getRow(); // Update position of source token: this.insertToken2Board(board, src, trgloc.y, trgloc.x); // fill the space with grass: this.insertToken2Board(board, StrategoBoard.grassToken, tmpr, tmpc); }
/** * Implements Range special attack model. * * @param board * @param mtkn * @return */ public List<Vector2D> powerMovementSystemRange(Board board, MovablePlayerToken mtkn) { List<Vector2D> movements = new ArrayList<Vector2D>(); int x = mtkn.getCol(); int y = mtkn.getRow(); for (int i = -2; i <= 2; i++) { for (int j = -2; j <= 2; j++) { movements.add(new Vector2D(y + i, x + j)); } } movements = validInBoard(movements); movements = validInPlayer(board, movements); // Because this system implements ranged attack, // valid targets are only enemy tokens: movements = validForAttack(board, movements); return movements; }
/** * <b>pre-condition</b>: The Token to exist in Board. Computes valid movement locations for the * token in board. * * @param board * @param tkn * @return */ public List<Vector2D> tokenSelection(Board board, Token tkn) { // List<Vector2D> moveLocations = new ArrayList<Vector2D>(); this.moveLocations = new ArrayList<Vector2D>(); // Determine if action is valid (is permitted): if (tkn instanceof MovablePlayerToken) { // Get available positions for movement/attack // based on token class: MovablePlayerToken mtkn = (MovablePlayerToken) tkn; // Special movement pattern for scouts, based on state of the board: if (mtkn instanceof Scout) { this.moveLocations = movementSystemScout(board, (Scout) mtkn); } else { // Get ABSOLUTE board locations: this.moveLocations = mtkn.getMovePattern(); // Vector2D pos = new Vector2D(mtkn.getRow(),mtkn.getCol()); // Check what locations are valid on the board: this.moveLocations = validInBoard(this.moveLocations); this.moveLocations = validInPlayer(board, this.moveLocations); } } // else return empty valid move locations: return this.moveLocations; }
/** * 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; }
public void attackToken( Board board, MovablePlayerToken src, PlayerToken trg, boolean specialPower) { // An attack happens only between PlayerTokens: // perform attack method of source token: String outcome = ""; // No need for an extra attack method, just interpret differently the results. if (specialPower && (src instanceof SpecialMovablePlayerToken)) { SpecialMovablePlayerToken scltkn = (SpecialMovablePlayerToken) src; outcome = scltkn.specialAttackTo(trg); } else { outcome = src.attackTo(trg); } if (outcome.equals("won")) { // Save location: int tmpc = trg.getCol(); int tmpr = trg.getRow(); // Remove token that lost from the board: takeToken(board, trg); // move token that won to its place: this.moveToken(board, src, new Vector2D(tmpr, tmpc)); } else if (outcome.equals("lost")) { // Remove token that lost from the board: takeToken(board, src); } else if (outcome.equals("tie")) { // remove both tokens from the board: takeToken(board, src); takeToken(board, trg); } else if (outcome.equals("wonNotMove")) { // Remove token that lost from the board: takeToken(board, trg); } else if (outcome.equals("nothing")) { // Nothing happens in the board. } else if (outcome.equals("convert")) { // Target Token is converted to the other side (probably // due to cookies).. convertToken(board, trg); } }
/** * Performs an action from source token to the target token. Actions can be: 1. Nothing (action * not permitted) 2. Move (valid movement action) 3. Attack (valid attack action) * * @param src The source token * @param trg The target token * @return The outcome of the action was successful. False: no action whatsoever. */ public boolean tokenAction( Board board, Token src, Token trg, Vector2D trgloc, StrategoAppViewer viewer, boolean specialPower) { // List<Vector2D> moveLocations = new ArrayList<Vector2D>(); // Determine if action is valid (is permitted): // Token action is already validated by the viewer, but the controller ought to check: // (in case viewer is not used): boolean found = false; // Get available positions for movement/attack: if (specialPower) { this.moveLocations = tokenSpecialSelection(board, src); } else { this.moveLocations = tokenSelection(board, src); } for (int i = 0; i < this.moveLocations.size(); i++) { if ((trgloc.y == this.moveLocations.get(i).y) && (trgloc.x == this.moveLocations.get(i).x)) { found = true; break; } } // if no valid movement/token detected: do not execute action: if (!found) { return false; } // Now that the movement is permitted: // Check what token action to perform: if (trg instanceof BackgroundToken) { // Grass is the only move-onto background token: this.moveToken(board, (MovablePlayerToken) src, trgloc); } else { // else this is an attack: this.attackToken(board, (MovablePlayerToken) src, (PlayerToken) trg, specialPower); } MovablePlayerToken saviour = null; // Check if a token moved in enemy's back row: for (int k = 0; k < getTurn().side().tokens.size(); k++) { if (getTurn().side().pname == "Fire") { if ((getTurn().side().tokens.get(k).getRow() == 0)) { saviour = (MovablePlayerToken) getTurn().side().tokens.get(k); } } else { if ((getTurn().side().tokens.get(k).getRow() == 7)) { saviour = (MovablePlayerToken) getTurn().side().tokens.get(k); } } } // Scouts can not save tokens: if (saviour instanceof Scout) { saviour = null; } else if (getTurn().side().getTotalSaves() > 2) { // Can not save more than twice: saviour = null; } else if ((saviour != null) && saviour.savedToken()) { // Can not save more than twice: // Get a random Token to save: for (int k = 0; k < getTurn().side().tokens.size(); k++) { if (getTurn().side().tokens.get(k).getCol() < 0) { if (getTurn().side().tokens.get(k) instanceof MovablePlayerToken) { if (saveToken(board, (MovablePlayerToken) getTurn().side().tokens.get(k))) { break; } } } } } // if player turn completed successfully, check if winning condition: getTurn().setWinner(doWeHaveAWinner(board, getTurn())); // Else change sides: if (getTurn().getWinner() == null) { getTurn().flip(); } else { endGame(getTurn()); } return true; }