C#版智能五子棋游戏(1)
C#版智能五子棋游戏(1) 看到zswang大牛组织的擂台赛,觉得挺有意思,不过随机性太强,现在来个稍复杂一点的,五子棋
[比赛规则]
1、五子连珠,可长连,无禁手,10分钟快棋
2、犯规(落在已有子的位置或多次落子)判输
3、比赛先手后手共五局,比分多的赢,若比分相同看赢局的时间总和,少的赢
4、赢得比赛的成为擂主,擂主可更新自己的代码
5、选手可以用以前的代码与新擂主打擂,不可以用相同的代码连续请求打擂
6、请求打擂请跟帖,以“请求打擂”为标题,帖上自己的代码,若代码较长,请给出下载地址
[机器人编写方法]
1、下载五子棋框架 http://download.csdn.net/source/430083
2、查看编写说明readme.cs
3、编写自己的玩家代码,编译成DLL文件与框架程序放在同一目录下,启动游戏,选择自己与对方的玩家,开始即可
[框架说明]
1、自己写的玩家类中不推荐使用多线程,线程由框架控制
2、您下载的代码中已经包含了三个已经实现的玩家,用户玩家由用户鼠标控制,一个简单的玩家和一个AI玩家
3、要框架源码的请与本人联系
4、由于本人在上班,会不定期上来看并给出打擂结果,希望有热心网友能够帮我来做这个工作
您可以实现IPlayer接口来完成机器人玩家
/// <summary>
/// 棋类游戏玩家接口,所有玩家必须实现本接口
/// 定义了初始化、通知落子,落子完成事件
/// </summary>
public interface IPlayer
{
/// <summary>
/// 落子事件,当需要落子时触发该事件
/// 当您认为需要进行落子时,您需要触发该事件,游戏引擎将设置该事件的处理程序,但在触发该事件时最好先判断是否为空
/// 你可以随时触发任意次本事件,但只有当DoChess方法被调用后(即游戏通知您可以进行落子)触发本事件是合法的,否则您将犯规
/// </summary>
event PutChessEventHandle PutChess;
/// <summary>
/// 玩家所执的棋类型
/// 您必须直接返回初始化时给您的棋类型
/// </summary>
ChessType ChessType { get; }
/// <summary>
/// 初始化玩家
/// </summary>
/// <param name="chessType">您所执的棋类型 </param>
void Init(ChessType chessType);
/// <summary>
/// 通知进行落子
/// 当对方玩家落子完成或由您开局等游戏引擎认为由您进行落子时将调用该方法
/// </summary>
/// <param name="chessData">通知您进行落子时的棋盘数据的副本 </param>
void DoChess(IChessData chessData);
}
或者继承BasePlayer类,只要重写DoChess方法,在适当的时候调用OnPutChess即可
这是一个最简单的机器人,作为原始擂主,抛砖引玉吧
using System;
using System.Collections.Generic;
using System.Text;
using QiuQiu.ChessEngine;
namespace MyPlayers
{
/// <summary>
/// 一个最简单的玩家类,随机落子
/// </summary>
[PlayerInfo(PlayerName = "SimplePlayer", Author = "QiuQiu", ModifyTime = "2008-4-23")]
public class SimplePlayer : BasePlayer
{
/// <summary>
/// 通知进行落子
/// </summary>
public override void DoChess(IChessData chessData)
{
Random rd = new Random(GetHashCode() + (int)DateTime.Now.Ticks);
int r = rd.Next(15);//随机行
int c = rd.Next(15);//随机列
if (!chessData.IsFull)
{
//棋盘未满
while (chessData.HasChess(new ChessPosition(r, c)))
{
//直至取到未落子的点
r = rd.Next(15);
c = rd.Next(15);
}
//执行落子
base.OnPutChess(r, c);
}
}
}
}
首先是ChessEngine程序集
IChessData 接口代码
IChessData 的实现 ChessData
IPlayer 接口,也就是玩家接口,打擂者要实现的接口,依赖于 IChessData
IPlayer实现基类BasePlayer
IChessEngine 接口,依赖于 IChessData和IPlayer
[比赛规则]
1、五子连珠,可长连,无禁手,10分钟快棋
2、犯规(落在已有子的位置或多次落子)判输
3、比赛先手后手共五局,比分多的赢,若比分相同看赢局的时间总和,少的赢
4、赢得比赛的成为擂主,擂主可更新自己的代码
5、选手可以用以前的代码与新擂主打擂,不可以用相同的代码连续请求打擂
6、请求打擂请跟帖,以“请求打擂”为标题,帖上自己的代码,若代码较长,请给出下载地址
[机器人编写方法]
1、下载五子棋框架 http://download.csdn.net/source/430083
2、查看编写说明readme.cs
3、编写自己的玩家代码,编译成DLL文件与框架程序放在同一目录下,启动游戏,选择自己与对方的玩家,开始即可
[框架说明]
1、自己写的玩家类中不推荐使用多线程,线程由框架控制
2、您下载的代码中已经包含了三个已经实现的玩家,用户玩家由用户鼠标控制,一个简单的玩家和一个AI玩家
3、要框架源码的请与本人联系
4、由于本人在上班,会不定期上来看并给出打擂结果,希望有热心网友能够帮我来做这个工作
您可以实现IPlayer接口来完成机器人玩家
/// <summary>
/// 棋类游戏玩家接口,所有玩家必须实现本接口
/// 定义了初始化、通知落子,落子完成事件
/// </summary>
public interface IPlayer
{
/// <summary>
/// 落子事件,当需要落子时触发该事件
/// 当您认为需要进行落子时,您需要触发该事件,游戏引擎将设置该事件的处理程序,但在触发该事件时最好先判断是否为空
/// 你可以随时触发任意次本事件,但只有当DoChess方法被调用后(即游戏通知您可以进行落子)触发本事件是合法的,否则您将犯规
/// </summary>
event PutChessEventHandle PutChess;
/// <summary>
/// 玩家所执的棋类型
/// 您必须直接返回初始化时给您的棋类型
/// </summary>
ChessType ChessType { get; }
/// <summary>
/// 初始化玩家
/// </summary>
/// <param name="chessType">您所执的棋类型 </param>
void Init(ChessType chessType);
/// <summary>
/// 通知进行落子
/// 当对方玩家落子完成或由您开局等游戏引擎认为由您进行落子时将调用该方法
/// </summary>
/// <param name="chessData">通知您进行落子时的棋盘数据的副本 </param>
void DoChess(IChessData chessData);
}
或者继承BasePlayer类,只要重写DoChess方法,在适当的时候调用OnPutChess即可
public abstract class BasePlayer : IPlayer
{
private ChessType _chessType;
/// <summary>
/// 落子事件,当需要落子时触发该事件
/// </summary>
public event PutChessEventHandle PutChess;
/// <summary>
/// 玩家所执的棋类型
/// </summary>
public ChessType ChessType { get { return _chessType; } }
/// <summary>
/// 初始化玩家
/// </summary>
/// <param name="chessData">棋盘数据 </param>
/// <param name="chessType">所执棋类型 </param>
public virtual void Init(ChessType chessType)
{
_chessType = chessType;
}
/// <summary>
/// 触发落子事件
/// </summary>
/// <param name="rowIndex">落子行位置 </param>
/// <param name="colIndex">落子列位置 </param>
protected void OnPutChess(int rowIndex, int colIndex)
{
if (PutChess != null)
{
PutChess(this, new PutChessEventArgs(new ChessPosition(rowIndex, colIndex)));
}
}
/// <summary>
/// 触发落子事件
/// </summary>
/// <param name="rowIndex">落子行位置 </param>
/// <param name="colIndex">落子列位置 </param>
protected void OnPutChess(ChessPosition chessPosition)
{
if (PutChess != null)
{
PutChess(this, new PutChessEventArgs(chessPosition));
}
}
/// <summary>
/// 通知进行落子
/// </summary>
public abstract void DoChess(IChessData chessData);
}
{
private ChessType _chessType;
/// <summary>
/// 落子事件,当需要落子时触发该事件
/// </summary>
public event PutChessEventHandle PutChess;
/// <summary>
/// 玩家所执的棋类型
/// </summary>
public ChessType ChessType { get { return _chessType; } }
/// <summary>
/// 初始化玩家
/// </summary>
/// <param name="chessData">棋盘数据 </param>
/// <param name="chessType">所执棋类型 </param>
public virtual void Init(ChessType chessType)
{
_chessType = chessType;
}
/// <summary>
/// 触发落子事件
/// </summary>
/// <param name="rowIndex">落子行位置 </param>
/// <param name="colIndex">落子列位置 </param>
protected void OnPutChess(int rowIndex, int colIndex)
{
if (PutChess != null)
{
PutChess(this, new PutChessEventArgs(new ChessPosition(rowIndex, colIndex)));
}
}
/// <summary>
/// 触发落子事件
/// </summary>
/// <param name="rowIndex">落子行位置 </param>
/// <param name="colIndex">落子列位置 </param>
protected void OnPutChess(ChessPosition chessPosition)
{
if (PutChess != null)
{
PutChess(this, new PutChessEventArgs(chessPosition));
}
}
/// <summary>
/// 通知进行落子
/// </summary>
public abstract void DoChess(IChessData chessData);
}
这是一个最简单的机器人,作为原始擂主,抛砖引玉吧
using System;
using System.Collections.Generic;
using System.Text;
using QiuQiu.ChessEngine;
namespace MyPlayers
{
/// <summary>
/// 一个最简单的玩家类,随机落子
/// </summary>
[PlayerInfo(PlayerName = "SimplePlayer", Author = "QiuQiu", ModifyTime = "2008-4-23")]
public class SimplePlayer : BasePlayer
{
/// <summary>
/// 通知进行落子
/// </summary>
public override void DoChess(IChessData chessData)
{
Random rd = new Random(GetHashCode() + (int)DateTime.Now.Ticks);
int r = rd.Next(15);//随机行
int c = rd.Next(15);//随机列
if (!chessData.IsFull)
{
//棋盘未满
while (chessData.HasChess(new ChessPosition(r, c)))
{
//直至取到未落子的点
r = rd.Next(15);
c = rd.Next(15);
}
//执行落子
base.OnPutChess(r, c);
}
}
}
}
首先是ChessEngine程序集
IChessData 接口代码
using System;
using System.Collections.Generic;
using System.Text;
namespace QiuQiu.ChessEngine
{
/// <summary>
/// 棋盘数据接口
/// 定义了取得棋子,设置棋子,判断是否有棋子,是否已满等
/// 适合用于二维落子型棋类数据,如果五子棋,黑白棋,围棋等
/// </summary>
public interface IChessData : ILookChessData
{
/// <summary>
/// 清空棋子数据
/// </summary>
void Clear();
/// <summary>
/// 设置指定位置的棋子
/// </summary>
/// <param name="chessPosition">棋子位置</param>
/// <param name="chessType">棋子类型</param>
void SetChess(ChessPosition chessPosition, ChessType chessType);
/// <summary>
/// 拷贝棋子数据
/// </summary>
/// <returns></returns>
IChessData Copy();
}
/// <summary>
/// 提供棋子数据的观察接口,不允许修改
/// </summary>
public interface ILookChessData
{
/// <summary>
/// 取得指定位置的棋子,不检查是否存在棋子
/// </summary>
/// <param name="chessPosition"></param>
/// <returns></returns>
ChessType GetChess(ChessPosition chessPosition);
/// <summary>
/// 取得指定位置的棋子
/// </summary>
/// <param name="chessPosition"></param>
/// <returns></returns>
ChessType GetChess(ChessPosition chessPosition, bool check);
/// <summary>
/// 取得指定位置是否存在棋子
/// </summary>
/// <param name="chessPosition"></param>
/// <returns></returns>
bool HasChess(ChessPosition chessPosition);
/// <summary>
/// 上一步棋
/// </summary>
ChessInfo LastChess { get; }
/// <summary>
/// 棋盘是否已满
/// </summary>
bool IsFull { get; }
/// <summary>
/// 棋盘行数
/// </summary>
int RowCount { get; }
/// <summary>
/// 棋盘列数
/// </summary>
int ColCount { get; }
/// <summary>
/// 棋子数量
/// </summary>
int ChessCount { get; }
}
}
using System.Collections.Generic;
using System.Text;
namespace QiuQiu.ChessEngine
{
/// <summary>
/// 棋盘数据接口
/// 定义了取得棋子,设置棋子,判断是否有棋子,是否已满等
/// 适合用于二维落子型棋类数据,如果五子棋,黑白棋,围棋等
/// </summary>
public interface IChessData : ILookChessData
{
/// <summary>
/// 清空棋子数据
/// </summary>
void Clear();
/// <summary>
/// 设置指定位置的棋子
/// </summary>
/// <param name="chessPosition">棋子位置</param>
/// <param name="chessType">棋子类型</param>
void SetChess(ChessPosition chessPosition, ChessType chessType);
/// <summary>
/// 拷贝棋子数据
/// </summary>
/// <returns></returns>
IChessData Copy();
}
/// <summary>
/// 提供棋子数据的观察接口,不允许修改
/// </summary>
public interface ILookChessData
{
/// <summary>
/// 取得指定位置的棋子,不检查是否存在棋子
/// </summary>
/// <param name="chessPosition"></param>
/// <returns></returns>
ChessType GetChess(ChessPosition chessPosition);
/// <summary>
/// 取得指定位置的棋子
/// </summary>
/// <param name="chessPosition"></param>
/// <returns></returns>
ChessType GetChess(ChessPosition chessPosition, bool check);
/// <summary>
/// 取得指定位置是否存在棋子
/// </summary>
/// <param name="chessPosition"></param>
/// <returns></returns>
bool HasChess(ChessPosition chessPosition);
/// <summary>
/// 上一步棋
/// </summary>
ChessInfo LastChess { get; }
/// <summary>
/// 棋盘是否已满
/// </summary>
bool IsFull { get; }
/// <summary>
/// 棋盘行数
/// </summary>
int RowCount { get; }
/// <summary>
/// 棋盘列数
/// </summary>
int ColCount { get; }
/// <summary>
/// 棋子数量
/// </summary>
int ChessCount { get; }
}
}
IChessData 的实现 ChessData
using System;
using System.Collections;
using System.Collections.Generic;
namespace QiuQiu.ChessEngine
{
/// <summary>
/// 棋子数据
/// </summary>
public class ChessData : IChessData
{
private int _rowCount;//棋行数
private int _colCount;//棋列数
private int _chessCount;//当前棋数
private ChessType[,] _chess;//棋子矩阵
private Stack<ChessInfo> _chessStep;//下棋历史
public event SetChessEventHandle SetChessing;
public event GetChessEventHandle GetChessing;
public ChessData() : this(15,15)
{
}
public ChessData(int rowCount,int colCount)
{
_rowCount = rowCount;
_colCount = colCount;
InitChessData();
}
/// <summary>
/// 初始化
/// </summary>
private void InitChessData()
{
_chess = new ChessType[_rowCount,_colCount];
for(int i = 0;i < _rowCount;i ++)
{
for(int j = 0;j < _colCount;j ++)
{
_chess[i,j] = ChessType.None;
}
}
_chessStep = new Stack<ChessInfo>();
_chessCount = 0;
}
/// <summary>
/// 清空棋子数据
/// </summary>
public void Clear()
{
InitChessData();
}
/// <summary>
/// 设置指定位置的棋子
/// </summary>
/// <param name="chessPosition"></param>
/// <param name="chessType"></param>
public void SetChess(ChessPosition chessPosition,ChessType chessType)
{
if(!HasChess(chessPosition))
{
if(chessPosition.RowIndex >= this._rowCount || chessPosition.ColIndex >= this._colCount)
return;
_chess[chessPosition.RowIndex,chessPosition.ColIndex] = chessType;
_chessStep.Push(new ChessInfo(chessPosition,chessType));
_chessCount ++;
//事件
if(SetChessing != null)
SetChessing(new SetChessEventArgs(chessPosition,chessType));
}
}
/// <summary>
/// 设置指定位置的棋子
/// </summary>
/// <param name="rowIndex"></param>
/// <param name="colIndex"></param>
/// <param name="chessType"></param>
public void SetChess(int rowIndex,int colIndex,ChessType chessType)
{
if(!HasChess(rowIndex,colIndex))
{
_chess[rowIndex,colIndex] = chessType;
_chessStep.Push(new ChessInfo(new ChessPosition(rowIndex,colIndex),chessType));
_chessCount ++;
//事件
if(SetChessing != null)
SetChessing(new SetChessEventArgs(rowIndex,colIndex,chessType));
}
}
/// <summary>
/// 取消上一次下棋动作
/// </summary>
public void UndoLastStep()
{
if(_chessStep.Count < 1)
return;
//取上一步
ChessInfo chess = (ChessInfo)_chessStep.Pop();
//设置位置为空
_chess[chess.ChessPosition.RowIndex, chess.ChessPosition.ColIndex] = ChessType.None;
_chessCount --;
//事件
if(SetChessing != null)
SetChessing(new SetChessEventArgs(chess.ChessPosition.RowIndex, chess.ChessPosition.ColIndex, ChessType.None));
}
/// <summary>
/// 取得指定位置的棋子
/// </summary>
/// <param name="rowIndex"></param>
/// <param name="colIndex"></param>
/// <returns></returns>
public ChessType GetChess(int rowIndex,int colIndex,bool check)
{
if(check)
{
if(!HasChess(rowIndex,colIndex))
{
throw new HasNoChessExceptions();
}
}
return GetChess(rowIndex,colIndex);
}
/// <summary>
/// 取得指定位置的棋子,不检查是否存在棋子不触发事件
/// </summary>
/// <param name="rowIndex"></param>
/// <param name="colIndex"></param>
/// <returns></returns>
public ChessType GetChess(int rowIndex,int colIndex)
{
return _chess[rowIndex,colIndex];
}
/// <summary>
/// 取得指定位置的棋子,不检查是否存在棋子
/// </summary>
/// <param name="chessPosition"></param>
/// <returns></returns>
public ChessType GetChess(ChessPosition chessPosition)
{
return GetChess(chessPosition.RowIndex,chessPosition.ColIndex);
}
/// <summary>
/// 取得指定位置的棋子
/// </summary>
/// <param name="chessPosition"></param>
/// <returns></returns>
public ChessType GetChess(ChessPosition chessPosition, bool check)
{
return GetChess(chessPosition.RowIndex, chessPosition.ColIndex,check);
}
/// <summary>
/// 取得指定位置是否存在棋子
/// </summary>
/// <param name="rowIndex"></param>
/// <param name="colIndex"></param>
/// <returns></returns>
public bool HasChess(int rowIndex,int colIndex)
{
if(rowIndex > _rowCount || colIndex > _colCount)
{
throw new IndexOutOfRangeExceptions();
}
try
{
return _chess[rowIndex,colIndex] != ChessType.None;
}
catch
{
return false;
}
}
/// <summary>
/// 取得指定位置是否存在棋子
/// </summary>
/// <param name="chessPosition"></param>
/// <returns></returns>
public bool HasChess(ChessPosition chessPosition)
{
return HasChess(chessPosition.RowIndex,chessPosition.ColIndex);
}
/// <summary>
/// 拷贝棋子数据
/// </summary>
/// <returns></returns>
public IChessData Copy()
{
ChessData chessData = new ChessData(this.RowCount,this.ColCount);
ChessType[,] chess = chessData.Chess;
for(int i = 0;i < RowCount;i ++)
{
for(int j = 0;j < ColCount;j ++)
{
chess[i,j] = _chess[i,j];
}
}
if(_chessStep.Count > 0)//只拷贝一步进去
chessData._chessStep.Push(_chessStep.Peek());
chessData._rowCount = _rowCount;
chessData._colCount = _colCount;
chessData._chessCount = _chessCount;
return (IChessData)chessData;
}
/// <summary>
/// 上一步棋
/// </summary>
public ChessInfo LastChess
{
get
{
if(_chessStep.Count > 0)
return (ChessInfo)_chessStep.Peek();
else
return new ChessInfo(new ChessPosition(0,0),ChessType.None);
}
}
/// <summary>
/// 棋子数据
/// </summary>
public ChessType[,] Chess
{
set
{
_chess = value;
}
get
{
return _chess;
}
}
/// <summary>
/// 棋子数
/// </summary>
public int ChessCount
{
get
{
return this._chessCount;
}
}
/// <summary>
/// 是否满
/// </summary>
public bool IsFull
{
get
{
return this._chessCount >= this._rowCount * this._colCount;
}
}
/// <summary>
/// 行数
/// </summary>
public int RowCount
{
get
{
return _rowCount;
}
}
/// <summary>
/// 列数
/// </summary>
public int ColCount
{
get
{
return _colCount;
}
}
}
}
using System.Collections;
using System.Collections.Generic;
namespace QiuQiu.ChessEngine
{
/// <summary>
/// 棋子数据
/// </summary>
public class ChessData : IChessData
{
private int _rowCount;//棋行数
private int _colCount;//棋列数
private int _chessCount;//当前棋数
private ChessType[,] _chess;//棋子矩阵
private Stack<ChessInfo> _chessStep;//下棋历史
public event SetChessEventHandle SetChessing;
public event GetChessEventHandle GetChessing;
public ChessData() : this(15,15)
{
}
public ChessData(int rowCount,int colCount)
{
_rowCount = rowCount;
_colCount = colCount;
InitChessData();
}
/// <summary>
/// 初始化
/// </summary>
private void InitChessData()
{
_chess = new ChessType[_rowCount,_colCount];
for(int i = 0;i < _rowCount;i ++)
{
for(int j = 0;j < _colCount;j ++)
{
_chess[i,j] = ChessType.None;
}
}
_chessStep = new Stack<ChessInfo>();
_chessCount = 0;
}
/// <summary>
/// 清空棋子数据
/// </summary>
public void Clear()
{
InitChessData();
}
/// <summary>
/// 设置指定位置的棋子
/// </summary>
/// <param name="chessPosition"></param>
/// <param name="chessType"></param>
public void SetChess(ChessPosition chessPosition,ChessType chessType)
{
if(!HasChess(chessPosition))
{
if(chessPosition.RowIndex >= this._rowCount || chessPosition.ColIndex >= this._colCount)
return;
_chess[chessPosition.RowIndex,chessPosition.ColIndex] = chessType;
_chessStep.Push(new ChessInfo(chessPosition,chessType));
_chessCount ++;
//事件
if(SetChessing != null)
SetChessing(new SetChessEventArgs(chessPosition,chessType));
}
}
/// <summary>
/// 设置指定位置的棋子
/// </summary>
/// <param name="rowIndex"></param>
/// <param name="colIndex"></param>
/// <param name="chessType"></param>
public void SetChess(int rowIndex,int colIndex,ChessType chessType)
{
if(!HasChess(rowIndex,colIndex))
{
_chess[rowIndex,colIndex] = chessType;
_chessStep.Push(new ChessInfo(new ChessPosition(rowIndex,colIndex),chessType));
_chessCount ++;
//事件
if(SetChessing != null)
SetChessing(new SetChessEventArgs(rowIndex,colIndex,chessType));
}
}
/// <summary>
/// 取消上一次下棋动作
/// </summary>
public void UndoLastStep()
{
if(_chessStep.Count < 1)
return;
//取上一步
ChessInfo chess = (ChessInfo)_chessStep.Pop();
//设置位置为空
_chess[chess.ChessPosition.RowIndex, chess.ChessPosition.ColIndex] = ChessType.None;
_chessCount --;
//事件
if(SetChessing != null)
SetChessing(new SetChessEventArgs(chess.ChessPosition.RowIndex, chess.ChessPosition.ColIndex, ChessType.None));
}
/// <summary>
/// 取得指定位置的棋子
/// </summary>
/// <param name="rowIndex"></param>
/// <param name="colIndex"></param>
/// <returns></returns>
public ChessType GetChess(int rowIndex,int colIndex,bool check)
{
if(check)
{
if(!HasChess(rowIndex,colIndex))
{
throw new HasNoChessExceptions();
}
}
return GetChess(rowIndex,colIndex);
}
/// <summary>
/// 取得指定位置的棋子,不检查是否存在棋子不触发事件
/// </summary>
/// <param name="rowIndex"></param>
/// <param name="colIndex"></param>
/// <returns></returns>
public ChessType GetChess(int rowIndex,int colIndex)
{
return _chess[rowIndex,colIndex];
}
/// <summary>
/// 取得指定位置的棋子,不检查是否存在棋子
/// </summary>
/// <param name="chessPosition"></param>
/// <returns></returns>
public ChessType GetChess(ChessPosition chessPosition)
{
return GetChess(chessPosition.RowIndex,chessPosition.ColIndex);
}
/// <summary>
/// 取得指定位置的棋子
/// </summary>
/// <param name="chessPosition"></param>
/// <returns></returns>
public ChessType GetChess(ChessPosition chessPosition, bool check)
{
return GetChess(chessPosition.RowIndex, chessPosition.ColIndex,check);
}
/// <summary>
/// 取得指定位置是否存在棋子
/// </summary>
/// <param name="rowIndex"></param>
/// <param name="colIndex"></param>
/// <returns></returns>
public bool HasChess(int rowIndex,int colIndex)
{
if(rowIndex > _rowCount || colIndex > _colCount)
{
throw new IndexOutOfRangeExceptions();
}
try
{
return _chess[rowIndex,colIndex] != ChessType.None;
}
catch
{
return false;
}
}
/// <summary>
/// 取得指定位置是否存在棋子
/// </summary>
/// <param name="chessPosition"></param>
/// <returns></returns>
public bool HasChess(ChessPosition chessPosition)
{
return HasChess(chessPosition.RowIndex,chessPosition.ColIndex);
}
/// <summary>
/// 拷贝棋子数据
/// </summary>
/// <returns></returns>
public IChessData Copy()
{
ChessData chessData = new ChessData(this.RowCount,this.ColCount);
ChessType[,] chess = chessData.Chess;
for(int i = 0;i < RowCount;i ++)
{
for(int j = 0;j < ColCount;j ++)
{
chess[i,j] = _chess[i,j];
}
}
if(_chessStep.Count > 0)//只拷贝一步进去
chessData._chessStep.Push(_chessStep.Peek());
chessData._rowCount = _rowCount;
chessData._colCount = _colCount;
chessData._chessCount = _chessCount;
return (IChessData)chessData;
}
/// <summary>
/// 上一步棋
/// </summary>
public ChessInfo LastChess
{
get
{
if(_chessStep.Count > 0)
return (ChessInfo)_chessStep.Peek();
else
return new ChessInfo(new ChessPosition(0,0),ChessType.None);
}
}
/// <summary>
/// 棋子数据
/// </summary>
public ChessType[,] Chess
{
set
{
_chess = value;
}
get
{
return _chess;
}
}
/// <summary>
/// 棋子数
/// </summary>
public int ChessCount
{
get
{
return this._chessCount;
}
}
/// <summary>
/// 是否满
/// </summary>
public bool IsFull
{
get
{
return this._chessCount >= this._rowCount * this._colCount;
}
}
/// <summary>
/// 行数
/// </summary>
public int RowCount
{
get
{
return _rowCount;
}
}
/// <summary>
/// 列数
/// </summary>
public int ColCount
{
get
{
return _colCount;
}
}
}
}
IPlayer 接口,也就是玩家接口,打擂者要实现的接口,依赖于 IChessData
using System;
using System.Collections.Generic;
using System.Text;
namespace QiuQiu.ChessEngine
{
/// <summary>
/// 棋类游戏玩家接口,所有玩家必须实现本接口
/// 定义了初始化、通知落子,落子完成事件
/// </summary>
public interface IPlayer
{
/// <summary>
/// 落子事件,当需要落子时触发该事件
/// 当您认为需要进行落子时,您需要触发该事件,游戏引擎将设置该事件的处理程序,但在触发该事件时最好先判断是否为空
/// 你可以随时触发任意次本事件,但只有当DoChess方法被调用后(即游戏通知您可以进行落子)触发本事件是合法的,否则您将犯规
/// </summary>
event PutChessEventHandle PutChess;
/// <summary>
/// 玩家所执的棋类型
/// 您必须直接返回初始化时给您的棋类型
/// </summary>
ChessType ChessType { get; }
/// <summary>
/// 初始化玩家
/// </summary>
/// <param name="chessType">您所执的棋类型</param>
void Init(ChessType chessType);
/// <summary>
/// 通知进行落子
/// 当对方玩家落子完成或由您开局等游戏引擎认为由您进行落子时将调用该方法
/// </summary>
/// <param name="chessData">通知您进行落子时的棋盘数据的副本</param>
void DoChess(IChessData chessData);
}
}
using System.Collections.Generic;
using System.Text;
namespace QiuQiu.ChessEngine
{
/// <summary>
/// 棋类游戏玩家接口,所有玩家必须实现本接口
/// 定义了初始化、通知落子,落子完成事件
/// </summary>
public interface IPlayer
{
/// <summary>
/// 落子事件,当需要落子时触发该事件
/// 当您认为需要进行落子时,您需要触发该事件,游戏引擎将设置该事件的处理程序,但在触发该事件时最好先判断是否为空
/// 你可以随时触发任意次本事件,但只有当DoChess方法被调用后(即游戏通知您可以进行落子)触发本事件是合法的,否则您将犯规
/// </summary>
event PutChessEventHandle PutChess;
/// <summary>
/// 玩家所执的棋类型
/// 您必须直接返回初始化时给您的棋类型
/// </summary>
ChessType ChessType { get; }
/// <summary>
/// 初始化玩家
/// </summary>
/// <param name="chessType">您所执的棋类型</param>
void Init(ChessType chessType);
/// <summary>
/// 通知进行落子
/// 当对方玩家落子完成或由您开局等游戏引擎认为由您进行落子时将调用该方法
/// </summary>
/// <param name="chessData">通知您进行落子时的棋盘数据的副本</param>
void DoChess(IChessData chessData);
}
}
IPlayer实现基类BasePlayer
using System;
using System.Collections.Generic;
using System.Text;
namespace QiuQiu.ChessEngine
{
public abstract class BasePlayer : IPlayer
{
private ChessType _chessType;
/// <summary>
/// 落子事件,当需要落子时触发该事件
/// </summary>
public event PutChessEventHandle PutChess;
/// <summary>
/// 玩家所执的棋类型
/// </summary>
public ChessType ChessType { get { return _chessType; } }
/// <summary>
/// 初始化玩家
/// </summary>
/// <param name="chessData">棋盘数据</param>
/// <param name="chessType">所执棋类型</param>
public virtual void Init(ChessType chessType)
{
_chessType = chessType;
}
/// <summary>
/// 触发落子事件
/// </summary>
/// <param name="rowIndex">落子行位置</param>
/// <param name="colIndex">落子列位置</param>
protected void OnPutChess(int rowIndex, int colIndex)
{
if (PutChess != null)
{
PutChess(this, new PutChessEventArgs(new ChessPosition(rowIndex, colIndex)));
}
}
/// <summary>
/// 触发落子事件
/// </summary>
/// <param name="rowIndex">落子行位置</param>
/// <param name="colIndex">落子列位置</param>
protected void OnPutChess(ChessPosition chessPosition)
{
if (PutChess != null)
{
PutChess(this, new PutChessEventArgs(chessPosition));
}
}
/// <summary>
/// 通知进行落子
/// </summary>
public abstract void DoChess(IChessData chessData);
}
}
using System.Collections.Generic;
using System.Text;
namespace QiuQiu.ChessEngine
{
public abstract class BasePlayer : IPlayer
{
private ChessType _chessType;
/// <summary>
/// 落子事件,当需要落子时触发该事件
/// </summary>
public event PutChessEventHandle PutChess;
/// <summary>
/// 玩家所执的棋类型
/// </summary>
public ChessType ChessType { get { return _chessType; } }
/// <summary>
/// 初始化玩家
/// </summary>
/// <param name="chessData">棋盘数据</param>
/// <param name="chessType">所执棋类型</param>
public virtual void Init(ChessType chessType)
{
_chessType = chessType;
}
/// <summary>
/// 触发落子事件
/// </summary>
/// <param name="rowIndex">落子行位置</param>
/// <param name="colIndex">落子列位置</param>
protected void OnPutChess(int rowIndex, int colIndex)
{
if (PutChess != null)
{
PutChess(this, new PutChessEventArgs(new ChessPosition(rowIndex, colIndex)));
}
}
/// <summary>
/// 触发落子事件
/// </summary>
/// <param name="rowIndex">落子行位置</param>
/// <param name="colIndex">落子列位置</param>
protected void OnPutChess(ChessPosition chessPosition)
{
if (PutChess != null)
{
PutChess(this, new PutChessEventArgs(chessPosition));
}
}
/// <summary>
/// 通知进行落子
/// </summary>
public abstract void DoChess(IChessData chessData);
}
}
IChessEngine 接口,依赖于 IChessData和IPlayer
using System;
using System.Collections.Generic;
using System.Text;
namespace QiuQiu.ChessEngine
{
/// <summary>
/// 棋类游戏引擎
/// 适用于双人对弈棋类游戏
/// </summary>
public interface IChessEngine : IDisposable
{
/// <summary>
/// 棋盘数据改变事件
/// </summary>
event EventHandler DataChange;
/// <summary>
/// 玩家交换事件
/// </summary>
event EventHandler PlayerChange;
/// <summary>
/// 事件触发事件
/// </summary>
event EngineEventHandle EventFire;
/// <summary>
/// 棋盘数据
/// </summary>
IChessData ChessData { get; }
/// <summary>
/// 玩家一
/// </summary>
IPlayer Plyer1 { get; set; }
/// <summary>
/// 玩家二
/// </summary>
IPlayer Plyer2 { get; set; }
/// <summary>
/// 当前玩家
/// </summary>
IPlayer CurrentPlayer { get; }
/// <summary>
/// 计时器
/// </summary>
ChessTimer Timer { get; }
/// <summary>
/// 时间限制
/// </summary>
TimeSpan TimeLimit { get; set; }
/// <summary>
/// 开始对弈
/// </summary>
void Start();
/// <summary>
/// 停止
/// </summary>
void Stop();
}
}
using System.Collections.Generic;
using System.Text;
namespace QiuQiu.ChessEngine
{
/// <summary>
/// 棋类游戏引擎
/// 适用于双人对弈棋类游戏
/// </summary>
public interface IChessEngine : IDisposable
{
/// <summary>
/// 棋盘数据改变事件
/// </summary>
event EventHandler DataChange;
/// <summary>
/// 玩家交换事件
/// </summary>
event EventHandler PlayerChange;
/// <summary>
/// 事件触发事件
/// </summary>
event EngineEventHandle EventFire;
/// <summary>
/// 棋盘数据
/// </summary>
IChessData ChessData { get; }
/// <summary>
/// 玩家一
/// </summary>
IPlayer Plyer1 { get; set; }
/// <summary>
/// 玩家二
/// </summary>
IPlayer Plyer2 { get; set; }
/// <summary>
/// 当前玩家
/// </summary>
IPlayer CurrentPlayer { get; }
/// <summary>
/// 计时器
/// </summary>
ChessTimer Timer { get; }
/// <summary>
/// 时间限制
/// </summary>
TimeSpan TimeLimit { get; set; }
/// <summary>
/// 开始对弈
/// </summary>
void Start();
/// <summary>
/// 停止
/// </summary>
void Stop();
}
}
转自csdn:http://topic.csdn.net/u/20080425/12/4bbb0f82-f963-4743-ac0e-f806333ac5f9.html
版权声明:本文为开发框架文库发布内容,转载请附上原文出处连接
NewDoc C/S框架网