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)); }
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; } } } } } }
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); }
/// <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; }
/// <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(); } } } }
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(); }