Ejemplo n.º 1
0
  /**
   * Luo uusi pelilauta, aiemman pohjalta. Pelataan uusi siirto koordinaatteihin x,y sen pelaajan
   * puolesta jonka vuoro nyt on. Herrasmiessopimuksella siirto -1, -1 tarkoittaa passausta.
   *
   * @param lauta
   * @param x
   * @param y
   */
  public Node(Pelilauta lauta, int x, int y) {
    this.x = x;
    this.y = y;
    this.simple = Pelilauta.toSimple(x, y);

    lauta.changeTurn();
    this.turn = lauta.getTurn();
    lauta.changeTurn();
    this.raveVierailut = 8;
    this.raveVoitot = 2;
    this.vierailut = 4;
    this.voitot = 1;
    tieBreaker = r.nextDouble();
  }
Ejemplo n.º 2
0
  /**
   * Päättää mitä siirtoja tästä nodesta eteenpäin ylipäätään tullaan harkitsemaan. Tämänhetkinen
   * versio ottaa satunnaisesti 20 pistettä.
   */
  public void expand(Pelilauta lauta) {
    boolean[] visited = new boolean[Pelilauta.getKoko() * Pelilauta.getKoko()];
    int pisteita;
    Pino<Node> lapsiJono = new Pino<>();

    for (int i = 0; i < visited.length; i++) {
      visited[i] = true;
    }
    int offset = r.nextInt(visited.length);
    int indeksi = 0;
    int uusiX, uusiY;
    pisteita = CriticalPointObserver.getCapturePoints(lauta, lapsiJono, visited);
    while ((indeksi < visited.length) && (pisteita < branchingFactor)) {
      uusiX = Pelilauta.toX((indeksi + offset) % visited.length);
      uusiY = Pelilauta.toY((indeksi + offset) % visited.length);
      if (visited[(indeksi + offset) % visited.length]) {
        visited[(indeksi + offset) % visited.length] =
            false; // Varmistetaan että samaa siirtoa ei lasketa moneen kertaan

        if (PlacementHandler.onkoLaillinenSiirto(lauta, uusiX, uusiY)) {
          lapsiJono.add(new Node(lauta, uusiX, uusiY));
          pisteita++;
          indeksi = 0;
          offset = r.nextInt(visited.length);
          continue;
        }
      }
      indeksi++;
    }

    Node passaus = new Node(lauta, -1, -1);
    lapsiJono.add(passaus);
    pisteita++;

    Node[] pisteet = new Node[pisteita];
    for (int i = 0; i < pisteita; i++) {
      pisteet[i] = lapsiJono.pop();
    }
    this.children = new NodenLapset(pisteet);
  }
Ejemplo n.º 3
0
  private void updateRAVE(Pino<Node> visited, int tulos, int[] amafTaulu) {
    Node currentNode;

    int lapsiIndeksi;

    while (visited.IsNotEmpty()) {
      currentNode = visited.pop();
      currentNode.vierailut++;
      if ((currentNode.getTurn() == Pelilauta.VALKEA && tulos > 0)
          || (currentNode.getTurn() == Pelilauta.MUSTA && tulos < 0)) {
        currentNode.voitot++;
      }

      lapsiIndeksi = 0;
      for (int i = Pelilauta.getKoko() * Pelilauta.getKoko() - 1; i >= 0; i--) {
        if (currentNode.children == null || lapsiIndeksi == currentNode.children.getKoko()) {
          break;
        }

        if (currentNode.children.getNode(lapsiIndeksi).getSimple() > i) {
          throw new IllegalStateException("Rave rikki");
        }
        if (currentNode.children.getNode(lapsiIndeksi).getSimple() == i) {
          if (amafTaulu[i] == currentNode.getTurn()) {
            currentNode.children.getNode(lapsiIndeksi).raveVierailut++;
            if ((currentNode.getTurn() == Pelilauta.MUSTA
                    && tulos > 0) // Värit käännetty koska kyse lapsista.
                || (currentNode.getTurn() == Pelilauta.VALKEA
                    && tulos < 0)) { // hiukan epäselvä tapa mutta toiminee.
              currentNode.children.getNode(lapsiIndeksi).raveVoitot++;
            }
          }
          lapsiIndeksi++;
        }
      }
    }
  }
Ejemplo n.º 4
0
  public static int simulScore(Pelilauta lauta) {
    int x;
    int y;
    double pisteet = -1 * GoAI.simulateKomi; // Alkuarvo on komi, valkealle annettava etu.
    /*
    Stone scoring + silmien lasku
    */
    int kivenvari;
    for (int i = 0; i < Pelilauta.getKoko() * Pelilauta.getKoko(); i++) {
      kivenvari = lauta.getRisteys(Pelilauta.toX(i), Pelilauta.toY(i));
      if (kivenvari == Pelilauta.MUSTA) {
        pisteet++;
      } else if (kivenvari == Pelilauta.VALKEA) {
        pisteet--;
      } else { // Tyhjä risteys
        x = Pelilauta.toX(i);
        y = Pelilauta.toY(i);

        if (lauta.getRisteys(x + 1, y) == Pelilauta.MUSTA
            || lauta.getRisteys(x - 1, y) == Pelilauta.MUSTA
            || lauta.getRisteys(x, y - 1) == Pelilauta.MUSTA
            || lauta.getRisteys(x, y + 1) == Pelilauta.MUSTA) {
          pisteet++;
        }
        if (lauta.getRisteys(x + 1, y) == Pelilauta.VALKEA
            || lauta.getRisteys(x - 1, y) == Pelilauta.VALKEA
            || lauta.getRisteys(x, y - 1) == Pelilauta.VALKEA
            || lauta.getRisteys(x, y + 1) == Pelilauta.VALKEA) {
          pisteet--;
        }
      }
    }
    // GoAI.piirraLauta(lauta);
    // System.out.println(pisteet + ", ");
    if (pisteet + GoAI.simulateKomi - Pelilauta.getKomi()
        > 0) { // NOTE: Simulate komi is added and real komi taken away, not the other way around.
      GoAI.actuaSimulateWins++;
    }
    GoAI.actualSimulateGames++;
    if (pisteet > 0) {
      return 1;
    }
    return -1;
  }
Ejemplo n.º 5
0
  /**
   * simuloi pelin. Pelaa sarjan siirtoja.
   *
   * @return Pelilauta, kun simulaatio on päättynyt. Laudalla ei pitäisi olla yhtäkään kuollutta
   *     ryhmää, ja silmien tulisi olla yhden pisteen kokoisia.
   */
  public static Pelilauta simulate(Pelilauta lauta, int[] amafTaulu) {
    int[] vapaatpisteet;
    int offset;
    int x, y;

    boolean noSensibleMovesLeft = false;
    boolean loytyiSiirto;

    while (!noSensibleMovesLeft && lauta.getMoveNumber() < 700) {
      vapaatpisteet = lauta.getMahdollisetPisteet();

      loytyiSiirto = false;
      if (lauta.isPassedOnLastMove()) {
        noSensibleMovesLeft = true;
      }
      if (vapaatpisteet != null) {
        if (CriticalPointObserver.getSelfAtariMove() != -1) {
          x = Pelilauta.toX(CriticalPointObserver.getSelfAtariMove());
          y = Pelilauta.toY(CriticalPointObserver.getSelfAtariMove());

          if (!PlacementHandler.tuhoaakoSiirtoOmanSilman(lauta, x, y)) {
            if (amafTaulu[Pelilauta.toSimple(x, y)] == 0) {
              amafTaulu[Pelilauta.toSimple(x, y)] = lauta.getTurn();
            }
            PlacementHandler.pelaaSiirto(lauta, x, y);
            noSensibleMovesLeft = false;
            loytyiSiirto = true;
            continue;
          }
        }

        offset = r.nextInt(vapaatpisteet.length);

        for (int i = 0; i < vapaatpisteet.length; i++) {
          x = Pelilauta.toX(vapaatpisteet[(i + offset) % vapaatpisteet.length]);
          y = Pelilauta.toY(vapaatpisteet[(i + offset) % vapaatpisteet.length]);
          if (!PlacementHandler.tuhoaakoSiirtoOmanSilman(lauta, x, y)) {
            if (amafTaulu[Pelilauta.toSimple(x, y)] == 0) {
              amafTaulu[Pelilauta.toSimple(x, y)] = lauta.getTurn();
            }
            PlacementHandler.pelaaSiirto(lauta, x, y);
            noSensibleMovesLeft = false;
            loytyiSiirto = true;
            break;
          }
        }
      }
      if (!loytyiSiirto) {
        PlacementHandler.pass(lauta);
      }
    }
    // GoAI.piirraLauta(lauta);
    /*String debug = "\n";
    for (int j = Pelilauta.getKoko() - 1; j >= 0; j--) {
    debug += "   ";
    for (int i = 0; i < Pelilauta.getKoko(); i++) {
    if (lauta.getRisteys(i, j) == Pelilauta.MUSTA) {
    debug += " " + "X" + " ";
    }
    else if (lauta.getRisteys(i, j) == Pelilauta.VALKEA) {
    debug += " " + "O" + " ";
    }
    else {
    debug += " " + "." + " ";
    }
    }
    debug += "\n";
    }
    GTP.logger.info(debug);*/
    return lauta;
  }
Ejemplo n.º 6
0
 public void setSimple(int simple) {
   this.x = Pelilauta.toX(simple);
   this.y = Pelilauta.toY(simple);
 }
Ejemplo n.º 7
0
 public static Pelilauta bayesSimulate(Pelilauta lauta, int[] amafTaulu) {
   double probability;
   double maxProbability;
   int maxSimple;
   while (lauta.getMoveNumber() < 700) {
     maxSimple = -1;
     maxProbability = -1;
     for (int i = 0; i < Pelilauta.getKoko() * Pelilauta.getKoko(); i++) {
       if (!PlacementHandler.onkoLaillinenSiirto(lauta, Pelilauta.toX(i), Pelilauta.toY(i))
           || PlacementHandler.tuhoaakoSiirtoOmanSilman(
               lauta, Pelilauta.toX(i), Pelilauta.toY(i))) {
         continue;
       }
       probability = 0;
       for (int k = -1; k < 2; k++) {
         for (int l = -1; l < 2; l++) {
           if (Pelilauta.onLaudalla(Pelilauta.toX(i) + k, Pelilauta.toY(i) + l)) {
             if (lauta.getTurn() == Pelilauta.MUSTA) {
               probability +=
                   Pattern.patternMovePredictions(
                       Pattern.match(lauta, Pelilauta.toX(i) + k, Pelilauta.toY(i) + l), -k, -l);
             } else {
               probability +=
                   Pattern.patternMovePredictions(
                       Pattern.swapColors(
                           Pattern.match(lauta, Pelilauta.toX(i) + k, Pelilauta.toY(i) + l)),
                       -k,
                       -l);
             }
           }
         }
       }
       if (probability > maxProbability) {
         maxSimple = i;
       }
     }
     if (maxSimple == -1) {
       if (lauta.isPassedOnLastMove()) {
         break;
       }
       PlacementHandler.pass(lauta);
       continue;
     }
     PlacementHandler.pelaaSiirto(lauta, Pelilauta.toX(maxSimple), Pelilauta.toY(maxSimple));
     if (amafTaulu[maxSimple] == 0) {
       amafTaulu[maxSimple] = lauta.getTurn();
     }
   }
   // System.err.println("Siirtoja: " + lauta.getMoveNumber());
   return lauta;
 }
Ejemplo n.º 8
0
 public int getSimple() {
   return Pelilauta.toSimple(x, y);
 }
Ejemplo n.º 9
0
  public double[] bayesExpand2(Pelilauta lauta, int max) {
    this.children = new NodenLapset();
    double[] values = new double[Pelilauta.getKoko() * Pelilauta.getKoko()];
    double[] negatives = new double[values.length];
    double sum;
    Node node;
    children.setMaxKoko(max);
    int pattern;
    int location;
    for (int i = 0; i < values.length; i++) {
      values[i] = 0;
    }
    for (int i = 0; i < Pelilauta.getKoko() * Pelilauta.getKoko(); i++) {
      if (!PlacementHandler.onkoLaillinenSiirto(lauta, Pelilauta.toX(i), Pelilauta.toY(i))) {
        continue;
      }
      pattern = Pattern.match(lauta, Pelilauta.toX(i), Pelilauta.toY(i));
      if (lauta.getTurn() == Pelilauta.VALKEA) {
        pattern = Pattern.swapColors(pattern);
      }

      for (int k = -1; k < 2; k++) {
        for (int l = -1; l < 2; l++) {
          if (Pelilauta.onLaudalla(Pelilauta.toX(i) + k, Pelilauta.toY(i) + l)) {
            location = Pelilauta.toSimple(Pelilauta.toX(i) + k, Pelilauta.toY(i) + l);
            // values[location] += Math.log(Pattern.patternMovePredictions(pattern, k, l)) -
            // Math.log(Pattern.patternMovePredictions(pattern, k, l));
            values[location] += Pattern.patternMovePredictions(pattern, k, l);
          }
        }
      }
    }
    sum = 0;
    for (int i = 0; i < Pelilauta.getKoko() * Pelilauta.getKoko(); i++) {
      if (!PlacementHandler.onkoLaillinenSiirto(lauta, Pelilauta.toX(i), Pelilauta.toY(i))) {
        continue;
      }
      sum += values[i];
    }

    for (int i = 0; i < values.length; i++) {
      if (!PlacementHandler.onkoLaillinenSiirto(lauta, Pelilauta.toX(i), Pelilauta.toY(i))) {
        continue;
      }
      values[i] = values[i] / (sum);
      node = new Node(lauta, Pelilauta.toX(i), Pelilauta.toY(i));
      node.raveVierailut += 5000 * values[i];
      node.raveVoitot += (node.raveVierailut * 56) / 100;
      this.children.addNode(node);
    }
    children.sort();
    return values;
  }
Ejemplo n.º 10
0
  public void bayesExpand(Pelilauta lauta) {
    double[] values = new double[Pelilauta.getKoko() * Pelilauta.getKoko()];
    int[] strengths = new int[values.length];
    children = new NodenLapset();
    double boardSum = 0.0;
    int strengthOfPrediction = 0;
    Node newNode;

    for (int i = 0; i < values.length; i++) {
      values[i] = Pattern.valueOf(Pattern.match(lauta, Pelilauta.toX(i), Pelilauta.toY(i)));
      strengths[i] = Pattern.getSeenTotal(Pattern.match(lauta, Pelilauta.toX(i), Pelilauta.toY(i)));
      boardSum += values[i];
      strengthOfPrediction +=
          Pattern.getSeenTotal(Pattern.match(lauta, Pelilauta.toX(i), Pelilauta.toY(i)));
    }
    Pelilauta testiLauta;
    double difference;
    int differenceInStrength;
    for (int i = 0; i < values.length; i++) {
      if (!PlacementHandler.onkoLaillinenSiirto(lauta, Pelilauta.toX(i), Pelilauta.toY(i))) {
        continue;
      }
      difference = 0.0;
      differenceInStrength = 0;
      testiLauta = lauta.kopioi();
      PlacementHandler.pelaaSiirto(testiLauta, Pelilauta.toX(i), Pelilauta.toY(i));
      for (int x = -1; x < 2; x++) {
        for (int y = -1; y < 2; y++) {
          if (Pelilauta.onLaudalla(Pelilauta.toX(i) + x, Pelilauta.toY(i) + y)) {
            difference +=
                values[i]
                    - Pattern.valueOf(
                        Pattern.match(testiLauta, Pelilauta.toX(i) + x, Pelilauta.toY(i) + y));
            differenceInStrength +=
                strengths[i]
                    - Pattern.getSeenTotal(
                        Pattern.match(testiLauta, Pelilauta.toX(i), Pelilauta.toY(i)));
          }
        }
      }
      newNode = new Node(lauta, Pelilauta.toX(i), Pelilauta.toY(i));
      newNode.raveVierailut =
          (int) Math.round(Math.log(strengthOfPrediction - differenceInStrength) * 1000);
      if (lauta.getTurn() == Pelilauta.MUSTA) {
        newNode.raveVoitot =
            (int)
                Math.round(
                    newNode.raveVierailut * (1 / (1 + Math.pow(Math.E, boardSum - difference))));
      } else {
        newNode.raveVoitot =
            (int)
                Math.round(
                    newNode.raveVierailut
                        * (1 - (1 / (1 + Math.pow(Math.E, boardSum - difference)))));
      }
      if (1.0 * newNode.raveVoitot / newNode.raveVierailut > 0.44) {
        children.addNode(newNode);
      }
    }
    children.setMaxKoko(branchingFactor);
    Node passaus = new Node(lauta, -1, -1);
    children.addNode(passaus);
    children.sort();
  }
Ejemplo n.º 11
0
  /**
   * Yrittää parhaalta vaikuttavaa siirtoa, simuloi siitä edespäin pelin loppuun saakka, ja
   * päivittää jokaisen MC-puun solmun matkan varrella tällä tuloksella.
   */
  public void selectAction(Pelilauta lauta) {
    Pelilauta currentLauta = lauta.kopioi();
    int[] amafTaulu = new int[Pelilauta.getKoko() * Pelilauta.getKoko()];

    if (isNoLegalMovesAvailable()) {
      return;
    }
    Pino<Node> visited = new Pino<>();
    visited.add(this);
    Node currentNode = this;
    int tulos;

    while (!currentNode.isLeaf()) {
      if (raveSuoritukset == 0) {
        currentNode = currentNode.select();
        PlacementHandler.pelaaSiirto(currentLauta, currentNode.getX(), currentNode.getY());
      } else {
        currentNode = currentNode.selectRAVE(currentNode.vierailut);
        if ((Pelilauta.toSimple(currentNode.getX(), currentNode.getY()) > -1)
            && (amafTaulu[Pelilauta.toSimple(currentNode.getX(), currentNode.getY())] == 0)) {
          amafTaulu[Pelilauta.toSimple(currentNode.getX(), currentNode.getY())] =
              currentNode.getTurn();
        }
        PlacementHandler.pelaaSiirto(currentLauta, currentNode.getX(), currentNode.getY());
      }
      visited.add(currentNode);
    }
    // currentNode.bayesExpand2(currentLauta, branchingFactor);
    currentNode.expand(currentLauta);

    if (raveSuoritukset == 0) {
      currentNode = currentNode.select();
      PlacementHandler.pelaaSiirto(currentLauta, currentNode.getX(), currentNode.getY());
    } else {
      currentNode = currentNode.selectRAVE(currentNode.vierailut);
      if (currentNode.getX() == -1
          && currentNode.getY() == -1
          && currentLauta.isPassedOnLastMove()) {
        tulos = -1;
        if (GTP.score(currentLauta) > 0) {
          tulos = 1;
        }

        updateRAVE(visited, tulos, amafTaulu);

        currentNode.children = null;

        return;
      }
      if ((Pelilauta.toSimple(currentNode.getX(), currentNode.getY()) > -1)
          && (amafTaulu[Pelilauta.toSimple(currentNode.getX(), currentNode.getY())] == 0)) {
        amafTaulu[Pelilauta.toSimple(currentNode.getX(), currentNode.getY())] =
            currentNode.getTurn();
      }
      PlacementHandler.pelaaSiirto(currentLauta, currentNode.getX(), currentNode.getY());
    }

    visited.add(currentNode);

    currentLauta = currentNode.simulate(currentLauta, amafTaulu);
    tulos = simulScore(currentLauta);

    if (raveSuoritukset == 0) {
      update(visited, tulos);
    } else {
      updateRAVE(visited, tulos, amafTaulu);
    }
    return;
  }