Advertisement
rj1twitch

Mine Sweeper clone made in Unity3d

Sep 20th, 2019
259
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 31.86 KB | None | 0 0
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.UI;
  5. using TMPro;
  6.  
  7. public class GameBoard : MonoBehaviour
  8. {
  9.    
  10.  
  11.     public Sprite cellCover;
  12.     public Sprite cellBG;
  13.     public Sprite mineSprite;
  14.     public Sprite flagSprite;
  15.  
  16.     GameObject flagContainer;
  17.     GameObject cellContainer;
  18.     GameObject mineContainer;
  19.     Canvas gameCanvas;
  20.  
  21.     Image[] mines;
  22.     Vector2Int[] mineLocations;
  23.  
  24.     public MineSweeperCell[,] cells;
  25.  
  26.  
  27.  
  28.     Vector2Int boardDimensions=new Vector2Int(20,15);
  29.     Vector2Int offSet=Vector2Int.zero;
  30.     int cellSize=40;
  31.     int numberOfMines;
  32.  
  33.  
  34.     //public Text debugtext;
  35.  
  36.  
  37.     public RectTransform rectTransform;
  38.  
  39.  
  40.  
  41.     public GameState currentGameState;
  42.    
  43.  
  44.  
  45.     //int dontcrash = 0;
  46.  
  47.  
  48.     bool flagMode;
  49.     List<FlagPlacement> flags;
  50.     public Image flagModeSprite;
  51.  
  52.  
  53.  
  54.  
  55.     public TextMeshProUGUI timerText;
  56.  
  57.     float timer = 0;
  58.  
  59.     const string audioSaveKey = "mute";
  60.  
  61.     // Start is called before the first frame update
  62.     void Start()
  63.     {
  64.         mainMenuGO.SetActive(true);
  65.         inGameMenuGO.SetActive(false);
  66.         pauseMenuGO.SetActive(false);
  67.         gameOverScreenGO.SetActive(false);
  68.         winScreenGO.SetActive(false);
  69.  
  70.  
  71.         gameCanvas = FindObjectOfType<Canvas>();
  72.  
  73.  
  74.  
  75.  
  76.  
  77.         flagContainer = new GameObject();
  78.         flagContainer.transform.parent = gameCanvas.transform;
  79.         flagContainer.transform.localPosition = Vector3.zero;
  80.         flagContainer.transform.localScale = new Vector3(1f, 1f, 1f);
  81.        
  82.  
  83.         cellContainer = new GameObject();
  84.         cellContainer.transform.parent = gameCanvas.transform;
  85.         cellContainer.transform.localPosition = Vector3.zero;
  86.         cellContainer.transform.localScale = new Vector3(1f,1f,1f);
  87.         rectTransform = cellContainer.AddComponent<RectTransform>();
  88.  
  89.  
  90.         mineContainer = new GameObject();
  91.         mineContainer.transform.parent = gameCanvas.transform;
  92.         mineContainer.transform.localPosition = Vector3.zero;
  93.         mineContainer.transform.localScale = new Vector3(1f, 1f, 1f);
  94.  
  95.  
  96.         flagContainer.transform.SetAsFirstSibling();
  97.         cellContainer.transform.SetAsFirstSibling();
  98.         mineContainer.transform.SetAsFirstSibling();
  99.  
  100.  
  101.         flagContainer.name="flagContainer";
  102.         cellContainer.name = "cellContainer";
  103.         mineContainer.name = "mineContainer";
  104.  
  105.  
  106.         flagMode = false;
  107.         flagModeSprite.color = Color.black;
  108.  
  109.  
  110.  
  111.         if (PlayerPrefs.HasKey(audioSaveKey))
  112.         {
  113.             if (PlayerPrefs.GetInt(audioSaveKey) == 1)
  114.             {
  115.                 muted = false;
  116.                 audioButtonImage.color = Color.white;
  117.             }
  118.             else
  119.             {
  120.                 muted = true;
  121.                 audioButtonImage.color = Color.black;
  122.             }
  123.  
  124.         }
  125.         else
  126.         {
  127.             muted = true;
  128.             audioButtonImage.color = Color.black;
  129.         }
  130.     }
  131.  
  132.  
  133.  
  134.     void Cheat()
  135.     {
  136.         cellContainer.transform.SetAsFirstSibling();
  137.     }
  138.  
  139.  
  140.     // Update is called once per frame
  141.     void Update()
  142.     {
  143.  
  144.  
  145.         if (!CaptureMouseClick())
  146.         {
  147.             HandleInteraction();
  148.         }
  149.  
  150.         if (currentGameState == GameState.INPROGRESS || currentGameState == GameState.FIRSTCLICK)
  151.         {
  152.             UpdateTimer();
  153.         }
  154.  
  155.  
  156.  
  157.  
  158.         if (CheckForWinCondition())
  159.         {
  160.             WinGame();
  161.         }
  162.  
  163.         if (Input.GetKeyDown(KeyCode.B))
  164.         {
  165.             //Cheat();
  166.         }
  167.     }
  168.  
  169.     void WinGame()
  170.     {
  171.         currentGameState = GameState.ENDED;
  172.  
  173.         winScreenGO.SetActive(true);
  174.  
  175.         string minSec = string.Format("{0}:{1:00}", (int)timer / 60, (int)timer % 60);
  176.         winScreenTimerText.text ="You Win!!  In "+ minSec+".";
  177.  
  178.     }
  179.  
  180.     bool CaptureMouseClick()
  181.     {
  182.         if (pauseMenuGO.activeSelf)
  183.         {
  184.             return (true);
  185.         }
  186.         if (winScreenGO.activeSelf)
  187.         {
  188.             return (true);
  189.         }
  190.         if (gameOverScreenGO.activeSelf)
  191.         {
  192.             return (true);
  193.         }
  194.  
  195.         return (false);
  196.     }
  197.  
  198.     void HandleInteraction()
  199.     {
  200.         if (Input.GetMouseButtonDown(0))
  201.         {
  202.             if (currentGameState == GameState.INPROGRESS)
  203.             {
  204.                 if (Input.GetMouseButtonDown(0))
  205.                 {
  206.                     if (!flagMode)
  207.                     {
  208.                         Vector2Int temp = HighlightCell(offSet, cellSize);
  209.                         if (temp.x != -1)
  210.                         {
  211.                             UncoverCell(temp);
  212.                         }
  213.                     }
  214.                     else
  215.                     {
  216.                         Vector2Int temp = HighlightCell(offSet, cellSize);
  217.                         if (temp.x != -1)
  218.                         {
  219.                             PlaceFlag(temp);
  220.                         }
  221.                     }
  222.                 }
  223.             }
  224.             else if (currentGameState == GameState.FIRSTCLICK)//spawn bombs after click
  225.             {
  226.                 if (Input.GetMouseButtonDown(0))
  227.                 {
  228.                     if (!flagMode)
  229.                     {
  230.                         Vector2Int temp = HighlightCell(offSet, cellSize);
  231.  
  232.                         if (temp.x != -1)
  233.                         {
  234.                             SpawnMines(numberOfMines, temp);
  235.                             UncoverCell(temp);
  236.                         }
  237.                     }
  238.                     else
  239.                     {
  240.                         Vector2Int temp = HighlightCell(offSet, cellSize);
  241.                         if (temp.x != -1)
  242.                         {
  243.                             PlaceFlag(temp);
  244.                         }
  245.                     }
  246.                 }
  247.             }
  248.         }
  249.     }
  250.  
  251.  
  252.     private void HandleMouseClick()
  253.     {
  254.  
  255.         if (currentGameState == GameState.INPROGRESS)
  256.         {
  257.  
  258.             Debug.Log("uncover cell");
  259.  
  260.             if (!flagMode)
  261.             {
  262.                 Vector2Int temp = HighlightCell(offSet, cellSize);
  263.                 if (temp.x != -1)
  264.                 {
  265.  
  266.                     UncoverCell(temp);
  267.  
  268.                 }
  269.             }
  270.             else
  271.             {
  272.                 Vector2Int temp = HighlightCell(offSet, cellSize);
  273.  
  274.  
  275.                 if (temp.x != -1)
  276.                 {
  277.                     PlaceFlag(temp);
  278.                 }
  279.             }
  280.  
  281.  
  282.         }
  283.         else if (currentGameState == GameState.FIRSTCLICK)
  284.         {
  285.  
  286.             Debug.Log("uncover cell");
  287.  
  288.             if (!flagMode)
  289.             {
  290.                 //int temp = HighlightCell(offSet,cellSize);
  291.                 Vector2Int temp = HighlightCell(offSet, cellSize);
  292.  
  293.                 if (temp.x != -1)
  294.                 {
  295.  
  296.                     SpawnMines(numberOfMines, temp);
  297.  
  298.  
  299.  
  300.  
  301.  
  302.                     UncoverCell(temp);
  303.  
  304.  
  305.                 }
  306.             }
  307.             else
  308.             {
  309.                 Vector2Int temp = HighlightCell(offSet, cellSize);
  310.  
  311.  
  312.                 if (temp.x != -1)
  313.                 {
  314.                     PlaceFlag(temp);
  315.                 }
  316.             }
  317.  
  318.  
  319.         }
  320.  
  321.     }
  322.  
  323.  
  324.  
  325.     void InitializeGameBoard(Vector2Int bDimensions, int cSize,Vector2Int bOffset,int nOfMines)
  326.     {
  327.         boardDimensions = bDimensions;
  328.         cellSize = cSize;
  329.         offSet = bOffset;
  330.         numberOfMines = nOfMines;
  331.  
  332.  
  333.         if (ShouldSpawnCells())
  334.         {
  335.             ClearCells();
  336.             SpawnBoard();
  337.         }
  338.         else
  339.         {
  340.             RestartGame();
  341.         }
  342.  
  343.         flagContainer.transform.SetAsFirstSibling();
  344.         cellContainer.transform.SetAsFirstSibling();
  345.         mineContainer.transform.SetAsFirstSibling();
  346.         currentGameState = GameState.FIRSTCLICK;
  347.  
  348.         flagMode = false;
  349.         flagModeSprite.color = Color.black;
  350.     }
  351.  
  352.  
  353.     void PlaceFlag(Vector2Int location)
  354.     {
  355.         if (flags == null)
  356.         {
  357.             flags = new List<FlagPlacement>();
  358.         }
  359.  
  360.         if (cells[location.x, location.y].isCovered)
  361.         {
  362.             //first check for flag already there
  363.             int index=-1;
  364.  
  365.             for (int i = 0; i < flags.Count; i++)
  366.             {
  367.                 if (flags[i].flagLocation.x == location.x && flags[i].flagLocation.y == location.y)
  368.                 {
  369.                     index = i;
  370.                 }
  371.             }
  372.  
  373.  
  374.             if (index != -1)
  375.             {
  376.                 Destroy(flags[index].flagImage);
  377.  
  378.                 flags.RemoveAt(index);
  379.             }
  380.             else
  381.             {
  382.                 flags.Add(InitializeFlag(new Vector2Int(location.x, location.y)));
  383.             }
  384.         }
  385.     }
  386.  
  387.     FlagPlacement InitializeFlag(Vector2Int location)
  388.     {
  389.         GameObject temp = new GameObject();
  390.         temp.transform.parent =flagContainer.transform;
  391.         temp.transform.localScale =new Vector3(1f,1f,1f);
  392.         temp.gameObject.SetActive(true);
  393.         temp.transform.position = cells[location.x, location.y].cellImage.transform.position;
  394.         temp.AddComponent<Image>().sprite = flagSprite;
  395.         temp.GetComponent<Image>().rectTransform.sizeDelta = new Vector2(cellSize-20f,cellSize-20f);
  396.  
  397.         FlagPlacement flpl = new FlagPlacement(temp, location);
  398.  
  399.         return (flpl);
  400.     }
  401.  
  402.     public void FlagButton()
  403.     {
  404.         if (flagMode = !flagMode)
  405.         {
  406.             flagModeSprite.color = Color.white;
  407.         }
  408.         else
  409.         {
  410.             flagModeSprite.color = Color.black;
  411.         }
  412.  
  413.  
  414.  
  415.     }
  416.  
  417.     void SpawnBoard(Vector2Int boardWidthAndHeight, Vector2Int boardOffSet, int boardCellSize)
  418.     {
  419.        
  420.  
  421.  
  422.         Vector2 startingPos = new Vector2(
  423.             ((-boardWidthAndHeight.x * boardCellSize) /2f)+boardCellSize/2f,
  424.             ((-boardWidthAndHeight.y * boardCellSize) / 2f) + boardCellSize / 2f);
  425.  
  426.  
  427.        
  428.  
  429.         cells = new MineSweeperCell[boardWidthAndHeight.x, boardWidthAndHeight.y];
  430.         //cellCovered=new bool[boardWidthAndHeight.x, boardWidthAndHeight.y];
  431.  
  432.  
  433.  
  434.         for (int y = 0; y < boardWidthAndHeight.y; y++)
  435.         {
  436.             for (int x = 0; x < boardWidthAndHeight.x; x++)
  437.             {
  438.                 cells[x, y] = InitiateCell();
  439.  
  440.                 cells[x, y].cellImage.transform.localPosition = new Vector3(
  441.                     (x* boardCellSize) +startingPos.x+boardOffSet.x,
  442.                     ((boardWidthAndHeight.y-(y+1))*boardCellSize)+startingPos.y+boardOffSet.y,
  443.                     0);
  444.             }
  445.         }
  446.  
  447.         ClearBombs();
  448.         ClearFlags();
  449.     }
  450.  
  451.     void SpawnBoard()
  452.     {
  453.        
  454.  
  455.  
  456.         Vector2 startingPos = new Vector2(
  457.             ((-boardDimensions.x * cellSize) /2f)+cellSize/2f,
  458.             ((-boardDimensions.y * cellSize) / 2f) + cellSize / 2f);
  459.  
  460.  
  461.        
  462.  
  463.         cells = new MineSweeperCell[boardDimensions.x, boardDimensions.y];
  464.         //cellCovered=new bool[boardWidthAndHeight.x, boardWidthAndHeight.y];
  465.  
  466.  
  467.  
  468.         for (int y = 0; y < boardDimensions.y; y++)
  469.         {
  470.             for (int x = 0; x < boardDimensions.x; x++)
  471.             {
  472.                 cells[x, y] = InitiateCell();
  473.  
  474.                 cells[x, y].cellImage.transform.localPosition = new Vector3(
  475.                     (x* cellSize) +startingPos.x+offSet.x,
  476.                     ((boardDimensions.y-(y+1))* cellSize) +startingPos.y+offSet.y,
  477.                     0);
  478.             }
  479.         }
  480.  
  481.         ClearBombs();
  482.         ClearFlags();
  483.     }
  484.  
  485.     Vector2Int HighlightCell(Vector2Int boardOffSet, int boardCellSize)
  486.     {
  487.         if (cells == null)
  488.         {
  489.             return (Vector2Int.zero);
  490.         }
  491.  
  492.         Vector2 uiPos = ConvertScreenSpaceToGridSpace();
  493.  
  494.         Vector2 startingPos = new Vector2(
  495.             ((-cells.GetLength(0) * boardCellSize) / 2f) + boardCellSize / 2f,
  496.             ((-cells.GetLength(1) * boardCellSize) / 2f) + boardCellSize / 2f);
  497.  
  498.         for (int y = 0; y < cells.GetLength(1); y++)
  499.         {
  500.             for (int x = 0; x < cells.GetLength(0); x++)
  501.             {
  502.                 Vector2 cellPos= new Vector3(
  503.                     (x * boardCellSize) + startingPos.x + boardOffSet.x,
  504.  
  505.                     ((cells.GetLength(1) - (y + 1)) * boardCellSize) + startingPos.y + boardOffSet.y
  506.                     );
  507.  
  508.                 if (CellContainsPoint(cellPos, uiPos, boardCellSize))
  509.                 {
  510.                     //debugtext.text = x+", "+y;
  511.                     return (new Vector2Int(x,y));
  512.                 }
  513.             }
  514.         }
  515.        
  516.  
  517.         return (new Vector2Int(-1,-1));
  518.     }
  519.  
  520.    
  521.  
  522.     Vector2 ConvertScreenSpaceToGridSpace()
  523.     {
  524.         Vector2 temp;
  525.         RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, Input.mousePosition, null, out temp);
  526.  
  527.         return (new Vector2(temp.x,temp.y));
  528.     }
  529.  
  530.     bool CellContainsPoint(Vector2 cellPos, Vector2 uiPos, int cellBounds)
  531.     {
  532.         if (uiPos.x < cellPos.x - (cellBounds / 2f) || uiPos.x > cellPos.x + (cellBounds / 2f))
  533.         {
  534.             return (false);
  535.         }
  536.         else if (uiPos.y < cellPos.y - (cellBounds / 2f) || uiPos.y > cellPos.y + (cellBounds / 2f))
  537.         {
  538.             return (false);
  539.         }
  540.  
  541.         return (true);
  542.     }
  543.  
  544.     MineSweeperCell InitiateCell()
  545.     {
  546.         GameObject tempGO = new GameObject();
  547.         GameObject tempTextGO = new GameObject();
  548.         Text tempText = tempTextGO.AddComponent<Text>();
  549.  
  550.         tempText.rectTransform.sizeDelta = new Vector2(cellSize - 10, cellSize - 10);
  551.         tempText.alignment = TextAnchor.MiddleCenter;
  552.         tempText.font = Resources.GetBuiltinResource(typeof(Font), "Arial.ttf") as Font;
  553.         tempText.fontSize = cellSize - 20;
  554.        
  555.  
  556.         tempGO.transform.parent = cellContainer.transform;
  557.         tempGO.transform.localScale = new Vector3(1f,1f,1f);
  558.  
  559.         tempTextGO.transform.parent = tempGO.transform;
  560.         tempTextGO.transform.localScale = new Vector3(1f, 1f, 1f);
  561.         tempTextGO.transform.localPosition = Vector3.zero;
  562.  
  563.         Image tempCell=tempGO.AddComponent<Image>();
  564.         tempCell.rectTransform.sizeDelta = new Vector2(cellSize, cellSize);
  565.         tempCell.sprite = cellCover;
  566.         tempCell.type = Image.Type.Sliced;
  567.  
  568.         MineSweeperCell tempMineCell = new MineSweeperCell(tempCell,tempText);
  569.  
  570.         return (tempMineCell);
  571.     }
  572.  
  573.  
  574.  
  575.     void SpawnMines(int n,Vector2Int excludedCell)
  576.     {
  577.         currentGameState = GameState.INPROGRESS;
  578.  
  579.         List<Vector2Int> tempList = new List<Vector2Int>();
  580.  
  581.         for (int y = 0; y < cells.GetLength(1); y++)
  582.         {
  583.             for (int x = 0; x < cells.GetLength(0); x++)
  584.             {
  585.                 if (excludedCell.x==x && excludedCell.y==y)
  586.                 {                  
  587.                 }
  588.                 else if (excludedCell.x-1 == x && excludedCell.y == y)
  589.                 {
  590.                 }
  591.                 else if (excludedCell.x + 1 == x && excludedCell.y == y)
  592.                 {
  593.                 }
  594.                 else if (excludedCell.x == x && excludedCell.y == y+1)
  595.                 {
  596.                 }
  597.                 else if (excludedCell.x - 1 == x && excludedCell.y == y+1)
  598.                 {
  599.                 }
  600.                 else if (excludedCell.x + 1 == x && excludedCell.y == y+1)
  601.                 {
  602.                 }
  603.                 else if (excludedCell.x == x && excludedCell.y == y - 1)
  604.                 {
  605.                 }
  606.                 else if (excludedCell.x - 1 == x && excludedCell.y == y - 1)
  607.                 {
  608.                 }
  609.                 else if (excludedCell.x + 1 == x && excludedCell.y == y - 1)
  610.                 {
  611.                 }
  612.                 else
  613.                 {
  614.                     tempList.Add(new Vector2Int(x,y));
  615.                 }
  616.             }
  617.         }
  618.  
  619.         int length = tempList.Count - n;
  620.  
  621.         for (int i = 0; i < length; i++)
  622.         {
  623.             int tempR = Random.Range(0, tempList.Count);
  624.             tempList.RemoveAt(tempR);
  625.         }
  626.  
  627.         mineLocations = tempList.ToArray();
  628.         mines = new Image[tempList.Count];
  629.  
  630.         for (int i = 0; i < tempList.Count; i++)
  631.         {
  632.             mines[i] = InitiateMine();
  633.             mines[i].transform.position = cells[mineLocations[i].x, mineLocations[i].y].cellImage.transform.position;
  634.         }
  635.     }
  636.  
  637.  
  638.     void SetImagePosition(Transform t, Vector2Int location)
  639.     {
  640.  
  641.     }
  642.  
  643.     void ClearBombs()
  644.     {
  645.         currentGameState = GameState.ENDED;
  646.  
  647.  
  648.         if (mines != null)
  649.         {
  650.             for (int i = 0; i < mines.Length; i++)
  651.             {
  652.                 Destroy(mines[i].gameObject);
  653.             }
  654.  
  655.             mines = null;
  656.             mineLocations = null;
  657.         }
  658.  
  659.         timer = 0;
  660.         UpdateTimer();
  661.     }
  662.  
  663.     Image InitiateMine()
  664.     {
  665.         GameObject tempGO = new GameObject();
  666.         tempGO.transform.parent = mineContainer.transform;
  667.         tempGO.transform.localScale = new Vector3(1f, 1f, 1f);
  668.  
  669.      
  670.         Image tempMine = tempGO.AddComponent<Image>();
  671.         tempMine.sprite = mineSprite;
  672.         tempMine.rectTransform.sizeDelta = new Vector2(cellSize,cellSize);
  673.  
  674.        
  675.  
  676.  
  677.         return (tempMine);
  678.     }
  679.  
  680.     //int dontcrash = 0;
  681.  
  682.  
  683.     void UncoveredMine()
  684.     {
  685.         currentGameState = GameState.ENDED;
  686.  
  687.         cellContainer.transform.SetAsFirstSibling();
  688.  
  689.         ShowGameOver();
  690.         ClearFlags();
  691.     }
  692.  
  693.    
  694.     void ShowGameOver()
  695.     {
  696.         gameOverScreenGO.SetActive(true);
  697.     }
  698.  
  699.     void UncoverCell(Vector2Int location)
  700.     {
  701.         if (CellContainsMine(location))//lose game
  702.         {
  703.             Debug.Log("bomb: "+location);
  704.             UncoveredMine();
  705.         }
  706.  
  707.         if (cells[location.x, location.y].isCovered)
  708.         {
  709.  
  710.             cells[location.x, location.y].cellImage.sprite = cellBG;
  711.             cells[location.x, location.y].isCovered = false;
  712.  
  713.  
  714.             //check nearby cells
  715.             RecursivelyUncoverCells(new Vector2Int(location.x, location.y));
  716.         }
  717.         else
  718.         {
  719.             //uncover all nearby cells if bombs are labeled
  720.             UncoverNearbyCells(location);
  721.         }
  722.     }
  723.  
  724.     void UncoverNearbyCells(Vector2Int location)
  725.     {
  726.         int bombCount = 0;
  727.         int flagCount = 0;
  728.  
  729.         for (int x = 0; x < 3; x++)
  730.         {
  731.             for (int y = 0; y < 3; y++)
  732.             {
  733.                 if (location.x - 1 + x >= 0 && location.x - 1 + x < cells.GetLength(0))
  734.                 {
  735.                     if (location.y - 1 + y >= 0 && location.y - 1 + y < cells.GetLength(1))
  736.                     {
  737.                         if (CellContainsMine(new Vector2Int(location.x - 1 + x, location.y - 1 + y)))
  738.                         {
  739.                             bombCount++;
  740.  
  741.  
  742.                         }
  743.  
  744.  
  745.  
  746.                         if (CellContainsFlag(new Vector2Int(location.x - 1 + x, location.y - 1 + y)))
  747.                         {
  748.                             flagCount++;
  749.                         }
  750.                     }
  751.                 }
  752.             }
  753.         }
  754.  
  755.         if (flagCount == bombCount)
  756.         {
  757.             for (int x = 0; x < 3; x++)
  758.             {
  759.                 for (int y = 0; y < 3; y++)
  760.                 {
  761.                     if (location.x - 1 + x >= 0 && location.x - 1 + x < cells.GetLength(0))
  762.                     {
  763.                         if (location.y - 1 + y >= 0 && location.y - 1 + y < cells.GetLength(1))
  764.                         {
  765.                             if (cells[location.x - 1 + x, location.y - 1 + y].isCovered)
  766.                             {
  767.                                 if (!CellContainsFlag(new Vector2Int(location.x - 1 + x, location.y - 1 + y)))
  768.                                 {
  769.  
  770.  
  771.                                     UncoverOneCell(new Vector2Int(location.x - 1 + x, location.y - 1 + y));
  772.                                 }
  773.                             }
  774.                         }
  775.                     }
  776.                 }
  777.             }
  778.         }
  779.     }
  780.  
  781.  
  782.  
  783.     void UncoverOneCell(Vector2Int location)
  784.     {
  785.  
  786.         if (CellContainsMine(location))//lose game
  787.         {
  788.             UncoveredMine();
  789.         }
  790.  
  791.  
  792.         for (int y = 0; y < cells.GetLength(1); y++)
  793.         {
  794.             for (int x = 0; x < cells.GetLength(0); x++)
  795.             {
  796.                 if (location.x == x && location.y == y)
  797.                 {
  798.  
  799.  
  800.  
  801.                     if (cells[x, y].isCovered)
  802.                     {
  803.  
  804.                         cells[x, y].cellImage.sprite = cellBG;
  805.                         cells[x, y].isCovered = false;
  806.  
  807.  
  808.  
  809.                         int bombCount = GetMineCountNumber(location);
  810.  
  811.                         if (bombCount > 0)
  812.                         {
  813.                             cells[location.x, location.y].cellText.text = bombCount.ToString();
  814.  
  815.                             cells[location.x, location.y].cellText.gameObject.SetActive(true);
  816.                         }
  817.  
  818.  
  819.                        
  820.                     }
  821.                    
  822.                     break;
  823.                 }
  824.  
  825.  
  826.  
  827.  
  828.             }
  829.         }
  830.  
  831.     }
  832.  
  833.     int GetMineCountNumber(Vector2Int location)
  834.     {
  835.         int mineCount = 0;
  836.  
  837.  
  838.         for (int x = 0; x < 3; x++)
  839.         {
  840.             for (int y = 0; y < 3; y++)
  841.             {
  842.                 if (location.x - 1 + x >= 0 && location.x - 1 + x < cells.GetLength(0))
  843.                 {
  844.                     if (location.y - 1 + y >= 0 && location.y - 1 + y < cells.GetLength(1))
  845.                     {
  846.                         if (CellContainsMine(new Vector2Int(location.x - 1 + x, location.y - 1 + y)))
  847.                         {
  848.                             mineCount++;
  849.                         }
  850.                     }
  851.                 }
  852.             }
  853.         }
  854.  
  855.  
  856.         return (mineCount);
  857.     }
  858.  
  859.     bool CellContainsFlag(Vector2Int location)
  860.     {
  861.         if (flags == null)
  862.         {
  863.             return (false);
  864.         }
  865.  
  866.  
  867.  
  868.         for (int i = 0; i < flags.Count; i++)
  869.         {
  870.             if (flags[i].flagLocation.x == location.x && flags[i].flagLocation.y == location.y)
  871.             {
  872.                 return (true);
  873.             }
  874.         }
  875.  
  876.         return (false);
  877.     }
  878.  
  879.     bool CellContainsMine(Vector2Int location)
  880.     {
  881.         for (int i = 0; i < mineLocations.Length; i++)
  882.         {
  883.             if (mineLocations[i].x==location.x && mineLocations[i].y==location.y)
  884.             {
  885.                 Debug.Log(i+": "+mineLocations[i]+" "+location);
  886.  
  887.                 return (true);
  888.             }
  889.         }
  890.  
  891.         return (false);
  892.     }
  893.  
  894.     void CheckForBombs(int x, int y)
  895.     {
  896.  
  897.  
  898.  
  899.  
  900.         int nx = x - 1;
  901.         int ny = y - 1;
  902.  
  903.         if (nx >= 0 && nx < cells.GetLength(0))
  904.         {
  905.             if (ny >= 0 && ny < cells.GetLength(1))
  906.             {
  907.             }
  908.         }
  909.     }
  910.  
  911.     int GetCellLocation(Vector2Int location)
  912.     {
  913.         int count = 1;
  914.  
  915.         for (int y = 0; y < cells.GetLength(1); y++)
  916.         {
  917.             for (int x = 0; x < cells.GetLength(0); x++)
  918.             {
  919.                 if (x==location.x && y==location.y)
  920.                 {
  921.                     return (count);
  922.  
  923.                 }
  924.  
  925.  
  926.  
  927.                 count++;
  928.             }
  929.         }
  930.  
  931.  
  932.         return (-1);
  933.     }
  934.  
  935.     void RecursivelyUncoverCells(Vector2Int location)
  936.     {
  937.         int mineCount = 0;
  938.  
  939.         for (int x = 0; x < 3; x++)
  940.         {
  941.             for (int y = 0; y < 3; y++)
  942.             {
  943.                 if (location.x - 1 + x >= 0 && location.x - 1 + x < cells.GetLength(0))
  944.                 {
  945.                     if (location.y - 1 + y >= 0 && location.y - 1 + y < cells.GetLength(1))
  946.                     {
  947.                         if (CellContainsMine(new Vector2Int(location.x - 1 + x, location.y - 1 + y)))
  948.                         {
  949.                             mineCount++;
  950.                         }
  951.                     }
  952.                 }
  953.             }
  954.         }
  955.  
  956.         if (mineCount > 0)
  957.         {
  958.             cells[location.x,location.y].cellText.text = mineCount.ToString();
  959.  
  960.             cells[location.x, location.y].cellText.gameObject.SetActive(true);
  961.         }
  962.         else//uncover all neighboring squares
  963.         {
  964.             for (int x = 0; x < 3; x++)
  965.             {
  966.                 for (int y = 0; y < 3; y++)
  967.                 {
  968.                     if (location.x - 1 + x >= 0 && location.x - 1 + x < cells.GetLength(0))
  969.                     {
  970.                         if (location.y - 1 + y >= 0 && location.y - 1 + y < cells.GetLength(1))
  971.                         {
  972.                             if (cells[location.x - 1 + x, location.y - 1 + y].isCovered)
  973.                             {
  974.                                 cells[location.x - 1 + x, location.y - 1 + y].cellImage.sprite = cellBG;
  975.                                 cells[location.x - 1 + x, location.y - 1 + y].isCovered = false;
  976.                                 RecursivelyUncoverCells(new Vector2Int(location.x - 1 + x, location.y - 1 + y));
  977.                             }
  978.                         }
  979.                     }
  980.                 }
  981.             }
  982.         }
  983.     }
  984.  
  985.  
  986.     public void RestartGame()
  987.     {
  988.         //SpawnBoard(boardDimensions, offSet, cellSize);
  989.         for (int y = 0; y < cells.GetLength(1); y++)
  990.         {
  991.             for (int x = 0; x <  cells.GetLength(0); x++)
  992.             {
  993.  
  994.  
  995.  
  996.                 cells[x, y].cellImage.sprite = cellCover;
  997.                 cells[x, y].isCovered = true;
  998.  
  999.                 cells[x, y].cellText.gameObject.SetActive(false);
  1000.                 cells[x, y].cellText.text = "";
  1001.  
  1002.  
  1003.                
  1004.  
  1005.  
  1006.                
  1007.  
  1008.             }
  1009.         }
  1010.  
  1011.  
  1012.         ClearBombs();
  1013.         ClearFlags();
  1014.  
  1015.  
  1016.         currentGameState = GameState.FIRSTCLICK;
  1017.  
  1018.  
  1019.  
  1020.         //hide menu
  1021.         mainMenuGO.SetActive(false);
  1022.         inGameMenuGO.SetActive(true);
  1023.         pauseMenuGO.SetActive(false);
  1024.         gameOverScreenGO.SetActive(false);
  1025.         winScreenGO.SetActive(false);
  1026.  
  1027.         //resort sprite containers
  1028.         flagContainer.transform.SetAsFirstSibling();
  1029.         cellContainer.transform.SetAsFirstSibling();
  1030.         mineContainer.transform.SetAsFirstSibling();
  1031.  
  1032.         flagMode = false;
  1033.         flagModeSprite.color = Color.black;
  1034.     }
  1035.  
  1036.     bool CheckForWinCondition()//either all empty cells uncovered or all bombs flagged
  1037.     {
  1038.      
  1039.  
  1040.  
  1041.         if (currentGameState == GameState.ENDED)
  1042.         {
  1043.             return (false);
  1044.         }
  1045.  
  1046.  
  1047.         bool winCondition = true;
  1048.  
  1049.         if (flags != null && mines!=null)
  1050.         {
  1051.             if (mines.Length == flags.Count)
  1052.             {
  1053.                 for (int y = 0; y < cells.GetLength(1); y++)
  1054.                 {
  1055.                     for (int x = 0; x < cells.GetLength(0); x++)
  1056.                     {
  1057.                         if (!CellContainsFlag(new Vector2Int(x, y)) && CellContainsMine(new Vector2Int(x, y)))
  1058.                         {
  1059.                             Debug.Log("did not win");
  1060.                             winCondition = false;
  1061.                         }
  1062.                     }
  1063.                 }
  1064.             }
  1065.             else
  1066.             {
  1067.                 winCondition = false;
  1068.             }
  1069.         }
  1070.         else
  1071.         {
  1072.             winCondition = false;
  1073.         }
  1074.        
  1075.         if (!winCondition && currentGameState==GameState.INPROGRESS)//check if only cells with bombs are covered
  1076.         {
  1077.             Debug.Log("check other");
  1078.  
  1079.             winCondition = true;
  1080.  
  1081.             for (int y = 0; y < cells.GetLength(1); y++)
  1082.             {
  1083.                 for (int x = 0; x < cells.GetLength(0); x++)
  1084.                 {
  1085.                     if (cells[x,y].isCovered && !CellContainsMine(new Vector2Int(x, y)))
  1086.                     {
  1087.                         winCondition = false;
  1088.                     }
  1089.                 }
  1090.             }
  1091.         }
  1092.  
  1093.         return (winCondition);
  1094.     }
  1095.  
  1096.     void ClearFlags()
  1097.     {
  1098.         if (flags != null)
  1099.         {
  1100.             for (int i = 0; i < flags.Count; i++)
  1101.             {
  1102.                 Destroy(flags[i].flagImage);
  1103.             }
  1104.  
  1105.  
  1106.             flags = null;
  1107.         }
  1108.     }
  1109.  
  1110.  
  1111.  
  1112.  
  1113.  
  1114.     //menu stuff
  1115.     public GameObject mainMenuGO;
  1116.     public GameObject inGameMenuGO;
  1117.     public GameObject pauseMenuGO;
  1118.     public GameObject gameOverScreenGO;
  1119.     public GameObject winScreenGO;
  1120.     public TextMeshProUGUI winScreenTimerText;
  1121.     public Image audioButtonImage;
  1122.     public AudioSource musicSource;
  1123.     float volumeLevel = .3f;
  1124.  
  1125.     bool muted = false;
  1126.  
  1127.     public void NewGame(int i)
  1128.     {
  1129.         //hide menu
  1130.         mainMenuGO.SetActive(false);
  1131.         inGameMenuGO.SetActive(true);
  1132.         pauseMenuGO.SetActive(false);
  1133.         gameOverScreenGO.SetActive(false);
  1134.         winScreenGO.SetActive(false);
  1135.  
  1136.         if (i == 1)//medium   20 by 12 grid with 30 bombs
  1137.         {
  1138.             InitializeGameBoard(new Vector2Int(20,12),80, new Vector2Int(0, -120), 30);
  1139.         }
  1140.         else if (i == 2)//hard  40 by 24 grid with 140 bombs
  1141.         {
  1142.             InitializeGameBoard(new Vector2Int(40, 24), 40, new Vector2Int(0, -116), 140);
  1143.         }
  1144.         else//easy  20 by 12 grid with 20 bombs
  1145.         {
  1146.             InitializeGameBoard(new Vector2Int(20, 12), 80,new Vector2Int(0,-120), 20);
  1147.         }
  1148.  
  1149.         if (!muted)
  1150.         {
  1151.             musicSource.Play();
  1152.         }
  1153.  
  1154.         timer = 0;
  1155.     }
  1156.  
  1157.     void UpdateTimer()
  1158.     {
  1159.         timer += Time.deltaTime;
  1160.         string minSec = string.Format("{0}:{1:00}", (int)timer / 60, (int)timer % 60);
  1161.         timerText.text = minSec;
  1162.     }
  1163.  
  1164.     public void AudioButton()
  1165.     {
  1166.         if (muted = !muted)
  1167.         {
  1168.             audioButtonImage.color = Color.black;
  1169.             musicSource.volume = 0;
  1170.  
  1171.             PlayerPrefs.SetInt(audioSaveKey, 0);
  1172.         }
  1173.         else
  1174.         {
  1175.             audioButtonImage.color = Color.white;
  1176.             musicSource.volume = volumeLevel;
  1177.  
  1178.             if (!musicSource.isPlaying)
  1179.             {
  1180.                 musicSource.Play();
  1181.             }
  1182.  
  1183.             PlayerPrefs.SetInt(audioSaveKey, 1);
  1184.         }
  1185.     }
  1186.  
  1187.     public void ExitGame()
  1188.     {
  1189.         mainMenuGO.SetActive(true);
  1190.         inGameMenuGO.SetActive(false);
  1191.         pauseMenuGO.SetActive(false);
  1192.         gameOverScreenGO.SetActive(false);
  1193.         winScreenGO.SetActive(false);
  1194.     }
  1195.  
  1196.     public void ResumeGame()
  1197.     {
  1198.         mainMenuGO.SetActive(false);
  1199.         inGameMenuGO.SetActive(true);
  1200.         pauseMenuGO.SetActive(false);
  1201.     }
  1202.  
  1203.     public void PauseGame()
  1204.     {
  1205.         mainMenuGO.SetActive(false);
  1206.         inGameMenuGO.SetActive(false);
  1207.         pauseMenuGO.SetActive(true);
  1208.     }
  1209.  
  1210.     bool ShouldSpawnCells()
  1211.     {
  1212.  
  1213.         if (cells == null)
  1214.         {
  1215.             return (true);
  1216.         }
  1217.  
  1218.         if (boardDimensions.x != cells.GetLength(0) || boardDimensions.y != cells.GetLength(1))
  1219.         {
  1220.             return (true);
  1221.         }
  1222.  
  1223.         return (false);
  1224.     }
  1225.  
  1226.     void ClearCells()
  1227.     {
  1228.         Debug.Log("ClearCells");
  1229.  
  1230.         if (cells == null)
  1231.         {
  1232.             return;
  1233.         }
  1234.  
  1235.         for (int x = 0; x < cells.GetLength(0); x++)
  1236.         {
  1237.             for (int y = 0; y < cells.GetLength(1); y++)
  1238.             {
  1239.                 Destroy(cells[x, y].cellImage.gameObject);
  1240.             }
  1241.         }
  1242.  
  1243.         cells = null;
  1244.     }
  1245. }
  1246.  
  1247. class FlagPlacement
  1248. {
  1249.     public GameObject flagImage;
  1250.     public Vector2Int flagLocation;
  1251.  
  1252.     public FlagPlacement(GameObject f,Vector2Int l)
  1253.     {
  1254.         flagImage = f;
  1255.         flagLocation = l;
  1256.     }
  1257. }
  1258.  
  1259. public class MineSweeperCell
  1260. {
  1261.     public Image cellImage;
  1262.     public Text cellText;
  1263.     public bool isCovered;
  1264.  
  1265.     public MineSweeperCell(Image i, Text t)
  1266.     {
  1267.         cellImage = i;
  1268.         cellText = t;
  1269.         isCovered = true;
  1270.     }
  1271. }
  1272.  
  1273. public enum GameState
  1274. {
  1275.     ENDED,INPROGRESS,FIRSTCLICK
  1276. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement