Wednesday, December 21, 2011

My First JavaScript Object...

I thought I'd learn a little more about JavaScript's Object-Oriented programming model by adding in a game object to display player moves to the board from my last post. I've never been a fan of JavaScript in the past, but since it's listed on GitHub as the most popular programming language, it seems like a good idea to become more familiar with it. So here goes!

I started by creating a game object that would store a game record and would return each individual move. Since SGF is, by far, the most common record for storing Go games I wanted to make my object compatible with this format. My JS object looked like this:


// The Game Object has the metadata about the game, the moves, and a method to access the moves
function Game( name, moves )
{
 this.name = name;
 this.moves = moves;
 this.currMove = 0;
 
 // getNextMove() gets the current move and then increments the counter to point to the next move
 this.getNextMove = function()
 {
  var nextMove = this.moves[this.currMove];
  this.currMove++;
  return nextMove;
 }

}

One thing to note is that the header for the SGF record contains a LOT  more metadata about the game. It contains information like the player's names, their level, the komi, etc. So if I pursue this in the future, I would change this object to contain all of this information.

Next, I used the following code to create an instance of this object. This is the record for an example game record with 17 moves:

var theGame = new Game("Test Game", [";B[pd]",
          ";W[dd]",
          ";B[pg]",
          ";W[qo]",
          ";B[cg]",
          ";W[fg]",
          ";B[pl]",
          ";W[co]",
          ";B[eg]",
          ";W[ep]",
          ";B[fp]",
          ";W[gp]",
          ";B[dg]",
          ";W[er]",
          ";B[dp]",
          ";W[dr]",
          ";B[gg]"]);

Since the method getNextMove( ) returns the sgf-format for each move, in order to use this on the game board, I wrote a function to convert the sgf format to the real screen coordinates:

// sgfToXy() converts this sgf format to a canvas x,y coordinate
function sgfToXy(theMove)
{
 // get the unicode value for the character 
 virtual_x = theMove.charCodeAt(3);
 virtual_y = theMove.charCodeAt(4);
 
 // subtract out 97 to transform the unicode number to the board position
 // NOTE: it would be nice if JavaScript had constants :-(
 virtual_x = virtual_x - 97;
 virtual_y = virtual_y - 97;
 
 // transform the virtual board value into a real screen coordinate
 real_x = 10 + virtual_x * 20;
 real_y = 10 + virtual_y * 20;
 
 // return an array with the points
 var theResult = {
   x: real_x,
   y: real_y
 }
 return theResult;

}

Now I can draw the game pieces with the canvas  x,y screen point provided by sgfToXy. I can also get the piece color from the B or W character in the move:

//draws the move (in sgf format) on the game board
function drawPiece(theMove)
{
 // first convert the move into an actual location to draw the piece
 var theConvertedValue = sgfToXy(theMove);
 
 // figure out the color of the piece
 if(theMove.charAt(1)== "B")
 {
  theColor = "black";
 } else
 {
  theColor = "white";
 }
 
 // use jCanvas to draw the piece
 $("canvas").drawArc({
    fillStyle: theColor,
    strokeWidth: 1,
    x: theConvertedValue.x, y: theConvertedValue.y,
    radius: 10
  });
}

In order to see the moves on the board, I created a button with a small onClick event handler. Here's the HTML I added to go.html:

<button onclick="drawNextMove()">Next Move</button>

And here's the actual event handler:

function drawNextMove()
{
 var theMove = theGame.getNextMove();
 drawPiece(theMove);
}

So at the end of this, what I have is a simple board and a button:



Looking over the code at this point, it's apparent the board should also be its own object as well. In the next post I'll tidy up the board code so it's its own object. I'll also make some other changes so it will be re-sizable, etc.

Following that, I wanted to experiment with using HTML5's offline storage. With 5 MB of storage and the average Go game taking up about 10K, it should be possible to store around 500 commented games!

No comments:

Post a Comment