예제 #1
0
  public int ai_move(int[][] board) {
    if (running) {
      System.out.println(
          "This AI appears to be running multiple ai_moves simultaneously. That can't be right.");
    }
    running = true;
    try {
      // System.out.println(2 + Math.random());
      if (recording) {
        if (out == null) {
          try {
            int ind = 1;
            File f = null;
            while (true) {
              try {
                Scanner sc = new Scanner(new File("AIReplay" + ind + ".txt"));
                ind++;
              } catch (Exception e) {
                break;
              }
            }
            out = new PrintWriter(new File("AIReplay" + ind + ".txt"));
            filename = "AIReplay" + ind + ".txt";
            out.println("AI Version: " + VERSION);
          } catch (Exception e) {
            System.out.println("Could not write to file.");
          }
        }
        fprint(board);
      }
      // if (fml == null) fml = new PrintWriter (new File("fmldebug.txt"));
      if (thisAIIsCheating && max(board) < 8) {
        board[0][0] = GameGUI.win_target;
      }
      if (debug2) sc.nextLine();
      if (debug2) print(board);
      if (debug) System.out.println("New cycle.");
      if (debug) sc.nextLine();
      if (dumbai) name += "Dumby";
      turn++;
      if (!queue.isEmpty()) {
        int temp = queue.removeFirst();
        if (temp > 0) {
          running = false;
          return temp;
        }
      }
      int boardsum = 0;
      for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 4; j++) {
          boardsum += board[i][j];
        }
      }
      boolean report = debug;
      /*if (Math.random() < 0.0001) {
      report = true;
      for (int i = 0; i < 4; i++) {
      	System.out.println(Arrays.toString(board[i]));
      }
      for (int i = 0; i < 4; i++) {
      	System.out.println(movable(board, i));
      }
      System.out.println();
      sc.nextLine();
      }*/
      if (dumbai) {
        if (!name.endsWith("Dumby")) name += "Dumby";
        System.out.println(turn);
        running = false;
        if (turn % 600 == 599) return KeyEvent.VK_DOWN;
        if (turn % 3 == 0) return KeyEvent.VK_UP;
        if (turn % 6 < 3) return KeyEvent.VK_LEFT;
        return KeyEvent.VK_RIGHT;
      } else {
        if (name.indexOf(".") < 0) name += VERSION;
      }
      // gamestart processing
      /*if(board[0][0] == 0) {
      	if (board[1][0] > board[0][1]) {
      		return KeyEvent.VK_UP;
      	}
      	if (board[1][0] < board[0][1]) {
      		return KeyEvent.VK_LEFT;
      	}
      	if (Math.random() < 0.5) return KeyEvent.VK_UP;
      	return KeyEvent.VK_LEFT;
      }*/
      long[] pref = {10, 20, 1, 1}; // LEFT, UP, RIGHT, DOWN

      // check if moving right/down is safe
      boolean occupied = true;

      for (int i = 0; i < 4; i++) {
        if (board[0][i] == 0) occupied = false;
        if (i < 3 && board[0][i] == board[0][i + 1]) occupied = false;
      }
      if (!occupied) {
        // pref[2] -= 100000000;
      }
      occupied = true;
      for (int i = 0; i < 4; i++) {
        if (board[i][0] == 0) occupied = false;
        if (i < 3 && board[i][0] == board[i + 1][0]) occupied = false;
      }
      if (!occupied) {
        // pref[3] -= 100000000;
      }

      pref[0] += 5;
      pref[1] += 5;

      // System.out.println(6 + Math.random());
      // simulate
      sum_board = sum(board);
      delta_sum_board_7over8 = delta(sum_board * 7 / 8);
      if (debug) print(board);
      max_depth = 0;
      for (int m = 0; m < 4; m++) {
        if (debug) System.out.println("Now testing move: " + m);
        int[][] sim = simulate(board, m);
        if (Arrays.deepEquals(sim, board)) {
          if (out != null) out.println("Move " + m + " invalid; skipping");
          if (GameGUI.out != null) GameGUI.out.println("Move " + m + " invalid; skipping");
          continue;
        }
        long worst = (long) 1999999999 * 1000000000;
        long avg = 0;
        int numt = 0;
        for (int i = 0; i < 4; i++) {
          for (int j = 0; j < 4; j++) {
            if (sim[i][j] > 0) continue;
            sim[i][j] = 2;
            long temp = predictor(sim, iter_max / (int) Math.pow((countBlank(sim) + 1), 1.6), 1);
            if (temp < worst) worst = temp;
            avg += 9 * temp;
            sim[i][j] = 4;
            temp = predictor(sim, iter_max / (int) Math.pow((countBlank(sim) + 1), 1.6), 1);
            if (temp < worst) worst = temp;
            avg += temp;
            sim[i][j] = 0;
            numt += 10;
          }
        }
        if (countBlank(sim) == 0) {
          long temp = predictor(sim, iter_max / (int) pow((countBlank(sim) + 1), 2), 1);
          if (temp < worst) worst = temp;
          avg += temp;
          numt++;
        }
        avg /= numt;
        worst = (worst_weight * worst + avg) / (worst_weight + 1);
        if (countBlank(sim) >= 8 && max(board) < 64) worst = avg;
        if (debug || debug2) System.out.println("Move " + m + " final eval: " + worst);
        if (out != null) out.println("Move " + m + " final eval: " + worst);
        if (GameGUI.out != null) GameGUI.out.println("Move " + m + " final eval: " + worst);
        pref[m] += worst;
      }
      if (debug2) System.out.println("Max depth: " + max_depth);
      if (out != null) out.println("Max depth: " + max_depth);
      if (GameGUI.out != null) GameGUI.out.println("Max depth: " + max_depth);

      // System.out.println(5 + Math.random());
      // process output
      int[] dir = new int[4];
      dir[0] = KeyEvent.VK_LEFT;
      dir[1] = KeyEvent.VK_UP;
      dir[2] = KeyEvent.VK_RIGHT;
      dir[3] = KeyEvent.VK_DOWN;
      if (report) System.out.println("Pref: " + Arrays.toString(pref));
      for (int i = 0; i < 4; i++) {
        int best = 0;
        for (int j = 0; j < 4; j++) {
          if (pref[j] > pref[best]) {
            best = j;
          }
        }
        pref[best] = Long.MIN_VALUE;
        if (movable(board, best)) {
          if (report) {
            report = false;
            if (debug) System.out.println("Chosen: " + best);
            if (debug) sc.nextLine();
          }
          // if (pref[best] < -50000000) queue.add(best - 2);
          running = false;
          return dir[best];
        }
        // System.out.println("Unmovable: " + best);
        // System.out.println("Pref: " + Arrays.toString(pref));
      }
      System.out.println("???");
      for (int i = 0; i < 4; i++) {
        System.out.println(Arrays.toString(board[i]));
      }
      // sc.nextLine();
    } catch (Exception e) {
      e.printStackTrace();
    }
    running = false;
    return KeyEvent.VK_LEFT;
  }
예제 #2
0
  public long predictor(int[][] board, int iters, int depth) { // returns future value, kinda
    // debnum+=4;
    // System.out.println(Math.random());
    if (depth > max_depth) max_depth = depth;
    // if (max(board) < 64 && depth == 1) return grade4(board);
    int div = 0;
    for (int i = 0; i < 4; i++) {
      int[][] sim = simulate(board, i);
      if (Arrays.deepEquals(sim, board)) continue;
      div += countBlank(sim);
    }
    if (!movable(board, 0) && !movable(board, 1) && !movable(board, 2) && !movable(board, 3)) {
      // if (max(board) == GameGUI.win_target) return grade(board);
      return (long) -1999999999 * 3 * sum(board);
    }
    div *= 2;
    if (div > iters) {
      // debnum-=4;
      return grade4(board);
    }
    iters /= div;
    long best = (long) -1999999999 * 800000000;
    if (debug) print(board);

    for (int m = 0; m < 4; m++) {
      // debnum--;
      int[][] sim = simulate(board, m);
      if (Arrays.deepEquals(sim, board)) continue;
      if (debug) System.out.println("Simulating: " + m);
      long worst = (long) 1999999999 * 800000000;
      long avg = 0;
      int numt = 0;
      for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 4; j++) {
          if (sim[i][j] > 0) continue;
          sim[i][j] = 2;
          long temp = predictor(sim, iters, depth + 1);
          if (temp < worst) worst = temp;
          avg += 9 * temp;
          sim[i][j] = 4;
          temp = predictor(sim, iters, depth + 1);
          if (temp < worst) worst = temp;
          avg += temp;
          sim[i][j] = 0;
          numt += 10;
        }
      }
      if (countBlank(sim) == 0) {
        // System.out.println("??");
        long temp = predictor(sim, iter_max / (int) pow((countBlank(sim) + 1), 2), depth + 1);
        if (temp < worst) worst = temp;
        avg += temp;
        numt++;
      }
      // avg -= worst;
      avg /= numt;
      if (debug) System.out.println("Result: " + worst);
      if ((avg + worst_weight * worst) / (worst_weight + 1) > best)
        best = (worst_weight * worst + avg) / (worst_weight + 1);
      // if (worst > best) best = worst;
      if (div >= 64 && max(board) < 64 && avg > best) best = avg;
    }
    return best;
  }