Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import java.io.BufferedReader;
- import java.io.File;
- import java.io.FileNotFoundException;
- import java.io.FileReader;
- import java.io.IOException;
- import java.util.ArrayList;
- import java.util.Date;
- public class Pacman7 {
- // レベル1完全探索 レベル2LRJ専用最適化 レベル3未定(現状はレベル2にVH当たり判定を付けただけ)
- final static int level = 3;
- // 足切りパラメータ
- final static int ashikiri = 5; // 1つの節に許される枝の数
- final static int cutoffset = 5; // このtまでは全枝を探索する
- final static int cutlength = 50; // 節と節の間の長さ
- final static int cutscore = 500; // tの最大値の制限
- // // レベル1参考設定
- // final static int level = 1;
- // final static int ashikiri = 0;
- // final static int cutoffset = 1;
- // final static int cutlength = 50;
- // final static int cutscore = 50;
- // // レベル2参考設定
- // final static int level = 2;
- // final static int ashikiri = 5;
- // final static int cutoffset = 5;
- // final static int cutlength = 50;
- // final static int cutscore = 250;
- // // レベル3参考設定
- // final static int level = 3;
- // final static int ashikiri = 5;
- // final static int cutoffset = 5;
- // final static int cutlength = 50;
- // final static int cutscore = 500;
- // 計算再開用 足切りパラメータや探索ロジックを変えたら無意味
- final static int skipsteps = 0;
- static int deftime = 0, defwidth = 0, defheight = 0;
- static int tsize = 0, xsize = 0, ysize = 0;
- final static int[][] move = { {0,0}, {0,1}, {-1,0}, {0,-1}, {1,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0} };
- final static int[] bits = {0, 1, 2, 4, 8, 16};
- final static int[] bitsoff = {0, 30, 29, 27, 23, 15};
- final static int cutheight = (cutscore % cutlength) > 0 ? (cutscore / cutlength + 1) * cutlength : cutscore;
- static char[][] tile = null;
- static byte[][] theory = null;
- static byte[][][][] atheory = null;
- static byte[][][][][] btheory = null;
- static byte[][][] vtheory = null;
- static byte[][][] ltheory = null;
- static byte[][][] rtheory = null;
- static byte[][] branch = null;
- static int[][] amove = null;
- static int[][] atest = null;
- static int[][][] vmove = null;
- static int[][][] hmove = null;
- static int[][][] lmove = null;
- static int[][][] rmove = null;
- static int[][][] jmove = null;
- static int vcount = 0, hcount = 0, lcount = 0, rcount = 0, jcount = 0;
- static int[][] dcountxy = null;
- static int[] dcountx = null, dcounty = null;
- static int dcount = 0;
- /**
- * @param args
- */
- public static void main(String[] args) {
- long starttime = System.currentTimeMillis();
- doPuzzle();
- long endtime = System.currentTimeMillis();
- System.out.println("" + (endtime - starttime) + "ms");
- }
- private static void doPuzzle() {
- // 問題データのファイル名 末尾に余分な改行とかがあるとヤバい
- String file_name = "pacman.txt";
- // ファイル読み込み
- ArrayList<String> strbuf = new ArrayList<String>();
- String line = null;
- try {
- File file = new File(file_name);
- BufferedReader reader = new BufferedReader(new FileReader(file));
- int pos = 0;
- line = reader.readLine();
- deftime = Integer.parseInt(line);
- line = reader.readLine();
- pos = line.indexOf(' ');
- defwidth = Integer.parseInt(line.substring(0, pos));
- defheight = Integer.parseInt(line.substring(pos + 1));
- int len = 0;
- while ((line = reader.readLine())!= null) {
- strbuf.add(line);
- len = line.length();
- xsize = (xsize > len) ? xsize : len;
- }
- ysize = strbuf.size();
- reader.close();
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- return;
- } catch (IOException e) {
- e.printStackTrace();
- return;
- }
- tsize = cutheight + 1;
- System.out.println("" + deftime + " " + defwidth + " " + defheight);
- System.out.println("" + cutheight + " " + xsize + " " + ysize);
- tile = new char[xsize][ysize];
- for (int y = 0; y < ysize; y++) {
- line = strbuf.get(y);
- for (int x = 0; x < line.length(); x++) {
- tile[x][y] = line.charAt(x);
- }
- }
- strbuf = null;
- // マップの解析
- theory = new byte[xsize][ysize];
- atheory = new byte[tsize][6][xsize][ysize];
- btheory = new byte[cutlength + 1][6][xsize][ysize][cutlength + 1];
- vtheory = new byte[6][xsize][ysize];
- ltheory = new byte[6][xsize][ysize];
- rtheory = new byte[6][xsize][ysize];
- branch = new byte[xsize][ysize];
- amove = new int[tsize][10];
- atest = new int[tsize][6];
- vmove = new int[6][tsize][4];
- hmove = new int[6][tsize][4];
- lmove = new int[6][tsize][4];
- rmove = new int[6][tsize][4];
- jmove = new int[6][tsize][4];
- dcountxy = new int[xsize][ysize];
- dcountx = new int[xsize];
- dcounty = new int[ysize];
- for (int y = 1; y < ysize - 1; y++) {
- for (int x = 1; x < xsize - 1; x++) {
- if (tile[x][y] != '#') {
- // 行き先は何方向?
- if (tile[x][y + 1] != '#') branch[x][y]++;
- if (tile[x - 1][y] != '#') branch[x][y]++;
- if (tile[x][y - 1] != '#') branch[x][y]++;
- if (tile[x + 1][y] != '#') branch[x][y]++;
- // 敵の基本方針、下左上右
- if (tile[x][y + 1] != '#') theory[x][y] = 1;
- else if (tile[x - 1][y] != '#') theory[x][y] = 2;
- else if (tile[x][y - 1] != '#') theory[x][y] = 3;
- else if (tile[x + 1][y] != '#') theory[x][y] = 4;
- // @の行動範囲を絞る
- if (tile[x][y + 1] != '#') {
- atheory[0][0][x][y] = (byte)(atheory[0][0][x][y] | 1);
- atheory[0][1][x][y] = (byte)(atheory[0][1][x][y] | 1);
- atheory[0][2][x][y] = (byte)(atheory[0][2][x][y] | 1);
- atheory[0][4][x][y] = (byte)(atheory[0][4][x][y] | 1);
- if ((level == 1) || (branch[x][y] == 1)) atheory[0][3][x][y] = (byte)(atheory[0][3][x][y] | 1);
- if ((level == 1) || (branch[x][y+1]> 2)) atheory[0][5][x][y] = (byte)(atheory[0][5][x][y] | 1);
- }
- if (tile[x - 1][y] != '#') {
- atheory[0][0][x][y] = (byte)(atheory[0][0][x][y] | 2);
- atheory[0][1][x][y] = (byte)(atheory[0][1][x][y] | 2);
- atheory[0][2][x][y] = (byte)(atheory[0][2][x][y] | 2);
- atheory[0][3][x][y] = (byte)(atheory[0][3][x][y] | 2);
- if ((level == 1) || (branch[x][y] == 1)) atheory[0][4][x][y] = (byte)(atheory[0][4][x][y] | 2);
- if ((level == 1) || (branch[x-1][y]> 2)) atheory[0][5][x][y] = (byte)(atheory[0][5][x][y] | 2);
- }
- if (tile[x][y - 1] != '#') {
- atheory[0][0][x][y] = (byte)(atheory[0][0][x][y] | 4);
- atheory[0][2][x][y] = (byte)(atheory[0][2][x][y] | 4);
- atheory[0][3][x][y] = (byte)(atheory[0][3][x][y] | 4);
- atheory[0][4][x][y] = (byte)(atheory[0][4][x][y] | 4);
- if ((level == 1) || (branch[x][y] == 1)) atheory[0][1][x][y] = (byte)(atheory[0][1][x][y] | 4);
- if ((level == 1) || (branch[x][y-1]> 2)) atheory[0][5][x][y] = (byte)(atheory[0][5][x][y] | 4);
- }
- if (tile[x + 1][y] != '#') {
- atheory[0][0][x][y] = (byte)(atheory[0][0][x][y] | 8);
- atheory[0][1][x][y] = (byte)(atheory[0][1][x][y] | 8);
- atheory[0][3][x][y] = (byte)(atheory[0][3][x][y] | 8);
- atheory[0][4][x][y] = (byte)(atheory[0][4][x][y] | 8);
- if ((level == 1) || (branch[x][y] == 1)) atheory[0][2][x][y] = (byte)(atheory[0][2][x][y] | 8);
- if ((level == 1) || (branch[x+1][y]> 2)) atheory[0][5][x][y] = (byte)(atheory[0][5][x][y] | 8);
- }
- if ((level == 1)){
- atheory[0][0][x][y] = (byte)(atheory[0][0][x][y] | 16);
- atheory[0][1][x][y] = (byte)(atheory[0][1][x][y] | 16);
- atheory[0][2][x][y] = (byte)(atheory[0][2][x][y] | 16);
- atheory[0][3][x][y] = (byte)(atheory[0][3][x][y] | 16);
- atheory[0][4][x][y] = (byte)(atheory[0][4][x][y] | 16);
- atheory[0][5][x][y] = (byte)(atheory[0][5][x][y] | 16);
- }
- // 敵の行動範囲を絞る
- switch (branch[x][y]) {
- case 1:
- if (tile[x][y + 1] != '#') {
- vtheory[3][x][y] = 1;
- ltheory[3][x][y] = 1;
- rtheory[3][x][y] = 1;
- } else if (tile[x - 1][y] != '#') {
- vtheory[4][x][y] = 2;
- ltheory[4][x][y] = 2;
- rtheory[4][x][y] = 2;
- } else if (tile[x][y - 1] != '#') {
- vtheory[1][x][y] = 3;
- ltheory[1][x][y] = 3;
- rtheory[1][x][y] = 3;
- } else if (tile[x + 1][y] != '#') {
- vtheory[2][x][y] = 4;
- ltheory[2][x][y] = 4;
- rtheory[2][x][y] = 4;
- }
- break;
- case 2:
- if (tile[x][y + 1] != '#') {
- vtheory[1][x][y] = 1;
- vtheory[2][x][y] = 1;
- vtheory[4][x][y] = 1;
- ltheory[1][x][y] = 1;
- ltheory[2][x][y] = 1;
- ltheory[4][x][y] = 1;
- rtheory[1][x][y] = 1;
- rtheory[2][x][y] = 1;
- rtheory[4][x][y] = 1;
- }
- if (tile[x - 1][y] != '#') {
- vtheory[1][x][y] = 2;
- vtheory[2][x][y] = 2;
- vtheory[3][x][y] = 2;
- ltheory[1][x][y] = 2;
- ltheory[2][x][y] = 2;
- ltheory[3][x][y] = 2;
- rtheory[1][x][y] = 2;
- rtheory[2][x][y] = 2;
- rtheory[3][x][y] = 2;
- }
- if (tile[x][y - 1] != '#') {
- vtheory[2][x][y] = 3;
- vtheory[3][x][y] = 3;
- vtheory[4][x][y] = 3;
- ltheory[2][x][y] = 3;
- ltheory[3][x][y] = 3;
- ltheory[4][x][y] = 3;
- rtheory[2][x][y] = 3;
- rtheory[3][x][y] = 3;
- rtheory[4][x][y] = 3;
- }
- if (tile[x + 1][y] != '#') {
- vtheory[1][x][y] = 4;
- vtheory[3][x][y] = 4;
- vtheory[4][x][y] = 4;
- ltheory[1][x][y] = 4;
- ltheory[3][x][y] = 4;
- ltheory[4][x][y] = 4;
- rtheory[1][x][y] = 4;
- rtheory[3][x][y] = 4;
- rtheory[4][x][y] = 4;
- }
- break;
- case 3:
- if (tile[x][y + 1] == '#') {
- vtheory[1][x][y] = 2 + 16 + 32 + 64;
- vtheory[2][x][y] = 2 + 16 + 32 + 64;
- vtheory[4][x][y] = 2 + 16 + 32 + 64;
- ltheory[1][x][y] = 4;
- ltheory[2][x][y] = 2;
- ltheory[4][x][y] = 3;
- rtheory[1][x][y] = 2;
- rtheory[2][x][y] = 3;
- rtheory[4][x][y] = 4;
- } else if (tile[x - 1][y] == '#') {
- vtheory[1][x][y] = 1 + 8 + 32 + 64;
- vtheory[2][x][y] = 1 + 8 + 32 + 64;
- vtheory[3][x][y] = 1 + 8 + 32 + 64;
- ltheory[1][x][y] = 4;
- ltheory[2][x][y] = 1;
- ltheory[3][x][y] = 3;
- rtheory[1][x][y] = 1;
- rtheory[2][x][y] = 3;
- rtheory[3][x][y] = 4;
- } else if (tile[x][y - 1] == '#') {
- vtheory[2][x][y] = 1 + 8 + 16 + 64;
- vtheory[3][x][y] = 1 + 8 + 16 + 64;
- vtheory[4][x][y] = 1 + 8 + 16 + 64;
- ltheory[2][x][y] = 1;
- ltheory[3][x][y] = 2;
- ltheory[4][x][y] = 4;
- rtheory[2][x][y] = 2;
- rtheory[3][x][y] = 4;
- rtheory[4][x][y] = 1;
- } else if (tile[x + 1][y] == '#') {
- vtheory[1][x][y] = 1 + 8 + 16 + 32;
- vtheory[3][x][y] = 1 + 8 + 16 + 32;
- vtheory[4][x][y] = 1 + 8 + 16 + 32;
- ltheory[1][x][y] = 1;
- ltheory[3][x][y] = 2;
- ltheory[4][x][y] = 3;
- rtheory[1][x][y] = 2;
- rtheory[3][x][y] = 3;
- rtheory[4][x][y] = 1;
- }
- break;
- case 4:
- vtheory[1][x][y] = 1 + 8 + 16 + 32 + 64;
- vtheory[2][x][y] = 1 + 8 + 16 + 32 + 64;
- vtheory[3][x][y] = 1 + 8 + 16 + 32 + 64;
- vtheory[4][x][y] = 1 + 8 + 16 + 32 + 64;
- ltheory[1][x][y] = 4;
- ltheory[2][x][y] = 1;
- ltheory[3][x][y] = 2;
- ltheory[4][x][y] = 3;
- rtheory[1][x][y] = 2;
- rtheory[2][x][y] = 3;
- rtheory[3][x][y] = 4;
- rtheory[4][x][y] = 1;
- break;
- }
- // オブジェクトの配置
- switch (tile[x][y]) {
- case '#': // 壁
- break;
- case ' ': // 空きマス
- break;
- case '.': // ドット
- dcount++;
- dcountx[x]++;
- dcounty[y]++;
- dcountxy[x][y]++;
- break;
- case '@': // 自機
- amove[0][0] = x;
- amove[0][1] = y;
- amove[0][3] = branch[x][y];
- amove[0][4] = -1;
- break;
- case 'V': // 敵 V
- vmove[vcount][0][0] = x;
- vmove[vcount][0][1] = y;
- vmove[vcount][0][2] = theory[x][y];
- vcount++;
- break;
- case 'H': // 敵 H
- hmove[hcount][0][0] = x;
- hmove[hcount][0][1] = y;
- hmove[hcount][0][2] = theory[x][y];
- hcount++;
- break;
- case 'L': // 敵 L
- lmove[lcount][0][0] = x;
- lmove[lcount][0][1] = y;
- lmove[lcount][0][2] = theory[x][y];
- lcount++;
- break;
- case 'R': // 敵 R
- rmove[rcount][0][0] = x;
- rmove[rcount][0][1] = y;
- rmove[rcount][0][2] = theory[x][y];
- rcount++;
- break;
- case 'J': // 敵 J
- jmove[jcount][0][0] = x;
- jmove[jcount][0][1] = y;
- jmove[jcount][0][2] = theory[x][y];
- jcount++;
- break;
- }
- }
- }
- }
- System.out.println("マップテーブル作成完了 " + new Date());
- // LRJは行動が決定的なのであらかじめ計算しておく
- for (int t = 0; t < cutheight; t++) {
- int m = 0, n = 0, x = 0, y = 0;
- for (int l = 0; l < lcount; l++) {
- m = lmove[l][t][2];
- x = lmove[l][t][0] + move[m][0];
- y = lmove[l][t][1] + move[m][1];
- lmove[l][t+1][0] = x;
- lmove[l][t+1][1] = y;
- lmove[l][t+1][2] = ltheory[m][x][y];
- }
- for (int r = 0; r < rcount; r++) {
- m = rmove[r][t][2];
- x = rmove[r][t][0] + move[m][0];
- y = rmove[r][t][1] + move[m][1];
- rmove[r][t+1][0] = x;
- rmove[r][t+1][1] = y;
- rmove[r][t+1][2] = rtheory[m][x][y];
- }
- for (int j = 0; j < jcount; j++) {
- m = jmove[j][t][2];
- x = jmove[j][t][0] + move[m][0];
- y = jmove[j][t][1] + move[m][1];
- n = jmove[j][t][3];
- if (n == 0) {
- jmove[j][t+1][0] = x;
- jmove[j][t+1][1] = y;
- jmove[j][t+1][2] = ltheory[m][x][y];
- if (branch[x][y] >= 3) n = 1;
- jmove[j][t+1][3] = n;
- } else {
- jmove[j][t+1][0] = x;
- jmove[j][t+1][1] = y;
- jmove[j][t+1][2] = rtheory[m][x][y];
- if (branch[x][y] >= 3) n = 0;
- jmove[j][t+1][3] = n;
- }
- }
- }
- System.out.println("LRJ移動テーブル作成完了 " + new Date());
- // ここからゼロシステムで未来予知
- for (int t = 1; t < tsize; t++) {
- for (int m = 0; m < 6; m++) {
- for (int x = 0; x < xsize; x++) {
- for (int y = 0; y < ysize; y++) {
- atheory[t][m][x][y] = atheory[0][m][x][y];
- }
- }
- }
- }
- // atheoryの1手読み
- for (int t = 0; t < tsize - 1; t++) {
- for (int m = 0; m < 6; m++) {
- for (int x = 1; x < xsize - 1; x++) {
- for (int y = 1; y < ysize - 1; y++) {
- if (atheory[t][m][x][y] > 0) {
- for (int c = 1; c < 5; c++) {
- if (((atheory[t][m][x][y] & bits[c])> 0) && preattack(t,x,y,x + move[c][0],y + move[c][1])) {
- atheory[t][m][x][y] = (byte)(atheory[t][m][x][y] & bitsoff[c]);
- if (branch[x+move[c][0]][y+move[c][1]] > 2) {
- atheory[t][m][x][y] = (byte)(atheory[t][m][x][y] | bits[5]);
- }
- }
- }
- if (((atheory[t][m][x][y] & bits[5])> 0) && preattack(t,x,y,x + move[5][0],y + move[5][1])) {
- atheory[t][m][x][y] = (byte)(atheory[t][m][x][y] & bitsoff[5]);
- }
- }
- }
- }
- }
- }
- // btheoryにコピー
- for (int t = 0; t < cutlength + 1; t++) {
- for (int m = 0; m < 6; m++) {
- for (int x = 1; x < xsize - 1; x++) {
- for (int y = 1; y < ysize - 1; y++) {
- btheory[t][m][x][y][0] = atheory[t + cutheight - cutlength][m][x][y];
- for (int d = 1; d < cutlength + 1; d++) {
- btheory[t][m][x][y][d] = btheory[t][m][x][y][0];
- }
- }
- }
- }
- }
- // btheoryの詰め 終盤の残りi回の移動をLRJから逃げ切る
- for (int i = 2; i < cutlength + 1; i++) {
- for (int t = 0; t < cutlength; t++) {
- for (int m = 0; m < 6; m++) {
- for (int x = 1; x < xsize - 1; x++) {
- for (int y = 1; y < ysize - 1; y++) {
- if (t > cutlength - i) {
- btheory[t][m][x][y][i] = 0;
- } else {
- for (int c = 1; c < 6; c++) {
- if (btheory[t+1][c][x+move[c][0]][y+move[c][1]][i-1] == 0) btheory[t][m][x][y][i] = (byte)(btheory[t][m][x][y][i] & bitsoff[c]);
- }
- }
- }
- }
- }
- }
- }
- // atheoryの詰め 中盤までの移動をLRJから逃げ切る
- for (int t = cutheight - cutlength - 1; t >= 0; t--) {
- for (int m = 0; m < 6; m++) {
- for (int x = 1; x < xsize - 1; x++) {
- for (int y = 1; y < ysize - 1; y++) {
- for (int c = 1; c < 6; c++) {
- if (atheory[t+1][c][x+move[c][0]][y+move[c][1]] == 0) atheory[t][m][x][y] = (byte)(atheory[t][m][x][y] & bitsoff[c]);
- }
- }
- }
- }
- }
- System.out.println("@移動テーブル作成完了 " + new Date());
- // 基本となる探索ループ
- int bestscore = cutscore;
- int beststeps = 0;
- int finishcount = 0;
- int offsetcount = 0;
- long searchcount = 0;
- int t = 0;
- int m = 0, x = 0, y = 0, x2 = 0, y2 = 0;
- while (true) {
- x = amove[t][0];
- y = amove[t][1];
- // 移動方針が決まってない=この枝がこのtに初めて来た場合
- if (amove[t][4] < 0) {
- // ドットを食べよう
- if (dcountxy[x][y] > 0) {
- dcountxy[x][y]--;
- dcountx[x]--;
- dcounty[y]--;
- dcount--;
- amove[t][5] = 1;
- } else {
- amove[t][5] = 0;
- }
- amove[t][6] = dcount;
- amove[t][7] = dcount;
- // フィニッシュ
- if (dcount == 0) {
- finishcount++;
- if (bestscore > t) {
- bestscore = t;
- beststeps = offsetcount;
- System.out.println("" + finishcount + "フィニッシュ" + bestscore + " " + new Date());
- for (int tt = 0; tt < t; tt++) {
- System.out.print("?jhkl.".charAt(amove[tt][2]));
- }
- System.out.println();
- // フィニッシュした枝には足切りボーナス
- if (ashikiri > 0) {
- if (cutheight > cutlength) amove[cutheight - cutlength][8] += cutlength * cutlength;
- if (cutheight > cutlength * 2) amove[cutheight - cutlength * 2][8] += cutlength;
- }
- }
- while ((t >= 0) && (amove[t][4] <= 0)){
- if (amove[t][5] > 0) {
- x = amove[t][0];
- y = amove[t][1];
- dcount++;
- dcountx[x]++;
- dcounty[y]++;
- dcountxy[x][y]++;
- }
- t--;
- }
- if (t < 0) break;
- continue;
- }
- if (t == cutoffset) {
- offsetcount++;
- System.out.println("" + amove[0][4] + "-" + offsetcount + " " + new Date());
- if (skipsteps > offsetcount) {
- while ((t >= 0) && (amove[t][4] <= 0)){
- if (amove[t][5] > 0) {
- x = amove[t][0];
- y = amove[t][1];
- dcount++;
- dcountx[x]++;
- dcounty[y]++;
- dcountxy[x][y]++;
- }
- t--;
- }
- if (t < 0) break;
- continue;
- }
- } else if (t == cutheight - cutlength) {
- searchcount++;
- }
- // 足切り
- if (ashikiri > 0) {
- if ((t % cutlength) == 0) {
- if (t == cutlength) {
- if (--amove[cutoffset][8] < 0) {
- int rollback = cutoffset;
- while ((t >= 0) && ((t > rollback) || (amove[t][4] <= 0))){
- if (amove[t][5] > 0) {
- x = amove[t][0];
- y = amove[t][1];
- dcount++;
- dcountx[x]++;
- dcounty[y]++;
- dcountxy[x][y]++;
- }
- t--;
- }
- if (t < 0) break;
- continue;
- }
- } else if (t > 0) {
- if (--amove[(t - cutlength)][8] < 0) {
- int rollback = t - cutlength;
- while ((t >= 0) && ((t > rollback) || (amove[t][4] <= 0))){
- if (amove[t][5] > 0) {
- x = amove[t][0];
- y = amove[t][1];
- dcount++;
- dcountx[x]++;
- dcounty[y]++;
- dcountxy[x][y]++;
- }
- t--;
- }
- if (t < 0) break;
- continue;
- }
- }
- }
- }
- // 手遅れ
- if (dcount >= (bestscore - t)) {
- while ((t >= 0) && (amove[t][4] <= 0)){
- if (amove[t][5] > 0) {
- x = amove[t][0];
- y = amove[t][1];
- dcount++;
- dcountx[x]++;
- dcounty[y]++;
- dcountxy[x][y]++;
- }
- t--;
- }
- if (t < 0) break;
- continue;
- }
- // VHの移動処理
- int vx = 0, vy = 0, vm = 0;
- for (int v = 0; v < vcount; v++) {
- vm = vmove[v][t][2];
- if (vm > 4) { vm = vthink(v, t); }
- vx = vmove[v][t][0] + move[vm][0];
- vy = vmove[v][t][1] + move[vm][1];
- vmove[v][t+1][0] = vx;
- vmove[v][t+1][1] = vy;
- vmove[v][t+1][2] = vtheory[vm][vx][vy];
- }
- for (int h = 0; h < hcount; h++) {
- vm = hmove[h][t][2];
- if (vm > 4) { vm = hthink(h, t); }
- vx = hmove[h][t][0] + move[vm][0];
- vy = hmove[h][t][1] + move[vm][1];
- hmove[h][t+1][0] = vx;
- hmove[h][t+1][1] = vy;
- hmove[h][t+1][2] = vtheory[vm][vx][vy];
- }
- // @の移動方針を決める
- if (t == 0) athink(t, x, y, 0); else athink(t, x, y, amove[t-1][2]);
- // 打つ手が無い
- if (amove[t][4] == 0) {
- while ((t >= 0) && (amove[t][4] <= 0)){
- if (amove[t][5] > 0) {
- x = amove[t][0];
- y = amove[t][1];
- dcount++;
- dcountx[x]++;
- dcounty[y]++;
- dcountxy[x][y]++;
- }
- t--;
- }
- if (t < 0) break;
- continue;
- }
- }
- // いよいよ@が移動しますよ
- amove[t][4]--;
- amove[t][8] = ashikiri;
- m = atest[t][amove[t][4]];
- amove[t][2] = m;
- x2 = x + move[m][0];
- y2 = y + move[m][1];
- // 敵に捕まった
- if (level % 2 == 1) {
- if (attack(t,x,y,x2,y2)) {
- while ((t >= 0)&&(amove[t][4] <= 0)) {
- if (amove[t][5] > 0) {
- x = amove[t][0];
- y = amove[t][1];
- dcount++;
- dcountx[x]++;
- dcounty[y]++;
- dcountxy[x][y]++;
- }
- t--;
- }
- if (t < 0) break;
- continue;
- }
- }
- // 時間が流れてゆく
- t++;
- x = amove[t-1][0] + move[amove[t-1][2]][0];
- y = amove[t-1][1] + move[amove[t-1][2]][1];
- amove[t][0] = x;
- amove[t][1] = y;
- amove[t][2] = 0;
- amove[t][3] = branch[x][y];
- amove[t][4] = -1;
- }
- // 結果は途中で出るので最後は要約だけ 探索指数は終盤に差し掛かった枝の数
- System.out.println("" + finishcount + "パターン" + bestscore + " step" + beststeps + " 探索指数" + searchcount + " "+ new Date());
- }
- // ∴さて‥‥どこへ行こうか?
- private static void athink(int t, int x, int y, int m) {
- int[] result = new int[6];
- int rescount = 0;
- int flags = (t >= (cutheight - cutlength)) ? btheory[t - (cutheight - cutlength)][m][x][y][dcount] : atheory[t][m][x][y];
- // 手詰まり
- if (flags == 0) {
- amove[t][4] = 0;
- return;
- }
- // 立ち止まる
- if ((flags & bits[5]) > 0) {
- result[rescount++] = 5;
- flags = flags & bitsoff[5];
- }
- // 一方向にしか進めない時は考える必要もない
- if ((flags != 1)&&(flags != 2)&&(flags != 4)&&(flags != 8)) {
- // 目の前の餌
- if (flags > 0) {
- if ((y - ysize / 2) > 0) {
- if (((flags & bits[1]) > 0) && (dcountxy[x][y + 1] > 0)) {
- result[rescount++] = 1;
- flags = flags & bitsoff[1];
- }
- if ((x - xsize / 2) > 0) {
- if (((flags & bits[4]) > 0) && (dcountxy[x + 1][y] > 0)) {
- result[rescount++] = 4;
- flags = flags & bitsoff[4];
- }
- if (((flags & bits[2]) > 0) && (dcountxy[x - 1][y] > 0)) {
- result[rescount++] = 2;
- flags = flags & bitsoff[2];
- }
- } else {
- if (((flags & bits[2]) > 0) && (dcountxy[x - 1][y] > 0)) {
- result[rescount++] = 2;
- flags = flags & bitsoff[2];
- }
- if (((flags & bits[4]) > 0) && (dcountxy[x + 1][y] > 0)) {
- result[rescount++] = 4;
- flags = flags & bitsoff[4];
- }
- }
- if (((flags & bits[3]) > 0) && (dcountxy[x][y - 1] > 0)) {
- result[rescount++] = 3;
- flags = flags & bitsoff[3];
- }
- } else {
- if (((flags & bits[3]) > 0) && (dcountxy[x][y - 1] > 0)) {
- result[rescount++] = 3;
- flags = flags & bitsoff[3];
- }
- if ((x - xsize / 2) > 0) {
- if (((flags & bits[4]) > 0) && (dcountxy[x + 1][y] > 0)) {
- result[rescount++] = 4;
- flags = flags & bitsoff[4];
- }
- if (((flags & bits[2]) > 0) && (dcountxy[x - 1][y] > 0)) {
- result[rescount++] = 2;
- flags = flags & bitsoff[2];
- }
- } else {
- if (((flags & bits[2]) > 0) && (dcountxy[x - 1][y] > 0)) {
- result[rescount++] = 2;
- flags = flags & bitsoff[2];
- }
- if (((flags & bits[4]) > 0) && (dcountxy[x + 1][y] > 0)) {
- result[rescount++] = 4;
- flags = flags & bitsoff[4];
- }
- }
- if (((flags & bits[1]) > 0) && (dcountxy[x][y + 1] > 0)) {
- result[rescount++] = 1;
- flags = flags & bitsoff[1];
- }
- }
- // すぐ近くの餌
- if (flags > 0) {
- if ((y - ysize / 2) > 0) {
- if (((flags & bits[1]) > 0) && (dcountxy[x][y + 2] > 0)) {
- result[rescount++] = 1;
- flags = flags & bitsoff[1];
- }
- if ((x - xsize / 2) > 0) {
- if (((flags & bits[4]) > 0) && (dcountxy[x + 2][y] > 0)) {
- result[rescount++] = 4;
- flags = flags & bitsoff[4];
- }
- if (((flags & bits[2]) > 0) && (dcountxy[x - 2][y] > 0)) {
- result[rescount++] = 2;
- flags = flags & bitsoff[2];
- }
- } else {
- if (((flags & bits[2]) > 0) && (dcountxy[x - 2][y] > 0)) {
- result[rescount++] = 2;
- flags = flags & bitsoff[2];
- }
- if (((flags & bits[4]) > 0) && (dcountxy[x + 2][y] > 0)) {
- result[rescount++] = 4;
- flags = flags & bitsoff[4];
- }
- }
- if (((flags & bits[3]) > 0) && (dcountxy[x][y - 2] > 0)) {
- result[rescount++] = 3;
- flags = flags & bitsoff[3];
- }
- } else {
- if (((flags & bits[3]) > 0) && (dcountxy[x][y - 2] > 0)) {
- result[rescount++] = 3;
- flags = flags & bitsoff[3];
- }
- if ((x - xsize / 2) > 0) {
- if (((flags & bits[4]) > 0) && (dcountxy[x + 2][y] > 0)) {
- result[rescount++] = 4;
- flags = flags & bitsoff[4];
- }
- if (((flags & bits[2]) > 0) && (dcountxy[x - 2][y] > 0)) {
- result[rescount++] = 2;
- flags = flags & bitsoff[2];
- }
- } else {
- if (((flags & bits[2]) > 0) && (dcountxy[x - 2][y] > 0)) {
- result[rescount++] = 2;
- flags = flags & bitsoff[2];
- }
- if (((flags & bits[4]) > 0) && (dcountxy[x + 2][y] > 0)) {
- result[rescount++] = 4;
- flags = flags & bitsoff[4];
- }
- }
- if (((flags & bits[1]) > 0) && (dcountxy[x][y + 2] > 0)) {
- result[rescount++] = 1;
- flags = flags & bitsoff[1];
- }
- }
- // 餌が多そうな方
- if (flags > 0) {
- int xl = 0, xh = 0, yl = 0, yh = 0;
- for (int xx = 0; xx < x; xx++) {
- xl += dcountx[xx];
- }
- for (int xx = x + 1; xx < xsize; xx++) {
- xh += dcountx[xx];
- }
- for (int yy = 0; yy < y; yy++) {
- yl += dcounty[yy];
- }
- for (int yy = 0; yy < ysize; yy++) {
- yh += dcounty[yy];
- }
- xl = xl * (xsize - x - 1) * ysize;
- xh = xh * (x - 1) * ysize;
- yl = yl * (ysize - y - 1) * xsize;
- yh = yh * (y - 1) * xsize;
- int xlh = (xl > xh) ? xl : xh;
- int ylh = (yl > yh) ? yl : yh;
- if (xlh > ylh) {
- if (xl > xh) {
- if ((flags & bits[2]) > 0) {
- result[rescount++] = 2;
- flags = flags & bitsoff[2];
- }
- if (yl > yh) {
- if ((flags & bits[3]) > 0) {
- result[rescount++] = 3;
- flags = flags & bitsoff[3];
- }
- } else {
- if ((flags & bits[1]) > 0) {
- result[rescount++] = 1;
- flags = flags & bitsoff[1];
- }
- }
- } else {
- if ((flags & bits[4]) > 0) {
- result[rescount++] = 4;
- flags = flags & bitsoff[4];
- }
- if (yl > yh) {
- if ((flags & bits[3]) > 0) {
- result[rescount++] = 3;
- flags = flags & bitsoff[3];
- }
- } else {
- if ((flags & bits[1]) > 0) {
- result[rescount++] = 1;
- flags = flags & bitsoff[1];
- }
- }
- }
- } else {
- if (yl > yh) {
- if ((flags & bits[3]) > 0) {
- result[rescount++] = 3;
- flags = flags & bitsoff[3];
- }
- if (xl > xh) {
- if ((flags & bits[2]) > 0) {
- result[rescount++] = 2;
- flags = flags & bitsoff[2];
- }
- } else {
- if ((flags & bits[4]) > 0) {
- result[rescount++] = 4;
- flags = flags & bitsoff[4];
- }
- }
- } else {
- if ((flags & bits[1]) > 0) {
- result[rescount++] = 1;
- flags = flags & bitsoff[1];
- }
- if (xl > xh) {
- if ((flags & bits[2]) > 0) {
- result[rescount++] = 2;
- flags = flags & bitsoff[2];
- }
- } else {
- if ((flags & bits[4]) > 0) {
- result[rescount++] = 4;
- flags = flags & bitsoff[4];
- }
- }
- }
- }
- }
- }
- }
- }
- // 落ち穂拾い
- if (flags > 0) {
- for (int i = 1; i < 6; i++) {
- if ((flags & bits[i]) > 0) {
- result[rescount++] = i;
- }
- }
- }
- // 事実上の戻り値に代入
- for (int i = 0; i < rescount; i++) {
- atest[t][i] = result[rescount - i - 1];
- }
- amove[t][4] = rescount;
- return;
- }
- // Vは考えた
- private static int vthink(int v, int t) {
- int vx = vmove[v][t][0];
- int vy = vmove[v][t][1];
- int ax = amove[t][0];
- int ay = amove[t][1];
- int dx = ax - vx;
- int dy = ay - vy;
- if (dy != 0) {
- if (dy > 0) {
- if (tile[vx][vy + 1] != '#') return 1;
- } else {
- if (tile[vx][vy - 1] != '#') return 3;
- }
- }
- if (dx != 0) {
- if (dx > 0) {
- if (tile[vx + 1][vy] != '#') return 4;
- } else {
- if (tile[vx - 1][vy] != '#') return 2;
- }
- }
- return theory[vx][vy];
- }
- // Hは考えた
- private static int hthink(int h, int t) {
- int hx = hmove[h][t][0];
- int hy = hmove[h][t][1];
- int ax = amove[t][0];
- int ay = amove[t][1];
- int dx = ax - hx;
- int dy = ay - hy;
- if (dx != 0) {
- if (dx > 0) {
- if (tile[hx + 1][hy] != '#') return 4;
- } else {
- if (tile[hx - 1][hy] != '#') return 2;
- }
- }
- if (dy != 0) {
- if (dy > 0) {
- if (tile[hx][hy + 1] != '#') return 1;
- } else {
- if (tile[hx][hy - 1] != '#') return 3;
- }
- }
- return theory[hx][hy];
- }
- // 当たり判定 LRJ
- private static boolean preattack(int t, int x1, int y1, int x2, int y2) {
- for (int l = 0; l < lcount; l++) {
- if ((lmove[l][t][0] == x2)&&(lmove[l][t][1] == y2)&&(lmove[l][t+1][0] == x1)&&(lmove[l][t+1][1] == y1)) return true;
- if ((lmove[l][t+1][0] == x2)&&(lmove[l][t+1][1] == y2)) return true;
- }
- for (int r = 0; r < rcount; r++) {
- if ((rmove[r][t][0] == x2)&&(rmove[r][t][1] == y2)&&(rmove[r][t+1][0] == x1)&&(rmove[r][t+1][1] == y1)) return true;
- if ((rmove[r][t+1][0] == x2)&&(rmove[r][t+1][1] == y2)) return true;
- }
- for (int j = 0; j < jcount; j++) {
- if ((jmove[j][t][0] == x2)&&(jmove[j][t][1] == y2)&&(jmove[j][t+1][0] == x1)&&(jmove[j][t+1][1] == y1)) return true;
- if ((jmove[j][t+1][0] == x2)&&(jmove[j][t+1][1] == y2)) return true;
- }
- return false;
- }
- // 当たり判定 VH
- private static boolean attack(int t, int x1, int y1, int x2, int y2) {
- for (int v = 0; v < vcount; v++) {
- if ((vmove[v][t][0] == x2)&&(vmove[v][t][1] == y2)&&(vmove[v][t+1][0] == x1)&&(vmove[v][t+1][1] == y1)) return true;
- if ((vmove[v][t+1][0] == x2)&&(vmove[v][t+1][1] == y2)) return true;
- }
- for (int h = 0; h < hcount; h++) {
- if ((hmove[h][t][0] == x2)&&(hmove[h][t][1] == y2)&&(hmove[h][t+1][0] == x1)&&(hmove[h][t+1][1] == y1)) return true;
- if ((hmove[h][t+1][0] == x2)&&(hmove[h][t+1][1] == y2)) return true;
- }
- return false;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement