// 最も近いユニットナンバー
 public int mostNear(int id1, int i, int id2) {
   int nearUnit = 0;
   int nearLength = 10;
   int length = 0;
   for (int j = 0; j < 3; j++) {
     length = GameBoard.distance(this.board.unitLocation[id1][i], this.board.unitLocation[id2][j]);
     if (length < nearLength) {
       nearUnit = j;
       nearLength = length;
     }
   }
   return nearUnit;
 }
Beispiel #2
0
  /**
   * ユニットを任意の場所に動かす
   *
   * <p>2015/08/31追加 失敗する条件は次の通り ・現在の座標と移動先の座標が同じ場合 ・座標が範囲外を参照した場合 ・移動距離が1マス以上を超えた場合
   *
   * @param x 動かした先の座標
   * @param y 動かした先の座標
   * @param index 動かすユニット番号 0-3
   * @return trure 成功 false 失敗
   */
  public boolean movePos(int x, int y, int index) {
    int id = this.whoIsPlay();

    //  範囲外参照チェック
    if (!GameBoard.availableArea(x, y)) {
      return false;
    }

    //  距離が0もしくは2以上の移動は無効
    if (GameBoard.distance(unitLocation[id][index], new Point(x, y)) != 1) {
      return false;
    }

    unitLocation[id][index].x = x;
    unitLocation[id][index].y = y;

    this.lastIndex = index;
    this.lastX = x;
    this.lastY = y;
    this.lastId = this.whoIsPlay();

    nextPhase();
    return true;
  }
  @Override
  public double STATIC_VALUE() {
    double score = 0.0;
    int enemyTeamId = playerTeamId == 0 ? 1 : 0;

    //  点数さによる評価
    //  バイアスをかけておかないとマイナスになる可能性がある
    score += k1 * (board.teamPoint[playerTeamId] - board.teamPoint[enemyTeamId] + 100);

    //  自分のユニットとタワーまでの距離
    //  2015/09/03変更
    //  平均値が小さく、分散が小さいものを選択する
    int eDist = 0;
    int pDist = 0;
    for (int i = 0; i < 4; i++) {
      pDist +=
          Math.pow(
              GameBoard.distanceTower(board.unitLocation[playerTeamId][i]),
              2); //  距離が多くなればなるほど点数が下がる
      eDist += Math.pow(GameBoard.distanceTower(board.unitLocation[enemyTeamId][i]), 2); //
    }

    score += k2 * (-pDist + eDist + 100);

    //  保持状態
    int tower = 0;
    for (int i = 0; i < 3; i++) {
      if (board.towerHold[i] == playerTeamId) {
        tower++;
      } else {
        tower--;
      }
    }
    score += k3 * (tower + 3);

    //  相性評価
    int length = 0;
    for (int i = 0; i < 3; i++) { // 全ての駒に対して
      int MNE = mostNear(playerTeamId, i, enemyTeamId); // MNE = mostNearEnemy
      Point P = this.board.unitLocation[playerTeamId][i];
      Point E = this.board.unitLocation[enemyTeamId][MNE];
      if (multiple(i, playerTeamId) < multiple(MNE, enemyTeamId)) // 相手のほうが多い
      {
        length -= GameBoard.distance(P, E);
      } else if (multiple(MNE, enemyTeamId) < multiple(i, playerTeamId)) // 自分のほうが多い
      {
        length += multiple(MNE, enemyTeamId);
      } else { // 同数
        if ((i != 3 && i == MNE + 1) || (i == 3 && MNE == 0)) // 勝てる時
        {
          length += multiple(MNE, enemyTeamId);
        } else if ((i != 0 && i == MNE - 1) || (i == 0 && MNE == 3)) // 負ける時
        {
          length -= GameBoard.distance(P, E);
        }
        // 引き分けは加算無し
      }
    }
    score += k4 * length;

    //  最後に打った手が自分の手ならマイナスを付けておく
    // if(board.lastId==playerTeamId) score = -score;
    //  現在の局面が相手なら
    /*
    if (playerTeamId == board.whoIsPlay()) {
        score = -score;
    }
            */
    this.score = score;
    return score;
  }