package loon.srpg.field; import loon.utils.CollectionUtils; /** * Copyright 2008 - 2011 * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. * * @project loonframework * @author chenpeng * @email:ceponline@yahoo.com.cn * @version 0.1 */ public class SRPGFieldMove { public int[][] moves; private int[][] needs; private static SRPGFieldMove instance; public static SRPGFieldMove getInstance(int[][] res) { if (instance == null) { instance = new SRPGFieldMove(res); } else { instance.set(res); } return instance; } public SRPGFieldMove(int[][] res) { this.set(res); } public void set(int[][] res) { this.moves = CollectionUtils.copyOf(res); } public int[][] getFieldCopy() { return CollectionUtils.copyOf(moves); } public int[][] moveArea(int x, int y, int size) { return moveArea(x, y, -1, -1, size); } public int[][] moveArea(int x, int y, int w, int h) { if (!movePossible(x, y, w, h)) { return null; } else { return moveArea(x, y, w, h, -1); } } public int[][] moveArea(int cx, int cy, int cw, int ch, int size) { int x = moves[0].length; int y = moves.length; this.needs = new int[y][x]; boolean[][] res = new boolean[y][x]; int[][] res1 = new int[y][x]; for (int j = 0; j < y; j++) { for (int i = 0; i < x; i++) { needs[j][i] = -1; res[j][i] = false; res1[j][i] = moves[j][i]; } } this.needs[cy][cx] = 0; res1[cy][cx] = 0; int index = 1; for (int i = 1; size == -1 || i <= size; i++) { boolean flag = false; int x1 = cx - index - 1; int y1 = cy - index - 1; int x2 = cx + index + 1; int y2 = cy + index + 1; if (x1 < 0) { x1 = 0; } if (y1 < 0) { y1 = 0; } if (x2 > x) { x2 = x; } if (y2 > y) { y2 = y; } for (int c1 = y1; c1 < y2; c1++) { for (int c2 = x1; c2 < x2; c2++) { if (res1[c1][c2] != 0) { continue; } if (c2 - 1 > -1) { res[c1][c2 - 1] = true; } if (c1 - 1 > -1) { res[c1 - 1][c2] = true; } if (c2 + 1 < x) { res[c1][c2 + 1] = true; } if (c1 + 1 < y) { res[c1 + 1][c2] = true; } } } for (int c1 = y1; c1 < y2; c1++) { for (int c2 = x1; c2 < x2; c2++) { if (!res[c1][c2] || res1[c1][c2] <= 0) { continue; } res1[c1][c2]--; if (res1[c1][c2] == 0 && needs[c1][c2] == -1) { needs[c1][c2] = i; flag = true; } } } if (cw != -1 && ch != -1 && needs[ch][cw] != -1) { break; } if (flag) { index++; } } return res1; } public int[][] moveRoute(int x1, int y1, int x2, int y2, int size) { int moveArea[][] = moveArea(x1, y1, size); int width = moveArea[0].length; int height = moveArea.length; if (x2 < 0 || y2 < 0 || x2 >= width || y2 >= height) { return null; } if (moveArea[y2][x2] != 0 || x1 == x2 && y1 == y2) { return null; } int[][] pos = new int[size][2]; pos[0][0] = x2; pos[0][1] = y2; for (int i = 1; i < size; i++) { pos[i][0] = -1; pos[i][1] = -1; } int moveX = x2; int moveY = y2; int index = size; int count = 1; do { if (count >= size) { break; } int csize = size + 1; int mx = moveX; int my = moveY; for (int j = 0; j < 4; j++) { moveX = (((j - 2) + 1) % 2) * -1 + mx; moveY = ((j - 2) % 2) * -1 + my; if (moveX < width && moveY < height && moveX > -1 && moveY > -1 && csize > needs[moveY][moveX] && needs[moveY][moveX] != -1) { csize = needs[moveY][moveX]; pos[count][0] = moveX; pos[count][1] = moveY; } } moveX = pos[count][0]; moveY = pos[count][1]; if (moveX == x1 && moveY == y1) { index = count; break; } count++; } while (true); int[][] result = new int[index][2]; for (int j = 0; j < index; j++) { for (int i = 0; i < 2; i++) { result[index - j - 1][i] = pos[j][i]; } } return result; } public int[][] movePower(int x, int y, int size) { moveArea(x, y, size); return needs; } public int[][] movePower(int x1, int y1, int x2, int y2) { moveArea(x1, y1, x2, y2); return needs; } public boolean[][] movePossible(int x, int y) { int mx = moves[0].length; int my = moves.length; boolean[][] res1 = new boolean[my][mx]; boolean[][] res2 = new boolean[my][mx]; int[][] movePossible = new int[my][mx]; for (int j = 0; j < my; j++) { for (int i = 0; i < mx; i++) { res1[j][i] = false; res2[j][i] = false; movePossible[j][i] = moves[j][i]; } } res1[y][x] = true; res2[y][x] = true; boolean flag = true; for (int count = 0; flag; count++) { flag = false; int nx1 = x - count - 1; int ny1 = y - count - 1; int nx2 = x + count + 2; int ny2 = y + count + 2; if (nx1 < 0) { nx1 = 0; } if (ny1 < 0) { ny1 = 0; } if (nx2 > mx) { nx2 = mx; } if (ny2 > my) { ny2 = my; } for (int j = ny1; j < ny2; j++) { for (int i = nx1; i < nx2; i++) { if (!res2[j][i]) { continue; } if (i - 1 > -1 && movePossible[j][i - 1] != -1) { res1[j][i - 1] = true; } if (j - 1 > -1 && movePossible[j - 1][i] != -1) { res1[j - 1][i] = true; } if (i + 1 < mx && movePossible[j][i + 1] != -1) { res1[j][i + 1] = true; } if (j + 1 < my && movePossible[j + 1][i] != -1) { res1[j + 1][i] = true; } } } for (int j = ny1; j < ny2; j++) { for (int i = nx1; i < nx2; i++) if (res1[j][i] && !res2[j][i]) { res2[j][i] = true; flag = true; } } } return res2; } public boolean movePossible(int x1, int y1, int x2, int y2) { return movePossible(x1, y1)[y2][x2]; } }