Thursday, August 4, 2011

A C# Implementation of Board Game: Balloon Cup

Balloon Cup is a 2-player board game published in 2003. The first time I played this game was in the summer of 2010. After I played this game a few times, I noticed that Balloon Cup involves a lot of planning, calculation, and evaluation, which makes this game very exciting as a strategy card game. Also the playing time of is not very long, because the rule is simple and the game setup is very easy. Usually, it takes only 20 minutes to finish a game, which is pretty short comparing with other board games. Since I am very interested in developing video game and I wish some day I can work in the game industry, I decide to implement this game as my first step.

Here is a description of Balloon Cup that I found over the Internet:

In Balloon Cup, the players compete in several short balloon flights (hops) to collect the colored cubes associated with each hop. Four landscape cards, two Plains alternating with two Mountains, are laid out and 1, 2, 3 or 4 cubes in assorted colors (gray, blue, green, yellow, red) are added. From a hand of 8 Balloon cards must try to pass each landscape by adding cards matching the colored blocks onto their side of table, although winds (and cunning) may occasionally cause them to play on their opponent’s side - a move that can really ruin the opponent’s plans.

High-valued balloons are played on the Mountains and low-valued balloons on the plains. Whoever is the better balloonist takes the cubes from the card, which is then flipped over and refilled with cubes. Mountains becomes Plains and vice-versa. 5 Trophy cards of value 3 to 7 are placed at the top of the cards. When a player has collected enough cubes of a given color, he earns the Trophy card for that color. Players may even trade 3 otherwise useless cubes for 1 they can use. The first player to earn 3 trophy cards is the winner!

To my understanding, a video console game should be formed by three parts: Graphics, Game System, and AI System. A successful console video game must have eye-pleasing graphics, an interesting game mechanism, and a challenging AI system. Therefore, how to develop those three parts are the biggest challenges in this project.

Graphics
In video game development, graphics is the most important part of a game. It involves human computer interaction, art design, and maths calculation. In this project, I am able to find some art works that are originally used in the Balloon Cup board game, such as the cover of the Balloon Cup, the image of 45 cards, the image of 4 boards and the image of 5 trophies. I also found 5 small balloon icons which can be used as "the blocks" in the game. Therefore the only art design that I did is the card back. Although I don't need to spend too much time on the art design, I still need to design the game layout. In order to make the game interface as a player-friendly interface, I decide to draw the trophies, boards and player's hands as the original game setup. In this case, player can easily get all the information directly. Here are some screen shots of the game interface.

Game Main Menu
Game Option Menu
Game Interface

Game System
Because Balloon Cup is a turn based card game, the game system is very simple, which means no multi-threading needed in this game. The game starts with player's turn. The player picks a card from the hand and puts it on a board, either player's side or computer's side. Then the game will check if the board is ready to settle. If not, player's turn ends and computer will make its move with a simple animation. Then switch turn and game goes on until some one wins the game. If the board is ready to settle, a short animation will occur. The blocks on that board will fly to the winner's block bank. If either computer or player has enough blocks to exchange for a trophy, system will automatically assign the trophy to the winner of that trophy by printing the name of winner next to the trophy card. When either computer or player first gets three trophies, the game ends and the winner's name will pop-up. Here is a screen shot of the middle of a game.

AI System
A good console game must have a good AI system. If the AI is too simple, players will easily get bored, because there is no challenge. However, the AI cannot be "too hard" (if that is possible), because no one would like to always lose. In my opinion, AI system should have multiple levels that can satisfy different needs. All the AI levels should provide at least "some kind of challenges" to the players. Of course, a "normal" level AI probably won't be a challenge for an experienced player, but it can be a challenge for a new comer. Also the difference between each AI level should be noticeable, so that players can easily tell which level they are in. In this game, I have two AI levels, "normal" and "hard". The "normal" AI have basic concept of its position on each board and can make move according to its position and hand. The "hard" AI (still working on) have the concept of importance of the block, which means AI will set different priorities to different boards according to the blocks on the board. Hopefully the "hard" AI can be finished in this week.

Here is the Google Project Hosting site for this project. Anyone who is interested may download the source from the "download" page. It has an executable file "balloon2.exe" inside the "/bin/debug" folder for your quick try out.

Tuesday, December 21, 2010

Tips in Upgrading Google Map Code From V2 To V3

Since I am kind of stuck on testing for my library, I decide to move to another direction of my project. I need to use my library to rebuild the visualization that I created last semester(Monitor, GeoMap, Stoplight), so that I can compare the code to tell if my library really help the WattDepot web application development. The Stoplight and Monitor are pretty easy to implemented (just retrieve the data and display). You may visit the project hosting page and check it out. The GeoMap visualization is little bit harder, because it contains some nested requests and data manipulation, also because it was using Google Map API version 2 and I need to migrate my code to adapt version 3 now. In this blog post, I will discuss about some changes that I dealt with when upgrading my code with Google Map API V3.

1. Map Object
The most fundamental object in Google Map API is the map object. In V3, MapTypeId is added as the required property to render the map. This property tells the map type is either "RoadMap", "Satellite", or something else. Another thing new in V3 is the way it calculates the zoom level by the bound. In V2, you need to call getBoundsZoomLevel(bound) to get the zoom level and set the map with the zoom level it returned. In V3, you simply need to call fitBounds(bound) and the whole thing is done.

2. Marker Object
In V2, marker object is a subclass of overlay. Once you created a marker, you need to call map.addOverLay(marker) to add marker to the map. In V3, the marker object has a map property. If this property is set, the marker will be added to the map stored in this property. Another minor change is that in V3, it uses markerImage object to replace the icon object in V2.


3. Infowindow Object
In V3, Google Map API introduce the infowindow object. Infowidnow object is basically the dialog box that usually comes up when a marker is clicked. In V2, only one dialog box can be showed in the map at one time and In V3 multiple dialog box can be showed simultaneously. In V2, this effect is invoked by openInfoWindowHtml() function inside an overlay object. You simply pass the html code showing in the dialog box as the parameter to the openInfoWindowHtml() function. In V3, infowindow object has a content property, which manages the content of the dialog box, and it also has a size property, which controls the size of the dialog box. (Note: dialog box size can only be set in size property. In V2, it can be set inside the content.)

By far, these are the changes that affacts my code the most. Upgrading the code to adapt a new version of a library always involves a lot of learning, debugging, and coding. This is exactly how I upgrade my code to use Google Map API V3. First, I found some sample code that using the Google Map API V3 and had a general idea of how much the api was changed. Then I went back to my code and checked which functions are replaced or gone. Last, I used the new way to rewrite the code for those broken functions and debug the program. Hopefully my experience can help some one who just start migrating his/her code to a new version of Google Map API.

Friday, December 17, 2010

Jsunit Try Out

After the basic functionality of my library is implemented, it is the time to add some quality assurance to the project. One of the most important quality assurance methods is unit testing.
However, I was kind of lost because I don't have any unit testing experience in JavaScript web application. At this point, my graduate adviser Dr. Johnson introduced Jsunit to me provided several links to help me get start on it. In this blogpost, I will discuss about something I learned about Jsunit.

Get Jsunit Running:
Jsunit is an open source software for JavaScript unit testing. It is very easy to download. You may simply go to the download page in Source Forge. Inside the Jsunit package, there is a file called "testRunner.html", which is the unit testing user interface. In testRunner page, I can input the path of my testing file in "File" field and click "Run" to run the unit test.
The test result would look like this:
Create a Unit Test:
Writing a unit test in JavaScript is nothing different from writing it in other languages. The only thing need to mention is that, in order to run Jsunit for unit testing, you must include the "JsUnitCore.js" in your test file. (Inside "app" folder) This is the place that contains all the Assert functions.

Problems in Jsunit:
After some experiment in Jsunit, I found some difficulties that I cannot get over with.

1. Test file must locate inside the Jsunit folder or its sub folders, otherwise in testRunner.html, your test file cannot be loaded to the Jsunit. For example, I put my test file in the same level as the Jsunit folder. Then I changed the script tag to:
<script type="text/javascript" src="jsUnit/app/jsUnitCore.js"></script>
Then, when I try to run my test in testRunner, it will tell me time out in loading the test file. However, if I put my file inside the Jsunit folder, and change the script tag accordingly, it works. This is very confusing to me. I have no idea why this happens. Its documentation on how to setup the testing environment is very short and not quite helpful.

2. Jsunit cannot test the AJAX response and its callback. Since my library is heavily related with AJAX, I need to test if my AJAX request will get the correct response. However, in Jsunit, I didn't find a way to test it. I think it is because Jsunit runs the test suite asynchronously, so it cannot wait for the AJAX response. I did some research online about the callbacks testing. Some people suggest using the clock object in "jsUnitMockTimeout.js" to simulate the state of after some time(say 10 secs). I tried it, it only works for the "system.timeout()" thing but not for the AJAX response.

Anyway, I realize that Jsunit is not supported by its developer any more, so I guess I need more research on how to overcome these problems. In all, my opinion is that Jsunit is an acceptable tool for unit testing. I certainly hope I can find another tool to replace it.

Tuesday, December 14, 2010

Something about converting XML to JSON

For the past few weeks, I have worked on several tasks and in the following several blog posts I would like to talk about what I have learned. This time, I am going to talk about something tricky I found in converting XML to JSON.

Actually, there is no universal standard in converting XML to JSON. Every one may have his/her own standard while converting. Here, I will explain the mechanism I used in my conversion function first.

Basic Concept:
Basically, convert Xml to JSON is to parse Xml and translate each node into a JSON object, then nest the JSON objects according to the Xml structure. The most common way to parse Xml is using a recursive function, so that it can recursively go through each node level. For each recursive cycle, the parser normally needs to handle three situations:

Use the following simple xml as an example:
  <book state="new">Lord of the Ring</book>
1. Attributes of an element. In this case, "state".
Only element can have attributes. So the function needs to loop through and save all the attributes before it goes further.

2. Elements with child nodes (nodeType = 1). In this case, "book"(it has a child node which contains the Text of "Lord of the Ring". So create an object with the node name and start parsing all its child nodes.

3. Text of an element (nodeType = 3).
In this case, "Lord of the Ring". So simply return the node value.

A little problem came up:
I followed these rules and my function appears working well. However, when I used it to parse a self-closed Xml element, it failed. For example: Parsing following xml,
  <book state="new" title="Lord of the Ring" />
Interesting discovery:
After some investigation, I found some thing very interesting. It looks like self-closed Xml element will have a leading empty Text node before the element node, which means the parser will get a Text node with a value of " " before the Element node with a value of "book". Since the parser will not continue parsing if the input is a Text node, it will not be able to parse the element node. Therefore, I need to add an condition statement to take care of this situation.

In the end, I posted the xmlToJson conversion function I built. Hopefully, it will help some developers that working on this subject.
 function xmlToJson(xml) {
var obj = {};
// element
if (xml.nodeType == 1) {
// check attributes
if (xml.attributes.length > 0) {
for (var j = 0; j < xml.attributes.length; j++) {
obj[xml.attributes[j].nodeName] = xml.attributes[j].nodeValue;
}
}
}
// check child node
if (xml.hasChildNodes()) {
for(var i = 0; i < xml.childNodes.length; i++) {
// check if the child node has another child node, if not,
// this child node is the text value of the parent node.
if (xml.childNodes[i].nodeType != 3 || i != xml.childNodes.length - 1) {
//check if this node name is existed in obj, if not, add
//this node as a property to current obj
if (typeof(obj[xml.childNodes[i].nodeName]) == 'undefined') {
obj[xml.childNodes[i].nodeName] = xmlToJson(xml.childNodes[i]);
}
else {
//check if there is the array for this node name, if not, create
//an array and add the existing one to the array
if (!(obj[xml.childNodes[i].nodeName] instanceof Array)) {
var old = obj[xml.childNodes[i].nodeName];
obj[xml.childNodes[i].nodeName] = [];
obj[xml.childNodes[i].nodeName].push(old);
}
obj[xml.childNodes[i].nodeName].push(xmlToJson(xml.childNodes[i]));
}
}
else {
//if it is a text node, just return the value. No object created
//for text node.
return xml.childNodes[i].nodeValue;
}
}
}
else {
//if it is a self closed element, it will have a blank text node before parser
//reach the element. Ignore it.
if (xml.nodeType == 3) {
return xml.nodeValue;
}
}
//return this object
return obj;
}

Tuesday, October 19, 2010

WattDepot Data Miner 1.0.1

Finally, this week I have finished the first version of the WattDepot Data Retrieval Library, which I called WattDepot DataMiner. I have also created a Google project hosting for WattDepot DataMiner. In this blog post, I will brief explain what feature this library has and direction of future development.

As I mentioned in previous blog post, WattDepot DataMiner is designed to facilitate developers in data retrieval tasks related with a WattDepot server. Therefore, first of all, it has three functions that take care of the Ajax calls:
1. a function to take care of the creation of a xmlHttpRequest object.
2. a function that sets all the important parameters of an Ajax call.
3. a function send the xmlHttpRequest and handle the response.

Since the data retrieved from the WattDepot server are Xml files, it is necessary to convert them into a more JavaScript oriented format, such as JSON, so that developers can easily manipulate the retrieved data. Therefore, WattDepot DataMiner has a convert function that convert the raw data to a JSON object.

Even though the retrieved data are represented in a JSON object, the internal structure is still the same as in the xml file. Since most people, who are new to WattDepot, probably are not familiar with the xml structure, it is hard for them to find the desiring field in the response. To help those people, there is a function that loop through a JSON object and return the node with a specific name.

Further more, WattDepot-DataMiner has three data-retrieval functions: getAllSources(), getSourceSensorData(), getSourceLatestSensorData(). These functions are some typical data-retrieval functions from all the data-retrieval functions. They used for test the functionality of other functions for now.

Future development that I planed:

1. Keep adding some more data-retrieval functions to the library, so that WattDepot DataMiner can handle more data retrieval tasks.
2. Use WattDepot DataMiner to rebuild some existing visualizations, so that I can find out what else feature I need to add to the library.

Tuesday, October 12, 2010

Understanding JavaScript Closures

This week, when I was studying other JavaScript libraries (prototype, JQuery), I noticed that closure is frequently used in the code. Then I decided to do some research on JavaScript closures. In this blog post, I would like to share something I learned about JavaScript closures.

1. What is JavaScript closure?

There are plenty definitions for JavaScript closure. It seems that every one has his own understanding towards it. In my understanding, closure is an internal reference that keeps the value of all the local variables that used inside a function even if the function has returned. It is intangible and always existing when a function is called within another function. Therefore, the key feature for JavaScript closure is that it keeps the value of the local variables within a certain scope(For example, a function).
Then you might say, an object can keeps the value of the variables well. What is the difference? The difference is that the variable in object can be accessed from outside where the variable in closure is not accessible from outside. For example:
function Person(name) {
this.message = name + " says hi!";
};
Person.prototype.greet = function greet() {
alert(this.message);
};

var Yichi = new Person('Yichi');
Yichi.greet();
In traditional object manner, people can modify the "message" variable by saying "Yichi.message = "somthing else";"
function Person(name) {
var message = name + " says hi!";
function greet() {
alert(message);
}
return greet;
};

var Yichi = Person('Yichi')();
When using closure, variable "message" is completely private.

2. When use JavaScript closure?

Since JavaScript closure keeps the local variables alive in a function, it is very useful for those functions that are called asynchronously. For example, AJAX callbacks, which I definitely going to use in my library, they only get called when they receive the response from the server. Another example is event handler, it is called only when certain event is triggered. The simplest example shows the power of closure would be setTimeOut function. Here is the traditional way without closure:
function handle() {
alert(message);
}

function setAlarm(message, timeout) {
setTimeout(handle, timeout);
}

setAlarm("Hello World!", 100);
In this case, variable "message" is undefined, because when handle() is called, the value of variable "message" is no longer kept in the memory. It will only work if you pass "message" as a parameter when calling handle(). Let's see how closure does:

function setAlarm(message, timeout) {
function handle() {
alert(message);
}
setTimeout(handle, timeout);
}

setAlarm("Hello World!", 100);
This time, the system will alert "Hello World!" after 100 milliseconds. It is because closure keeps the value of "message" in the scope of "setAlarm" function, and since "handle" is called within this scope, so it knows the value of "message". From this example, we can tell that using closure will save your work in a smart way.

3. Be careful with JavaScript closure

Since other programming languages, such as C or Java, do not have any feature like JavaScript closure, new JavaScript developers are not familiar with this concept. Therefore, extra caution is really necessary when using closure in the code. One common bug producer is defining function within a loop. Let's focus on the following example:
function main(link) {
for (var i = 0; i < list.length; i++) {
link[i].onClick = function() {
alert(i + 1);
}
}
}

main(document.getElementsByTagName("a"));
It looks like it will alert an index number when click on a link. However, this piece of code is not going to work that way. Assume there are 3 links in the page. Then the list length is 3 in the code. In this case, 'i' will be 4 when loop ends. Since closure keeps all the local variables within the parent function, it will always alert '5' when link.onClick is triggered. To fix this bug, it has to be like this:
function main(link) {
for (var i = 0; i < list.length; i++) {
link[i].onClick = (function(j) {
return function() {alert(j + 1);}
})(i);
}
}

main(document.getElementsByTagName("a"));
In the above example, another anonymous function is defined, which creates a new closure that only stores the local variable "j". Because "j" stores a snapshot of "i", so the system will alert different numbers (1,2,3 in this case).
This example shows that we must fully understand closure and use it correctly, otherwise, weird bugs might raise.

Tuesday, October 5, 2010

Data Communication in JSON

This week, I did some research on JSON, which I am going to use in my JavaScript Library for data representation. Here, I am going to talk about JSON in three aspects:

1. What is JSON?

JSON (JavaScript Object Notation) is a light weight data interchange format alternative to using XML. From its definition we can tell one important thing: JSON is a JavaScript Object. It is formed by numbers of key value pairs. Since the value can be any data type, developer can store other arrays or other objects, nesting them as deeply as needed.

An example of JSON would look like:
{
name : "Yichi",
major : "Computer Science",
hobbies : [
"Travel","Video Game"
]
}

An example of XML would look like:
  <name>"Yichi"</name>
<major>"Computer Science"</major>
<hobbies>"Travel"</hobbies>
<hobbies>"Video Game"</hobbies>


2. Why use JSON? (compare with XML)

As you might notice, JSON does not have tons of open and close tags or long list of attributes. It is more structured and more human readable than XML. Not only the size of data file is smaller, JSON is also easier to use in programing! Let's use the above data file as an example. Let's say I need to find the value of "name". If the data is in XML format, the code would look like:
var temp = xmldoc.getElementsByTagName('Name')[0].childNodes[0].nodeValue;
However, if the data is in JSON format, the code is much simpler:
var temp = jsondoc.name;

So, JSON is more JavaScript-Oriented than XML.

3. How to generate JSON?

Since WattDepot is going to provide data in XML format and I am not able to make any change on the server side, I need to find a way to convert XML data to JSON. Actually, there are some existing libraries out there for converting XML to JSON. One of them is Google Data API. In Google.Data.JSON package, it contains a xml_to_json($xml) method that can convert a XML file to JSON format. Here is a reference. In this case, I can simply use Google Data API in my library to handle the conversion.

Hopefully, my blog can help those JSON beginners like me:)