package Logic;/* * Copyright (C) 2014 Saeed Masoumi & Saeed Rajabzade. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301 USA */ /* in class ro static kardam chon tooye bazi faghat ye naghshe darim ke hamun aval tarif mishe ... */ import mahyarise.common.GameObjectID; import mahyarise.judge.GameManager; import java.util.ArrayList; import java.util.Arrays; // Need refactor public class Map { private static final int MB_LEFT_LANE_RIGHT_PATTERN[][] = {{11,11,11,12}, {11,11,11,12}, {11,11,11,12}, {11,11,11,12}, {11,11,11,12}}; private static final int MB_RIGHT_LANE_LEFT_PATTERN[][] = {{12,11,11,11}, {12,11,11,11}, {12,11,11,11}, {12,11,11,11}, {12,11,11,11}}; private static final int MB_UP_LANE_DOWN_PATTERN[][] = {{11,11,11,11,11}, {11,11,11,11,11}, {11,11,11,11,11}, {12,12,12,12,12}}; private static final int MB_DOWN_LANE_UP_PATTERN[][] = {{12,12,12,12,12}, {11,11,11,11,11}, {11,11,11,11,11}, {11,11,11,11,11}}; // num for patterns ... private static final int NUM_MBL_LR = 101; private static final int NUM_MBR_LL = 102; private static final int NUM_MBU_LD = 103; private static final int NUM_MBD_LU = 104; private static final int[][] HQ_PATTERN = {{10,10,10,10,10}, {10,10,10,10,10}, {10,10,10,10,10}, {10,10,10,10,10}, {10,10,10,10,10}}; private int columnsLength, rowsLength; private Cell[][] cells; public Map() { } public Map(Cell[][] cells) { this.cells = cells; } /** * @param col * @param row * Map Builder for Judge */ public Map(int col ,int row) { cells = new Cell[row][col]; this.columnsLength = col; this.rowsLength = row; } public Map(int[][] types) { columnsLength = types.length; rowsLength = types[0].length; cells = new Cell[rowsLength][columnsLength]; for (int col = 0; col < columnsLength; col++) for (int row = 0; row < rowsLength; row++) { cells[row][col] = new Cell(types[row][col], col, row); } } public void loadMap(int[][] types) { cells = new Cell[rowsLength][columnsLength]; for (int row = 0; row < types.length; row++) for (int col = 0; col < types[0].length; col++) { cells[row][col] = new Cell(types[row][col], col, row); } findHeadQuarters(); this.markingPath(); // mark paths -> 0, 1, 2 this.pathFinding(); // mark cells -> 0, 1, 2, 3, 4 } public Cell getCell(int col, int row) { return cells[row][col]; } public void setColumnsLength(int columnsLength) { this.columnsLength = columnsLength; } public void setRowsLength(int rowsLength) { this.rowsLength = rowsLength; } public int getRowsLength() { return rowsLength; } public int getColLength() { return columnsLength; } public void setCellsType(int type, int col, int row) { cells[row][col] = new Cell(type, col, row); } public int getCellsType(int col, int row) { return cells[row][col].getType(); } public int getLaneNum(int col, int row) {return cells[row][col].getLaneNum();} // TODO convert ArrayList to 2D Array directly public void findHeadQuarters() { boolean mathHQhasBeenMarked = false; for (int col = columnsLength - HQ_PATTERN[0].length ; col >= 0; col--) for (int row = 0; row <= rowsLength - HQ_PATTERN.length; row++) { int[][] pattern = new int[HQ_PATTERN.length][HQ_PATTERN[0].length]; for (int i = row; i < row + 5; i++) for (int j = col; j < col + 5; j++) pattern[i - row][j - col] = cells[i][j].getType(); if (Arrays.deepEquals(pattern, HQ_PATTERN)) { if (mathHQhasBeenMarked) { Game.getTeamCE().getHeadQuarter().setLeftUpCornerCell(cells[row][col]); } else Game.getTeamMath().getHeadQuarter().setLeftUpCornerCell(cells[row][col]); mathHQhasBeenMarked = true; } } Game.getTeamCE().getHeadQuarter().setHQInCells(); Game.getTeamMath().getHeadQuarter().setHQInCells(); } public boolean isOutOfMap(int col, int row) { return col < 0 || row < 0 || col >= columnsLength || row >= columnsLength; } private boolean isNotHQ(int col, int row) { return isOutOfMap(col, row) && (cells[row][col].getType() != GameState.CELL_TYPE_HQ); } public void pathFinding() { for (int col = 0; col < columnsLength; col++) for(int row = 0; row < rowsLength; row ++) { if (cells[row][col].isPath()) { for (int distance = 0; ; distance ++) { if (isOutOfPath(col + distance, row) || isOutOfPath(col - distance, row) || isOutOfPath(col, row + distance) || isOutOfPath(col, row - distance) || isOutOfPath(col + distance, row + distance) || isOutOfPath(col - distance, row - distance) || isOutOfPath(col + distance, row - distance) || isOutOfPath(col - distance, row + distance)) { cells[row][col].setLaneNum(distance); break; } } } } this.markingWays(); } public void markingWays() { for (int col = 0; col <= columnsLength - MB_RIGHT_LANE_LEFT_PATTERN[0].length; col++) for (int row = 0; row <= rowsLength - MB_RIGHT_LANE_LEFT_PATTERN.length; row++) { int[][] pattern = new int[MB_RIGHT_LANE_LEFT_PATTERN.length][MB_RIGHT_LANE_LEFT_PATTERN[0].length]; for (int i = row; i < row + MB_RIGHT_LANE_LEFT_PATTERN.length; i++) for (int j = col; j < col + MB_RIGHT_LANE_LEFT_PATTERN[0].length; j++) { pattern[i - row][j - col] = cells[i][j].getType(); } if (Arrays.deepEquals(pattern, MB_RIGHT_LANE_LEFT_PATTERN)) { mark(NUM_MBR_LL, col, row); findMilitaryBases(NUM_MBR_LL, col, row); } else if (Arrays.deepEquals(pattern, MB_LEFT_LANE_RIGHT_PATTERN)) { mark(NUM_MBL_LR, col, row); findMilitaryBases(NUM_MBL_LR, col, row); } } for (int col = 0; col <= columnsLength - MB_DOWN_LANE_UP_PATTERN[0].length; col++) for (int row = 0; row <= rowsLength - MB_DOWN_LANE_UP_PATTERN.length; row++) { int [][] pattern = new int[MB_DOWN_LANE_UP_PATTERN.length][MB_DOWN_LANE_UP_PATTERN[0].length]; for (int i = row; i < row + MB_DOWN_LANE_UP_PATTERN.length; i++) for (int j = col; j < col + MB_DOWN_LANE_UP_PATTERN[0].length; j++) { pattern[i - row][j - col] = cells[i][j].getType(); } if (Arrays.deepEquals(pattern, MB_DOWN_LANE_UP_PATTERN)) { mark(NUM_MBD_LU, col, row); findMilitaryBases(NUM_MBD_LU, col, row); } else if (Arrays.deepEquals(pattern, MB_UP_LANE_DOWN_PATTERN)) { mark(NUM_MBU_LD, col, row); findMilitaryBases(NUM_MBU_LD, col, row); } } } public void findMilitaryBases(int patternType, int col, int row) { int index = 0; Cell[] lane = new Cell[5]; int teamID = 1; if (patternType == NUM_MBR_LL) { for (int i = row; i < row + 5; i++) { lane[index++] = cells[i][col]; if (cells[i][col + 4].getObjectsList().contains(Game.getTeamCE().getHeadQuarter())) teamID = GameState.TEAM_CE; if (cells[i][col + 4].getObjectsList().contains(Game.getTeamMath().getHeadQuarter())) teamID = GameState.TEAM_MATH; } // if ((col > columnsLength/2) || (col == columnsLength/2 && row < rowsLength/2)) // teamID = GameState.TEAM_MATH; // else teamID = GameState.TEAM_CE; MilitaryBase mb = new MilitaryBase(GameObjectID.create(MilitaryBase.class), Game.getTeamByID(teamID), GameState.ORIENTATION_VERTICAL, cells[row][col + 1]); Game.getTeamByID(teamID).getMilitaryBases().put(lane[0].getPathNum(), mb); mb.setLane(lane); mb.setPathNumber(lane[0].getPathNum()); } else if (patternType == NUM_MBL_LR) { for (int i = row; i < row + 5; i++) { lane[index++] = cells[i][col + 3]; if (cells[i][col - 1].getObjectsList().contains(Game.getTeamCE().getHeadQuarter())) teamID = GameState.TEAM_CE; if (cells[i][col - 1].getObjectsList().contains(Game.getTeamMath().getHeadQuarter())) teamID = GameState.TEAM_MATH; } MilitaryBase mb = new MilitaryBase(GameObjectID.create(MilitaryBase.class), Game.getTeamByID(teamID), GameState.ORIENTATION_VERTICAL, cells[row][col]); Game.getTeamByID(teamID).getMilitaryBases().put(lane[0].getPathNum(), mb); mb.setLane(lane); mb.setPathNumber(lane[0].getPathNum()); } else if (patternType == NUM_MBD_LU) { for (int i = col; i < col + 5; i++) { lane[index++] = cells[row][i]; if (cells[row + 4][i].getObjectsList().contains(Game.getTeamCE().getHeadQuarter())) teamID = GameState.TEAM_CE; if (cells[row + 4][i].getObjectsList().contains(Game.getTeamMath().getHeadQuarter())) teamID = GameState.TEAM_MATH; } if ((col > columnsLength/2) || (col == columnsLength/2 && row < rowsLength/2)) teamID = GameState.TEAM_MATH; else teamID = GameState.TEAM_CE; MilitaryBase mb = new MilitaryBase(GameObjectID.create(MilitaryBase.class), Game.getTeamByID(teamID), GameState.ORIENTATION_HORIZONTAL, cells[row + 1][col]); Game.getTeamByID(teamID).getMilitaryBases().put(lane[0].getPathNum(), mb); mb.setLane(lane); mb.setPathNumber(lane[0].getPathNum()); } else if (patternType == NUM_MBU_LD) { for (int i = col; i < col + 5; i++) { lane[index++] = cells[row + 3][i]; if (cells[row - 1][i].getObjectsList().contains(Game.getTeamCE().getHeadQuarter())) teamID = GameState.TEAM_CE; if (cells[row - 1][i].getObjectsList().contains(Game.getTeamMath().getHeadQuarter())) teamID = GameState.TEAM_MATH; } if ((col > columnsLength/2) || (col == columnsLength/2 && row < rowsLength/2)) teamID = GameState.TEAM_MATH; else teamID = GameState.TEAM_CE; MilitaryBase mb = new MilitaryBase(GameObjectID.create(MilitaryBase.class), Game.getTeamByID(teamID), GameState.ORIENTATION_HORIZONTAL, cells[row][col]); Game.getTeamByID(teamID).getMilitaryBases().put(lane[0].getPathNum(), mb); mb.setLane(lane); mb.setPathNumber(lane[0].getPathNum()); } } public void mark(int patternNum, int col, int row) { ArrayList<Cell> isChecked = new ArrayList<Cell>(); int x = 0; if (patternNum == NUM_MBD_LU) { for (int i = col; i < MB_DOWN_LANE_UP_PATTERN[0].length + col; i++) { DFS_forWays(i, row, cells[row][i].getLaneNum(), x++, isChecked); } } //TODO need some refactorings :D else if (patternNum == NUM_MBU_LD) { for (int i = col; i < MB_UP_LANE_DOWN_PATTERN[0].length + col; i++) { DFS_forWays(i, row + MB_UP_LANE_DOWN_PATTERN.length, cells[row + MB_UP_LANE_DOWN_PATTERN.length][i].getLaneNum(), x++, isChecked); } } else if (patternNum == NUM_MBR_LL) { for (int i = row; i < MB_RIGHT_LANE_LEFT_PATTERN.length + row; i++) { DFS_forWays(col, row, cells[i][col].getLaneNum(), x++, isChecked); } } else { for (int i = row; i < MB_LEFT_LANE_RIGHT_PATTERN.length + row; i++) { DFS_forWays(col + MB_LEFT_LANE_RIGHT_PATTERN[0].length, i, cells[i][col + MB_LEFT_LANE_RIGHT_PATTERN[0].length].getLaneNum(), x++, isChecked); } } } public void DFS_forWays(int col, int row, int laneNumber, int mark, ArrayList<Cell> checkedList) { if (checkedList.contains(cells[row][col]) || cells[row][col].getLaneNum() != laneNumber) return; checkedList.add(cells[row][col]); cells[row][col].setLaneNum(mark); for (int i = -1; i <= 1; i += 2) { if (!isOutOfPath(col, row + i) && cells[row + i][col].getLaneNum() == laneNumber) DFS_forWays(col, row + i, laneNumber, mark, checkedList); if (!isOutOfPath(col + i, row) && cells[row][col + i].getLaneNum() == laneNumber) DFS_forWays(col + i, row, laneNumber, mark, checkedList); // if (DFS(col + i, row, laneNumber, checkedList) || DFS(col, row + i,laneNumber, checkedList)) // { // break; // } } } public boolean isOutOfPath(int col, int row) { if (col < 0 || col >= columnsLength || row < 0 || row >= rowsLength || cells[row][col].getType() == Cell.CELL_TYPE_UNUSED || cells[row][col].getType() == Cell.CELL_TYPE_HQ) return true; return false; } public void markingPath() { ArrayList<Cell> checkedList = new ArrayList<Cell>(); int x = 0; for (int row = 0; row < rowsLength; row++) for (int col = 0; col < columnsLength; col++) { if (!checkedList.contains(cells[row][col]) && cells[row][col].getType() == GameState.CELL_TYPE_LANE) DFS_forPath(col, row, checkedList, x++); } } public void DFS_forPath(int col, int row, ArrayList<Cell> checkedList, int x) { if (checkedList.contains(cells[row][col])) return; checkedList.add(cells[row][col]); cells[row][col].setPathNum(x); for (int i = -1; i <= 1; i += 2) { if (!isOutOfPath(col, row + i) && cells[row + i][col].getType() == GameState.CELL_TYPE_LANE) DFS_forPath(col, row + i, checkedList, x); if (!isOutOfPath(col + i, row) && cells[row][col + i].getType() == GameState.CELL_TYPE_LANE) DFS_forPath(col + i, row, checkedList, x); } } public void printMapLaneNumbers() { for (int row = 0; row < rowsLength; row++) { for (int col = 0; col < columnsLength; col++) { System.out.print(cells[row][col].getLaneNum() + " "); } System.out.println(); } } public void printPathNumbers() { for (int row = 0; row < rowsLength; row++) { for (int col = 0; col < columnsLength; col++) { System.out.print(cells[row][col].getPathNum() + " "); } System.out.println(); } } }