private bool BleedValue(RuleSet rule, RuleValue value, Direction direction) { int x, y; if(rule.mID == RuleID.RI_ROW) { x = direction == Direction.RIGHT ? value.minIndex : value.maxIndex; y = rule.mIndex; } else { x = rule.mIndex; y = direction == Direction.DOWN ? value.minIndex : value.maxIndex; } int idx = GetIndex(x, y); // Have we already found our start position? if (mBoard[idx] == SquareType.ST_BLACK) { bool canContinue = false; for (int i = 0; i < value.mValue; ++i) { SetBoardValue(idx, SquareType.ST_BLACK); value.AddIndex(idx); canContinue = ShiftIndex(ref idx, direction); } if (canContinue) SetBoardValue(idx, SquareType.ST_WHITE); value.ClampMinMax(rule.GetBleedValue(x, y), value.mValue - 1, direction); return true; } bool foundPortion = false; bool isValid = false; for (int i = 0; i < value.mValue; ++i) { if (mBoard[idx] == SquareType.ST_UNKNOWN) { if (foundPortion) // If we already found a portion of ourselves, it's impossible for this to not be black { SetBoardValue(idx, SquareType.ST_BLACK); //if (direction == Direction.RIGHT || direction == Direction.DOWN) //value.ClampMinMax(i + (value.mValue - 1)); value.ClampMinMax(rule.GetBleedValue(x, y), i + (value.mValue - 1), direction); //else // value.ClampMinMax(value.maxIndex - i - (value.mValue - 1)); } isValid = ShiftIndex(ref idx, direction); continue; } if (mBoard[idx] == SquareType.ST_WHITE) // It's not possible to fit in this space. Blank it out, and move ourselves forward { Debug.Assert(foundPortion == false); // It shouldn't be possible to have found a portion of ourselves, and then run out of room. int initIdx = GetIndex(x, y); for (int j = 0; j < i; ++j) { SetBoardValue(initIdx, SquareType.ST_WHITE); ShiftIndex(ref initIdx, direction); } if (direction == Direction.RIGHT || direction == Direction.DOWN) value.minIndex += (i + 1); else value.maxIndex -= (i+1); return BleedValue(rule, value, direction); } if (mBoard[idx] == SquareType.ST_BLACK) { if (!foundPortion) // special case. We can sometimes reduce our max range by 1 if this would make two black runs collide { int p; if (GetIndexOffset(idx, value.mValue, direction, rule, out p)) { if (mBoard[p] == SquareType.ST_BLACK) { value.ClampMinMax(rule.GetBleedValue(x, y), i + (value.mValue - 2), direction); } } } foundPortion = true; //if (direction == Direction.RIGHT || direction == Direction.DOWN) // value.SetMaxIndex(value.minIndex + i + (value.mValue - 1)); //else // value.SetMinIndex(value.maxIndex - i - (value.mValue - 1)); value.ClampMinMax(rule.GetBleedValue(x, y), i + (value.mValue - 1), direction); } isValid = ShiftIndex(ref idx, direction); } if (isValid) { if (foundPortion && mBoard[idx] == SquareType.ST_WHITE) { SetBoardValue(x, y, SquareType.ST_BLACK); BleedValue(rule, value, direction); } else if (mBoard[idx] == SquareType.ST_BLACK) { int initIdx = GetIndex(x, y); while (isValid && mBoard[idx] == SquareType.ST_BLACK) { SetBoardValue(initIdx, SquareType.ST_WHITE); if (direction == Direction.RIGHT || direction == Direction.DOWN) ++value.minIndex; else --value.maxIndex; ShiftIndex(ref initIdx, direction); isValid = ShiftIndex(ref idx, direction); } } } return false; }