protected void CreateBlockToRegionMap() { // create a map between blocks and healthy small color enclosed regions foreach (GoBlockBase lGoBlockBase in Board.AllBlocks) { if (!lGoBlockBase.IsEmptyBlock()) { GoBlock lGoBlock = (GoBlock)lGoBlockBase; List <ColorEnclosedRegion> lUsedColorEnclosedRegions = new List <ColorEnclosedRegion>(); foreach (ColorEnclosedRegion lColorEnclosedRegion in PotentialVitalRegions) { if (lColorEnclosedRegion.Neighbors.Contains(lGoBlock)) { // if (lColorEnclosedRegion.IsSmallEnclosed()) if (lColorEnclosedRegion.IsHealthyFor(lGoBlock)) { lUsedColorEnclosedRegions.Add(lColorEnclosedRegion); } } } Blocks.Add(lGoBlock, lUsedColorEnclosedRegions); } } }
public GoChain(GoBlock goBlock, Region AccessibleLiberties) { Blocks = new List <GoBlock>(); Blocks.Add(goBlock); Liberities = new Region(goBlock.Liberties, AccessibleLiberties, Region.MergeType.And); UsedLiberities = new List <int>(); }
public GoChain(GoBlock goBlock, Region AccessibleLiberties) { Blocks = new List<GoBlock>(); Blocks.Add(goBlock); Liberities = new Region(goBlock.Liberties, AccessibleLiberties, Region.MergeType.And); UsedLiberities = new List<int>(); }
public void AddBlock(GoBlock goBlock) { Blocks.Add(goBlock); if (Liberities != null) Liberities.Add(goBlock.Liberties); else Liberities = new Region(goBlock.Liberties); }
public bool IsHealthyFor(GoBlock goBlock) { foreach (GoEmptyBlock lGoEmptyBlock in EmptyBlocks) { if (!goBlock.Members.IsOnlyAdjacent(lGoEmptyBlock.Members)) { return(false); } } return(true); }
public void AddBlock(GoBlock goBlock) { Blocks.Add(goBlock); if (Liberities != null) { Liberities.Add(goBlock.Liberties); } else { Liberities = new Region(goBlock.Liberties); } }
public GoBlockUndoCapture(GoBlock goBlock) { // save changable properties of original object Block = goBlock; }
public GoBlockUndoMerge(GoBlock mergedBlock, List <GoBlock> oldBlocks) { // save changable properties of original object MergedBlock = mergedBlock; OldBlocks = oldBlocks; }
public void AddDeadBlock(GoBlock goBlock) { Update(goBlock, SafetyFlag.Dead | (goBlock.BlockColor.IsBlack ? SafetyFlag.Black : SafetyFlag.White)); }
public void AddAliveBlock(GoBlock goBlock) { Update(goBlock, SafetyFlag.Alive | (goBlock.BlockColor.IsBlack ? SafetyFlag.Black : SafetyFlag.White)); }
public GoBlockUndoMerge(GoBlock mergedBlock, List<GoBlock> oldBlocks) { // save changable properties of original object MergedBlock = mergedBlock; OldBlocks = oldBlocks; }
public GoEmptyBlock(GoBlock goBlock) : base(goBlock.Board, Color.Empty) { Members = new Region(goBlock.Members); MemberList = Members.ToList(); // slow might be a faster way }
protected void ExecutePlay(int index, Color color, bool allowUndo) { // get empty block that this stone is being placed on GoEmptyBlock lInEmptyBlock = (GoEmptyBlock)Cells[index].Block; // if the stone empties the EmptyBlock, remove the EmptyBlock if (lInEmptyBlock.EmptySpaceCount == 1) { // save undo operation onto stack if (allowUndo) UndoStack.Add(new GoEmptyBlockUndoRemove(lInEmptyBlock)); } else { // if empty block is split, divide empty block if (lInEmptyBlock.IsCutPoint(index)) { // save undo operation onto stack if (allowUndo) UndoStack.Add(new GoEmptyBlockUndoRemove(lInEmptyBlock)); List<GoEmptyBlock> lNewEmptyBlocks = new List<GoEmptyBlock>(4); foreach (int lNeighbor in Coord.GetNeighbors(index)) // is move point in lInEmptyBlock? if (lInEmptyBlock.IsMember(lNeighbor)) { // is move not any new block? bool lFound = false; foreach (GoEmptyBlock lEmptyBlock in lNewEmptyBlocks) if (lEmptyBlock.IsMember(lNeighbor)) { lFound = true; break; } // if yes to all above then, do this: if (!lFound) lNewEmptyBlocks.Add(new GoEmptyBlock(lInEmptyBlock, index, lNeighbor)); } foreach (GoEmptyBlock lEmptyBlock in lNewEmptyBlocks) foreach (int lIndex in lEmptyBlock.MemberList) Cells[lIndex].AssignCell(lEmptyBlock); } else { // save undo operation onto stack if (allowUndo) UndoStack.Add(new GoEmptyBlockUndoRemoveLiberty(lInEmptyBlock, index)); // remove member of in the EmptyBlock lInEmptyBlock.RemoveMember(index); } } List<GoBlockBase> lNeighboringBlocks = GetNeighboringBlocks(index); List<GoBlock> lFriendlyBlocks = new List<GoBlock>(4); List<GoBlock> lEnemyBlocks = new List<GoBlock>(4); foreach (GoBlockBase lBlock in lNeighboringBlocks) { // get a list of friendly blocks if (lBlock.BlockColor == color) lFriendlyBlocks.Add((GoBlock)lBlock); else // get a list of enemy blocks if (lBlock.BlockColor == color.Opposite) lEnemyBlocks.Add((GoBlock)lBlock); } List<GoBlock> lNotCapturedBlocks = new List<GoBlock>(4); List<GoBlock> lCapturedBlocks = new List<GoBlock>(4); if (lEnemyBlocks.Count > 0) { // get a sub-list of enemy blocks in atari foreach (GoBlock lEnemyBlock in lEnemyBlocks) if (lEnemyBlock.InAtari()) lCapturedBlocks.Add(lEnemyBlock); else lNotCapturedBlocks.Add(lEnemyBlock); int lStonesCaptured = 0; foreach (GoBlock lCapturedBlock in lCapturedBlocks) { // save undo operation onto stack if (allowUndo) UndoStack.Add(new GoBlockUndoCapture(lCapturedBlock)); GoEmptyBlock lNewEmptyBlock = new GoEmptyBlock(lCapturedBlock); // remove captured blocks from enemy adjacent lists foreach (GoBlock lGoBlock in lCapturedBlock.AdjacentBlocks.StoneBlocks) foreach (GoBlock lBlock in lCapturedBlocks) foreach (int lStone in lBlock.MemberList) if (lGoBlock.IsEnemy(lStone)) lGoBlock.EnemyStoneCaptured(lStone); // removing points from board foreach (int lStone in lCapturedBlock.MemberList) Cells[lStone].AssignCell(lNewEmptyBlock); lStonesCaptured = lStonesCaptured + lCapturedBlock.StoneCount; } // adjust capture count (undoable because board state was saved earlier) CapturedStoneCnt[color.Opposite.ToInteger()] += lStonesCaptured; // save undo operation onto stack if (allowUndo) UndoStack.Add(new GoBlockUndoEnemyStone(lNotCapturedBlocks, index)); // fill liberties of enemy blocks that were not captured foreach (GoBlock lNotCapturedBlock in lNotCapturedBlocks) lNotCapturedBlock.EnemyStonePlaced(index); } // setup simple ko point, if any if ((lCapturedBlocks.Count == 1) && (lFriendlyBlocks.Count == 0)) if (lCapturedBlocks[0].StoneCount == 1) SimpleKoPoint = lCapturedBlocks[0].Members.GetFirst(); // future improve // save undo operation onto stack if (allowUndo) UndoStack.Add(new GoCellUndoChange(Cells[index])); if (lFriendlyBlocks.Count == 0) { // create a block for the stone GoBlock lNewGoBlock = new GoBlock(this, color); // set stone to color Cells[index].AssignCell(lNewGoBlock); // add the connecting stone to new block lNewGoBlock.AddStone(index); } else if (lFriendlyBlocks.Count == 1) { GoBlock lFriendlyBlock = lFriendlyBlocks[0]; // set stone to color Cells[index].AssignCell(lFriendlyBlock); // save undo operation onto stack if (allowUndo) UndoStack.Add(new GoBlockUndoAddStone(lFriendlyBlock, index)); // add stone to block lFriendlyBlock.AddStone(index); } else { // create merger block GoBlock lMergedGoBlock = new GoBlock(this, color); // set stone to color Cells[index].AssignCell(lMergedGoBlock); // save undo operation onto stack if (allowUndo) UndoStack.Add(new GoBlockUndoMerge(lMergedGoBlock, lFriendlyBlocks)); // add the connecting stone to new block lMergedGoBlock.AddStone(index); // add stones to merged block foreach (GoBlock lFriendlyBlock in lFriendlyBlocks) foreach (int lStone in lFriendlyBlock.MemberList) { lMergedGoBlock.AddStone(lStone); Cells[lStone].AssignCell(lMergedGoBlock); } } }
public GoBlockUndoAddStone(GoBlock goBlock, int index) { // save changable properties of original object Block = goBlock; Index = index; }
public bool IsHealthyFor(GoBlock goBlock) { foreach (GoEmptyBlock lGoEmptyBlock in EmptyBlocks) if (!goBlock.Members.IsOnlyAdjacent(lGoEmptyBlock.Members)) return false; return true; }
public bool IsNeightbor(GoBlock goBlock) { return (Neighbors.Contains(goBlock)); }
protected void ExecutePlay(int index, Color color, bool allowUndo) { // get empty block that this stone is being placed on GoEmptyBlock lInEmptyBlock = (GoEmptyBlock)Cells[index].Block; // if the stone empties the EmptyBlock, remove the EmptyBlock if (lInEmptyBlock.EmptySpaceCount == 1) { // save undo operation onto stack if (allowUndo) { UndoStack.Add(new GoEmptyBlockUndoRemove(lInEmptyBlock)); } } else { // if empty block is split, divide empty block if (lInEmptyBlock.IsCutPoint(index)) { // save undo operation onto stack if (allowUndo) { UndoStack.Add(new GoEmptyBlockUndoRemove(lInEmptyBlock)); } List <GoEmptyBlock> lNewEmptyBlocks = new List <GoEmptyBlock>(4); foreach (int lNeighbor in Coord.GetNeighbors(index)) { // is move point in lInEmptyBlock? if (lInEmptyBlock.IsMember(lNeighbor)) { // is move not any new block? bool lFound = false; foreach (GoEmptyBlock lEmptyBlock in lNewEmptyBlocks) { if (lEmptyBlock.IsMember(lNeighbor)) { lFound = true; break; } } // if yes to all above then, do this: if (!lFound) { lNewEmptyBlocks.Add(new GoEmptyBlock(lInEmptyBlock, index, lNeighbor)); } } } foreach (GoEmptyBlock lEmptyBlock in lNewEmptyBlocks) { foreach (int lIndex in lEmptyBlock.MemberList) { Cells[lIndex].AssignCell(lEmptyBlock); } } } else { // save undo operation onto stack if (allowUndo) { UndoStack.Add(new GoEmptyBlockUndoRemoveLiberty(lInEmptyBlock, index)); } // remove member of in the EmptyBlock lInEmptyBlock.RemoveMember(index); } } List <GoBlockBase> lNeighboringBlocks = GetNeighboringBlocks(index); List <GoBlock> lFriendlyBlocks = new List <GoBlock>(4); List <GoBlock> lEnemyBlocks = new List <GoBlock>(4); foreach (GoBlockBase lBlock in lNeighboringBlocks) { // get a list of friendly blocks if (lBlock.BlockColor == color) { lFriendlyBlocks.Add((GoBlock)lBlock); } else // get a list of enemy blocks if (lBlock.BlockColor == color.Opposite) { lEnemyBlocks.Add((GoBlock)lBlock); } } List <GoBlock> lNotCapturedBlocks = new List <GoBlock>(4); List <GoBlock> lCapturedBlocks = new List <GoBlock>(4); if (lEnemyBlocks.Count > 0) { // get a sub-list of enemy blocks in atari foreach (GoBlock lEnemyBlock in lEnemyBlocks) { if (lEnemyBlock.InAtari()) { lCapturedBlocks.Add(lEnemyBlock); } else { lNotCapturedBlocks.Add(lEnemyBlock); } } int lStonesCaptured = 0; foreach (GoBlock lCapturedBlock in lCapturedBlocks) { // save undo operation onto stack if (allowUndo) { UndoStack.Add(new GoBlockUndoCapture(lCapturedBlock)); } GoEmptyBlock lNewEmptyBlock = new GoEmptyBlock(lCapturedBlock); // remove captured blocks from enemy adjacent lists foreach (GoBlock lGoBlock in lCapturedBlock.AdjacentBlocks.StoneBlocks) { foreach (GoBlock lBlock in lCapturedBlocks) { foreach (int lStone in lBlock.MemberList) { if (lGoBlock.IsEnemy(lStone)) { lGoBlock.EnemyStoneCaptured(lStone); } } } } // removing points from board foreach (int lStone in lCapturedBlock.MemberList) { Cells[lStone].AssignCell(lNewEmptyBlock); } lStonesCaptured = lStonesCaptured + lCapturedBlock.StoneCount; } // adjust capture count (undoable because board state was saved earlier) CapturedStoneCnt[color.Opposite.ToInteger()] += lStonesCaptured; // save undo operation onto stack if (allowUndo) { UndoStack.Add(new GoBlockUndoEnemyStone(lNotCapturedBlocks, index)); } // fill liberties of enemy blocks that were not captured foreach (GoBlock lNotCapturedBlock in lNotCapturedBlocks) { lNotCapturedBlock.EnemyStonePlaced(index); } } // setup simple ko point, if any if ((lCapturedBlocks.Count == 1) && (lFriendlyBlocks.Count == 0)) { if (lCapturedBlocks[0].StoneCount == 1) { SimpleKoPoint = lCapturedBlocks[0].Members.GetFirst(); // future improve } } // save undo operation onto stack if (allowUndo) { UndoStack.Add(new GoCellUndoChange(Cells[index])); } if (lFriendlyBlocks.Count == 0) { // create a block for the stone GoBlock lNewGoBlock = new GoBlock(this, color); // set stone to color Cells[index].AssignCell(lNewGoBlock); // add the connecting stone to new block lNewGoBlock.AddStone(index); } else if (lFriendlyBlocks.Count == 1) { GoBlock lFriendlyBlock = lFriendlyBlocks[0]; // set stone to color Cells[index].AssignCell(lFriendlyBlock); // save undo operation onto stack if (allowUndo) { UndoStack.Add(new GoBlockUndoAddStone(lFriendlyBlock, index)); } // add stone to block lFriendlyBlock.AddStone(index); } else { // create merger block GoBlock lMergedGoBlock = new GoBlock(this, color); // set stone to color Cells[index].AssignCell(lMergedGoBlock); // save undo operation onto stack if (allowUndo) { UndoStack.Add(new GoBlockUndoMerge(lMergedGoBlock, lFriendlyBlocks)); } // add the connecting stone to new block lMergedGoBlock.AddStone(index); // add stones to merged block foreach (GoBlock lFriendlyBlock in lFriendlyBlocks) { foreach (int lStone in lFriendlyBlock.MemberList) { lMergedGoBlock.AddStone(lStone); Cells[lStone].AssignCell(lMergedGoBlock); } } } }
public bool IsNeightbor(GoBlock goBlock) { return(Neighbors.Contains(goBlock)); }