A Barter Session Engine for a Game

The JavaScript code included below implements a simulated barter session for a computer game. To see it in action, copy it into an .html file and open that file in a web browser that runs JavaScript.  Or, for an online version, visit http://thiscouldbebetter.neocities.org/barter.html.

To make a trade, use the buttons labeled with “<” and “>” to move items from each trader’s “Held” list into their “Offered” list, and then click the “Trade” button to propose a trade. The total value of each offered set of goods is not presented anywhere in the interface yet, but each “Red Torus” is worth 1, each “Green Box” is worth 2, and each “Blue Sphere” is worth 5. Note that the trader represented on the right side of the interface (“Merchant”), will not agree to trade at a loss.

It still needs some work. I’d eventually like to add a “Details” pane that shows information about the selected good, and of course something that calculates the total value of all the goods in an offer. On the plus side, the code happens to include an implementation of a simple user interface framework, more-or-less accidentally.

TradingSession

<html>
<body>
<script type='text/javascript'>

// main

function TradingTest()
{
	this.main = function()
	{
		var itemDefns = 
		[
			new ItemDefn("Red Torus", 1),
			new ItemDefn("Green Box", 2),
			new ItemDefn("Blue Sphere", 5),
		];

		ArrayHelper.addLookupsToArray(itemDefns, "name");

		var tradingSession = new TradingSession
		(
			"Trading Session Test",
			[
				new Trader
				(
					"You",
					// itemsHeld
					[
						new Item(itemDefns["Red Torus"], 2),
						new Item(itemDefns["Blue Sphere"], 4),
						new Item(itemDefns["Green Box"], 22),
					]
				),
				new Trader
				(
					"Merchant",
					// itemsHeld
					[
						new Item(itemDefns["Red Torus"], 100),
						new Item(itemDefns["Blue Sphere"], 5),
						new Item(itemDefns["Green Box"], 3),
					]
				),
			]
		);

		var universe = new Universe
		(
			itemDefns,
			tradingSession
		);

		Globals.Instance.initialize
		(
			universe
		);
	}
}

// classes

function ArrayHelper()
{}
{
	ArrayHelper.addLookupsToArray = function(arrayToAddLookupsTo, propertyName)
	{
		for (var i = 0; i < arrayToAddLookupsTo.length; i++)
		{
			var item = arrayToAddLookupsTo[i];
			arrayToAddLookupsTo[item[propertyName]] = item;
		}
	}
}

function Button(name, style, size, pos, text, click, tagItem)
{
	this.name = name;
	this.style = style;
	this.size = size;
	this.pos = pos;
	this.text = text;
	this.click = click;
	this.tagItem = tagItem;
}
{
	Button.prototype.htmlElementBuild = function()
	{
		var gridCellSizeInPixels = this.style.gridCellSize;

		var returnValue = document.createElement("button");

		returnValue.control = this;

		var sizeInPixels = this.size.clone().multiply(gridCellSizeInPixels);
		returnValue.style.width = sizeInPixels.x;
		returnValue.style.height = sizeInPixels.y;
		var posInPixels = this.pos.clone().multiply(gridCellSizeInPixels);
		returnValue.style.position = "absolute";
		returnValue.style.left = posInPixels.x;
		returnValue.style.top = posInPixels.y;
		returnValue.innerHTML = this.text;
		returnValue.onclick = this.click;

		this.htmlElement = returnValue;
		return returnValue;
	}

	Button.prototype.htmlElementUpdate = function()
	{
		// todo
	}
}

function Container(name, style, size, pos, children)
{
	this.name = name;
	this.style = style;
	this.size = size;
	this.pos = pos;
	this.children = children;

	for (var i = 0; i < this.children.length; i++)
	{
		var child = this.children[i];
		this.children[child.name] = child;
	}
}
{
	Container.prototype.htmlElementBuild = function()
	{
		var gridCellSizeInPixels = this.style.gridCellSize;

		var returnValue = document.createElement("div");

		returnValue.style.border = "1px solid";
		var sizeInPixels = this.size.clone().multiply(gridCellSizeInPixels);
		returnValue.style.width = sizeInPixels.x;
		returnValue.style.height = sizeInPixels.y;
		returnValue.style.position = "absolute";
		var posInPixels = this.pos.clone().multiply(gridCellSizeInPixels);
		returnValue.style.left = posInPixels.x;
		returnValue.style.top = posInPixels.y;

		for (var i = 0; i < this.children.length; i++)
		{
			var child = this.children[i];
			var htmlElementForChild = child.htmlElementBuild();
			returnValue.appendChild(htmlElementForChild);
		}				

		this.htmlElement = returnValue;
		return returnValue;
	}

	Container.prototype.htmlElementUpdate = function()
	{
		for (var i = 0; i < this.children.length; i++)
		{
			var child = this.children[i];
			child.htmlElementUpdate();
		}		
	}

}

function ControlStyle(name, gridCellSize)
{
	this.name = name;
	this.gridCellSize = gridCellSize;
}
{
	function ControlStyle_Instances()
	{
		if (ControlStyle.Instances != null)
		{
			return ControlStyle.Instances;
		}

		ControlStyle.Instances = this;

		this.Default = new ControlStyle
		(
			"Default Style", 
			new Coords(10, 10) // gridCellSize
		);

		return this;
	}

	ControlStyle.Instances = new ControlStyle_Instances();
}

function Coords(x, y, z)
{
	this.x = x;
	this.y = y;
	this.z = z;
}
{
	Coords.NumberOfDimensions = 3;

	Coords.prototype.add = function(other)
	{
		this.x += other.x;
		this.y += other.y;
		this.z += other.z;

		return this;
	}

	Coords.prototype.clone = function()
	{
		return new Coords(this.x, this.y, this.z);
	}

	Coords.prototype.crossProduct = function(other)
	{
		return new Coords
		(
			this.y * other.z - this.z * other.y,
			this.z * other.x - this.x * other.z,
			this.x * other.y - this.y * other.x
		);
	}

	Coords.prototype.dimension = function(dimensionIndex)
	{
		var returnValue;

		if (dimensionIndex == 0)
		{
			returnValue = this.x;
		}
		else if (dimensionIndex == 1)
		{
			returnValue = this.y;
		}
		else 
		{
			returnValue = this.z;
		}

		return returnValue;
	}

	Coords.prototype.dimension_Set = function(dimensionIndex, value)
	{
		if (dimensionIndex == 0)
		{
			this.x = value;
		}
		else if (dimensionIndex == 1)
		{
			this.y = value;
		}
		else 
		{
			this.z = value;
		}

		return this;
	}

	Coords.prototype.dotProduct = function(other)
	{
		var returnValue = 
			this.x * other.x 
			+ this.y * other.y
			+ this.z * other.z;

		return returnValue;
	}

	Coords.prototype.divideScalar = function(scalar)
	{
		this.x /= scalar;
		this.y /= scalar;
		this.z /= scalar;

		return this;
	}

	Coords.prototype.magnitude = function()
	{
		return Math.sqrt
		(
			this.x * this.x
			+ this.y * this.y
			+ this.z * this.z
		);
	}

	Coords.prototype.multiply = function(other)
	{
		this.x *= other.x;
		this.y *= other.y;
		this.z *= other.z;

		return this;
	}

	Coords.prototype.multiplyScalar = function(scalar)
	{
		this.x *= scalar;
		this.y *= scalar;
		this.z *= scalar;

		return this;
	}

	Coords.prototype.normalize = function()
	{
		return this.divideScalar(this.magnitude());
	}

	Coords.prototype.overwriteWith = function(other)
	{
		this.x = other.x;
		this.y = other.y;
		this.z = other.z;

		return this;
	}

	Coords.prototype.overwriteWithDimensions = function(x, y, z)
	{
		this.x = x;
		this.y = y;
		this.z = z;

		return this;
	}

	Coords.prototype.subtract = function(other)
	{
		this.x -= other.x;
		this.y -= other.y;
		this.z -= other.z;

		return this;
	}

	Coords.prototype.trimToRangeMinMax = function(min, max)
	{
		for (var d = 0; d < Coords.NumberOfDimensions; d++)
		{
			var thisDimension = this.dimension(d);

			var minDimension = min.dimension(d);
			var maxDimension = max.dimension(d);

			if (thisDimension < minDimension)
			{
				thisDimension = minDimension;
			} 
			else if (thisDimension > maxDimension)
			{
				thisDimension = maxDimension;				
			}

			this.dimension_Set(d, thisDimension);
		}
	}
}

function Item(defn, quantity)
{
	this.defn = defn;
	this.quantity = quantity;
}
{
	Item.prototype.clone = function()
	{
		return new Item(this.defn, this.quantity);
	}

	// listable
	Item.prototype.buildTextAsListable = function()
	{
		return this.defn.name + "(" + this.quantity + ")";
	}

}

function ItemDefn(name, pricePerUnit)
{
	this.name = name;
	this.pricePerUnit = pricePerUnit;
}

function ItemSet(name, items)
{
	this.name = name;
	this.items = items;
	this.itemsSelected = [];
}
{
	ItemSet.prototype.itemAdd = function(itemToAdd)
	{
		var itemExisting = null;

		for (var i = 0; i < this.items.length; i++)
		{
			var item = this.items[i];
			if (item.defn == itemToAdd.defn)
			{
				itemExisting = item;
				break;
			}
		}

		if (itemExisting == null)
		{
			this.items.splice(0, 0, itemToAdd);
		}
		else
		{
			itemExisting.quantity += itemToAdd.quantity;
		}
	}

	ItemSet.prototype.itemRemove = function(itemToRemove)
	{
		var itemExisting = null;

		for (var i = 0; i < this.items.length; i++)
		{
			var item = this.items[i];
			if (item.defn == itemToRemove.defn)
			{
				itemExisting = item;
				break;
			}
		}

		if (itemExisting == itemToRemove)
		{
			this.items.splice(this.items.indexOf(itemToRemove), 1);
		}
		else if (itemExisting != null)
		{
			itemExisting.quantity -= itemToRemove.quantity;
			if (itemExisting.quantity <= 0)
			{
				this.items.splice(this.items.indexOf(itemExisting), 1);
			}
		}
	}

	ItemSet.prototype.priceOfAllItems = function()
	{
		var returnValue = 0;

		for (var i = 0; i < this.items.length; i++)
		{
			var item = this.items[i];
			var itemValue = item.quantity * item.defn.pricePerUnit;
			returnValue += itemValue;
		}

		return returnValue;
	}

	// control

	ItemSet.prototype.controlBuild = function(style, size, pos)
	{
		var listBoxSize = new Coords(size.x - 2, size.y - 4);
		var listBoxItemSize = new Coords(listBoxSize.x, 2);

		var returnValue = new Container
		(
			"container" + this.name,
			style,
			size,
			pos,
			[
				new Label("labelName", style, new Coords(1, 1), this.name),
				new ListBox
				(
					"listBoxForItems", 
					style, 
					listBoxSize,
					new Coords(1, 3), // pos
					listBoxItemSize,
					ListBoxItem.buildManyFromListables
					(
						this.items
					)
				),
			]
		);

		this.control = returnValue;
		return returnValue;
	}

	ItemSet.prototype.controlUpdate = function()
	{
		var listBoxForItems = this.control.children["listBoxForItems"];
		listBoxForItems.items = ListBoxItem.buildManyFromListables
		(
			this.items
		);

		if (listBoxForItems.htmlElement != null)
		{
			listBoxForItems.htmlElementUpdate();
		}
	}

	ItemSet.prototype.itemsSelectedFromControl = function()
	{
		var listBox = this.control.children["listBoxForItems"];
		var itemsSelected = listBox.listablesForItemsSelected();

		return itemsSelected;
	}

}

function Globals()
{}
{
	Globals.Instance = new Globals();

	Globals.prototype.initialize = function(universe)
	{
		this.universe = universe;
		var venue = this.universe.tradingSession;
		document.body.appendChild
		(
			venue.controlBuild
			(
				ControlStyle.Instances.Default,
				new Coords(88, 25) // size
			).htmlElementBuild()
		);
	}
}

function Label(name, style, pos, text)
{
	this.name = name;
	this.style = style;
	this.pos = pos;
	this.text = text;
}
{
	Label.prototype.htmlElementBuild = function()
	{
		var gridCellSizeInPixels = this.style.gridCellSize;

		var returnValue = document.createElement("div");
		returnValue.style.position = "absolute";
		var posInPixels = this.pos.clone().multiply(gridCellSizeInPixels);
		returnValue.style.left = posInPixels.x;
		returnValue.style.top = posInPixels.y;
		returnValue.innerHTML = this.text;

		this.htmlElement = returnValue;
		return returnValue;
	}

	Label.prototype.htmlElementUpdate = function()
	{
		// do nothing
	}
}

function ListBox(name, style, size, pos, sizePerItem, items)
{
	this.name = name;
	this.style = style;
	this.size = size;
	this.pos = pos;
	this.sizePerItem = sizePerItem;
	this.items = items;
}
{
	ListBox.prototype.listablesForItemsSelected = function()
	{
		var returnValues = [];

		for (var i = 0; i < this.items.length; i++)
		{
			var item = this.items[i];
			if (item.htmlElement.selected == true)
			{
				returnValues.push(item.listable);
			}
		}

		return returnValues;
	}

	// html

	ListBox.prototype.htmlElementBuild = function()
	{
		var gridCellSizeInPixels = this.style.gridCellSize;

		var returnValue = document.createElement("select");

		returnValue.style.border = "1px solid";
		var sizeInPixels = this.size.clone().multiply(gridCellSizeInPixels);
		returnValue.style.width = sizeInPixels.x;
		returnValue.style.height = sizeInPixels.y;
		var posInPixels = this.pos.clone().multiply(gridCellSizeInPixels);
		returnValue.style.position = "absolute";
		returnValue.style.left = posInPixels.x;
		returnValue.style.top = posInPixels.y;

		returnValue.size = Math.floor
		(
			this.size.y / this.sizePerItem.y
		);

		this.htmlElement = returnValue;

		this.htmlElementUpdate();

		return returnValue;
	}

	ListBox.prototype.htmlElementUpdate = function()
	{
		var htmlElementsToRemove = [];

		var htmlElementsForItems = this.htmlElement.children;

		for (var i = 0; i < htmlElementsForItems.length; i++)
		{
			var htmlElementForItem = htmlElementsForItems[i];
			var item = htmlElementForItem.control;
			if (this.items.indexOf(item) <= 0)
			{
				htmlElementsToRemove.push(htmlElementForItem);
			}
		}

		while (htmlElementsToRemove.length > 0)
		{
			var htmlElementToRemove = htmlElementsToRemove[0];
			htmlElementsToRemove.splice(0, 1);
			this.htmlElement.removeChild(htmlElementToRemove);
		}

		for (var i = 0; i < this.items.length; i++)
		{
			var item = this.items[i];

			if (item.htmlElement == null)
			{
				var htmlElementForItem = item.htmlElementBuild
				(
					this.sizePerItem
				);
				this.htmlElement.appendChild(htmlElementForItem);
			}
		}
	}
}

function ListBoxItem(listable, text)
{
	this.listable = listable;
	this.text = text;
}
{
	ListBoxItem.buildManyFromListables = function(listables)
	{
		var returnValues = [];

		for (var i = 0; i < listables.length; i++)
		{
			var listable = listables[i];	

			var listBoxItem = new ListBoxItem
			(
				listable,
				listable.buildTextAsListable()
			)

			returnValues.push(listBoxItem);
		}

		return returnValues;
	}

	ListBoxItem.prototype.htmlElementBuild = function(size)
	{
		var returnValue = document.createElement("option");

		returnValue.control = this;

		returnValue.style.width = size.x;
		returnValue.style.height = size.y;
		returnValue.value = this.text;
		returnValue.innerHTML = this.text;

		this.htmlElement = returnValue;
		return returnValue;
	}

	ListBoxItem.prototype.htmlElementUpdate = function()
	{
		// todo
	}
}

function Trader(name, itemsHeld)
{
	this.name = name;
	this.itemSetHeld = new ItemSet("Held", itemsHeld);
	this.itemSetOffered = new ItemSet("Offered", []);
	this.itemSetsHeldAndOffered = 
	[
		this.itemSetHeld,
		this.itemSetOffered,
	];
}
{
	// controls

	Trader.prototype.controlBuild = function(style, size, pos, reverseItemSets)
	{
		var buttonSize = new Coords(4, 2);
		var sizeOfButtonPane = new Coords(buttonSize.x + 2, size.y - 4)
		var itemSetSize = new Coords((size.x  - sizeOfButtonPane.x - 4) / 2, size.y - 4);

		var itemSetIndexLeft = (reverseItemSets == true ? 1 : 0);

		var buttonOfferOneClick = function(event) 
		{ 
			var buttonClicked = event.target.control;
			var trader = buttonClicked.tagItem;
			var itemSetFrom = trader.itemSetHeld;
			var itemSetTo = trader.itemSetOffered;
			var itemsToMove = itemSetFrom.itemsSelectedFromControl();
			var quantityToMove = 1;

			for (var i = 0; i < itemsToMove.length; i++)
			{
				var itemToMove = itemsToMove[i];
				if (itemToMove.quantity > quantityToMove)
				{
					itemToMove = new Item(itemToMove.defn, quantityToMove);
				}
				itemSetFrom.itemRemove(itemToMove);
				itemSetTo.itemAdd(itemToMove);
			}

			trader.controlUpdate();
		};

		var buttonOfferTenClick = function(event) 
		{ 
			var buttonClicked = event.target.control;
			var trader = buttonClicked.tagItem;
			var itemSetFrom = trader.itemSetHeld;
			var itemSetTo = trader.itemSetOffered;
			var itemsToMove = itemSetFrom.itemsSelectedFromControl();
			var quantityToMove = 10;

			for (var i = 0; i < itemsToMove.length; i++)
			{
				var itemToMove = itemsToMove[i];
				if (itemToMove.quantity > quantityToMove)
				{
					itemToMove = new Item(itemToMove.defn, quantityToMove);
				}
				itemSetFrom.itemRemove(itemToMove);
				itemSetTo.itemAdd(itemToMove);
			}

			trader.controlUpdate();
		};

		var buttonStashOneClick = function(event) 
		{ 
			var buttonClicked = event.target.control;
			var trader = buttonClicked.tagItem;
			var itemSetFrom = trader.itemSetHeld;
			var itemSetTo = trader.itemSetOffered;
			var itemsToMove = itemSetFrom.itemsSelectedFromControl();
			var quantityToMove = 1;

			for (var i = 0; i < itemsToMove.length; i++)
			{
				var itemToMove = itemsToMove[i];
				if (itemToMove.quantity > quantityToMove)
				{
					itemToMove = new Item(itemToMove.defn, quantityToMove);
				}
				itemSetFrom.itemRemove(itemToMove);
				itemSetTo.itemAdd(itemToMove);
			}

			trader.controlUpdate();
		};

		var buttonStashTenClick = function(event) 
		{ 
			var buttonClicked = event.target.control;
			var trader = buttonClicked.tagItem;
			var itemSetFrom = trader.itemSetHeld;
			var itemSetTo = trader.itemSetOffered;
			var itemsToMove = itemSetFrom.itemsSelectedFromControl();
			var quantityToMove = 10;

			for (var i = 0; i < itemsToMove.length; i++)
			{
				var itemToMove = itemsToMove[i];
				if (itemToMove.quantity > quantityToMove)
				{
					itemToMove = new Item(itemToMove.defn, quantityToMove);
				}
				itemSetFrom.itemRemove(itemToMove);
				itemSetTo.itemAdd(itemToMove);
			}

			trader.controlUpdate();
		};

		var returnValue = new Container
		(
			this.name,
			style,
			size, 
			pos,
			[
				new Label("labelName", style, new Coords(1, 1), this.name),
				this.itemSetsHeldAndOffered[itemSetIndexLeft].controlBuild
				(
					style, itemSetSize, new Coords(1, 3)
				),
				new Container
				(
					"containerItemTransferButtons",
					style,
					sizeOfButtonPane,
					new Coords(itemSetSize.x + 2, 3),
					[
						new Button
						(
							"buttonOfferTen", 
							style, 
							buttonSize, 
							new Coords(1, sizeOfButtonPane.y / 2 - 6), 
							(itemSetIndexLeft == 0 ? "10>" : "<10"),
							buttonOfferTenClick,
							this // tagItem
						),
						new Button
						(
							"buttonOfferOne", 
							style, 
							buttonSize, 
							new Coords(1, sizeOfButtonPane.y / 2 - 3), 
							(itemSetIndexLeft == 0 ? ">" : "<"),
							buttonOfferOneClick,
							this // tagItem
						),
						new Button
						(
							"buttonStashOne", 
							style, 
							buttonSize, 
							new Coords(1, sizeOfButtonPane.y / 2), 
							(itemSetIndexLeft == 0 ? "<" : ">"),
							buttonStashOneClick,
							this //tagItem
						),
						new Button
						(
							"buttonStashTen", 
							style, 
							buttonSize, 
							new Coords(1, sizeOfButtonPane.y / 2 + 3), 
							(itemSetIndexLeft == 0 ? "<10" : "10>"),
							buttonStashTenClick,
							this //tagItem
						),
					]
				),
				this.itemSetsHeldAndOffered[1 - itemSetIndexLeft].controlBuild
				(
					style, 
					itemSetSize, 
					new Coords
					(
						itemSetSize.x + sizeOfButtonPane.x + 3, 
						3
					)
				),
			]
		);

		this.control = returnValue;
		return returnValue;
	}

	Trader.prototype.controlUpdate = function()
	{
		this.itemSetHeld.controlUpdate();
		this.itemSetOffered.controlUpdate();
	}
}

function TradingSession(name, traders)
{
	this.name = name;
	this.traders = traders;

	ArrayHelper.addLookupsToArray(this.traders, "name");
}
{
	TradingSession.prototype.exchange = function()
	{
		for (var t = 0; t < this.traders.length; t++)
		{
			var traderThis = this.traders[t];
			var traderOther = this.traders[1 - t];

			var itemsFrom = traderThis.itemSetOffered.items;
			var itemsTo = traderOther.itemSetHeld.items;

			while (itemsFrom.length > 0)
			{
				var itemToMove = itemsFrom[0];
				itemsFrom.splice(0, 1);
				itemsTo.push(itemToMove);
			}
		}
	}

	// controls

	TradingSession.prototype.controlBuild = function(style, size)
	{
		var gridCellSize = style.gridCellSize;

		var sizeOfCenterPane = new Coords(7, size.y - 4)
		var sizePerTrader = new Coords
		(
			(size.x - sizeOfCenterPane.x - 4) / 2,
			size.y - 4
		);

		var buttonTradeClick = function(event)
		{
			var buttonClicked = event.target.control;
			var session = buttonClicked.tagItem;

			var pricesOfOffersForTraders =
			[
				session.traders[0].itemSetOffered.priceOfAllItems(),
				session.traders[1].itemSetOffered.priceOfAllItems(),
			];

			var profitForTrader1 = 
				pricesOfOffersForTraders[0] 
				- pricesOfOffersForTraders[1];

			if (profitForTrader1 < 0)
			{
				alert
				(
					"That's not a profitable trade for " 
					+ session.traders[1].name
					+ "!"
				);
				return;
			} 

			for (var t = 0; t < session.traders.length; t++)
			{
				var traderFrom = session.traders[t];
				var traderTo = session.traders[1 - t];

				var itemSetFrom = traderFrom.itemSetOffered;
				var itemSetTo = traderTo.itemSetHeld;
				var itemsToMove = itemSetFrom.items.slice(0);

				for (var i = 0; i < itemsToMove.length; i++)
				{
					var itemToMove = itemsToMove[i];
					itemSetFrom.itemRemove(itemToMove);
					itemSetTo.itemAdd(itemToMove);
				}

				session.controlUpdate();
			}
		}

		var returnValue = new Container
		(
			"container" + this.name,
			style,
			size,
			new Coords(1, 1), // pos
			// children 
			[
				new Label("labelName", style, new Coords(1, 1), this.name),
				this.traders[0].controlBuild
				(
					style,
					sizePerTrader,
					new Coords(1, 3),
					false // reverseItemSets
				),
				new Container
				(
					"containerCenterPane",
					style,
					sizeOfCenterPane,
					new Coords(sizePerTrader.x + 2, 3),
					[
						new Button
						(
							"buttonTrade", 
							style, 
							new Coords(5, 2), // size 
							new Coords(1, sizeOfCenterPane.y / 2), 
							"Trade",
							buttonTradeClick,
							this // tagItem
						),

					]
				),
				this.traders[1].controlBuild
				(
					style,
					sizePerTrader, 
					new Coords(sizePerTrader.x + sizeOfCenterPane.x + 3, 3),
					true // reverseItemSets
				),
			]
		);

		this.control = returnValue;
		return returnValue;
	}

	TradingSession.prototype.controlUpdate = function()
	{
		this.traders[0].controlUpdate();
		this.traders[1].controlUpdate();
	}
}

function Universe(itemDefns, tradingSession)
{
	this.itemDefns = itemDefns;
	this.tradingSession = tradingSession;
}

// run

new TradingTest().main();

</script>
</body>
</html>
This entry was posted in Uncategorized and tagged , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s