Friday, July 18, 2008

Mahjong! My favorite game

[ Updated for Silverlight 2]

Mahjong has been my favorite game since the days I started using Linux (SUSE 10.2). I just tried and made "Something" (Play it full screen. F11). So I can play my favorite game in my off time. Of course it was again with Silverlight. Now here is the explanation and logic used to make this game.



Page has 4 grids each with 15x9 dimension. So ultimately it gives the impression of a 3D stack. Each cell (total 15x9x4 cells) can be filled with a tile or left empty. The grids are been filled with tiles such a way it looks like a nice structure. In this structure 4th grid (I am calling as 4th rank) is empty. There are total 144 tiles. There are 12 types of tiles.


Each Tile is a user control. It has two canvases with rounded corner rectangles to make the nice 3D effect.

On the top canvas there are two rectangles. One for holding the tile image, another one to have mouse over effect.(Yellow one).

Each tile has 4 types of animations associated with it. (ClickAnimation, ClickOutAnimation, MouseOverAnimation, NotMatch). Click out animation will happen if user clicks the same tile twice. Not mach animation will happen when user tries to match wrong set of tiles.

Each tile has one TileNumber that determines the image to be put in the tile and it also helps in finding match.

Algorithm and code


Each tile is having four variables associated with it.

TileNumber- Used to find match.

TilePosition- Gives rank, row and column in a 3 dimensional structure.

ParentPage- A reference to the Page class so it can call its methods.

IsClicked- Tells if the tile has already been clicked

Before starting any animation it will call its ParentPage method CheckIfFree to see if the tile is free.

On click of the tile after confirming it is free It will again call another parent page method TileClicked. This method will try to match this current tile with the previous tile clicked. If it matches It will destroy two tiles or it will show the NotMatch animation.

The constructor of this user control takes a random number from Page and set the tile image accordingly.

Main Page and logic:

In the Page there are 4 grids (4th one is empty in this tile structure I am now using).

First I am making the look of the board with a 3 dimensional array. Each element of that array represents empty or occupied state in boolean.

After making the grid structure I am adding tiles which are marked occupied.

In making the tiles for each tile GetTileNumber method returns one random number between 0 to 11 and it returns such a way that every number will be for 12 times making total 144 tiles.

This is the tile number used generally and I am also using for my game.

int[] TileTypeCount;
TileTypeCount = new int[12];

private int GetTileNumber()
int tileNo;
tileNo = rnd.Next(12);
} while (TileTypeCount[tileNo] >= 12);

return tileNo;

Filling tiles for the fast grid. Lowest level

// for set 1 rank 0
for (int row = MaxRow - 1; row >= 0; row--)
for (int col = 0; col < MaxCol; col++)
if (TileGridStructure[0, row, col]) continue;
TileStructure tile = new TileStructure(GetTileNumber(), this, new Position(0, row, col));
Grid.SetRow(tile, row);
Grid.SetColumn(tile, col);
TileCollection[0, row, col] = tile;

TileGridStructure tells if this place is to be filled with a tile or not.

Here you will find the complete source code.

Bye for now. Please leave a comment if you have any doubt or correction.

No comments: