Пример #1
0
    public bool IsConstructable(NodeObject node)
    {
        int matchCount   = 0;
        int connectCount = 0;

        for (int i = 0; i < Direction.Length; i++)
        {
            Vector2Int neighborPos = node.Position + Direction[i];
            var        neighbor    = entireNodes[neighborPos];
            if (neighbor.NodeType == ENodeType.Wall)
            {
                connectCount++;
                continue;
            }

            EJointType joint         = node.GetJoint(i);
            EJointType neighborJoint = neighbor.GetJoint2(i);
            if (joint == EJointType.None ||
                neighborJoint == EJointType.None)
            {
                connectCount++;
            }
            else if (joint == neighborJoint)
            {
                connectCount++;
                matchCount++;
            }
        }

        Log.Debug($"Connect : {connectCount} / {matchCount}");

        return((connectCount == 4) && (matchCount > 0));
    }
Пример #2
0
    private void FixNode(NodeObject node)
    {
        Vector2Int pos = node.Position;

        for (int i = 0; i < Direction.Length; i++)
        {
            EJointType joint = node.GetJoint(i);
            if (joint != EJointType.None)
            {
                if (node.Neighbors[i] == null)
                {
                    Vector2Int neighborPos = pos + Direction[i];
                    if (entireNodes.ContainsKey(neighborPos))
                    {
                        NodeObject neighbor = entireNodes[neighborPos];
                        EJointType nJoint   = neighbor.GetJoint2(i);
                        if (joint == nJoint)
                        {
                            node.Neighbors[i] = neighbor;
                            neighbor.Neighbors[(i + 2) % 4] = node;
                        }
                    }
                }
            }
        }
    }
Пример #3
0
    private int CalcLongestWayScoreRecursive(NodeObject node, EJointType joint, ref HashSet <NodeObject> visited)
    {
        int highestScore = 0;

        visited.Add(node);
        if (node.NodeType == ENodeType.Entrance)
        {
            return(0);
        }

        for (int i = 0; i < 4; i++)
        {
            var joint1 = node.GetJoint(i);
            if (joint == joint1)
            {
                var neighbor = node.Neighbors[i];
                if (!ReferenceEquals(null, neighbor))
                {
                    if (!visited.Contains(neighbor))
                    {
                        var joint2 = neighbor.GetJoint2(i);
                        if (joint1 == joint2)
                        {
                            int score = CalcLongestWayScoreRecursive(neighbor, joint, ref visited);
                            highestScore = score > highestScore ? score : highestScore;
                        }
                    }
                }
            }
        }

        return(1 + highestScore);
    }
Пример #4
0
        /// <summary>
        /// Creates instance with provided joint information
        /// </summary>
        /// <param name="_JointType">Type of this joint</param>
        /// <param name="_JointPosition">Position of this joint in piece</param>
        /// <param name="_JointWidth">Width of this joint</param>
        /// <param name="_JointHeight">Height of this joint</param>
        public SJointInfo(EJointType _JointType, EJointPosition _JointPosition, int _JointWidth, int _JointHeight)
        {
            _jointType     = _JointType;
            _jointPosition = _JointPosition;

            _jointWidth  = _JointWidth;
            _jointHeight = _JointHeight;
        }
Пример #5
0
        /// <summary>
        /// Creates instance with provided joint information
        /// </summary>
        /// <param name="_JointType">Type of this joint</param>
        /// <param name="_JointPosition">Position of this joint in piece</param>
        /// <param name="_JointWidth">Width of this joint</param>
        /// <param name="_JointHeight">Height of this joint</param>
        public SJointInfo(EJointType _JointType, EJointPosition _JointPosition, int _JointWidth, int _JointHeight)
        {
            _jointType = _JointType;
            _jointPosition = _JointPosition;

            _jointWidth = _JointWidth;
            _jointHeight = _JointHeight;
        }
Пример #6
0
    /// <summary>
    /// This method is called throw SendMessage from piece when it collides with appropriate collider for its placement.
    /// </summary>
    /// <param name="ObjNum">Number of collider this piece found its place with</param>
    private void PiecePlaceFound(int ObjNum)
    {
        if (_CurrentHoldingPiece != null)
        {
            int PieceRow = 0;
            int PieceCol = 0;

            if (ArrayPosToRC(ObjNum, PiecesInCol, PiecesInRow, out PieceRow, out PieceCol))
            {
                //Get this piece joints information for placement position calculation
                SPieceInfo TempPieceInfo = _PuzzleMaker._CreatedImagePiecesData[PieceRow, PieceCol].PieceMetaData;

                SJointInfo[] TempJointsInfo = TempPieceInfo.GetJoints();

                Vector3 PieceColliderPosition = _ChildColliders[ObjNum].transform.position;

                Vector3 CalculatedPosition = new Vector3();


                #region "Calculate Adjusted X Position For Piece Placement"

                // Calculate X Position
                // Default scaleX of piece is 1 in world
                bool LeftJointPresent  = false;
                bool RightJointPresent = false;

                SJointInfo TempLeftJointInfo  = TempPieceInfo.GetJoint(EJointPosition.Left, out LeftJointPresent);
                SJointInfo TempRightJointInfo = TempPieceInfo.GetJoint(EJointPosition.Right, out RightJointPresent);

                EJointType TempLeftJointType  = TempLeftJointInfo.JointType;
                EJointType TempRightJointType = TempRightJointInfo.JointType;

                float LeftJointWorldScale  = (float)TempLeftJointInfo.JointWidth / (float)_PuzzleMaker.PieceWidthWithoutJoint;
                float RightJointWorldScale = (float)TempRightJointInfo.JointWidth / (float)_PuzzleMaker.PieceWidthWithoutJoint;

                if (LeftJointPresent && RightJointPresent && TempLeftJointType == EJointType.Male && TempRightJointType == EJointType.Male)
                {
                    CalculatedPosition.x = _ChildColliders[ObjNum].transform.position.x + (RightJointWorldScale / 2) - (LeftJointWorldScale / 2);
                }
                else if (LeftJointPresent && TempLeftJointType == EJointType.Male)
                {
                    CalculatedPosition.x = _ChildColliders[ObjNum].transform.position.x - (LeftJointWorldScale / 2f);
                }
                else if (RightJointPresent && TempRightJointType == EJointType.Male)
                {
                    CalculatedPosition.x = _ChildColliders[ObjNum].transform.position.x + (RightJointWorldScale / 2f);
                }
                else
                {
                    CalculatedPosition.x = _ChildColliders[ObjNum].transform.position.x;
                }

                #endregion

                #region "Calculate Adjusted Y Position For Piece Placement"

                // Calculate Y Position
                // Default scaleY of piece is calculated with aspect ratio of image and ScaleX = 1

                bool TopJointPresent    = false;
                bool BottomJointPresent = false;

                SJointInfo TempTopJointInfo    = TempPieceInfo.GetJoint(EJointPosition.Top, out TopJointPresent);
                SJointInfo TempBottomJointInfo = TempPieceInfo.GetJoint(EJointPosition.Bottom, out BottomJointPresent);

                EJointType TempTopJointType    = TempTopJointInfo.JointType;
                EJointType TempBottomJointType = TempBottomJointInfo.JointType;

                float TopJointWorldScale    = (float)TempTopJointInfo.JointHeight / (float)_PuzzleMaker.PieceWidthWithoutJoint;
                float BottomJointWorldScale = (float)TempBottomJointInfo.JointHeight / (float)_PuzzleMaker.PieceWidthWithoutJoint;


                if (TopJointPresent && BottomJointPresent && TempTopJointType == EJointType.Male && TempBottomJointType == EJointType.Male)
                {
                    CalculatedPosition.y = _ChildColliders[ObjNum].transform.position.y + (TopJointWorldScale / 2) - (BottomJointWorldScale / 2);
                }
                else if (TopJointPresent && TempTopJointType == EJointType.Male)
                {
                    CalculatedPosition.y = _ChildColliders[ObjNum].transform.position.y + (TopJointWorldScale / 2);
                }
                else if (BottomJointPresent && TempBottomJointType == EJointType.Male)
                {
                    CalculatedPosition.y = _ChildColliders[ObjNum].transform.position.y - (BottomJointWorldScale / 2);
                }
                else
                {
                    CalculatedPosition.y = _ChildColliders[ObjNum].transform.position.y;
                }

                #endregion


                // Z position
                CalculatedPosition.z = _ChildColliders[ObjNum].transform.position.z;


                // _CurrentHoldingPiece.transform.position = _ChildColliders[ObjNum].transform.position;
                _CurrentHoldingPiece.transform.position = CalculatedPosition;

                //Disable this piece
                _CurrentHoldingPiece.GetComponent <CharacterController>().enabled = false;

                //Call event function
                OnPiecePlaced(_CurrentHoldingPiece, ObjNum);

                _CurrentHoldingPiece = null;

                //Update trackers
                _NoOfPiecesPlaced++;

                //Check for Puzzle complete
                if (_NoOfPiecesPlaced >= _PuzzlePieces.Length)
                {
                    OnPuzzleComplete();
                }
            }
        }
    }
Пример #7
0
    public void GetScore(ScoreViewModel scoreViewModel)
    {
        connExits.Clear();
        foreach (var node in entireNodes)
        {
            if (node.Value.NodeType == ENodeType.Entrance)
            {
                connExits.Add(node.Value, new HashSet <Vector2Int>()
                {
                    node.Value.Position
                });
            }
        }

        foreach (var node in connExits)
        {
            for (int i = 0; i < 4; i++)
            {
                CollectNeighborRecursive(node.Key, node.Key.Neighbors[i], i);
            }
        }

        Dictionary <SortedSet <NodeObject>, int> exitScore = new Dictionary <SortedSet <NodeObject>, int>();
        HashSet <Vector2Int> passNode = new HashSet <Vector2Int>();

        foreach (var node in connExits)
        {
            if (passNode.Contains(node.Key.Position))
            {
                continue;
            }

            SortedSet <NodeObject> exitGroup = new SortedSet <NodeObject>();
            foreach (var comp in connExits)
            {
                if (node.Key.Position != comp.Key.Position)
                {
                    if (node.Value.Contains(comp.Key.Position) && comp.Value.Contains(node.Key.Position))
                    {
                        exitGroup.Add(node.Key);
                        exitGroup.Add(comp.Key);
                        passNode.Add(node.Key.Position);
                        passNode.Add(comp.Key.Position);
                    }
                }
            }
            if (exitGroup.Count > 1)
            {
                exitScore.Add(exitGroup, node.Value.Count);
            }
        }

        int networkScore = 0;

        foreach (var score in exitScore)
        {
            int scoreCalc = (score.Key.Count - 1) * 4;
            networkScore += scoreCalc;
            Log.Debug($"Score : {scoreCalc}");
        }

        Log.Debug($"TotalNetworkScore : {networkScore}");
        scoreViewModel.NetworkScore = networkScore;

        List <NodeObject> rails = new List <NodeObject>();
        List <NodeObject> roads = new List <NodeObject>();

        foreach (var node in entireNodes)
        {
            if (node.Value.NodeType == ENodeType.Entrance)
            {
                continue;
            }

            if (node.Value.IsRailRoute)
            {
                rails.Add(node.Value);
            }

            if (node.Value.IsRoadRoute)
            {
                roads.Add(node.Value);
            }
        }

        HashSet <NodeObject> visited = new HashSet <NodeObject>();
        int railScore = 0;

        foreach (var rail in rails)
        {
            visited.Clear();
            int currentRailScore = CalcLongestWayScoreRecursive(rail, EJointType.Rail, ref visited);
            railScore = railScore < currentRailScore ? currentRailScore : railScore;
        }

        int roadScore = 0;

        foreach (var road in roads)
        {
            visited.Clear();
            int currentRoadScore = CalcLongestWayScoreRecursive(road, EJointType.Road, ref visited);
            roadScore = roadScore < currentRoadScore ? currentRoadScore : roadScore;
        }

        Log.Debug($"TotalRailScore : {railScore}");
        Log.Debug($"TotalRoadScore : {roadScore}");
        scoreViewModel.RailScore = railScore;
        scoreViewModel.RoadScore = roadScore;

        int penaltyScore = 0;

        foreach (var node in entireNodes.Values)
        {
            if (!IsEdgeNode(node))
            {
                for (int i = 0; i < 4; i++)
                {
                    EJointType joint = node.GetJoint(i);
                    if (joint != EJointType.None)
                    {
                        Vector2Int neighborPos = node.Position + Direction[i];
                        if (entireNodes.ContainsKey(neighborPos))
                        {
                            NodeObject neighbor = entireNodes[neighborPos];
                            if (!IsEdgeNode(neighbor))
                            {
                                EJointType nJoint = neighbor.GetJoint2(i);
                                if (joint != nJoint)
                                {
                                    penaltyScore++;
                                }
                            }
                        }
                    }
                }
            }
        }

        Log.Debug($"TotalFaultScore : {penaltyScore}");
        scoreViewModel.PenaltyScore = penaltyScore;
        scoreViewModel.Calculate();
    }