C# Source Code GameLogic.cs
using System;
using System.Drawing;
// The Slide Puzzle game logic uses a grid of cells to determine moves. For example,
// when grid cell 0 is the empty block, only the blocks in grid cells 1 or 3
// can trade places.
//      --------------	    --------------
//     | 0  | 1  | 2  |    |XXXX| 1  |    |
//     |    |    |    |    |XXXX|    |    |
//      --------------	    --------------
//     | 3  | 4  | 5  |    | 3  |    |    |
//     |    |    |    |    |    |    |    |
//      --------------	    --------------
//     | 6  | 7  | 8  |    |    |    |    |
//     |    |    |    |    |    |    |    |
//      --------------	    --------------
public class GameLogic
{
	private Random rNumber = new Random(unchecked((int)DateTime.Now.Ticks));
	private int CurrentState = 0;
	private int XOffset = 0;
	private int YOffset = 0;
	private int BlockWidth = 0;
	private int BlockHeight = 0;
	
	// Using a 3x3 grid system, list valid moves for each grid cell
	private int[][] Moves = new int [][] 
						{
							new int[] {1, 3},
							new int[] {0, 2, 4},
							new int[] {1, 5},
							new int[] {0, 4, 6},
							new int[] {1, 3, 5, 7},
							new int[] {2, 4, 8},
							new int[] {3, 7},
							new int[] {4, 6, 8},
							new int[] {5, 7}
						};
		
	// Set game state variables to attributes of the blocks
	public GameLogic(int x, int y, int width, int height)
	{
		XOffset = x;
		YOffset = y;
		BlockWidth = width;
		BlockHeight = height;
	}
	// Determine if the move is valid based on x:y coordinate
	public bool IsGoodMove(Point p)
	{
		int x = (p.X - XOffset) / BlockWidth;
		int y = (p.Y - XOffset) / BlockHeight;
		int gridLocation = x + (y * 3);
		// Test if the grid cell of desired move matches valid grid cell
		for (int i = 0; i < Moves[CurrentState].Length; i++)
		{
			if (gridLocation == Moves[CurrentState][i])
			{
				CurrentState = gridLocation;
				return true;
			}
		}
		return false;
	}
	// Generate a valid random move
	public int SetRandomMove()
	{
		int iMove = rNumber.Next(Moves[CurrentState].Length);
		CurrentState = Moves[CurrentState][iMove];
		return CurrentState;
	}
	// Dermine which grid the x:y coordinate is in
	public int GetBlockOrder(Point p)
	{
		int x = (p.X - XOffset) / BlockWidth;
		int y = (p.Y - XOffset) / BlockHeight;
		return x + (y * 3);
	}
}