//After the squares are generated add their neighbours to each other. private void fillNeighbours() { for (int x = 0; x < width; x++) { for (int z = 0; z < height; z++) { GridSquareScript obj = grid[x, z]; obj.position = new Vector2(x, z); for (int x1 = x - 1; x1 <= x + 1; x1++) { for (int z1 = z - 1; z1 <= z + 1; z1++) { if (x1 < 0 || x1 >= width) { continue; } if (z1 < 0 || z1 >= height) { continue; } if (x1 == x && z1 == z) { continue; } obj.neighbors.Add(grid[x1, z1]); } } } } }
public void setWall() { if (walkable) { childRenderer.material.SetColor("_Color", Color.blue); wall.SetActive(true); walkable = false; //Debug.Log("Wall is active"); } else { childRenderer.material.SetColor("_Color", Color.white); wall.SetActive(false); walkable = true; //Debug.Log("Wall is inactive"); } if (start == this) { start = null; } if (end == this) { end = null; } }
private void GameOneStepSixTap() { print("Tapped game one step six"); overlay.HideFtueMessages(); grid.ClearFtueHighlights(); overlay.ShowFtueGameplayMessage(Constants.FtueStrings.GameOneStringEight); grid.ResetFtueGrid(); currentTarget = grid.GetFtueTargetAtIndex(39); grid.HighlightSquare(currentTarget.Index); overlay.SubscribeForFullScreenTap(GameOneStepSevenTap); analyticsController.TutorialStepComplete(8, "SquareRule"); }
public void setStart() { if (start != null) { start.childRenderer.material.SetColor("_Color", Color.white); } start = this; childRenderer.material.SetColor("_Color", Color.green); if (end == start) { end = null; } //Debug.Log("Start selected"); }
public void setEnd() { if (end != null) { end.childRenderer.material.SetColor("_Color", Color.white); } end = this; childRenderer.material.SetColor("_Color", Color.red); if (start == end) { start = null; } //Debug.Log("End Selected"); }
private void GameOneStepFiveTap() { print("Tapped game one step five"); overlay.HideFtueMessages(); grid.ClearFtueHighlights(); overlay.ShowFtueGameplayMessage(Constants.FtueStrings.GameOneStringSix, showTapHand: false); keyboard.ShowKeyboard();//SetKeyboardEnabled(true); keyboard.HighlightKeyboard(); currentQuestion = ResponseQuestion.questionTwo; grid.ResetFtueGrid(); currentTarget = grid.GetFtueTargetAtIndex(63); grid.HighlightColumn(currentTarget.Index); grid.ShowArrowHighlight(0, FtueArrowDirection.Up); analyticsController.TutorialStepComplete(6, "ColQuestion"); }
/* * The Heuristic needs to be strictly less than the actual distance to * get a correct implementation. The easiest is Euclidean distance, but * a better heuristic would be octile distance. */ public static float heuristic(GridSquareScript current) { //Octile distance is the shortest possible distance on a regular square grid. //The squares themselves lie on the XZ plane. Vector2 uses XY, so a bit of translation is needed. float difX = Mathf.Abs(GridSquareScript.end.position.x - current.position.x); float difY = Mathf.Abs(GridSquareScript.end.position.y - current.position.y); //The shorter distance is the diagonal distance. 1.41 is a suitable distance measure for the diagonal. float diag = (difX < difY ? difX : difY) * Mathf.Sqrt(2); //The straight distance is the difference between the two axes. float straight = Mathf.Abs(difX - difY); //The total distance is the sum of the two. return(diag + straight); }
public void StartGameOne(GridController gridController, KeyboardController keyboardController) { print("Start FTUE game One"); overlay = SceneActivationBehaviour <OverlayUISceneActivator> .Instance; grid = gridController; keyboard = keyboardController; keyboard.SetKeyboardClickHandler(KeyboardFtueInput); grid.ResetFtueGrid(); currentTarget = grid.GetFtueTargetAtIndex(34); overlay.ShowFtueSkipButton(true); overlay.ShowFtueGameplayMessage(Constants.FtueStrings.GameOneStringOne); overlay.SubscribeForFullScreenTap(GameOneStepOneTap); grid.HighlightRow(currentTarget.Index); grid.ShowArrowHighlight(27, FtueArrowDirection.Left); analyticsController.TutorialStepComplete(1, "OneRule"); }
public bool IsRuleValid() { int errorCount = 0; int[] levelDataArray = levelData.Select(x => Int32.Parse(x.ToString())).ToArray(); if (levelDataArray.Length != 81) { //Debug.LogError($"Rule id: {Id} length is invalid ({levelDataArray.Length})"); Debug.LogError($"Rule id: {Id} length is invalid ({levelDataArray.Length})"); errorCount += 1; } if (targetIndexes.Length != 3) { Debug.LogError($"Rule id: {Id} target length is invalid"); errorCount += 1; } GameObject gameObject = new GameObject(); for (int i = 0; i < levelDataArray.Length; i++) { gameObject.AddComponent <GridSquareScript>(); } GridSquareScript[] gridSquares = gameObject.GetComponentsInChildren <GridSquareScript>(); for (int i = 0; i < gridSquares.Length; i++) { bool isTarget = targetIndexes.Contains(i); GridSquareScript gridSquare = gridSquares[i]; gridSquare.SetupTestGridSquare(i, levelDataArray[i], isTarget); } Debug.LogWarning($"************* RULE {Id} *************"); targetSolutions = new GridSolutionType[targetIndexes.Length]; difficultyRating = 0; for (int i = 0; i < targetIndexes.Length; i++) { int targetCount = 0; GridSquareScript target = gridSquares[targetIndexes[i]]; Debug.LogWarning($"---------- TARGET {target.Index} ---------"); for (int j = 1; j <= 9; j++) { target.UpdateTestGridNumber(j); Debug.LogWarning($"---------- Number {target.Number} ---------"); GridSolutionType solution = GridSolver.SolveGridAtIndex(gridSquares, target); if (solution != GridSolutionType.None) { targetCount += 1; Debug.LogWarning($"Rule id: {Id} target {targetIndexes[i]} has solution with {j} ({solution})"); targetSolutions[i] = solution; } } //RESET TARGET AFTER TEST SO DOESN"T EFFECT NEXT TARGET!!! target.UpdateTestGridNumber(0); if (targetCount != 1) { Debug.LogError($"Rule id: {Id} target {targetIndexes[i]} has {targetCount} solutions"); errorCount += 1; } else { difficultyRating += (int)targetSolutions[i]; } } DestroyImmediate(gameObject); #if UNITY_EDITOR EditorUtility.SetDirty(this); #endif return(errorCount == 0); }
// There should only be one pathfinder at any given time, so yeah, everything is static. public static IEnumerator findPath() { openList = new List <GridSquareScript>(); closedList = new List <GridSquareScript>(); WaitForSeconds wait = new WaitForSeconds(0.1f); GridSquareScript.start.distanceFromStart = 0; GridSquareScript.start.distanceFromEnd = heuristic(GridSquareScript.start); closedList.Add(GridSquareScript.start); foreach (GridSquareScript n in GridSquareScript.start.neighbors) { //add the neighbors to the open list. n.parent = GridSquareScript.start; n.distanceFromEnd = heuristic(n); n.distanceFromStart = n.parent.distanceFromStart + (n.position - n.parent.position).magnitude; n.childRenderer.material.SetColor("_Color", Color.yellow); openList.Add(n); yield return(wait); } while (!closedList.Contains(GridSquareScript.end)) { if (openList.Count == 0) { //There are no more squares to explore. break; } GridSquareScript current = openList[0]; float curDist = current.distanceFromStart + current.distanceFromEnd; foreach (GridSquareScript sq in openList) { if (curDist > sq.distanceFromEnd + sq.distanceFromStart) { //Swap to the smallest total distance. curDist = sq.distanceFromEnd + sq.distanceFromStart; current = sq; } } if (current == GridSquareScript.end) { //We've found the path, time to render it. //TODO: Finish the path rendering. //We've found the path current.childRenderer.material.SetColor("_Color", Color.red); GridSquareScript next = current; float total = 0; while (current.parent != null) { total = total + 1; current = current.parent; } float len = 1; next = next.parent; while (next.parent != null) { next.childRenderer.material.SetColor("_Color", Color.Lerp(Color.red, Color.green, len / total)); len = len + 1; next = next.parent; yield return(wait); } break; } else { //Shows the selected open node. current.childRenderer.material.SetColor("_Color", Color.magenta); yield return(wait); foreach (GridSquareScript n in current.neighbors) { if (closedList.Contains(n)) { continue; } if (!n.walkable) { continue; } if (openList.Contains(n)) { float th = heuristic(n); float tds = current.distanceFromStart + (n.position - current.position).magnitude; if (n.distanceFromStart + n.distanceFromEnd > th + tds) { n.parent = current; n.distanceFromEnd = th; n.distanceFromStart = tds; n.text.text = n.text.text + "\nD=" + n.distanceFromStart + "\nF=" + n.distanceFromEnd + "\nT=" + (n.distanceFromEnd + n.distanceFromStart); } continue; } n.parent = current; n.distanceFromEnd = heuristic(n); n.distanceFromStart = n.parent.distanceFromStart + (n.position - n.parent.position).magnitude; n.childRenderer.material.SetColor("_Color", Color.yellow); n.text.text = n.text.text + "\nD=" + n.distanceFromStart + "\nF=" + n.distanceFromEnd + "\nT=" + (n.distanceFromEnd + n.distanceFromStart); openList.Add(n); yield return(wait); } openList.Remove(current); closedList.Add(current); current.childRenderer.material.SetColor("_Color", Color.grey); } } yield return(wait); }