public boolean isMoveDoable(ScoreDirector scoreDirector) { Object leftValue = variableDescriptor.getValue(leftEntity); Object rightEntity = inverseVariableSupply.getInverseSingleton(rightValue); if (ObjectUtils.equals(leftValue, rightValue) || ObjectUtils.equals(leftEntity, rightValue) || ObjectUtils.equals(rightEntity, leftValue)) { return false; } if (rightEntity == null) { Object leftAnchor = anchorVariableSupply.getAnchor(leftEntity); Object rightAnchor = determineRightAnchor(); // TODO Currently unsupported because we fail to create a valid undoMove... even though doMove // supports it if (leftAnchor == rightAnchor) { return false; } } if (!variableDescriptor.isValueRangeEntityIndependent()) { ValueRangeDescriptor valueRangeDescriptor = variableDescriptor.getValueRangeDescriptor(); Solution workingSolution = scoreDirector.getWorkingSolution(); if (rightEntity != null) { ValueRange rightValueRange = valueRangeDescriptor.extractValueRange(workingSolution, rightEntity); if (!rightValueRange.contains(leftValue)) { return false; } } ValueRange leftValueRange = valueRangeDescriptor.extractValueRange(workingSolution, leftEntity); if (!leftValueRange.contains(rightValue)) { return false; } } return true; }
@Override protected void doMoveOnGenuineVariables(ScoreDirector scoreDirector) { Object leftAnchor = anchorVariableSupply.getAnchor(leftEntity); Object rightAnchor = determineRightAnchor(); Object leftValue = variableDescriptor.getValue(leftEntity); Object rightEntity = inverseVariableSupply.getInverseSingleton(rightValue); // Sometimes null if (leftAnchor != rightAnchor) { // Change the left entity scoreDirector.changeVariableFacade(variableDescriptor, leftEntity, rightValue); // Change the right entity if (rightEntity != null) { scoreDirector.changeVariableFacade(variableDescriptor, rightEntity, leftValue); } } else { Object lastEntityInChainOrLeftEntity = findLastEntityInChainOrLeftEntity(); if (lastEntityInChainOrLeftEntity == leftEntity) { // Reverses loop on the side that doesn't include the anchor, because rightValue is earlier // than leftEntity Object leftNextEntity = inverseVariableSupply.getInverseSingleton(leftEntity); scoreDirector.changeVariableFacade(variableDescriptor, leftEntity, rightValue); reverseChain(scoreDirector, leftValue, leftEntity, rightEntity); if (leftNextEntity != null) { scoreDirector.changeVariableFacade(variableDescriptor, leftNextEntity, rightEntity); } } else { // Reverses loop on the side that does include the anchor, because rightValue is later than // leftEntity Object lastEntityInChain = lastEntityInChainOrLeftEntity; Object leftNextEntity = inverseVariableSupply.getInverseSingleton(leftEntity); Object entityAfterAnchor = inverseVariableSupply.getInverseSingleton(leftAnchor); // Change the head of the chain reverseChain(scoreDirector, leftValue, leftEntity, entityAfterAnchor); // Change leftEntity scoreDirector.changeVariableFacade(variableDescriptor, leftEntity, rightValue); // Change the tail of the chain reverseChain(scoreDirector, lastEntityInChain, leftAnchor, rightEntity); scoreDirector.changeVariableFacade(variableDescriptor, leftNextEntity, rightEntity); } } }
public Move createUndoMove(ScoreDirector scoreDirector) { Object leftAnchor = anchorVariableSupply.getAnchor(leftEntity); Object rightAnchor = determineRightAnchor(); Object leftValue = variableDescriptor.getValue(leftEntity); if (leftAnchor != rightAnchor) { return new TailChainSwapMove( variableDescriptor, inverseVariableSupply, anchorVariableSupply, leftEntity, leftValue); } else { Object rightEntity = inverseVariableSupply.getInverseSingleton(rightValue); if (rightEntity != null) { return new TailChainSwapMove( variableDescriptor, inverseVariableSupply, anchorVariableSupply, rightEntity, rightValue); } else { // TODO Currently unsupported because we fail to create a valid undoMove... even though // doMove supports it throw new IllegalStateException( "Impossible state, because isMoveDoable() should not return true."); } } }
protected Object determineRightAnchor() { return !variableDescriptor.isValueNoPotentialAnchor(rightValue) ? rightValue : anchorVariableSupply.getAnchor(rightValue); }