Beispiel #1
0
        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);
                }
            }
        }
Beispiel #2
0
 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>();
 }
Beispiel #3
0
 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>();
 }
Beispiel #4
0
        public void AddBlock(GoBlock goBlock)
        {
            Blocks.Add(goBlock);

            if (Liberities != null)
                Liberities.Add(goBlock.Liberties);
            else
                Liberities = new Region(goBlock.Liberties);
        }
Beispiel #5
0
        public bool IsHealthyFor(GoBlock goBlock)
        {
            foreach (GoEmptyBlock lGoEmptyBlock in EmptyBlocks)
            {
                if (!goBlock.Members.IsOnlyAdjacent(lGoEmptyBlock.Members))
                {
                    return(false);
                }
            }

            return(true);
        }
Beispiel #6
0
        public void AddBlock(GoBlock goBlock)
        {
            Blocks.Add(goBlock);

            if (Liberities != null)
            {
                Liberities.Add(goBlock.Liberties);
            }
            else
            {
                Liberities = new Region(goBlock.Liberties);
            }
        }
Beispiel #7
0
 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));
 }
Beispiel #11
0
 public GoBlockUndoMerge(GoBlock mergedBlock, List<GoBlock> oldBlocks)
 {
     // save changable properties of original object
     MergedBlock = mergedBlock;
     OldBlocks = oldBlocks;
 }
Beispiel #12
0
 public GoEmptyBlock(GoBlock goBlock)
     : base(goBlock.Board, Color.Empty)
 {
     Members    = new Region(goBlock.Members);
     MemberList = Members.ToList();              // slow might be a faster way
 }
Beispiel #13
0
        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);
                        }
                }
        }
Beispiel #14
0
 public GoBlockUndoAddStone(GoBlock goBlock, int index)
 {
     // save changable properties of original object
     Block = goBlock;
     Index = index;
 }
Beispiel #15
0
 public void AddDeadBlock(GoBlock goBlock)
 {
     Update(goBlock, SafetyFlag.Dead | (goBlock.BlockColor.IsBlack ? SafetyFlag.Black : SafetyFlag.White));
 }
Beispiel #16
0
 public void AddAliveBlock(GoBlock goBlock)
 {
     Update(goBlock, SafetyFlag.Alive | (goBlock.BlockColor.IsBlack ? SafetyFlag.Black : SafetyFlag.White));
 }
Beispiel #17
0
        public bool IsHealthyFor(GoBlock goBlock)
        {
            foreach (GoEmptyBlock lGoEmptyBlock in EmptyBlocks)
                if (!goBlock.Members.IsOnlyAdjacent(lGoEmptyBlock.Members))
                    return false;

            return true;
        }
Beispiel #18
0
 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);
                    }
                }
            }
        }
Beispiel #20
0
 public bool IsNeightbor(GoBlock goBlock)
 {
     return(Neighbors.Contains(goBlock));
 }
 public GoBlockUndoCapture(GoBlock goBlock)
 {
     // save changable properties of original object
     Block = goBlock;
 }
Beispiel #22
0
 public GoBlockUndoAddStone(GoBlock goBlock, int index)
 {
     // save changable properties of original object
     Block = goBlock;
     Index = index;
 }
Beispiel #23
0
 public GoEmptyBlock(GoBlock goBlock)
     : base(goBlock.Board, Color.Empty)
 {
     Members = new Region(goBlock.Members);
     MemberList = Members.ToList();	// slow might be a faster way
 }