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!
}
}
}