unity – How to show it to the user when the game ends?


I have a Sudoku game which generates a new game by touching the button, and with the function restard().

The problem is that it has a coroutine (IEnumerator solution()) to show me when I fill in all the panel numbers:

string message = correctSolution? "Congratulations, you managed to solve": "Try again";
Debug.Log (message);

The problem is that when the game ends, nothing happens, it remains inactive, without knowing if it is finished correctly or not.

I don’t know how I should display the message when completing the game correctly: “Congratulations, I successfully finished the game with a record time of: {time}”

As I said, currently the game does not show anything when it is completed, and thus, we do not know if the solution is correct.
I show the Script that handles this part of the game.

Remove parts of the code like the Hint Generator and all of it to make it less extensive
I hope you can give me some idea to achieve this, it took days and I can’t get it right and the game shows the message when it has been completed correctly

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using System.Text;

[System.Serializable]
public class cell
{
  public Text label;
  public int solution;
  public bool clue;
  public int gridIndex;
}

public class Sudoku : MonoBehaviour
{

  public enum clueGenerator
  {
    simple,
    efficient,
    automatic,
  }

  //hide these variables in the inspector (we're using a custom inspector)
  [HideInInspector]
  public clueGenerator clueGeneratorType;
  [HideInInspector]
  public float effectTime;
  [HideInInspector]
  public Color emptyColor;
  [HideInInspector]
  public Color labelColor;
  [HideInInspector]
  public Color clueColor;
  [HideInInspector]
  public Color clueLabelColor;
  [HideInInspector]
  public Color correctColor;
  [HideInInspector]
  public Color wrongColor;
  [HideInInspector]
  public float fadeSpeed;
  [HideInInspector]
  public int simpleClueGeneratorMinClues;

  //visible in the inspector
  // visible en el inspector
  public GameObject cell;
  public GameObject cellGrid;
  public Text loadingText;
  public GameObject numbers;
  public Image newButton;
  public Sprite cellBackground;
  public Text maxCluesText;
  public Slider maxCluesSlider;
  public Image maxCluesHandle;

  //not visible in the inspector
  int maxClues;
  int clueAttempts;

  GridLayoutGroup grid;
  RectTransform rect;

  bool fade;
  int solutionCount;

  [HideInInspector]
  public List<cell> cells = new List<cell>();
  List<int> notClues = new List<int>();

  void Start()
  {
    //don't yet show the numbers
    numbers.SetActive(false);

    //give the 'new' button a transparent color until the puzzle has been generated
    newButton.color = new Color(newButton.color.r, newButton.color.g, newButton.color.b, 0.3f);

    //get the grid and transform components
    grid = GetComponent<GridLayoutGroup>();
    rect = GetComponent<RectTransform>();

    


    //find the cell size and assign it to the grid
    float cellWidth = rect.rect.width / 3 - (2 * grid.spacing.x / 3) - (((float)grid.padding.left + (float)grid.padding.right) / 3);
    grid.cellSize = new Vector2(cellWidth, cellWidth);

    //get the last clues slider value if it wasn't 0 (0 would mean the player prefs were deleted)
    if (PlayerPrefs.GetInt("max clues") != 0)
    {
      maxCluesSlider.value = PlayerPrefs.GetInt("max clues");
      maxCluesText.text = PlayerPrefs.GetInt("max clues") + "";
      maxClues = PlayerPrefs.GetInt("max clues");
    }
    else
    {
      //if the player prefs were deleted, reset the clues slider to 50
      maxCluesSlider.value = 50;
      maxCluesText.text = 50 + "";
      maxClues = 50;
    }


    //get the start slider color based on the slider value
    maxCluesHandle.color = new Color((100f - (float)maxClues) / 100f, (float)maxClues / 130f, 0.2f, 1);

    //if we're using the automatic generator, use the max amount of clues to find out whether we should use the simple or the efficient way of generating clues
    if (clueGeneratorType == clueGenerator.automatic)
    {
      if (maxClues < simpleClueGeneratorMinClues)
      {
        clueGeneratorType = clueGenerator.efficient;
      }
      else
      {
        clueGeneratorType = clueGenerator.simple;
      }
    }
   
    //start generating the puzzle
    generate();

   // timeR.instanciar.iniciarTiempo();
  }

  void Update()
  {
    //if the puzzle has been generated and we're fading in the grid
    if (fade)
    {
      //change the button alpha and hide the loading text
      newButton.color = new Color(newButton.color.r, newButton.color.g, newButton.color.b, 1f);
      loadingText.color = new Color(1, 1, 1, 0);

      //show the numbers we can choose from
      if (!numbers.activeSelf)
        StartCoroutine(showNumbers());

      //if the cells are not fully visible yet
      if (cells[0].label.transform.parent.GetChild(1).GetComponent<Image>().color.a > 0)
      {
        //fade out all cell cover objects -- 
        for (int i = 0; i < 81; i++)
        {
          Image cellCover = cells[i].label.transform.parent.GetChild(1).GetComponent<Image>();
          cellCover.color = new Color(cellCover.color.r, cellCover.color.g, cellCover.color.b, cellCover.color.a - (Time.deltaTime * fadeSpeed));
        }
      }
      else
      {
        //stop fading--- 
        fade = false;
      }
    }
  }

  IEnumerator showNumbers()
  {
    //disable all numbers
    foreach (Transform child in numbers.transform)
    {
      child.gameObject.SetActive(false);
    }

    //enable the parent object
    numbers.SetActive(true);

    //for each number, enable it and wait a moment
    for (int i = 1; i <= 10; i++)
    {
      numbers.transform.GetChild(i).gameObject.SetActive(true);
      yield return new WaitForSeconds(effectTime / 15);
    }

    //wait 0.5 seconds and enable the first child object
    yield return new WaitForSeconds(0.5f);
    numbers.transform.GetChild(0).gameObject.SetActive(true);
  }

  public void generate()
  {
    //first, add all empty cells
    for (int i = 0; i < 81; i++)
    {
      cells.Add(new cell { solution = 0 });
    }

    //if we need to regenerate the puzzle, start again
    if (regenerate())
    {
      cells.Clear();
      generate();
      return;
    }
    else
    {
      //if we don't need to generate again, load the grid
      StartCoroutine(loadGrid());
    }
  }

  public bool regenerate()
  {
    //for all rows and columns in the grid
    for (int i = 0; i < 9; i++)
    {
      for (int I = i * 9; I < i * 9 + 9; I++)
      {
        //store the grid index so we know the section of the grid that contains this cell
        cells[I].gridIndex = i;
        //by default, each cell is a clue
        cells[I].clue = true;

        //get the number for this cell
        int number = getNumber(I);

        //10 is not possible, so if the number is not 10, use the number as the solution for this cell
        if (number != 10)
        {
          cells[I].solution = number;
        }
        else
        {
          //if the number returned 10, we know it's not possible so we need to regenerate the grid
          return true;
        }
      }
    }

    //if all numbers fit, we don't have to generate the main grid again
    return false;
  }

  IEnumerator loadGrid()
  {
    //for each sub-grid (there's 9 small grids with 9 cells each, part of one big grid)
    for (int i = 0; i < 9; i++)
    {
      //create the sub-grid and parent it to this main grid
      GameObject newGrid = Instantiate(cellGrid);
      newGrid.transform.SetParent(transform, false);

      //get the grid and transform components
      GridLayoutGroup newGridLayout = newGrid.GetComponent<GridLayoutGroup>();
      RectTransform newRect = newGrid.GetComponent<RectTransform>();

      //for all cells in this sub-grid
      for (int I = i * 9; I < i * 9 + 9; I++)
      {
        //wait a short moment and create the cell
        yield return new WaitForSeconds(effectTime / 81);
        GameObject newCell = Instantiate(cell);

        //get the cell label
        cells[I].label = newCell.transform.GetChild(0).GetComponent<Text>();

        //parent the cell to the sub-grid and name it after its index
        newCell.transform.SetParent(newGrid.transform, false);
        newCell.name = I + "";

        //get the cell size and assign it to the grid
        float cellWidth = newRect.rect.width / 3 - (2 * newGridLayout.spacing.x / 3) - (((float)newGridLayout.padding.left + (float)newGridLayout.padding.right) / 3);
        newGridLayout.cellSize = new Vector2(cellWidth, cellWidth);
      }
    }

    //wait a moment and get the clues
    yield return new WaitForSeconds(0.2f);
    getClues();
  }

  public int getNumber(int i)
  {
    //get a random number from 1 to 9
    int number = Random.Range(1, 10);

    //use the random number as the start number and continue to 9
    for (int n = number; n < 10; n++)
    {
      //check if the number fits and if it does, return it
      if (horizontal(n, i, false) && vertical(n, i, false) && box(n, i, false))
        return n;
    }
    //if none of the previous numbers fit, try again from 1 to the random number
    for (int N = 1; N < number; N++)
    {
      if (horizontal(N, i, false) && vertical(N, i, false) && box(N, i, false))
        return N;
    }

    //if all numbers from 1 to 9 don't fit, return 10 to let it know we couldn't find a fitting number
    return 10;
  }

  public int clues()
  {
    int clueCount = 0;

    //add one to the number of clues for each clue
    for (int i = 0; i < 81; i++)
    {
      if (cells[i].clue)
        clueCount++;
    }

    //return the total number of clues
    return clueCount;
  }

  public void checkForClue(int cell)
  {
    //total number of solutions
    solutionCount = 0;

    //disable the clue at this cell position
    cells[cell].clue = false;
    cells[cell].label.text = "";

    //clear all cell positions that or not clues
    notClues.Clear();

    //for all cells, add the cells that are not clues
    for (int i = 0; i < 81; i++)
    {
      if (!cells[i].clue)
        notClues.Add(i);
    }

    //check the number of solutions
    checkSolutions();

    //if the number of solutions for the current grid is not 1, we need to enable this clue to make sure the puzzle has 1 solution
    if (solutionCount != 1)
    {
      cells[cell].clue = true;
      cells[cell].label.text = cells[cell].solution + "";
    }

    return;
  }

  public void checkSolutions()
  {
    int i = 0;

    //check for new solutions
    while (newSolution(i))
    {
      solutionCount++;
      i = notClues.Count - 1;

      //two solutions already means we need to enable the clue so we can return
      if (solutionCount > 1)
        return;
    }
  }

  public bool newSolution(int i)
  {
    int I = i;

    //go through all cell positions that are not clues
    while (I < notClues.Count)
    {

      //if it can backtrack this position, go to the next cell that is not a clue
      if (backtrack(notClues[I]))
      {
        I++;
      }
      //if it can't, while the not-clue cell index is bigger than 0, go back to the last cell that is not a clue
      else
      {
        if (I > 0)
        {
          I--;
        }
        else
        {
          //if this is the first one again, there's no solution left
          return false;
        }
      }
    }

    //if we went through all cells, there's a new solution
    return true;
  }

  public bool backtrack(int i)
  {
    //start with the number 1
    int startValue = 1;

    //if the cell has a number, set the start value to that number + 1
    if (cells[i].label.text != "")
      startValue = int.Parse(cells[i].label.text) + 1;

    //if the text had the number 9 (9 + 1 = 10) we can't check another number so this cell can not be filled and we need to return
    if (startValue == 10)
    {
      cells[i].label.text = "";
      return false;
    }

    //until 9, for all values check if they are valid and if they are, return true since we found a succesfull value
    for (int I = startValue; I < 10; I++)
    {
      if (horizontal(I, i, true) && vertical(I, i, true) && box(I, i, true))
      {
        cells[i].label.text = "" + I;
        return true;
      }
    }

    //after checking all values, return false since we didn't find a valid value
    cells[i].label.text = "";
    return false;
  }

  public void showSolution()
  {
    //show the solution for this puzzle
    StartCoroutine(solution());
  }

  IEnumerator solution()
  {
    bool correctSolution = true;

    //for all cells in the grid
    for (int i = 0; i < 81; i++)
    {
      //if this cell is not a clue
      if (!cells[i].clue)
      {
        //get the cell image component
        Image image = cells[i].label.transform.parent.GetComponent<Image>();

        //if the player filled in the right number, show the green color
        if (cells[i].label.text == cells[i].solution + "")
        {
          image.color = correctColor;
        }
        else
        {
          //if the player had a wrong number, show the red color
          image.color = wrongColor;
        }

        //show the solution and wait a moment for a nice effect
        cells[i].label.text = cells[i].solution + "";
        yield return new WaitForSeconds(effectTime / 81);
      }
    }
    string message = correctSolution ? " Felicidades, conseguiste resolver" : " Vuelve a intentarlo";
    Debug.Log(message);
  }

  public bool box(int number, int n, bool checkingClues)
  {
    //box start position
    int startPosition = 0;

    //find the start position in this sub-grid (which automatically is the start position since we're checking the box)
    for (int i = n; i >= 0; i--)
    {
      if (i % 9 == 0)
      {
        startPosition = i;
        break;
      }
    }

    //for all cells in the sub-grid
    for (int I = startPosition; I < startPosition + 9; I++)
    {
      //if we're not checking clues
      if (!checkingClues)
      {
        //return false if this is not the cell that we were checking and the solution of this cell is the number
        if (I != n && cells[I].solution == number)
          return false;
      }
      else
      {
        //if we are checking for clues, do the same but now check the actual label
        if (I != n && cells[I].label.text == number + "")
          return false;
      }
    }

    //if we've checked all cells in this sub-grid, return true
    return true;
  }

  public void restart()
  {
    //if we can load a new puzzle, restart the current scene
    if (newButton.color.a == 1)
      SceneManager.LoadScene(SceneManager.GetActiveScene().name);
  }
}



Source link

More To Explore

Share on facebook
Share on twitter
Share on linkedin
Share on email