using System; using System.Collections; using System.Collections.Generic; using System.Linq; using UnityEngine; using Gamelogic; using Gamelogic.Grids; /** This example shows how the Grids library work with normal Unity Planes. */ public class SliderPuzzle : GLMonoBehaviour { private class SliderCell { public RectPoint originalGridPoint; public GameObject cellObject; } public GameObject cellPrefab; public GameObject root; public int puzzleSize; public Texture2D puzzleImage; private RectGrid grid; private IMap3D map; private Vector2 cellDimensions = new Vector2(200, 200); private RectPoint emptyCell; public void Start() { BuildGrid(); StartCoroutine(InitPuzzle()); } public void Update() { HandleCell(); if (IsGameFinished()) { Debug.Log("Game finished: you solved the puzzle!"); } } private bool IsGameFinished() { return grid .Where(gridPoint => gridPoint != emptyCell) .All(gridPoint => grid[gridPoint].originalGridPoint == gridPoint); } private void HandleCell() { if (Input.GetMouseButtonDown(0)) { Vector3 worldPosition = ExampleUtils.ScreenToWorld(Input.mousePosition); RectPoint gridPosition = map[worldPosition]; if (grid.Contains(gridPosition)) { if (grid.GetNeighbors(gridPosition).Contains(emptyCell)) { SwapWithEmpty(gridPosition); } } } } private void SwapWithEmpty(RectPoint gridPosition) { grid[emptyCell] = grid[gridPosition]; grid[emptyCell].cellObject.transform.localPosition = map[emptyCell]; grid[gridPosition] = null; emptyCell = gridPosition; } private void BuildGrid() { grid = RectGrid.Rectangle(puzzleSize, puzzleSize); map = new RectMap(cellDimensions) .AnchorCellMiddelCenter() .WithWindow(ExampleUtils.ScreenRect) .AlignMiddelCenter(grid) .To3DXY(); float textureScale = 1f / puzzleSize; Vector2 textureScaleVector = new Vector2(textureScale, textureScale); foreach (RectPoint point in grid) { GameObject cellObject = Instantiate(cellPrefab); cellObject.transform.parent = root.transform; cellObject.transform.localPosition = map[point]; cellObject.renderer.material.mainTexture = puzzleImage; cellObject.renderer.material.mainTextureScale = textureScaleVector; cellObject.renderer.material.mainTextureOffset = new Vector2(-textureScale * (point.X + 1), textureScale * point.Y); SliderCell cell = new SliderCell(); cell.cellObject = cellObject; cell.originalGridPoint = point; grid[point] = cell; } emptyCell = RectPoint.Zero; grid[emptyCell].cellObject.renderer.enabled = false; } private IEnumerator InitPuzzle2() { RectPoint lastPoint = emptyCell; RectPoint lastLastPoint = emptyCell; for (int i = 0; i < 2 * puzzleSize * puzzleSize; i++) { RectPoint randomNeighbor = grid.GetNeighbors(emptyCell) .Where(point => (point != lastLastPoint)) .SampleRandom(1) .First(); lastLastPoint = lastPoint; lastPoint = randomNeighbor; SwapWithEmpty(randomNeighbor); yield return new WaitForSeconds(0.2f); } } private IEnumerator InitPuzzle() { Queue memory = new Queue(); memory.Enqueue(emptyCell); memory.Enqueue(emptyCell); for (int i = 0; i < 2 * puzzleSize * puzzleSize; i++) { RectPoint oldPath = memory.Dequeue(); RectPoint randomNeighbor = grid.GetNeighbors(emptyCell) .Where(point => (point != oldPath)) .SampleRandom(1) .First(); memory.Enqueue(randomNeighbor); SwapWithEmpty(randomNeighbor); yield return new WaitForSeconds(0.2f); //Let us see the shuffle! } } }