Android Open Source - abalone-android Board






From Project

Back to project page abalone-android.

License

The source code is released under:

GNU General Public License

If you think the Android project abalone-android listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/**
* Copyright (c) 2010-2011 Yaroslav Geryatovich, Alexander Yakushev
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
*/// www . ja  v  a 2 s.  c o  m
package com.bytopia.abalone.mechanics;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import android.util.Log;

/**
 * Class that represents a playing board with all cells and marbles in them.
 * 
 * @author Bytopia
 */
public class Board implements Cloneable, Serializable {

  /**
   * Array of cell descriptions.
   */
  private byte[][] field;

  /**
   * Number of white marbles captured.
   */
  private int whiteCaptured = 0;

  /**
   * Number of black marbles captured.
   */
  private int blackCaptured = 0;

  /**
   * Constructs a board with a default classic layout and black marbles
   * downside.
   */
  public Board() {
    this(new ClassicLayout(), Side.BLACK);
  }

  /**
   * Constructs a board with an arbitrary layout and a given side on the
   * bottom.
   * 
   * @param l
   *            layout that will set the starting position
   * @param downSide
   *            side whose position will be on the bottom
   */
  public Board(Layout l, byte downSide) {
    if (downSide == Side.BLACK)
      field = l.getBlackStartField();
    else
      field = l.getWhiteStartField();
  }

  /**
   * Returns the array that describes every cell.
   * 
   * @return array of cell descriptions
   */
  public byte[][] getField() {
    return field;
  }

  /**
   * Returns the state of the given cell - non-existing, empty, white or black
   * marble.
   * 
   * @param c
   *            cell on the board
   * @return numeric representation of cell state. All states are listed in
   *         the Layout class
   */
  public byte getState(Cell c) {
    return field[c.row][c.column];
  }

  /**
   * Returns the state of the given cell by its coordinates - non-existing,
   * empty, white or black marble.
   * 
   * @param row
   *            X coordinate of the cell
   * @param column
   *            Y coordinate of the cell
   * @return numeric representation of cell state. All states are listed in
   *         the Layout class
   */
  public byte getState(int row, int column) {
    return field[row][column];
  }

  /**
   * Sets the given state to the cell on the board.
   * 
   * @param c
   *            given cell
   * @param state
   *            numeric representation of cell state
   */
  public void setState(Cell c, byte state) {
    field[c.row][c.column] = state;
  }

  /**
   * Returns what the type would the move have if performed on this board.
   * 
   * @param m
   *            move to be performed
   * @return move type instance
   */
  public MoveType getMoveType(Move m) {
    Group destination = m.getDestination();
    // If move is a leap
    boolean result = true;
    for (Cell c : destination.getCells()) {
      if (getState(c) != Layout.E)
        result = false;
    }
    if (result == true)
      return new MoveType(MoveType.LEAP, m.getSource(), destination);
    // If move is a pushing move...
    if (m.isPushing()) {
      byte d = m.getDirection();
      // ...check if it is a silent pushing move
      if (getState(m.getPeak().shift(d)) == Layout.E)
        return new MoveType(MoveType.SILENTPUSH, m.getSource(),
            destination);
      // Otherwise it's a enemy pushing move
      int nCell = getState(m.getPeak().shift(d));
      if (nCell == Layout.N)
        return new MoveType(MoveType.NOMOVE);
      int nnCell = getState(m.getPeak().shift(d).shift(d));
      byte enemyMarble = Side.opposite(m.getSide());
      if (nCell == enemyMarble
          && (nnCell == Layout.E || nnCell == Layout.N))
        return new MoveType(MoveType.ENEMYPUSH, new Group(m.getTail(),
            m.getPeak().shift(d)), destination);
      if (nnCell == Layout.N || m.getSource().getSize() == 2)
        return new MoveType(MoveType.NOMOVE);
      int nnnCell = getState(m.getPeak().shift(d).shift(d).shift(d));
      if (nCell == enemyMarble && nnCell == enemyMarble
          && (nnnCell == Layout.E || nnnCell == Layout.N))
        return new MoveType(MoveType.ENEMYPUSH, new Group(m.getTail(),
            m.getPeak().shift(d).shift(d)), destination);
    }
    return new MoveType(MoveType.NOMOVE);
  }

  /**
   * Perform a given move on the current board.
   * 
   * @param m
   *            move to be performed
   */
  public void makeMove(Move m) {
    int type = getMoveType(m).getResult();
    if (type == MoveType.LEAP || type == MoveType.SILENTPUSH) {
      for (Cell c : m.getSource().getCells())
        setState(c, Layout.E);
      for (Cell c : m.getDestination().getCells())
        setState(c, m.getSide());
    } else {
      byte src = Layout.E, dest;
      Cell c = m.getTail();

      do {
        dest = getState(c);
        if (dest == Layout.N)
          if (m.getSide() == Side.WHITE)
            blackCaptured++;
          else
            whiteCaptured++;
        else
          setState(c, src);
        src = dest;
        c = c.shift(m.getDirection());
      } while (dest != Layout.E && dest != Layout.N);
    }
  }

  /**
   * Returns a string representing the board in a form of ASCII symbols
   */
  @Override
  public String toString() {
    StringBuilder s = new StringBuilder();
    s.append("       1 2 3 4 5");
    int j = 1;
    for (byte[] row : field) {
      for (int i = 0; i < Math.abs(6 - j); i++) {
        s.append(" ");
      }
      if (j != 1 && j != 11) {
        s.append((char) ((int) 'A' + j - 2) + " ");
      }
      for (int cell : row)
        if (cell == Layout.E)
          s.append("- ");
        else if (cell == Layout.W)
          s.append("o ");
        else if (cell == Layout.B)
          s.append("@ ");
      if (j != 1 && j <= 5)
        s.append(Integer.toString(j + 4));
      s.append("\n");
      j++;
    }
    return s.toString();
  }

  /**
   * Returns how many marbles are captured for the given side.
   * 
   * @param side
   *            black or white side
   * @return number of marbles captured for (not by) this side
   */
  public int getMarblesCaptured(byte side) {
    return side == Side.WHITE ? whiteCaptured : blackCaptured;
  }

  /**
   * Returns the list of all marbles, i.e. list of cells with any marbles
   * inside.
   * 
   * @return list of cells with marbles
   */
  public List<Cell> getAllMarbles() {
    List<Cell> list = new ArrayList<Cell>();
    for (int i = 1; i <= 9; i++)
      for (int j = Cell.minColumn[i]; j <= Cell.maxColumn[i]; j++)
        if (getState(i, j) == Side.WHITE
            || getState(i, j) == Side.BLACK)
          list.add(Cell.storage[i][j]);
    return list;
  }

  /**
   * Returns the list of marbles of a given side, i.e. list of cells with
   * marbles of this side inside.
   * 
   * @param side
   *            black or white side
   * @return list of cells with marbles of this side
   */
  public List<Cell> getSideMarbles(byte side) {
    List<Cell> list = new ArrayList<Cell>();
    for (int i = 1; i <= 9; i++)
      for (int j = Cell.minColumn[i]; j <= Cell.maxColumn[i]; j++)
        if (getState(i, j) == side)
          list.add(Cell.storage[i][j]);
    return list;
  }

  /**
   * Clones the board returning the same board.
   */
  @Override
  public Board clone() {
    Board b = new Board();
    byte[][] f = new byte[11][11];
    for (int i = 0; i < 11; i++)
      System.arraycopy(field[i], 0, f[i], 0, 11);
    b.field = f;
    b.whiteCaptured = whiteCaptured;
    b.blackCaptured = blackCaptured;
    return b;
  }

  /**
   * Returns the possible group to be moved on this board by given starting
   * cell, ending cell, side of player and presumably direction of selection.
   * Used by Player class.
   * 
   * @param start
   *            starting cell of the group
   * @param end
   *            possible ending cell of the group (if the cell is the same
   *            color as the player's side and group is legal)
   * @param d
   *            direction of cell selection
   * @param side
   *            side of the player
   * @return the group of interval start-end, if it is legal for this player.
   *         Otherwise the largest possible interval from start to the last
   *         legal cell in a given direction taken from start cell is returned
   */
  public Group getUsableGroup(Cell start, Cell end, byte d, byte side) {
    if (getState(start) == side)
      if (getState(start.shift(d)) == side
          && start.findDistance(end) >= 1)
        if (getState(start.shift(d).shift(d)) == side
            && start.findDistance(end) >= 2)
          return new Group(start, start.shift(d).shift(d));
        else
          return new Group(start, start.shift(d));
      else
        return new Group(start);
    else
      return null;
  }

  /**
   * Sets the number of captured white marbles
   * 
   * @param whiteCaptured
   *            Quantity of white marbles captured by the enemy
   */
  public void setWhiteCaptured(int whiteCaptured) {
    this.whiteCaptured = whiteCaptured;
  }

  /**
   * Sets the number of captured black marbles
   * 
   * @param whiteCaptured
   *            Quantity of black marbles captured by the enemy
   */
  public void setBlackCaptured(int blackCaptured) {
    this.blackCaptured = blackCaptured;
  }

}




Java Source Code List

com.bytopia.abalone.BoardRenderer.java
com.bytopia.abalone.BoardView.java
com.bytopia.abalone.GameActivity.java
com.bytopia.abalone.GameOptionsActivity.java
com.bytopia.abalone.LoseBallsView.java
com.bytopia.abalone.MainMenuActivity.java
com.bytopia.abalone.Options.java
com.bytopia.abalone.Scenario.java
com.bytopia.abalone.SelectLayoutActivity.java
com.bytopia.abalone.SplashAcitvity.java
com.bytopia.abalone.TutorialActivity.java
com.bytopia.abalone.TutorialBoardView.java
com.bytopia.abalone.mechanics.AiAnn.java
com.bytopia.abalone.mechanics.AiBeatrice.java
com.bytopia.abalone.mechanics.AiCharlotte.java
com.bytopia.abalone.mechanics.AiDeborah.java
com.bytopia.abalone.mechanics.ArtificialIntilligence.java
com.bytopia.abalone.mechanics.BelgianLayout.java
com.bytopia.abalone.mechanics.Board.java
com.bytopia.abalone.mechanics.Cell.java
com.bytopia.abalone.mechanics.ClassicLayout.java
com.bytopia.abalone.mechanics.ConsoleWatcher.java
com.bytopia.abalone.mechanics.Debug.java
com.bytopia.abalone.mechanics.Direction.java
com.bytopia.abalone.mechanics.EmptyLayout.java
com.bytopia.abalone.mechanics.Game.java
com.bytopia.abalone.mechanics.GermanLayout.java
com.bytopia.abalone.mechanics.Group.java
com.bytopia.abalone.mechanics.Layout.java
com.bytopia.abalone.mechanics.MoveType.java
com.bytopia.abalone.mechanics.Move.java
com.bytopia.abalone.mechanics.Player.java
com.bytopia.abalone.mechanics.Side.java
com.bytopia.abalone.mechanics.TestLayout.java
com.bytopia.abalone.mechanics.Watcher.java