Tuesday, January 13, 2015

Mastermind

I quite like JavaScript and wanted to know a little more about drag and drop so I decided to make an online version of Mastermind.

Visual Studio makes it easier to write JavaScript.  It has good IntelliSense and you can quickly locate your functions and variables. You can also debug the JavaScript by stepping through the code line by line.

In the game, you can drag the pieces from anywhere.  For instance you can take a piece from the row below and drag it up.

The game can be played here: mastermind.azurewebsites.net.

If you are curious about the JavaScript then you can download it from here and save it to your computer.  (You may get security warnings).

Rinus

Tuesday, October 14, 2014

HTML 5 and javascript game programming.

pac.azurewebsites.net


I want to get better at javascript and I still think that the best way to learn something new is to just dive in and start using it.

Only when you actually try and create something do you realize what you know, wish you knew, or thought you knew but don't.

So the challenge was to create a Pacman game.  I wanted to make something fairly close to the original.  For instance I knew that each ghost had its own movment pattern but I did not know what it was.  I found this great site that explains the rules of the ghost behavior: Understanding ghost behavior

So the ghost behavior made it into the game.

Other features are:
  • Just like the original, the ghosts will attack in waves and then back off and then attack again.
  • When you eat a ghost, the eyes zoom back to the home base.
  • Pacman can outrun the ghost because it can take corners quicker than the ghosts.
  • If you stay too long on a level, then the red ghost will become quite fast. Don't hang around too long.
  • And also - there is also a high score table!
So what are you waiting for? Have a go at: http://pac.azurewebsites.net

Wednesday, September 25, 2013

Create an online text adventure using ASP.NET MVC

I think the best way to learn a new technology is to start using it in a way that is interesting, motivating and challenging. For me that usually means writing a game.

I learned C++ by writing my own versions of arcade games such as PacMan, Frogger or Tetris.

So when I decided to learn Microsoft's ASP.NET MVC framework, the natural choice was to create a game that would work in a web browser. The game of choice was a text adventure called 'Inca Curse' that I used to play as a kid.

MVC stands for Model, View, Controller. It's a way to organize your program into three distinct groups that each have their own responsibilities. The Controller takes care of the programming logic The View takes care of how your program presents itself to the browser and the Model takes care of the data: usually by reading and writing to a database.

I already knew how to program using ASP.NET Forms and still the learning curve was quite steep. I had to brush up on my C# skills and of course the MVC framework has its own set of challenges.  But once I got the hang of it, I really liked the way it worked.  It is quite elegant and allows you to create large, complex sites with relative ease.

MVC uses conventions.  For instance when you want to create code that responds to www.site.com/product, then you'd create a controller and call it ProductController.  Inside ProductController you can write methods that responds to Add, Edit or Remove.

An example: www.site.com/product/edit/22
This URL will look in ProductController for the Edit method which it will execute with parameter 22. 

Another example - http://incacurse.azurewebsites.net/adventure/start will execute the Start method of the AdventureController.  The web server will execute the code and serve a new page to the browser.

There is also a default controller that will execute when the website is requested without any additional information. For instance, if a user would browse to http://incacurse.azurewebsites.net (no controller, no method), the server would in fact serve the Index method of the HomeController.  So the result would be the exactly the same as browsing to http://incacurse.azurewebsites.net/home/index

Inca curse uses cookies to store all the data needed to play the game.  This data consists of the current location, all objects (and the location where the object is stored or if it is held by you), certain game states, and a copy of the text on the screen. 

If you use Internet Explorer and are curious, then you can actually look at the cookies and how the cookie data changes as you move from location to location.  Just press F12, click on Network, Start Capturing, Go to Detailed View, click on the 'Cookies' tab.  Here is an example of a typical cookie:
1100000003070610161719252712482122000013000021012327210050282942454647323600000003030024002400020100000000I AM IN A JUNGLE CLEARING |EXITS ARE SOUTH|I CAN ALSO SEE :|A BRANCH|TELL ME WHAT TO DO|GET BRANCH|IT IS HEAVY WITH LOTS OF LEAVES|TELL ME WHAT TO DO|HELP|TARZAN WOULD WEAR THEM SO WHY NOT STRIP THEM?|TELL ME WHAT TO DO|HELP|TARZAN WOULD WEAR THEM SO WHY NOT STRIP THEM?|TELL ME WHAT TO DO|THEEND
Cookies are just simple text files and it is possible to edit the cookie in order to cheat.  All you need to do is find the cookie on your computer.

Now just for fun - here is part of the actual code of the Index method inside the Adventure Controller:

public class AdventureController : Controller
{

    [HttpGet]  //This code responds to browser Get requests
    public ActionResult Index()

    {
        // Game class deals with the logic of the game
        Game game = new Game(); 
        // Parse class deals parsing user input.
 
       Parse parse = new Parse();
        if (CookieExists())
        {
            // If yes, Load Cookie data            

            string s = ReadCookie();
            parse.CookieToData(s, game, screen);
        }
        else
        {
            // no cookie found, it must be the start of a new game

            screen.ShowLocation(game);
            screen.WriteLine("TELL ME WHAT TO DO");

        }

        // Viewbag can be used to pass information to the view
        // In this game 22 lines of text are passed to the view

        SetViewBag();

        // Return the View to the browser
        return View();
    }
}


And this is what the game looks like when you play it.



Have a go!  Try you luck at the adventure.   If you go to the 'hints' section, you will get a brief introduction to the wonderful world of text adventures.

Wednesday, July 10, 2013

T-SQL Cursor vs Merge

Today we'll have a look at Microsoft SQL Server programming and specifically the CURSOR and MERGE statements.

A cursor can be used to loop through a set of rows programmatically.  Their use is discouraged because they tend to perform poorly.  It's usually faster to work with a set of records instead of 'walking through' a table, one row at a time.

Let's have a look at the difference in performance between a cursor and the merge statement. 

Imagine a table with stock prices (dbo.Securities) that is updated with new prices every day.
After each update, we want to move SecurityID, Price and PriceDate to the dbo.PriceHistory table. 

We will need to check if the combination of SecurityID and PriceDate exists in the target table.  If it doesn't then we will INSERT a new row.  If it does exist then we will have to UPDATE the existing record. 

We could write a stored procedure that uses a cursor as follows:

CREATE PROCEDURE dbo.SP_InsertPriceHistory AS
SET NOCOUNT ON;
DECLARE @MySecID int;
DECLARE @MyDate date;
DECLARE @MyPrice numeric(12,4);

DECLARE MyCur CURSOR FAST_FORWARD

  FOR SELECT Securityid, Price, PriceDate
  FROM dbo.Securities ORDER BY SecurityID;
OPEN MyCur;
FETCH NEXT FROM MyCur INTO @MySecID, @MyPrice, @MyDate;
WHILE @@FETCH_STATUS = 0
BEGIN
  --Check if record exists
    

  IF EXISTS (SELECT * FROM dbo.PriceHistory

             WHERE PriceDate = @MyDate and SecurityID = @MySecID)
    BEGIN
      --Record exists - Update
      UPDATE dbo.PriceHistory SET PriceDate = @MyPrice
        WHERE (SecurityID = @MySecID AND PriceDate = @MyDate);
    END
  ELSE
    BEGIN
       
      --Record does not exist - Insert
      INSERT INTO dbo.PriceHistory (SecurityID, PriceDate, Price)
        VALUES(@MySecID, @MyDate, @MyPrice);
        
    END
  FETCH NEXT FROM MyCur INTO @MySecID, @MyPrice, @MyDate;
END
CLOSE MyCur;
DEALLOCATE MyCur;


We can achieve the same result using the Merge statement.  The stored procedure might look like this:

CREATE PROCEDURE dbo.SP_InsertPriceHistory AS
SET NOCOUNT ON;

MERGE INTO dbo.PriceHistory AS TGT
  USING dbo.Securities AS SRC
  ON SRC.SecurityID = TGT.SecurityID AND

    SRC.PriceDate = TGT.PriceDate
  WHEN MATCHED THEN

    UPDATE SET TGT.Price = SRC.Price;
  WHEN NOT MATCHED 
THEN
    INSERT VALUES(SRC.SecurityID, SRC.PriceDate, SRC.Price);


SQL server will check for a match between the source and target table by comparing both the SecurityID and PriceDate columns.

If there is a match then it will run the code after WHEN MATCHED THEN

If there is no match then it means that no price is stored for this particular security on this date and it will run the code after WHEN NOT MATCHED THEN

Not only is this code easier to read, it is also much faster.  On a table with approx. 2500 records, the cursor took 124 milliseconds to finish.  The merge statement finished in 32 milliseconds.

For more details on Merge have a look at Merge on Microsoft technet. 

PS we can slightly improve the performance of both stored procedures by checking if an update is really necessary.  We can do this by comparing the price of the source with the price of the target table.  If the price is the same then we can skip the update.

Friday, July 5, 2013

iPod game programming.

Two of my kids bought an iPod touch and I was impressed with the display and how well the touch screen responded to finger movements.  I wanted one too!  So I bought myself a present (an iPod touch 4th generation) and thought it might be fun to learn how to program it.  I had an idea for a game with a Jetpac.

I installed Xcode, Apple's free development suite and chose Cocos 2D as the graphics library after reading some good reviews.  Cocos is great.  It's easy to use, robust and comes with great 2D support.  It even allows you to use a physics engine in your game but I wanted to keep things simple and chose not to include this.  After all, a flying Jetpac is not rocket science...

I've done some game programming before on the PC using Visual C++ and DirectX and I was very impressed with the simplicity and beauty of the Xcode editor and compiler.  It comes with a useful iPod simulator (so you can quickly test the game while you are coding) but creating games is much more rewarding when you can play them on a real iPod.

Unfortunately this is not possible unless you sign up for Apple's IOS Developer Program which costs EUR 80 per year.  Needless to say, I signed up.  Another benefit of the IOS Developer Program is that it allows you to submit your apps to the iTunes store (after Apple has checked it).

It was fun learning the Cocos 2D library and the dialect of C that Apple calls Objective C.  I now have the beginnings of an actual game.  It's a simple platform game called 'Jetpac Piggy' because I like Jetpacs (and piggies).  Some of the highlights are:

  • Parallax scrolling (background layers move at different speeds depending on how far away they're supposed to be - giving the impression of depth).
  • 5 levels (so far).
  • Realistic Jetpac thrust, created with a particle designer.
  • Simple controls.  If you tilt the iPod left, space-piggy will fly left, and tilting it to the right will err... make it fly to the left some more.  Wait!  I can fix this! 
  • There are 2 buttons.  One is for thrust, the other is for using one of the space shields.  Useful when you get too close to a space mine.
  • iPod graphics are fast.  60 frames per second with 2 full-screen, scrolling backgrounds and various sprites and particles is not a problem at all.
Here is a screenshot (apologies to NASA for the egg-shaped planet - lets just say the visuals are distorted by the strong gravitational field on this particular planet):


More to follow...