protected void Clear() { AllBlocks = new List <GoBlockBase>(); GoEmptyBlock lEmptyBlock = new GoEmptyBlock(this); UndoStack = new UndoStack(this); Turn = Color.Black; ZobrishHashes = new Dictionary <ZobristHash, int>(); LastMove = CoordinateSystem.PASS; MoveList = new List <KeyValuePair <Color, int> >(); SimpleKoPoint = CoordinateSystem.PASS; MoveNbr = 0; Komi = 0; GameOver = false; CapturedStoneCnt = new int[2]; ColorEnclosedRegions = null; SafetyStatusMap = null; ZobristHash = new ZobristHash(); Cells = new GoCell[Coord.BoardArea]; for (int i = 0; i < Coord.BoardArea; i++) { Cells[i] = new GoCell(i, this, lEmptyBlock); } for (int i = 0; i < Coord.BoardArea; i++) { Cells[i].SetNeighbors(); } }
protected void CreateRegions(Color color) { int lColorIndex = color.ToInteger(); Regions[lColorIndex] = new List <ColorEnclosedRegion>(); List <GoEmptyBlock> lReviewed = new List <GoEmptyBlock>(); foreach (GoBlockBase lGoBlockBase in Board.AllBlocks) { if (lGoBlockBase.IsEmptyBlock()) { GoEmptyBlock lGoEmptyBlock = (GoEmptyBlock)lGoBlockBase; if (!lReviewed.Contains(lGoEmptyBlock)) { ColorEnclosedRegion lColorEnclosedRegion = new ColorEnclosedRegion(lGoEmptyBlock, color); Regions[lColorIndex].Add(lColorEnclosedRegion); foreach (GoBlockBase lGoBlockBase2 in lColorEnclosedRegion.Members) { if (lGoBlockBase2.IsEmptyBlock()) { lReviewed.Add((GoEmptyBlock)lGoBlockBase2); } } } } } }
// public int NeighborCnt; public GoCell(int index, GoBoard goBoard, GoEmptyBlock goEmptyBlock) { Board = goBoard; Color = Color.Empty; Block = goEmptyBlock; Index = index; Board.ZobristHash.Delta(Color, Index); }
public override void Undo(GoBoard goBoard) { GoEmptyBlock lEmptyBlock = (GoEmptyBlock)goBoard.Cells[Block.MemberList[0]].Block; // clear liberties in adjacent blocks foreach (int lStone in Block.MemberList) { foreach (GoBlock lGoBlock in lEmptyBlock.AdjacentBlocks.StoneBlocks) { // if (lGoBlock.IsNeighbor(lStone)) // if (lGoBlock.BlockColor != Block.BlockColor) lGoBlock.Liberties.Remove(lStone); } } // placing stones back onto the board foreach (int lStone in Block.MemberList) { goBoard.Cells[lStone].AssignCell(Block); } }
public GoEmptyBlock(GoEmptyBlock goEmptyBlock, int pCutPoint, int direction) : base(goEmptyBlock.Board, Color.Empty) { Members = new Region(goEmptyBlock.Members, pCutPoint, direction); MemberList = Members.ToList(); }
public ColorEnclosedRegion(GoEmptyBlock goEmptyBlock, Color defender) { Board = goEmptyBlock.Board; Defender = defender; Size = 0; Version = 2004; _RegionNbr = goEmptyBlock.BlockNbr; Members = new List <GoBlockBase>(); EmptyBlocks = new List <GoEmptyBlock>(); Neighbors = new List <GoBlock>(); InteriorAttackerBlocks = new List <GoBlock>(); Is2Vital = TriState.Unknown; Is1Vital = TriState.Unknown; IsSmall = TriState.Unknown; _EnclosedArea = null; _EmptyRegion = null; Stack <GoBlockBase> lWork = new Stack <GoBlockBase>(); lWork.Push(goEmptyBlock); while (lWork.Count != 0) { GoBlockBase lGoBlockBase = lWork.Pop(); if (!Members.Contains(lGoBlockBase)) { Members.Add(lGoBlockBase); if (lGoBlockBase.IsEmptyBlock()) { EmptyBlocks.Add((GoEmptyBlock)lGoBlockBase); Size = Size + ((GoEmptyBlock)lGoBlockBase).EmptySpaceCount; } else { InteriorAttackerBlocks.Add((GoBlock)lGoBlockBase); Size = Size + ((GoBlock)lGoBlockBase).StoneCount; } foreach (GoBlockBase lGoBlockBaseAdjacent in lGoBlockBase.AdjacentBlocks.AllBlocks) { if (lGoBlockBaseAdjacent.BlockColor == Defender) { if (!Neighbors.Contains((GoBlock)lGoBlockBaseAdjacent)) { Neighbors.Add((GoBlock)lGoBlockBaseAdjacent); } } else if (!Members.Contains(lGoBlockBaseAdjacent)) { lWork.Push(lGoBlockBaseAdjacent); } } } } EnclosingBlocks = new List <GoBlock>(Neighbors.Count); InteriorDefenderBlocks = new List <GoBlock>(); foreach (GoBlock lGoBlock in Neighbors) { bool lFound = false; foreach (GoEmptyBlock lGoEmptyBlock in lGoBlock.AdjacentBlocks.EmptyBlocks) { if (!EmptyBlocks.Contains(lGoEmptyBlock)) { lFound = true; break; } } if (lFound) { EnclosingBlocks.Add(lGoBlock); } else { InteriorDefenderBlocks.Add(lGoBlock); } } if (EnclosingBlocks.Count == 0) { InteriorDefenderBlocks.Clear(); } }
public GoEmptyBlockUndoRemoveLiberty(GoEmptyBlock goEmptyBlock, int index) { // save changable properties of original object EmptyBlock = goEmptyBlock; Index = index; }
protected Region _EnclosingBlocksLibertyArea; // lazy evaluation #endregion Fields #region Constructors public ColorEnclosedRegion(GoEmptyBlock goEmptyBlock, Color defender) { Board = goEmptyBlock.Board; Defender = defender; Size = 0; Version = 2004; _RegionNbr = goEmptyBlock.BlockNbr; Members = new List<GoBlockBase>(); EmptyBlocks = new List<GoEmptyBlock>(); Neighbors = new List<GoBlock>(); InteriorAttackerBlocks = new List<GoBlock>(); Is2Vital = TriState.Unknown; Is1Vital = TriState.Unknown; IsSmall = TriState.Unknown; _EnclosedArea = null; _EmptyRegion = null; Stack<GoBlockBase> lWork = new Stack<GoBlockBase>(); lWork.Push(goEmptyBlock); while (lWork.Count != 0) { GoBlockBase lGoBlockBase = lWork.Pop(); if (!Members.Contains(lGoBlockBase)) { Members.Add(lGoBlockBase); if (lGoBlockBase.IsEmptyBlock()) { EmptyBlocks.Add((GoEmptyBlock)lGoBlockBase); Size = Size + ((GoEmptyBlock)lGoBlockBase).EmptySpaceCount; } else { InteriorAttackerBlocks.Add((GoBlock)lGoBlockBase); Size = Size + ((GoBlock)lGoBlockBase).StoneCount; } foreach (GoBlockBase lGoBlockBaseAdjacent in lGoBlockBase.AdjacentBlocks.AllBlocks) if (lGoBlockBaseAdjacent.BlockColor == Defender) { if (!Neighbors.Contains((GoBlock)lGoBlockBaseAdjacent)) Neighbors.Add((GoBlock)lGoBlockBaseAdjacent); } else if (!Members.Contains(lGoBlockBaseAdjacent)) lWork.Push(lGoBlockBaseAdjacent); } } EnclosingBlocks = new List<GoBlock>(Neighbors.Count); InteriorDefenderBlocks = new List<GoBlock>(); foreach (GoBlock lGoBlock in Neighbors) { bool lFound = false; foreach (GoEmptyBlock lGoEmptyBlock in lGoBlock.AdjacentBlocks.EmptyBlocks) { if (!EmptyBlocks.Contains(lGoEmptyBlock)) { lFound = true; break; } } if (lFound) EnclosingBlocks.Add(lGoBlock); else InteriorDefenderBlocks.Add(lGoBlock); } if (EnclosingBlocks.Count == 0) InteriorDefenderBlocks.Clear(); }
public void AddTerritoryBlock(GoEmptyBlock goEmptyBlock, Color color) { Update(goEmptyBlock, SafetyFlag.Territory | (color.IsBlack ? SafetyFlag.Black : SafetyFlag.White)); }
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); } } } }
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); } } }
protected void Clear() { AllBlocks = new List<GoBlockBase>(); GoEmptyBlock lEmptyBlock = new GoEmptyBlock(this); UndoStack = new UndoStack(this); Turn = Color.Black; ZobrishHashes = new Dictionary<ZobristHash, int>(); LastMove = CoordinateSystem.PASS; MoveList = new List<KeyValuePair<Color, int>>(); SimpleKoPoint = CoordinateSystem.PASS; MoveNbr = 0; Komi = 0; GameOver = false; CapturedStoneCnt = new int[2]; ColorEnclosedRegions = null; SafetyStatusMap = null; ZobristHash = new ZobristHash(); Cells = new GoCell[Coord.BoardArea]; for (int i = 0; i < Coord.BoardArea; i++) Cells[i] = new GoCell(i, this, lEmptyBlock); for (int i = 0; i < Coord.BoardArea; i++) Cells[i].SetNeighbors(); }
public GoEmptyBlockUndoRemove(GoEmptyBlock goEmptyBlock) { // save changable properties of original object EmptyBlock = goEmptyBlock; }