/// <summary>Override; see base.</summary> public override ConstraintResult Process(SolverState state) { if (state.LastPlacedCell != null && !AffectedCells.Contains(state.LastPlacedCell.Value)) { return(null); } var innerTakens = new bool[Subconstraints.Length][][]; List <Constraint> newSubconstraints = null; for (var sc = 0; sc < Subconstraints.Length; sc++) { var substate = new SolverStateImpl { Parent = state, Takens = Ut.NewArray <bool>(state.GridSize, state.MaxValue - state.MinValue + 1) }; var result = Subconstraints[sc].Process(substate); innerTakens[sc] = substate.Takens; if (result is ConstraintReplace) { throw new NotImplementedException("The OrConstraint does not support subconstraints that replace themselves with new constraints."); } else if (result is ConstraintViolation) { if (newSubconstraints == null) { newSubconstraints = new List <Constraint>(Subconstraints.Take(sc)); } } else if (newSubconstraints != null) { newSubconstraints.Add(Subconstraints[sc]); } } foreach (var cell in AffectedCells) { state.MarkImpossible(cell, value => innerTakens.All(taken => taken == null || taken[cell][value - state.MinValue])); } if (newSubconstraints != null) { return new[] { new OrConstraint(newSubconstraints) } } ; return(null); } }
protected override bool InternalApply() { var containedTraps = Fight.GetTriggers().OfType <Trap>().Where(entry => entry.VisibleState == GameActionFightInvisibilityStateEnum.INVISIBLE && Caster.IsEnnemyWith(entry.Caster) && AffectedCells.Contains(entry.Shape.Cell)); foreach (var trap in containedTraps) { trap.VisibleState = GameActionFightInvisibilityStateEnum.VISIBLE; ContextHandler.SendGameActionFightMarkCellsMessage(Fight.Clients, trap); } foreach (var target in GetAffectedActors().Where(target => target.VisibleState == GameActionFightInvisibilityStateEnum.INVISIBLE && target.IsEnnemyWith(Caster))) { target.SetInvisibilityState(GameActionFightInvisibilityStateEnum.VISIBLE); } return(true); }
/// <summary>Override; see base.</summary> public override ConstraintResult Process(SolverState state) { if (state.LastPlacedCell != null && !AffectedCells.Contains(state.LastPlacedCell.Value)) { return(null); } var productAlready = 1; var cellsLeftToFill = 0; foreach (var cell in AffectedCells) { if (state[cell] is int value) { productAlready *= value; } else { cellsLeftToFill++; } } if (cellsLeftToFill == 0 || (productAlready == 0 && Product == 0)) { return(null); } var alreadyBroken = productAlready == 0 || (Product % productAlready != 0); foreach (var cell in AffectedCells) { state.MarkImpossible(cell, value => alreadyBroken || // The last remaining cell must have the exact required value (cellsLeftToFill == 1 && productAlready * value != Product) || // The remaining cells must be factors of whatever is left to multiply (cellsLeftToFill > 1 && value == 0 ? (Product != 0) : ((Product / productAlready) % value != 0))); } return(null); }
public override ConstraintResult Process(SolverState state) { if (state.LastPlacedCell == null) { // The focus cell cannot be so large that it points outside the grid, // nor can it have a value that points at a cell that already contains something other than a 9 state.MarkImpossible(AffectedCells[0], v => v > AffectedCells.Length - 1 || state.IsImpossible(AffectedCells[v], 9)); } else if (state.LastPlacedCell.Value == AffectedCells[0]) { // The focus cell has been set, therefore place the 9 in the correct position state.MustBe(AffectedCells[state.LastPlacedValue], 9); for (var i = 1; i < AffectedCells.Length; i++) { if (i != state.LastPlacedValue) { state.MarkImpossible(AffectedCells[i], 9); } } } else if (AffectedCells.Contains(state.LastPlacedCell.Value)) { var index = AffectedCells.IndexOf(state.LastPlacedCell.Value); if (state.LastPlacedValue == 9) { // A 9 has been placed somewhere, therefore set the focus cell to the correct value // (This is the main difference with FindTheValueConstraint; it’s an optimization that assumes uniqueness) state.MustBe(AffectedCells[0], index); } else { // A value other than 9 has been placed somewhere, therefore the focus cell cannot point at it anymore state.MarkImpossible(AffectedCells[0], index); } } return(null); }