Last active
February 22, 2016 00:26
-
-
Save jrmoserbaltimore/7ee657eeb0f58e220d0c to your computer and use it in GitHub Desktop.
Horrendous code
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using System.Collections; | |
using System.Collections.Generic; | |
using BlackCore.GameWorld; | |
namespace BlackCore.GameWorld | |
{ | |
public interface IRoom | |
{ | |
/* SelectLayer: Selects which layer to access. Returns an object | |
* with IRoom interface. Selection must be safe: selecting a | |
* layer doesn't change the underlying object. | |
* | |
* Mode selects from game modes. These modes are defined in a | |
* hierarchy, such as Difficulty.Rotation. State indicates indexed | |
* states, selected by state settings triggered by events. | |
* | |
* Modes are applied first in hierarchy, followed by state. | |
*/ | |
IRoom SelectMode(Dictionary<string, int> mode, int state); | |
/* GetTile: Gets the tile at that location. | |
* Returns the final tile definition after merging modes and states. | |
*/ | |
int Tile(int x, int y, int layer); | |
/* GetTileReal: Same as GetTile, but returns NULL and DELETE tiles */ | |
int RealTile(int x, int y, int layer); | |
/* SetTile: Sets a tile on the appropriate layer */ | |
void SetTile(int x, int y, int layer, int tile); | |
/* Direct access to mode/state data */ | |
int Tile(int x, int y, int layer, | |
Dictionary<string, int> mode, int state); | |
int RealTile(int x, int y, int layer, | |
Dictionary<string, int> mode, int state); | |
void SetTile(int x, int y, int layer, int tile, | |
Dictionary<string, int> mode, int state); | |
} | |
public class RoomProxy : IRoom { | |
protected Dictionary<string, int> mode; | |
protected int state; | |
protected IRoom room; | |
/* Constructor | |
* Sets up mode and state to use for Tile(), RealTile(), and SetTile() calls | |
*/ | |
RoomProxy(Dictionary<string, int> mode, int state, IRoom room) | |
{ | |
if (mode == null) | |
{ | |
throw new System.ArgumentNullException("mode","Cannot be null") ; | |
} | |
if (room == null) | |
{ | |
throw new System.ArgumentNullException("room","Cannot be null") ; | |
} | |
this.mode = mode; | |
this.state = state; | |
this.room = room; | |
} | |
/* This calls downward. It would also make sense to return a RoomProxy | |
* by RoomProxy(mode, state, room), but this is more generic. */ | |
IRoom SelectMode(Dictionary<string, int> mode, int state) | |
{ | |
room.SelectMode(mode, state); | |
} | |
/* Selected methods | |
* These call based on the mode and state selection */ | |
int Tile(int x, int y, int layer) | |
{ | |
room.Tile(x, y, layer, mode, state); | |
} | |
int RealTile(int x, int y, int layer) | |
{ | |
room.RealTile(x, y, layer, mode, state); | |
} | |
void SetTile(int x, int y, int layer, int tile) | |
{ | |
room.SetTile(x, y, layer, tile, mode, state); | |
} | |
/* Direct Methods | |
* These pass directly */ | |
int Tile(int x, int y, int layer, | |
Dictionary<string, int> mode, int state) | |
{ | |
room.Tile(x, y, layer, mode, state); | |
} | |
int RealTile(int x, int y, int layer, | |
Dictionary<string, int> mode, int state) | |
{ | |
room.RealTile(x, y, layer, mode, state); | |
} | |
void SetTile(int x, int y, int layer, int tile, | |
Dictionary<string, int> mode, int state) | |
{ | |
room.SetTile(x, y, layer, tile, mode, state); | |
} | |
} | |
public class Room : IRoom | |
{ | |
/* childMode - Name of next layer down | |
* Each layer only needs to know which mode[childMode] to call | |
* its lower layer for. | |
* | |
* For example: the root node may know to call down for | |
* "Difficulty", looking up children[mode["Difficulty"]]. | |
*/ | |
protected string childMode = null; | |
protected Dictionary<int, IRoom> children = null; | |
protected Dictionary<int, IRoom> states = null; | |
protected int width; | |
protected int height; | |
Room (int width, int height) { | |
this.width = width; | |
this.height = height; | |
} | |
Room (int width, int height, string childMode, Dictionary<int, IRoom> children); | |
: this(width, height) { | |
this.childMode = childMode; | |
this.children = children; | |
} | |
/* Provides a RoomProxy with the selected mode */ | |
IRoom SelectMode(Dictionary<string, int> mode, int state) { | |
return RoomProxy(mode, state, this); | |
} | |
/* Default methods | |
* Each of these calls with no further traversal down the tree. | |
*/ | |
int Tile(int x, int y, int layer) { | |
return Tile(x, y, layer, null, 0); | |
} | |
int RealTile(int x, int y, int layer) { | |
return RealTile(x, y, layer, null, 0); | |
} | |
void SetTile(int x, int y, int layer, int tile) { | |
SetTile(x, y, layer, tile, null, 0); | |
} | |
/* Direct Methods | |
* These target a particular layer/state. | |
* If there's no key for a step further in the hierarchy, | |
* then return this node's value at (x,y,layer) | |
*/ | |
int Tile(int x, int y, int layer, | |
Dictionary<string, int> mode, int state) { | |
IRoom child; | |
int tile = 0; | |
child = GetChild(mode); | |
/* Get the ultimate resolution of the tile down the tree */ | |
if (child != null) | |
tile = child.Tile(x, y, layer, mode, state); | |
/* 0 = null tile; check for state */ | |
else if (states.ContainsKey(state)) | |
tile = states[state].Tile(x, y, layer); | |
/* just use default state tile */ | |
else if (states.ContainsKey(0)) | |
tile = this.states[0].Tile(x, y, layer); | |
else /* FIXME: Need custom exception */ | |
throw new System.InvalidOperationException("No default state 0"); | |
return tile; | |
} | |
int RealTile(int x, int y, int layer, | |
Dictionary<string, int> mode, int state) { | |
IRoom child; | |
int tile = 0; | |
child = GetChild(mode); | |
/* This only returns the exact state at the end, even if | |
* it's a null state */ | |
if (child != null) | |
tile = child.RealTile(x, y, layer, mode, state); | |
else if (states.ContainsKey(state)) | |
tile = states[state].RealTile(x, y, layer); | |
/* state == 0 is special */ | |
else if (states.ContainsKey(0)) | |
tile = this.states[0].RealTile(x, y, layer); | |
else /* Total fail. FIXME: Need custom exception */ | |
throw new System.InvalidOperationException("No default state 0"); | |
/* We return the tile even if it's a null tile */ | |
return tile; | |
} | |
void SetTile(int x, int y, int layer, int tile, | |
Dictionary<string, int> mode, int state) { | |
IRoom child; | |
int tile = 0; | |
child = GetChild(mode); | |
/* Get the ultimate resolution of the tile down the tree */ | |
if (child != null) | |
child.SetTile(x, y, layer, mode, state); | |
else { | |
if (!states.ContainsKey(state)) | |
states.Add(state, new RoomState(width, height)); | |
states[state].SetTile(x, y, layer, tile); | |
} | |
} | |
protected IRoom GetChild(Dictionary<string, int> mode) { | |
IRoom child; | |
if (mode.ContainsKey(childMode)) { | |
/* No such child, but explicitly requested, so fail */ | |
if (!children.TryGetValue(mode[childMode], child)) { | |
// FIXME: Throw exception | |
} | |
return child; | |
} | |
return null; | |
} | |
} | |
/* States for multi-state rooms */ | |
public class RoomState : IRoom { | |
protected int[,,] tiles = null; | |
RoomState (int width, int height) { | |
tiles = new int[width, height, 4]; | |
} | |
/* Should do nothing. Never call. */ | |
IRoom SelectMode(Dictionary<string, int> mode, int state) { | |
return this; | |
} | |
/* Default methods | |
* Each of these calls with no further traversal down the tree. | |
*/ | |
int Tile(int x, int y, int layer) { | |
return tiles[x,y,layer]; | |
} | |
/* No deeper */ | |
int RealTile(int x, int y, int layer) { | |
return Tile(x, y, layer); | |
} | |
void SetTile(int x, int y, int layer, int tile) { | |
tiles[x,y,layer] = tile; | |
} | |
/* Direct methods don't apply */ | |
int Tile(int x, int y, int layer, | |
Dictionary<string, int> mode, int state) { | |
return Tile(x, y, layer); | |
} | |
int RealTile(int x, int y, int layer, | |
Dictionary<string, int> mode, int state) { | |
return RealTile(x, y, layer); | |
} | |
void SetTile(int x, int y, int layer, int tile, | |
Dictionary<string, int> mode, int state) { | |
SetTile(x, y, layer, tile); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment