Skip to content

Instantly share code, notes, and snippets.

@gamemachine
Created March 14, 2015 06:50
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save gamemachine/102be3ace8a308a3bd5f to your computer and use it in GitHub Desktop.
Save gamemachine/102be3ace8a308a3bd5f to your computer and use it in GitHub Desktop.
using System;
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
namespace PvpGame
{
public class GridValue
{
public enum EntityType
{
None,
Tree,
Rock
}
public string id;
public Vector3 position;
public EntityType entityType;
public GameObject go;
}
public class Grid
{
public static Dictionary<string, Grid> grids = new Dictionary<string, Grid> ();
private Dictionary<int, Dictionary<string, GridValue>> cells = new Dictionary<int, Dictionary<string, GridValue>> ();
private Dictionary<string, GridValue> objectIndex = new Dictionary<string, GridValue> ();
private Dictionary<string, int> cellsIndex = new Dictionary<string, int> ();
public static float coordOffset = 5000f;
private int max;
private int cellSize = 0;
private float convFactor;
private int width;
private int cellCount;
public Grid (int max, int cellSize)
{
this.max = max;
this.cellSize = cellSize;
this.convFactor = 1.0f / this.cellSize;
this.width = (int)(this.max / this.cellSize);
this.cellCount = this.width * this.width;
}
public int Count ()
{
return objectIndex.Count;
}
public static Grid FindOrCreate (string id, int max, int cellSize)
{
if (!grids.ContainsKey (id)) {
grids [id] = new Grid (max, cellSize);
}
return grids [id];
}
public HashSet<int> CellsWithinBounds (float x, float z)
{
x += coordOffset;
z += coordOffset;
HashSet<int> mcells = new HashSet<int> ();
int offset = this.cellSize;
int startX = (int)(x - offset);
int startZ = (int)(z - offset);
int endX = (int)(x + offset);
int endZ = (int)(z + offset);
for (int rowNum = startX; rowNum <= endX; rowNum += offset) {
for (int colNum = startZ; colNum <= endZ; colNum += offset) {
if (rowNum >= 0 && colNum >= 0) {
mcells.Add (Hash (rowNum, colNum));
}
}
}
return mcells;
}
public List<GridValue> Neighbors (float x, float z, GridValue.EntityType entityType)
{
List<GridValue> result = new List<GridValue> ();
ICollection<GridValue> gridValues;
HashSet<int> cells = CellsWithinBounds (x, z);
foreach (int cell in cells) {
gridValues = GridValuesInCell (cell);
if (gridValues == null) {
continue;
}
foreach (GridValue gridValue in gridValues) {
if (gridValue != null) {
if (entityType == GridValue.EntityType.None) {
result.Add (gridValue);
} else if (gridValue.entityType == entityType) {
result.Add (gridValue);
}
}
}
}
return result;
}
public ICollection<GridValue> GridValuesInCell (int cell)
{
if (cells.ContainsKey (cell)) {
return cells [cell].Values;
} else {
return null;
}
}
public void Set (GridValue gridValue)
{
bool hasExisting = false;
int oldCellValue = -1;
string id = gridValue.id;
if (objectIndex.ContainsKey (id)) {
hasExisting = true;
oldCellValue = cellsIndex [id];
}
int cell = Hash (gridValue.position.x + coordOffset, gridValue.position.z + coordOffset);
Dictionary<string, GridValue> cellGridValues;
if (hasExisting && oldCellValue != cell) {
if (cells.ContainsKey (oldCellValue)) {
cellGridValues = cells [oldCellValue];
if (cellGridValues.ContainsKey (id)) {
cellGridValues.Remove (id);
}
if (cellGridValues.Count == 0) {
cells.Remove (oldCellValue);
}
}
}
cellsIndex [id] = cell;
objectIndex [id] = gridValue;
if (cells.ContainsKey (cell)) {
cellGridValues = cells [cell];
cellGridValues [id] = gridValue;
} else {
cellGridValues = new Dictionary<string, GridValue> ();
cellGridValues [id] = gridValue;
cells [cell] = cellGridValues;
}
}
public int Hash (float x, float z)
{
return (int)((x * this.convFactor)) + (int)((z * this.convFactor)) * this.width;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment