Package generator

Source Code of generator.BoardManager

package generator;

import java.util.PriorityQueue;

import engine.Board;

/**
* BoardManager provides static methods to modify board.
*/
public final class BoardManager {

  // *************************************************************************
  // Content
 
  /**
   * Removes all elements from the board
   * and makes all fields empty.
   *
   * @param board - the given board
   */
  public static void removeElements(Board board) {
    for (int y=0;y<board.height;y++)
      for (int x=0;x<board.width;x++)
        board.setElement(x,y,Board.EMPTY);
  }
 
  /**
   * Removes all blocks from the board.
   *
   * @param board - the given board
   */
  public static void removeBlocks(Board board) {
    for (int y=0;y<board.height;y++)
      for (int x=0;x<board.width;x++)
        if (board.isBlock(x,y))
          board.setElement(x,y,Board.EMPTY);
    board.doFramesToStability();
  }

  /**
   * Removes all surrounded solids and makes empty areas there.
   *
   * @param board - the given board
   */
  public static void removeSurroundedSolids(Board board) {
    boolean[][] surrounded = new boolean[board.width][board.height];
    for (int y=1;y<board.height-1;y++)
      for (int x=1;x<board.width-1;x++)
        if (board.isSurroundedSolid(x,y))
          surrounded[x][y] = true;
    for (int y=1;y<board.height-1;y++)
      for (int x=1;x<board.width-1;x++)
        if (surrounded[x][y])
          board.setElement(x,y,Board.EMPTY);
  }

  /**
   * Converts concrete from the board to solid.
   *
   * @param board - the given board
   */
  public static void convertConcrete(Board board) {
    for (int y=0;y<board.height;y++)
      for (int x=0;x<board.width;x++)
        if (board.getType(x,y) == Board.CONCRETE)
          board.setElement(x,y,Board.SOLID);
  }

  // *************************************************************************
  // Resize
 
  /**
   * Gets the resized board. The original content (without border)
   * is copied to new board starting from given shift x and shift y.
   * Content outside the board is not copied.  
   *
   * @param board - board to be resized
   * @param width - new width
   * @param height - new height
   * @param shiftx - shift x of original content
   * @param shifty - shift y of original content
   */
  public static Board getResized(Board board,int width,int height,int shiftx,int shifty) {
    Board newBoard = new Board(width,height);
    int x1 = 0,x2 = width,y1 = 0,y2 = height;
    if (x1 < shiftx) x1 = shiftx;
    if (x2 > board.width+shiftx) x2 = board.width+shiftx;
    if (y1 < shifty) y1 = shifty;
    if (y2 > board.height+shifty) y2 = board.height+shifty;
    for (int y=y1;y<y2;y++)
      for (int x=x1;x<x2;x++) {
        newBoard.setElement(x,y,
            board.getType(x-shiftx,y-shifty),
            board.getColor(x-shiftx,y-shifty),
            board.getAction(x-shiftx,y-shifty));
      }
    return newBoard;
  }
 
  // *************************************************************************
  // Make connected
 
  /**
   * Makes a connectivity between empty or containing block fields.
   *
   * @param board - the board to be connected
   */
  public static void makeConnected(Board board) {

    final byte END= 0;
    final byte UP = 1;
    final byte RIGHT = UP+1;
    final byte DOWN = UP+2;
    final byte LEFT = UP+3;
   
    final int WEIGHT_SOLID = 1;
    final int WEIGHT_SOLID_CONCRETE = 1;
    final int WEIGHT_ELEVATOR = 50;
    final int WEIGHT_UNDER_ELEVATOR = 50;
    final int WEIGHT_NEAR_ELEVATOR = 10;
    final int WEIGHT_PAINTER = 50;
    final int WEIGHT_UNDER_PAINTER = 50;
    final int WEIGHT_NEAR_LAVA = 50;
    final int WEIGHT_LAVA = 100;
   
    int x=-1, y=-1;
    for(int i=0; i < board.width; i++)
      for(int j=0; j < board.height; j++)
        if (board.isEmpty(i,j)) {
          x = i; y = j; i = board.width; break;
        }
    if (x == -1 || y == -1) return;
 
    int [][][] tab = new int[board.width][board.height][2];
    for(int i=0; i < board.width; i++)
      for(int j=0; j < board.height; j++)
        tab[i][j][0] = Byte.MAX_VALUE; 
    tab[x][y][0] = 0;
    tab[x][y][1] = END;
    PriorityQueue<Field> queue = new PriorityQueue<Field>();
    queue.add(new Field(x,y,0));
   

    while(queue.size() > 0) {
      Field f = queue.remove();
      int posX, posY, direction;
      for (int i=0;i<4;i++) {
        switch (i) {
          case 0: posX = f.x-1; posY=f.y;   direction = LEFT;  break;
          case 1: posX = f.x;   posY=f.y-1; direction = UP;    break;
          case 2: posX = f.x;   posY=f.y+1; direction = DOWN;  break;
          case 3: posX = f.x+1; posY=f.y;   direction = RIGHT; break;
          default: assert false; posX=posY=direction=0; break;
        }
       
        if (board.isInside(posX, posY) && tab[posX][posY][0] > f.distance) {
          int type = board.getType(posX,posY);
         
          if (f.distance == 0 && isAsEmpty(posX, posY, board))  {
            tab[posX][posY][0] = 0; tab[posX][posY][1]=END;
            queue.remove(new Field(posX,posY,0));
            queue.add(new Field(posX,posY,0));
          }
         
          if (type != Board.EMPTY && !board.isBlock(posX, posY) &&
              tab[posX][posY][0] > f.distance+1) {
            if (board.getType(posX-1,posY) != Board.LAVA &&
                board.getType(posX+1,posY) != Board.LAVA &&
                board.getType(posX,posY-1) != Board.LAVA &&
                board.getType(posX,posY-1) != Board.ELEVATOR &&
                board.getType(posX,posY-1) != Board.PAINTER) {
              if (board.getType(posX-1,posY+1) == Board.ELEVATOR
                  || board.getType(posX+1,posY+1) == Board.ELEVATOR)
                tab[posX][posY][0] = f.distance+WEIGHT_NEAR_ELEVATOR;               
              else if (type == Board.CONCRETE)
                tab[posX][posY][0] = f.distance+WEIGHT_SOLID_CONCRETE;
              else if (type == Board.ELEVATOR || type == Board.ELEVATOR_ROOT)
                tab[posX][posY][0] = f.distance+WEIGHT_ELEVATOR;
              else if (type == Board.PAINTER)
                tab[posX][posY][0] = f.distance+WEIGHT_PAINTER;
              else if (type == Board.LAVA)
                tab[posX][posY][0] = f.distance+WEIGHT_LAVA;         
              else
                tab[posX][posY][0] = f.distance+WEIGHT_SOLID;              
            } else if (board.getType(posX,posY-1) == Board.ELEVATOR
                && direction == DOWN) {
              tab[posX][posY][0] = f.distance+WEIGHT_UNDER_ELEVATOR;
            } else if (board.getType(posX,posY-1) == Board.PAINTER
                && direction == DOWN) {
              tab[posX][posY][0] = f.distance+WEIGHT_UNDER_PAINTER;
            } else if ((board.getType(posX-1, posY) == Board.LAVA
                || board.getType(posX+1, posY) == Board.LAVA)
                && (direction == DOWN || direction == UP)){
              tab[posX][posY][0] = WEIGHT_NEAR_LAVA;
            } else if ((board.getType(posX, posY-1) == Board.LAVA)
                && (direction == DOWN)){
              tab[posX][posY][0] = WEIGHT_NEAR_LAVA;
            }
            tab[posX][posY][1] = direction;
            queue.remove(new Field(posX,posY,0));
            queue.add(new Field(posX,posY,tab[posX][posY][0]));
          }
         
          if ((type == Board.EMPTY || board.isBlock(posX, posY) ||
              (type == Board.ELEVATOR || type == Board.ELEVATOR_ROOT)
              && board.getType(posX, posY+1)!= Board.SOLID)
              && f.distance > 0 && tab[posX][posY][0] > f.distance+1) {
            tab[posX][posY][0] = 0; tab[posX][posY][1]=END;
            queue.remove(new Field(posX,posY,0));
            queue.add(new Field(posX,posY,0));
           
            while( direction != END) {
              if (direction == UP) posY++; else if (direction == LEFT) posX++;
              else if (direction == DOWN) posY--; else posX--;
              direction =  tab[posX][posY][1];
              tab[posX][posY][0] = 0; tab[posX][posY][1] = END;
              if (direction != END) {
                if (board.getType(posX-1, posY) == Board.LAVA)
                  board.setElement(posX-1, posY, Board.SOLID);
                if (board.getType(posX+1, posY) == Board.LAVA)
                  board.setElement(posX+1, posY, Board.SOLID);         
                queue.remove(new Field(posX,posY,0));
                queue.add(new Field(posX,posY,0));
                if (board.getType(posX, posY) == Board.ELEVATOR
                    || board.getType(posX, posY) == Board.ELEVATOR_ROOT) {
                  int k = posY;
                  while (k>0 && (board.getType(posX, k) == Board.ELEVATOR ||
                      board.getType(posX, k) == Board.ELEVATOR_ROOT)) {
                    board.setElement(posX, k, Board.EMPTY); k--;
                  }
                  k = posY+1;
                  while (k<board.height && (board.getType(posX, k) == Board.ELEVATOR ||
                      board.getType(posX, k) == Board.ELEVATOR_ROOT)) {
                    board.setElement(posX, k, Board.EMPTY); k++;
                  }
                }               
                board.setElement(posX,posY, Board.EMPTY);
              }
            }
          }
         
        }
      }     
    }
   
  }
   
  /*
   * Checks if the field should be treated like a empty during making
   * connectivity.
   *
   * @param x - field's x
   * @param y - field's y
   * @param board
   * @return true - if the field should be treated like empty
   */
  private static boolean isAsEmpty(int x, int y, Board board ) {
    int type = board.getType(x,y);
    if (type == Board.EMPTY || board.isBlock(x,y) ||
       (type == Board.ELEVATOR || type == Board.ELEVATOR_ROOT)
        && board.getType(x, y+1) != Board.SOLID)
      return true;   
    if (type == Board.ICE) {
      while (board.getType(x, y-1) == Board.ICE) y--;
      if (!board.isSolid(x, y-1)) return true;
    }
    return false;
  }


  /*
   * Class used in method makeConnected(board). Contains the field coordinates
   * and its distance from connected part of the board.
   */
  private static class Field implements Comparable<Field>{   
 
    public int x, y, distance;
   
    public Field(int x, int y, int distance) {
      this.x = x;
      this.y = y;
      this.distance = distance;
    }
       
    @Override
    public boolean equals(Object obj) {
      if (obj instanceof Field) {
        if (((Field) obj).x == x && ((Field) obj).y ==y) return true;
        else return false;       
      }
      return false;
    }

    @Override
    public int compareTo(Field f) {
      if (distance > f.distance) return 1;
      else if (distance < f.distance) return -1;
      return 0;
    }   
  }
 
}
TOP

Related Classes of generator.BoardManager

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.