|
using System;
namespace gma.Mobile.Mines
{
public enum Player
{
None = 0,
Red = 1,
Blue = 2
}
public delegate void OnCellChangedEvent(byte x, byte y);
public delegate void OnGameOverEvent(Player TheWinner);
public delegate void OnFlagSetEvent(byte x, byte y);
public interface IGame
{
event OnCellChangedEvent OnCellChanged;
event OnGameOverEvent OnGameOver;
void Restart();
void ClickCell(byte x, byte y);
void SetFlag(byte x, byte y);
Field GetField();
bool IsGameOver();
byte GetLastX();
byte GetLastY();
bool IsMultiplayer();
}
public abstract class GameBase:IGame
{
#region Events
/// <summary>
/// This event occures when a cell was chenged.
/// </summary>
public event OnCellChangedEvent OnCellChanged;
/// <summary>
/// This event occures when the geme is over. Loose or win.
/// </summary>
public event OnGameOverEvent OnGameOver;
//public event OnFlagSetEvent OnFlagSet;
#endregion
/// <summary>
/// An underlaying field.
/// </summary>
protected Field _field;
public Field GetField()
{
return _field;
}
public GameBase(byte aWidth, byte aHeight, byte aBombCount)
{
_field=new Field(aWidth, aHeight, aBombCount);
Restart();
}
public GameBase(ref Field aField)
{
_field=aField;
Restart();
}
public bool IsMultiplayer()
{
return (this is MultiPlayerGame);
}
private Player _currentPlayer=Player.Red;
public Player CurrentPlayer
{
get {return _currentPlayer;}
set {_currentPlayer=value;}
}
public CellState GetFlagColorOfCurrentPlayer()
{
if (CurrentPlayer==Player.Blue) return CellState.FlagBlue;
else return CellState.FlagRed;
}
private int _closedCount=0;
public int ClosedCount
{
get {return _closedCount;}
set {_closedCount=value;}
}
private int _flagCountRed=0;
public int FlagCountRed
{
get {return _flagCountRed;}
}
private int _flagCountBlue=0;
public int FlagCountBlue
{
get {return _flagCountBlue;}
}
public int FlagCount
{
get {return _flagCountBlue+_flagCountRed;}
}
public void Restart()
{
_currentPlayer=Player.Red;
_field.Init();
_flagCountBlue=0;
_flagCountRed=0;
ClosedCount = _field.Width * _field.Height;
}
protected void GameOver(Player TheWinner)
{
_currentPlayer=Player.None;
if (OnGameOver!=null) OnGameOver(TheWinner);
}
public bool IsGameOver()
{
return (_currentPlayer==Player.None);
}
private byte _lastX=0;
public byte GetLastX() {return _lastX;}
private byte _lastY=0;
public byte GetLastY() {return _lastY;}
public virtual void ClickCell(byte x, byte y)
{
_lastX=x;
_lastY=y;
ClickCellIntern(x,y);
}
/// <summary>
/// Opens a cell and area around it when there is no mine under it.
/// </summary>
/// <param name="x">Horizontale coordinate.</param>
/// <param name="y">Vertical coordinate.</param>
/// <param name="Probably">true - when the cell must be only marked and not opened.</param>
private void ClickCellIntern(byte x, byte y)
{
if (CurrentPlayer==Player.None) return;
// when the cell was already opened then do nothing
if (_field.CellStates[x,y]==CellState.Open) return;
CellState BeforeState = _field.CellStates[x,y];
//open it
_field.CellStates[x,y]=CellState.Open;
// inform others that this cell was modified.
CellChanged(x,y, BeforeState, _field.CellStates[x,y]);
// the cell is empty open it recursively
if (_field.Bombs[x,y]==0) ClickOnEmptyCell(x,y);
}
public void CellChanged(byte x, byte y, CellState BeforeState, CellState AfterState)
{
if (BeforeState==AfterState) return;
if (AfterState==CellState.Open) ClosedCount--;
if (AfterState==CellState.FlagRed) _flagCountRed++;
if (BeforeState==CellState.FlagRed && AfterState==CellState.Closed) _flagCountRed--;
if (AfterState==CellState.FlagBlue) _flagCountBlue++;
if (BeforeState==CellState.FlagBlue && AfterState==CellState.Closed) _flagCountBlue--;
if (OnCellChanged!=null) OnCellChanged(x,y);
}
public abstract void SetFlag(byte x, byte y);
private void ClickOnEmptyCell(byte x, byte y)
{
// when the counter is 0 im means the cell is empty
if (_field.Bombs[x,y]==0)
// all neighbour cells must be also recursively opened
for(int i=-1; i<=1; i++)
for(int j=-1; j<=1; j++)
if (!((x+i<1) || (y+j<1) || (x+i>_field.Width) || (y+j>_field.Height) ))
// recursion
ClickCellIntern((byte)(x+i),(byte)(y+j));
}
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.