示例#1
0
        public void DrawLayout(Graphics g)
        {
            if (layout_ == null)
            {
                return;
            }
            SolidBrush blackBrush = new SolidBrush(Color.Black);
            Pen        inLinePen  = new Pen(blackBrush);

            foreach (Pieces pieces in piecesList_)
            {
                GoPoint dian = layout_.GetPoint(pieces.Coord.Row, pieces.Coord.Col);
                if (dian.Type == GoPointType.BLACK)
                {
                    PointF center = GetCenter(pieces.Coord);
                    g.DrawImage(Pieces.black_, center.X - 9, center.Y - 9, 18, 18);
                    //g.FillRectangle(blackBrush, center.X - 5, center.Y - 5, 10, 10);
                }
                else if (dian.Type == GoPointType.WHITE)
                {
                    PointF center = GetCenter(pieces.Coord);
                    g.DrawImage(Pieces.white_, center.X - 9, center.Y - 9, 18, 18);
                    //g.DrawRectangle(inLinePen, center.X - 5, center.Y - 5, 10, 10);
                }
            }
        }
示例#2
0
    // @return  True if the specified color can play in the given Point
    public bool IsValidPlay(Vector2 point, GoColor colorStone)
    {
        int x = (int)point.x;
        int y = (int)point.y;

        // Check: If Point is empty. If not, we cannot play there
        if (!IsPointEmpty(point))
        {
            Debug.Log("[GB] Could not create @ ( " + x + ", " + y + "); already occupied");
            return(false);
        }

        // Check: If new Stone would be immediately be captured
        if (IsGroupCaptured(point, colorStone))
        {
            // If a Stone would immediately be captured, we can play it
            // IFF that move would capture enemy Stone(s)
            // AND we aren't violating the rule of Ko
            List <Vector2> list_blocked = new List <Vector2>();
            list_blocked.Add(point);

            // Check adjacent spots to see if we can capture enemy Stone(s)
            List <Vector2> list_adjacent      = GetAdjacentPoints(point);
            bool           b_capture_detected = false;
            foreach (Vector2 point_adj in list_adjacent)
            {
                GoPoint gp_adj = gridPoints[(int)point_adj.x, (int)point_adj.y];
                // We only care about checking against enemy stones

                GoStone stone_adj = gp_adj.GetStone();
                if (stone_adj.Color != colorStone)
                {
                    b_capture_detected |= IsGroupCaptured(point_adj, stone_adj.Color, list_blocked);
                }
            }

            // If no captured were found, play is illegal
            if (!b_capture_detected)
            {
                Debug.Log("[GB] Could not create @ ( " + x + ", " + y + "); illegal move (surrounded)");
                return(false);
            }
            // Check for Ko
            else
            {
                GoTurn turn_prev = gameStateManager.GetTurnPrev();
                if (turn_prev.piecesCaptured == 1 && IsGroupCaptured(turn_prev.pointPlay, turn_prev.turnColor, list_blocked))
                {
                    Debug.Log("[GB] Could not create @ ( " + x + ", " + y + "); illegal move (Ko)");
                    return(false);
                }
            }
        }

        return(true);
    }
示例#3
0
        private void CheckDian(GoLayout layout, int row, int col, GoPointType type)
        {
            GoPoint dian = layout.GetPoint(row, col);

            if (dian == null)
            {
                throw new Exception("Dian get error");
            }
            Assert.AreEqual(dian.Type, type);
        }
示例#4
0
    // Place piece on the board and handle board state management
    private void PlacePiece(GoStone piece, Vector2 pointGrid)
    {
        int     point_x        = (int)pointGrid.x;
        int     point_y        = (int)pointGrid.y;
        GoPoint point_center   = gridPoints[point_x, point_y];
        GoColor color_attacker = piece.Color;
        GoColor color_enemy    = (color_attacker == GoColor.GC_Black ? GoColor.GC_White : GoColor.GC_Black);

        // Place GoPiece GameObject in the GoPoint
        point_center.SetPiece(piece);

        //// Decrement neighboring point's empty count
        //UpdateAdjacentEmptySpaces(pointGrid, (color_attacker == GoColor.GC_Black));

        // Check if we have captured any enemy pieces (Up/Down/Left/Right
        Queue <Vector2> queue_adjacents = new Queue <Vector2>();
        List <Vector2>  list_adj        = GetAdjacentPoints(pointGrid);

        foreach (Vector2 point_adj in list_adj)
        {
            queue_adjacents.Enqueue(point_adj);
        }

        int count_captured = 0;

        while (queue_adjacents.Count > 0)
        {
            // Retrieve Vector2
            Vector2 vec_curr = queue_adjacents.Dequeue();

            // Check if valid
            if (IsValidPoint(vec_curr))
            {
                // Retrieve GoPoint
                GoPoint point_curr = gridPoints[(int)vec_curr.x, (int)vec_curr.y];
                // Check if valid, if enemy color
                if (!point_curr.IsEmpty() && point_curr.GetStone().Color == color_enemy)
                {
                    // If so, check if surrounded.
                    if (IsGroupCaptured(vec_curr, color_enemy))
                    {
                        // If so, remove group and report score to GoStateManager
                        count_captured += TryCaptureGroup(vec_curr, color_enemy);
                    }
                }
            }
        }

        // Report captured stones
        if (count_captured > 0)
        {
            gameStateManager.OnStonesCaptured(color_attacker, count_captured);
        }
    }
示例#5
0
 public void CheckVisitStatus(GoLayout layout)
 {
     for (int i = 0; i < layout.Size; i++)
     {
         for (int j = 0; j < layout.Size; j++)
         {
             GoPoint dian = layout.GetPoint(i, j);
             Assert.AreEqual(false, dian.IsVisited());
         }
     }
 }
示例#6
0
 void Layout_DianChanged()
 {
     piecesList_.Clear();
     if (layout_ == null)
     {
         return;
     }
     for (int i = 0; i < GoLayout.SIZE; i++)
     {
         for (int j = 0; j < GoLayout.SIZE; j++)
         {
             GoPoint dian = layout_.GetPoint(i, j);
             if (dian.Type != GoPointType.EMPTY)
             {
                 piecesList_.Add(new Pieces(i, j, dian.Type));
             }
         }
     }
 }
示例#7
0
    // Use this for initialization
    void Start()
    {
        // Calculate the length of a grid square's size, in pixels :NOTE: assuming our board's grid is square
        txtGridSquareLengthSide = texturePlayfieldDimensions.x / (gridSize - 1);
        // Calculate grid pos radius (squared)
        txtGridPosRadiusSq  = (txtGridSquareLengthSide) * 0.25f;
        txtGridPosRadiusSq *= txtGridPosRadiusSq;

        // Populate the grid points 2D array
        gridPoints = new GoPoint[gridSize, gridSize];
        for (int x = 0; x < gridSize; x++)
        {
            for (int y = 0; y < gridSize; y++)
            {
                // Calculate vectors
                Vector2 point_board = new Vector2(x, y);
                Vector2 pos_txt     = textureCoordsUL + (txtGridSquareLengthSide * new Vector2(x, y));

                // Convert grid position to board's local position
                float pos_x = transform.localScale.x * (((point_board.x * txtGridSquareLengthSide) + textureCoordsUL.x) / textureDimensions.x);
                pos_x -= (0.5f * transform.localScale.x);
                float pos_z = transform.localScale.z * (((point_board.y * txtGridSquareLengthSide) + textureCoordsUL.y) / textureDimensions.y);
                pos_z -= (0.5f * transform.localScale.z);
                Vector3 pos_3D = new Vector3(pos_x, 0.0f, pos_z);

                // Set up adjacency flags for current point (Up/Right/Down/Left)
                int flags_adjacent = 0x0000;

                flags_adjacent |= ((y == (gridSize - 1) ? GoPoint.FLAG_NONE : GoPoint.FLAG_EMPTY) << GoPoint.OFFSET_U);
                flags_adjacent |= ((y == 0 ? GoPoint.FLAG_NONE : GoPoint.FLAG_EMPTY) << GoPoint.OFFSET_D);
                flags_adjacent |= ((x == 0 ? GoPoint.FLAG_NONE : GoPoint.FLAG_EMPTY) << GoPoint.OFFSET_L);
                flags_adjacent |= ((x == (gridSize - 1) ? GoPoint.FLAG_NONE : GoPoint.FLAG_EMPTY) << GoPoint.OFFSET_R);

                // Create Point
                gridPoints[x, y] = new GoPoint(point_board, pos_txt, pos_3D, flags_adjacent);
            }
        }
    }
示例#8
0
    //  Retrieve immediately adjacent liberties for a given point.
    //  Allied adjacent stones do NOT count as liberties.
    //  @param point    Point on the board to check for liberties
    //  @return         # of empy adjacent spaces
    public int GetLibertiesAdjacent(Vector2 point)
    {
        // Return -1 if invalid point
        if (!IsValidPoint(point))
        {
            return(-1);
        }

        // Otherwise, count # of empty adjacent points
        int            count_liberties = 0;
        List <Vector2> list_adj        = GetAdjacentPoints(point);

        foreach (Vector2 point_adj in list_adj)
        {
            GoPoint gp_adj = gridPoints[(int)point_adj.x, (int)point_adj.y];
            if (gp_adj.IsEmpty())
            {
                count_liberties++;
            }
        }

        return(count_liberties);
    }
示例#9
0
        // Factory
        // Create new Group for a given point on the board
        public static GroupInfo CreateGroup(GoBoard board, Vector2 point)
        {
            // Sanity Check: Cannot create group if point is not valid
            if (!board.IsValidPoint(point))
            {
                return(null);
            }

            GroupInfo group = new GroupInfo();

            // Create hash to store all points that have been checked
            HashSet <GoPoint> hash_group = new HashSet <GoPoint>();
            // Create queue to store list of points that need to be checked
            Queue <GoPoint> queue_points = new Queue <GoPoint>();

            int x_curr = (int)point.x;
            int y_curr = (int)point.y;

            // Use initial point to determine the group's State (Empty/Black/White)
            GoPoint point_curr = board.gridPoints[x_curr, y_curr];

            group.groupType = point_curr.PointState;

            // Queue initial point
            queue_points.Enqueue(board.gridPoints[x_curr, y_curr]);
            while (queue_points.Count > 0)
            {
                // Retrieve next point
                point_curr = queue_points.Dequeue();
                x_curr     = (int)point_curr.PointBoard.x;
                y_curr     = (int)point_curr.PointBoard.y;

                bool b_state_same = false;

                // Only proceed if we haven't seen this point yet
                if (!hash_group.Contains(point_curr))
                {
                    // Check current point is the same state as our Group
                    if (point_curr.PointState == group.GroupType)
                    {
                        b_state_same = true;
                    }
                }

                // If same, then we want to add it to our Group and check adjacent points
                if (b_state_same)
                {
                    // Add Point to Group
                    group.GroupPoints.Add(point_curr.PointBoard);

                    // Retrieve adjacent points if allied
                    List <Vector2> list_adj = board.GetAdjacentPoints(point_curr.PointBoard);
                    foreach (Vector2 point_adj in list_adj)
                    {
                        queue_points.Enqueue(board.gridPoints[(int)point_adj.x, (int)point_adj.y]);
                    }
                }

                // Mark GoPoint as checked
                hash_group.Add(point_curr);
            }

            // If our Group's type is not territory, check for liberties
            if (group.GroupType != GoColor.GC_Empty)
            {
                foreach (Vector2 gp_curr in group.GroupPoints)
                {
                    List <Vector2> points_adj = board.GetAdjacentPoints(gp_curr);
                    foreach (Vector2 point_adj in points_adj)
                    {
                        if (board.GetPoint(point_adj).IsEmpty())
                        {
                            group.groupLiberties.Add(point_adj);
                        }
                    }
                }
            }

            return(group);
        }
示例#10
0
    // @param   listExcludes   List of board Points that will not be checkable. Used to simulate empty spaces actually having enemy Stones within
    public bool IsGroupCaptured(Vector2 point, GoColor groupColor, List <Vector2> listExcludes)
    {
        // Check: Bounds
        if (!IsValidPoint(point))
        {
            return(false);
        }

        int x_start = (int)point.x;
        int y_start = (int)point.y;

        // Create hash to store all points that have been checked
        HashSet <GoPoint> hash_group = new HashSet <GoPoint>();
        // Create queue to store list of points that need to be checked
        Queue <GoPoint> queue_points = new Queue <GoPoint>();

        // Insert excluded points into our HashSet
        foreach (Vector2 point_exclude in listExcludes)
        {
            if (IsValidPoint(point_exclude))
            {
                hash_group.Add(gridPoints[(int)point_exclude.x, (int)point_exclude.y]);
            }
        }

        int     x_curr     = x_start;
        int     y_curr     = y_start;
        GoPoint point_curr = gridPoints[x_curr, y_curr];

        bool b_first = true;    // We don't want to check the Point/Stone at the initial position; so we can check even if no Stone is placed yet

        while (b_first || queue_points.Count > 0)
        {
            bool b_allied_piece = (b_first || false);

            // Check current point's Stone (or lack thereof)
            if (!b_first)
            {
                // Retrieve next point
                point_curr = queue_points.Dequeue();
                x_curr     = (int)point_curr.PointBoard.x;
                y_curr     = (int)point_curr.PointBoard.y;

                // Only proceed if we haven't seen this point yet
                if (!hash_group.Contains(point_curr))
                {
                    // If we don't find a stone, then there is at least one open space and the group is not captured
                    if (point_curr.IsEmpty())
                    {
                        return(false);
                    }
                    // Next, check if we have found an enemy Stone. If so, we don't want to check adjacent spaces
                    if (point_curr.GetStone().Color == groupColor)
                    {
                        b_allied_piece = true;
                    }
                }
            }

            // We only want to skip the checks for our initial point
            b_first = false;

            // Retrieve adjacent points if allied
            if (b_allied_piece)
            {
                List <Vector2> list_adj = GetAdjacentPoints(point_curr.PointBoard);

                foreach (Vector2 point_adj in list_adj)
                {
                    queue_points.Enqueue(gridPoints[(int)point_adj.x, (int)point_adj.y]);
                }
            }

            // Mark GoPoint as checked
            hash_group.Add(point_curr);
        }

        // If we run out of points to check without having found an empty spot, this group is captured
        return(true);
    }