/**
   * Returns a FieldIndex which Keeps a count on how many times a particular field is used with an
   * equality check in the sinks.
   */
  private FieldIndex registerFieldIndex(
      final int index, final InternalReadAccessor fieldExtractor) {
    FieldIndex fieldIndex = null;

    // is linkedlist null, if so create and add
    if (this.hashedFieldIndexes == null) {
      this.hashedFieldIndexes = new LinkedList<FieldIndex>();
      fieldIndex = new FieldIndex(index, fieldExtractor);
      this.hashedFieldIndexes.add(fieldIndex);
    }

    // still null, so see if it already exists
    if (fieldIndex == null) {
      fieldIndex = findFieldIndex(index);
    }

    // doesn't exist so create it
    if (fieldIndex == null) {
      fieldIndex = new FieldIndex(index, fieldExtractor);
      this.hashedFieldIndexes.add(fieldIndex);
    }

    fieldIndex.increaseCounter();

    return fieldIndex;
  }
  private FieldIndex findFieldIndex(final int index) {
    for (FieldIndex node = this.hashedFieldIndexes.getFirst();
        node != null;
        node = node.getNext()) {
      if (node.getIndex() == index) {
        return node;
      }
    }

    return null;
  }
  public void byPassModifyToBetaNode(
      final InternalFactHandle factHandle,
      final ModifyPreviousTuples modifyPreviousTuples,
      final PropagationContext context,
      final InternalWorkingMemory workingMemory) {
    final Object object = factHandle.getObject();

    // We need to iterate in the same order as the assert
    if (this.hashedFieldIndexes != null) {
      // Iterate the FieldIndexes to see if any are hashed
      for (FieldIndex fieldIndex = this.hashedFieldIndexes.getFirst();
          fieldIndex != null;
          fieldIndex = fieldIndex.getNext()) {
        if (!fieldIndex.isHashed()) {
          continue;
        }
        // this field is hashed so set the existing hashKey and see if there is a sink for it
        final AlphaNode sink = (AlphaNode) this.hashedSinkMap.get(new HashKey(fieldIndex, object));
        if (sink != null) {
          // only alpha nodes are hashable
          sink.getObjectSinkPropagator()
              .byPassModifyToBetaNode(factHandle, modifyPreviousTuples, context, workingMemory);
        }
      }
    }

    // propagate unhashed
    if (this.hashableSinks != null) {
      for (ObjectSinkNode sink = this.hashableSinks.getFirst();
          sink != null;
          sink = sink.getNextObjectSinkNode()) {
        // only alpha nodes are hashable
        ((AlphaNode) sink)
            .getObjectSinkPropagator()
            .byPassModifyToBetaNode(factHandle, modifyPreviousTuples, context, workingMemory);
      }
    }

    if (this.otherSinks != null) {
      // propagate others
      for (ObjectSinkNode sink = this.otherSinks.getFirst();
          sink != null;
          sink = sink.getNextObjectSinkNode()) {
        // compound alpha, lianode or betanode
        sink.byPassModifyToBetaNode(factHandle, modifyPreviousTuples, context, workingMemory);
      }
    }
  }
Exemplo n.º 4
0
  private static ArrayList<SkillType> FindTowersInCluster(boolean[][] cluster, Player player) {
    // checks if there is a piece in front of the given piece,
    // if there is, there might be a tower; calling specific find-tower functions
    // does this for all 8 directions.

    ArrayList<Towers> towerList = new ArrayList<Towers>();
    for (int nx = 0;
        nx < Gameboard.COLUMNS_AND_ROWS;
        nx++) { // checking for all elements in the cluster...
      for (int ny = 0; ny < Gameboard.COLUMNS_AND_ROWS; ny++) {
        if (cluster[nx][ny]) {

          for (int i = 0; i < 8; i++) { // ...in all directions
            FieldIndex f = new FieldIndex(nx, ny);
            FieldIndex start = f.Up(i);
            if (start.Valid() && cluster[start.x()][start.y()]) {
              towerList.addAll(FindShootTower(i, start, cluster));
              towerList.addAll(FindBuildTower(i, start, cluster));
              if (i < 4) {
                towerList.addAll(FindSilenceTower(i, start, cluster));
                towerList.addAll(FindFiveTower(i, start, cluster));
              }
              if (i < 2) {
                towerList.addAll(FindMultipleSkillsTower(i, start, cluster));
              }
            }
          }
        }
      }
    }
    ArrayList<SkillType> skillList = new ArrayList<SkillType>();
    // marking the positions of the towers as built:

    // Gdx.app.log("Tower", "found "+Integer.toString(towerList.size())+" towers:");
    for (Towers t : towerList) {
      // Gdx.app.log("", t.toString());
      if (!player.isSilenced()) {
        for (FieldIndex f : t.tower) {
          if (!f.Valid()) {
            Gdx.app.error("Tower", "Invalid Tower: " + t.toString());
          }
          Game.getInstance().getGameboard().setMarkToBuilt(f.x(), f.y(), player);
        }
      }
      skillList.add(t.towerType);
    }
    return skillList;
  }
  private FieldIndex unregisterFieldIndex(final int index) {
    final FieldIndex fieldIndex = findFieldIndex(index);
    fieldIndex.decreaseCounter();

    // if the fieldcount is 0 then remove it from the linkedlist
    if (fieldIndex.getCount() == 0) {
      this.hashedFieldIndexes.remove(fieldIndex);

      // if the linkedlist is empty then null it
      if (this.hashedFieldIndexes.isEmpty()) {
        this.hashedFieldIndexes = null;
      }
    }

    return fieldIndex;
  }
  public ObjectSink[] getSinks() {
    if (this.sinks != null) {
      return sinks;
    }
    ObjectSink[] sinks = new ObjectSink[size()];
    int at = 0;

    if (this.hashedFieldIndexes != null) {
      // Iterate the FieldIndexes to see if any are hashed
      for (FieldIndex fieldIndex = this.hashedFieldIndexes.getFirst();
          fieldIndex != null;
          fieldIndex = fieldIndex.getNext()) {
        if (!fieldIndex.isHashed()) {
          continue;
        }
        // this field is hashed so set the existing hashKey and see if there is a sink for it
        final int index = fieldIndex.getIndex();
        final Iterator it = this.hashedSinkMap.newIterator();
        for (ObjectEntry entry = (ObjectEntry) it.next();
            entry != null;
            entry = (ObjectEntry) it.next()) {
          HashKey hashKey = (HashKey) entry.getKey();
          if (hashKey.getIndex() == index) {
            sinks[at++] = (ObjectSink) entry.getValue();
          }
        }
      }
    }

    if (this.hashableSinks != null) {
      for (ObjectSinkNode sink = this.hashableSinks.getFirst();
          sink != null;
          sink = sink.getNextObjectSinkNode()) {
        sinks[at++] = sink;
      }
    }

    if (this.otherSinks != null) {
      for (ObjectSinkNode sink = this.otherSinks.getFirst();
          sink != null;
          sink = sink.getNextObjectSinkNode()) {
        sinks[at++] = sink;
      }
    }
    this.sinks = sinks;
    return sinks;
  }
  public void propagateModifyObject(
      final InternalFactHandle factHandle,
      final ModifyPreviousTuples modifyPreviousTuples,
      final PropagationContext context,
      final InternalWorkingMemory workingMemory) {
    final Object object = factHandle.getObject();

    // Iterates the FieldIndex collection, which tells you if particularly field is hashed or not
    // if the field is hashed then it builds the hashkey to return the correct sink for the current
    // objects slot's
    // value, one object may have multiple fields indexed.
    if (this.hashedFieldIndexes != null) {
      // Iterate the FieldIndexes to see if any are hashed
      for (FieldIndex fieldIndex = this.hashedFieldIndexes.getFirst();
          fieldIndex != null;
          fieldIndex = fieldIndex.getNext()) {
        if (!fieldIndex.isHashed()) {
          continue;
        }
        // this field is hashed so set the existing hashKey and see if there is a sink for it
        final AlphaNode sink = (AlphaNode) this.hashedSinkMap.get(new HashKey(fieldIndex, object));
        if (sink != null) {
          // go straight to the AlphaNode's propagator, as we know it's true and no need to retest
          sink.getObjectSinkPropagator()
              .propagateModifyObject(factHandle, modifyPreviousTuples, context, workingMemory);
        }
      }
    }

    // propagate unhashed
    if (this.hashableSinks != null) {
      for (ObjectSinkNode sink = this.hashableSinks.getFirst();
          sink != null;
          sink = sink.getNextObjectSinkNode()) {
        doPropagateModifyObject(factHandle, modifyPreviousTuples, context, workingMemory, sink);
      }
    }

    if (this.otherSinks != null) {
      // propagate others
      for (ObjectSinkNode sink = this.otherSinks.getFirst();
          sink != null;
          sink = sink.getNextObjectSinkNode()) {
        doPropagateModifyObject(factHandle, modifyPreviousTuples, context, workingMemory, sink);
      }
    }
  }
  public ObjectSinkPropagator removeObjectSink(final ObjectSink sink) {
    this.sinks = null; // dirty it, so it'll rebuild on next get
    if (sink.getType() == NodeTypeEnums.AlphaNode) {
      final AlphaNode alphaNode = (AlphaNode) sink;
      final AlphaNodeFieldConstraint fieldConstraint = alphaNode.getConstraint();

      if (fieldConstraint instanceof IndexableConstraint) {
        final IndexableConstraint indexableConstraint = (IndexableConstraint) fieldConstraint;
        final FieldValue value = indexableConstraint.getField();

        if (isHashable(indexableConstraint)) {
          final InternalReadAccessor fieldAccessor = indexableConstraint.getFieldExtractor();
          final int index = fieldAccessor.getIndex();
          final FieldIndex fieldIndex = unregisterFieldIndex(index);

          if (fieldIndex.isHashed()) {
            HashKey hashKey = new HashKey(index, value, fieldAccessor);
            this.hashedSinkMap.remove(hashKey);
            if (fieldIndex.getCount() <= this.alphaNodeHashingThreshold - 1) {
              // we have less than three so unhash
              unHashSinks(fieldIndex);
            }
          } else {
            this.hashableSinks.remove(alphaNode);
          }

          if (this.hashableSinks != null && this.hashableSinks.isEmpty()) {
            this.hashableSinks = null;
          }

          return size() == 1 ? new SingleObjectSinkAdapter(getSinks()[0]) : this;
        }
      }
    }

    this.otherSinks.remove((ObjectSinkNode) sink);

    if (this.otherSinks.isEmpty()) {
      this.otherSinks = null;
    }

    return size() == 1 ? new SingleObjectSinkAdapter(getSinks()[0]) : this;
  }
Exemplo n.º 9
0
  private static boolean[][] FindClusterRecurse(FieldIndex ind, boolean[][] taken, Mark type) {
    // recursive function that finds a cluster
    Gameboard board = Game.getInstance().getGameboard();

    taken[(int) ind.x()][(int) ind.y()] = true;

    for (FieldIndex i : ind.GetNeigbours()) {
      if (board.getMark(i.x(), i.y()) == type && taken[i.x()][i.y()] == false) {
        taken = FindClusterRecurse(i, taken, type);
      }
    }
    return taken;
  }
Exemplo n.º 10
0
  private static ArrayList<Towers> FindMultipleSkillsTower(
      int direction, FieldIndex startPoint, boolean[][] cluster) {
    // checks for the two last pieces of a multiple-skills tower in the given direction
    // startPoint should be the second index
    // returns number of found towers

    ArrayList<Towers> towerList = new ArrayList<Towers>();
    FieldIndex right = startPoint.Right(direction);
    if (right.Valid() && cluster[right.x()][right.y()]) {
      FieldIndex down = right.Down(direction);
      if (down.Valid() && cluster[down.x()][down.y()]) {
        Towers tower = new Towers(startPoint, direction); // initing the tower
        tower.add(right);
        tower.add(down);
        tower.towerType = SkillType.SKILLCAP;
        towerList.add(tower);
      }
    }
    return towerList;
  }
Exemplo n.º 11
0
  public ObjectSinkPropagator addObjectSink(ObjectSink sink, int alphaNodeHashingThreshold) {
    this.sinks = null; // dirty it, so it'll rebuild on next get
    if (sink.getType() == NodeTypeEnums.AlphaNode) {
      final AlphaNode alphaNode = (AlphaNode) sink;
      final InternalReadAccessor readAccessor = getHashableAccessor(alphaNode);

      if (readAccessor != null) {
        final int index = readAccessor.getIndex();
        final FieldIndex fieldIndex = registerFieldIndex(index, readAccessor);

        // DROOLS-678 : prevent null values from being hashed as 0s
        final FieldValue value = ((IndexableConstraint) alphaNode.getConstraint()).getField();
        if (fieldIndex.getCount() >= this.alphaNodeHashingThreshold
            && this.alphaNodeHashingThreshold != 0
            && !value.isNull()) {
          if (!fieldIndex.isHashed()) {
            hashSinks(fieldIndex);
          }

          // no need to check, we know  the sink  does not exist
          this.hashedSinkMap.put(
              new HashKey(index, value, fieldIndex.getFieldExtractor()), alphaNode, false);
        } else {
          if (this.hashableSinks == null) {
            this.hashableSinks = new ObjectSinkNodeList();
          }
          this.hashableSinks.add(alphaNode);
        }
        return this;
      }
    }

    if (this.otherSinks == null) {
      this.otherSinks = new ObjectSinkNodeList();
    }

    this.otherSinks.add((ObjectSinkNode) sink);
    return this;
  }
Exemplo n.º 12
0
  private static ArrayList<Towers> FindShootTower(
      int direction, FieldIndex startPoint, boolean[][] cluster) {
    // checks for the two last pieces of a shoot tower in the given direction
    // startpoint should be the second index
    // returns number of found towers

    FieldIndex right = startPoint.Right(direction);
    FieldIndex left = startPoint.Left(direction);
    boolean leftPart = left.Valid() && cluster[left.x()][left.y()];
    boolean rightPart = right.Valid() && cluster[right.x()][right.y()];

    ArrayList<Towers> towerList = new ArrayList<Towers>();

    if (leftPart && rightPart) {
      Towers tow = new Towers(startPoint, direction);
      tow.add(left);
      tow.add(right);
      tow.towerType = SkillType.SHOOT;
      towerList.add(tow);
    }
    return towerList;
  }
Exemplo n.º 13
0
  void unHashSinks(final FieldIndex fieldIndex) {
    final int index = fieldIndex.getIndex();
    // this is the list of sinks that need to be removed from the hashedSinkMap
    final List<HashKey> unhashedSinks = new ArrayList<HashKey>();

    final Iterator iter = this.hashedSinkMap.newIterator();
    ObjectHashMap.ObjectEntry entry = (ObjectHashMap.ObjectEntry) iter.next();

    while (entry != null) {
      final AlphaNode alphaNode = (AlphaNode) entry.getValue();
      final IndexableConstraint indexableConstraint =
          (IndexableConstraint) alphaNode.getConstraint();

      // only alpha nodes that have an Operator.EQUAL are in sinks, so only check if it is
      // the right field index
      if (index == indexableConstraint.getFieldExtractor().getIndex()) {
        final FieldValue value = indexableConstraint.getField();
        if (this.hashableSinks == null) {
          this.hashableSinks = new ObjectSinkNodeList();
        }
        this.hashableSinks.add(alphaNode);

        unhashedSinks.add(new HashKey(index, value, fieldIndex.getFieldExtractor()));
      }

      entry = (ObjectHashMap.ObjectEntry) iter.next();
    }

    for (HashKey hashKey : unhashedSinks) {
      this.hashedSinkMap.remove(hashKey);
    }

    if (this.hashedSinkMap.isEmpty()) {
      this.hashedSinkMap = null;
    }

    fieldIndex.setHashed(false);
  }
Exemplo n.º 14
0
  void hashSinks(final FieldIndex fieldIndex) {
    if (this.hashedSinkMap == null) {
      this.hashedSinkMap = new ObjectHashMap();
    }

    final int index = fieldIndex.getIndex();
    final InternalReadAccessor fieldReader = fieldIndex.getFieldExtractor();

    ObjectSinkNode currentSink = this.hashableSinks.getFirst();

    while (currentSink != null) {
      final AlphaNode alphaNode = (AlphaNode) currentSink;
      final AlphaNodeFieldConstraint fieldConstraint = alphaNode.getConstraint();
      final IndexableConstraint indexableConstraint = (IndexableConstraint) fieldConstraint;

      // position to the next sink now because alphaNode may be removed if the index is equal. If we
      // were to do this
      // afterwards, currentSink.nextNode would be null
      currentSink = currentSink.getNextObjectSinkNode();

      // only alpha nodes that have an Operator.EQUAL are in hashableSinks, so only check if it is
      // the right field index
      if (index == indexableConstraint.getFieldExtractor().getIndex()) {
        final FieldValue value = indexableConstraint.getField();
        this.hashedSinkMap.put(new HashKey(index, value, fieldReader), alphaNode);

        // remove the alpha from the possible candidates of hashable sinks since it is now hashed
        hashableSinks.remove(alphaNode);
      }
    }

    if (this.hashableSinks.isEmpty()) {
      this.hashableSinks = null;
    }

    fieldIndex.setHashed(true);
  }
Exemplo n.º 15
0
 private Towers(FieldIndex f, int direction) {
   tower = new ArrayList<FieldIndex>(4);
   tower.add(f.Down(direction));
   tower.add(f);
 }
Exemplo n.º 16
0
 private static ArrayList<Towers> FindFiveTower(
     int direction, FieldIndex startPoint, boolean[][] cluster) {
   // checks for the three last pieces of a five-in-a-row tower in the given direction
   // startPoint should be the second index
   // returns a list of found towers
   ArrayList<Towers> towerList = new ArrayList<Towers>();
   Towers tower = new Towers(startPoint, direction);
   FieldIndex up = startPoint.Up(direction);
   if (up.Valid() && cluster[up.x()][up.y()]) {
     tower.add(up);
     up = up.Up(direction);
     if (up.Valid() && cluster[up.x()][up.y()]) {
       tower.add(up);
       up = up.Up(direction);
       if (up.Valid() && cluster[up.x()][up.y()]) {
         tower.add(up);
         towerList.add(tower);
         Game.getInstance().setShowVictoryScreen(true);
         return towerList;
       }
     }
   }
   return towerList; // returning the empty tower list
 }
Exemplo n.º 17
0
  private static ArrayList<Towers> FindSilenceTower(
      int direction, FieldIndex startPoint, boolean[][] cluster) {
    // checks for the two last pieces of a silence tower in the given direction
    // startPoint should be the second index
    // returns number of found towers

    ArrayList<Towers> towerList = new ArrayList<Towers>();
    FieldIndex right = startPoint.Right(direction);
    FieldIndex left = startPoint.Left(direction);
    boolean leftPart = left.Valid() && cluster[left.x()][left.y()];
    boolean rightPart = right.Valid() && cluster[right.x()][right.y()];

    if (leftPart) {
      FieldIndex up = left.Up(direction);
      if (up.Valid() && cluster[up.x()][up.y()]) {
        Towers leftTower = new Towers(startPoint, direction); // initing the tower
        leftTower.add(left);
        leftTower.add(up);
        leftTower.towerType = SkillType.SILENCE;
        towerList.add(leftTower);
      }
    }
    if (rightPart) {
      FieldIndex up = right.Up(direction);
      if (up.Valid() && cluster[up.x()][up.y()]) {
        Towers rightTower = new Towers(startPoint, direction); // initing the tower
        rightTower.add(right);
        rightTower.add(up);
        rightTower.towerType = SkillType.SILENCE;
        towerList.add(rightTower);
      }
    }
    return towerList;
  }
Exemplo n.º 18
0
 public HashKey(FieldIndex fieldIndex, Object value) {
   this.setValue(fieldIndex.getIndex(), value, fieldIndex.getFieldExtractor());
 }