Beispiel #1
0
		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;
		}