|
|||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
IntroductionThis is a C# implementation of JawBreaker, A free game shipped with Pocket PC 2003. BackgroundAfter playing Jawbreaker on my pocket pc for couple of days, I was having some issues with the program. One was it allowed only one Undo and the board had a fixed number of cells. I also wanted to play this game on my PC. So I decided to write the program in C#. I never programmed a game before. So I used this as a learning experience. The game has no AI and very simple to implement (Caution: It is very addictive). Using the codeThe zip file contains source code that was compiled for Visual Studio.NET 2003. Just open the solution file and compile it. The executable created is called JawBreaker.exe. You could play the game very easily. All you have to do is get as many similar cells together and then remove them (The more the cells, the higher the score). The first click selects the block of similar neighbor cells recursively. If you click anywhere on the selected block the entire block is removed. The objective of the game is to score as many points as possible. Program DesignThe program is organized into 3 classes:
Cell
int row;
int col;
int type;
public Cell(int row,int col,int type)
{
this.row=row;
this.col=col;
this.type=type;
}
BoardThe // Members of the Board class
private int rows;
private int cols;
private int types;
private Cell[,] data;
private ArrayList selected;
private Stack undoStack;
private Stack redoStack;
private int totalScore;
When cells are removed, those locations are set to be null. The above member variables explain the state of the game. The variable
The function //Selects the neighborhood Cells recursively
public void Select(Cell c)
{
selected.Add(c);
ArrayList arl=GetNeighborhoodCells(c);
if(arl.Count==0)
{
return;
}
foreach(Cell cell in arl)
{
if(cell.Type==c.Type&&!selected.Contains(cell))
{
Select(cell);
}
}
}
The function // Removes cells from the board
public void Remove(ArrayList arl)
{
if(arl.Count>0)
{
//Fist push the current data to Undo Stack
undoStack.Push(GetTypeArray());
//Clear the redo Stack..
redoStack.Clear();
foreach(Cell c in arl)
{
data[c.Row,c.Col]=null;
}
//Sync the board
Syncronize();
//update the score
totalScore+=GetScore(arl.Count);
}
}
The function public bool Undo()
{
if(undoStack.Count>0)
{
selected.Clear();
//Push to redo
int[,] current=GetTypeArray();
int[,] popped=(int[,])undoStack.Pop();
//update the scores
totalScore-=GetScore(
GetActiveCells(popped)-GetActiveCells(current));
redoStack.Push(current);
SetTypeArray(popped);
return true;
}
return false;
}
The function public bool Redo()
{
if(redoStack.Count>0)
{
selected.Clear();
int[,] current=GetTypeArray();
int[,] popped=(int[,])redoStack.Pop();
//update score
totalScore+=GetScore(GetActiveCells(
current)-GetActiveCells(popped));
//push current to undo
undoStack.Push(current);
//pop for redo stack
SetTypeArray(popped);
return true;
}
return false;
}
The function public void Initialize()
{
Random r=new Random();
for(int i=0;i<rows;i++)
{
for(int j=0;j<cols;j++)
{
data[i,j]=new Cell(i,j,r.Next(types));
}
}
totalScore=0;
undoStack.Clear();
redoStack.Clear();
selected.Clear();
}
The function //Checks if all the moves are finished
public bool GameFinished()
{
for(int i=0;i<rows;i++)
{
for(int j=0;j<cols;j++)
{
Cell c=data[i,j];
if(c!=null)
{
ArrayList arl=GetNeighborhoodCells(c);
foreach (Cell ce in arl)
{
if(c.Type==ce.Type)
return false;
}
}
}
}
return true;
}
MainForm
The public void DrawBall(Graphics grfx,Rectangle rect,Color c,bool Selected)
{
if(Selected)
{
grfx.FillRectangle(Brushes.Goldenrod,rect);
}
GraphicsPath path=new GraphicsPath();
path.AddEllipse(rect);
PathGradientBrush pgbrush= new PathGradientBrush(path);
pgbrush.CenterPoint=new Point((rect.Right- rect.Left)
/3+rect.Left,(rect.Bottom - rect.Top) /3+rect.Top);
pgbrush.CenterColor=Color.White;
pgbrush.SurroundColors=new Color[] { c };
grfx.FillRectangle(pgbrush,rect);
grfx.DrawEllipse(new Pen(c),rect);
}
The method public void DrawBoard(Graphics grfx)
{
//Do Double Buffering
Bitmap offScreenBmp;
Graphics offScreenDC;
offScreenBmp = new Bitmap(boardPanel.Width, boardPanel.Height);
offScreenDC = Graphics.FromImage(offScreenBmp);
offScreenDC.Clear(boardPanel.BackColor);
offScreenDC.SmoothingMode=SmoothingMode.AntiAlias;
int height=boardPanel.Height-1;
int width=boardPanel.Width-1;
int rectHeight=(int)Math.Round((double)height/b.Cols);
int rectWidth=(int)Math.Round((double)width/b.Rows);
int x=0;
int y=0;
ArrayList arl=b.Selected;
for(int i=0;i<b.Rows;i++)
{
x=0;
for(int j=0;j<b.Cols;j++)
{
Rectangle r=new Rectangle(x,y,rectWidth-2,rectHeight-2);
Cell c=b.Data[i,j];
if(c!=null)
{
if(arl.Contains(c))
{
DrawBall(offScreenDC,r,colors[c.Type],true);
}
else
{
DrawBall(offScreenDC,r,colors[c.Type],false);
}
}
else
{
//Do nothing
}
x+=rectWidth;
}
y+=rectHeight;
}
if(arl.Count>0)
{
//Select the first cell(The cell the user clicked on first)
Cell c=(Cell)arl[0];
//Calculate the x and y coordinates
int x1=c.Col*rectWidth;
int y1=c.Row*rectHeight;
//Show the Score..s
Rectangle scr=new Rectangle(x1,y1,30,30);
//offScreenDC.F
StringFormat sf=new StringFormat();
sf.Alignment=StringAlignment.Center;
sf.LineAlignment=StringAlignment.Center;
offScreenDC.DrawString(b.CurrentSelection.ToString(),
new Font("Arial",8,FontStyle.Bold),Brushes.Black,scr,sf);
}
grfx.DrawImageUnscaled(offScreenBmp, 0, 0);
}
User movesUser moves are handled by the private void boardPanel_MouseDown(object sender, MouseEventArgs e)
{
int x=e.X;
int y=e.Y;
int height=boardPanel.Height-1;
int width=boardPanel.Width-1;
int rectHeight=(int)Math.Round((double)height/b.Cols);
int rectWidth=(int)Math.Round((double)width/b.Rows);
int col=(int)x/rectWidth;
int row=(int)y/rectHeight;
ArrayList selected=b.Selected;
Cell currentCell=b.Data[row,col];
if(currentCell!=null)
{
if(selected.Contains(currentCell))
{
expectedScore.Text="Current Selection: 0";
b.Remove(selected);
UpdateScore();
}
else
{
b.Selected.Clear();
b.Select(currentCell);
expectedScore.Text="Current Selection: "+
GetScore(b.Selected.Count);
}
}
else
{
//He clicked on a null Cell -> Clear the selection
b.Selected.Clear();
expectedScore.Text="Current Selection: 0";
}
DrawBoard(boardPanel.CreateGraphics());
if(b.GameFinished())
{
if(MessageBox.Show(this,"Game Over!!. Your total Score was: "+
b.Score+"\nDo you want to Start a New Game?",
"JawBreaker",MessageBoxButtons.YesNo,
MessageBoxIcon.Exclamation)==DialogResult.Yes)
{
NewGame();
}
}
}
After every move it checks for Points of InterestI did a quick and dirty History
|
||||||||||||||||||||||||||||||||