Skip to content

Instantly share code, notes, and snippets.

@jrmoserbaltimore
Last active February 22, 2016 00:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save jrmoserbaltimore/7ee657eeb0f58e220d0c to your computer and use it in GitHub Desktop.
Save jrmoserbaltimore/7ee657eeb0f58e220d0c to your computer and use it in GitHub Desktop.
Horrendous code
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