/** * Copyright (C) 2013 Gundog Studios LLC. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.godsandtowers.core.grid; import java.io.BufferedReader; import java.io.Externalizable; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.ObjectInput; import java.io.ObjectOutput; import com.gundogstudios.modules.Modules; import com.gundogstudios.util.FastMath; public class Board implements Externalizable { private static final String PATH = "boards/"; private static final String SEPERATOR = ","; private Square[][] squares; private String baseTileset; private String name; public Board() { } protected Board(String name, String baseTileset, String[][] boardText) { this.name = name; this.baseTileset = baseTileset; this.squares = parse(baseTileset, boardText); } public static Board generateRandom() { Board board; Grid grid; do { board = createBoard(); grid = new Grid(board); } while (!grid.checkSquares()); return board; } private static Board createBoard() { Board board = new Board(); board.baseTileset = Boards.TILESETS[FastMath.random(0, Boards.TILESETS.length - 1)]; int row = (int) (FastMath.random() * 20 + 7); int column = (int) (FastMath.random() * 20 + 7); if (row > column) { int tmp = row; row = column; column = tmp; } board.squares = new Square[row][column]; for (int r = 0; r < row; r++) { for (int c = 0; c < column; c++) { board.squares[r][c] = new Square(r, c); } } float starts = 1; do { int c = (int) (FastMath.random() * 3); int r = (int) (FastMath.random() * row); board.squares[r][c].setStart(); } while ((FastMath.random() < (1f / ++starts))); float finishes = 1; do { int c = column - 1 - (int) (FastMath.random() * 3); int r = (int) (FastMath.random() * row); board.squares[r][c].setFinish(); } while ((FastMath.random() < (1f / ++finishes))); float count; count = 1; do { int c = (int) (FastMath.random() * column); int r = (int) (FastMath.random() * row); if (board.squares[r][c].getModel() != Square.EMPTY) continue; board.squares[r][c].setAttackRateBonus(); } while ((FastMath.random() < (1f / ++count) * 1.5f)); count = 1; do { int c = (int) (FastMath.random() * column); int r = (int) (FastMath.random() * row); if (board.squares[r][c].getModel() != Square.EMPTY) continue; board.squares[r][c].setDamageBonus(); } while ((FastMath.random() < (1f / ++count) * 1.5f)); count = 1; do { int c = (int) (FastMath.random() * column); int r = (int) (FastMath.random() * row); if (board.squares[r][c].getModel() != Square.EMPTY) continue; board.squares[r][c].setRangeBonus(); } while ((FastMath.random() < (1f / ++count) * 1.5f)); count = 1; do { int c = (int) (FastMath.random() * column); int r = (int) (FastMath.random() * row); if (board.squares[r][c].getModel() != Square.EMPTY) continue; board.squares[r][c].setTree(board.baseTileset); } while ((FastMath.random() < (1f / ++count) * 2f)); count = 1; do { int c = (int) (FastMath.random() * column); int r = (int) (FastMath.random() * row); if (board.squares[r][c].getModel() != Square.EMPTY) continue; board.squares[r][c].setRock(board.baseTileset); } while ((FastMath.random() < (1f / ++count) * 2f)); return board; } private static Square[][] parse(String baseTileset, String[][] boardText) { int rows = boardText.length; int columns = boardText[0].length; Square[][] squares = new Square[rows][columns]; for (int r = 0; r < rows; r++) { for (int c = 0; c < columns; c++) { squares[r][c] = new Square(r, c); squares[r][c].load(baseTileset, boardText[r][c]); } } if (rows > columns) { Square[][] newSquares = new Square[columns][rows]; for (int r = 0; r < rows; r++) { for (int c = 0; c < columns; c++) { newSquares[c][r] = squares[r][c]; newSquares[c][r].swap(); } } } return squares; } public static Board load(String boardName) { try { Board board = new Board(); InputStream stream = Modules.ASSETS.openInput(PATH, boardName); BufferedReader reader = new BufferedReader(new InputStreamReader(stream)); String[] header = reader.readLine().split(SEPERATOR); board.baseTileset = header[0]; int row = Integer.parseInt(header[1]); int column = Integer.parseInt(header[2]); String[][] boardText = new String[row][column]; for (int r = 0; r < row; r++) { String[] line = reader.readLine().split(SEPERATOR); for (int c = 0; c < column; c++) { boardText[r][c] = line[c]; } } board.squares = parse(board.baseTileset, boardText); stream.close(); return board; } catch (IOException e) { Modules.LOG.error("Board", "Failed to load board: " + boardName + " - " + e.getMessage()); return null; } } @Override public String toString() { StringBuilder output = new StringBuilder(); for (int r = 0; r < getRows(); r++) { output.append("\n"); for (int c = 0; c < getColumns(); c++) { output.append(squares[r][c] + ","); } } output.append("\n"); return output.toString(); } public String getBackgroundTextureName() { return baseTileset + "_ground"; } public String getWallTextureName() { return baseTileset + "_wall"; } public String getName() { return name; } public int getRows() { return squares.length; } public int getColumns() { return squares[0].length; } public Square getSquare(int row, int column) { return squares[row][column]; } @Override public void writeExternal(ObjectOutput out) throws IOException { out.writeObject(baseTileset); out.writeObject(name); out.writeObject(squares); } @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { baseTileset = (String) in.readObject(); name = (String) in.readObject(); squares = (Square[][]) in.readObject(); } }