解决方案 »
- 怎么实现winform 更新功能,谢谢大家
- VS2010 beta2 或 正式版 要什么才会发行呢,估计 还有express版本
- 反射问题
- 无边框窗口 用GDI 画背景 窗口拖动放大时总有黑边,如何去掉黑边??
- 请高手指点:用命令CSC来编译C#类的方法
- 在启动客户端VSS时,出现Access to file "rights.dat" denied信息,如何解决这个问题
- Socket的在大数据量时出现10048(应该是地址重复绑定的错)错误??
- SMS\obj\x86\Debug 文件夹下是什么?
- 如何将datagrid中的一行数据隐藏起来?
- 我的.net里有同时访问 oracle 和 sqlserver 的代码,每次运行访问 oracle 的程序后, iis 便会陷入瘫痪。请问这是为什么?
- DirectShowLib 无法初始化摄像头
- C# 中关于Settings.settings 的问题
/// <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);
}
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;
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);
}
} }
}
有时间有能力的时候攻一下擂
[email protected]
个人觉得这个贴人气高不起来,原因主要有两点
第一个,这个程序难度教先的高,涉及算法问题。
第二个,搂主没提供框架的源码,这个不合理,
之前的擂台赛大家关注的理由就是开源,建立工程和实现接口简单,只用复制粘贴就可以了,这个接口比那个复杂,不是我们实现不了,而是不想那么麻烦。
如果说提供一个完整的工程,直接打开那还可以,让我们自己弄,还是算了。而且最关键的,SimplePlayer 这个机器人更本就是一个傻子,对我们实现擂台没有实际价值。而另一个聪明的机器人你又不给源码,这不是明摆着下套儿吗!建议如同前一个项目,提供搂主的实现过程,否则便没有擂台的意义了
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;
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;
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;
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;
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;
using System.Collections.Generic;
using System.Text;
using System.Threading;namespace QiuQiu.ChessEngine
{
/// <summary>
/// 游戏引擎
/// </summary>
public class ChessEngine : IChessEngine
{
#region private fields
private IPlayer _plyer1;//玩家1
private IPlayer _plyer2;//玩家2
private IPlayer _currentPlayer;//当前玩家
private IChessData _chessData;//棋子数据
private Thread _doChessThread;//下棋线程
private IChessLogic _chessLogic;//下棋逻辑
private ChessTimer _timer;//计时器
private TimeSpan _timeLimit = TimeSpan.FromMinutes(10); private bool _disposed = false; /// <summary>
/// 数据变化时触发该事件
/// </summary>
public event EventHandler DataChange;
/// <summary>
/// 当前玩家改变时触发该事件
/// </summary>
public event EventHandler PlayerChange;
/// <summary>
/// 其他事件发生时触发该事件
/// </summary>
public event EngineEventHandle EventFire; public TimeSpan TimeLimit
{
get { return _timeLimit; }
set { _timeLimit = value; }
} /// <summary>
/// 计时器
/// </summary>
public ChessTimer Timer
{
get { return _timer; }
} /// <summary>
/// 获取棋子数据的副本
/// </summary>
public IChessData ChessData
{
get { return _chessData.Copy(); }
} /// <summary>
/// 玩家1
/// </summary>
public IPlayer Plyer1
{
get { return _plyer1; }
set { _plyer1 = value; }
} /// <summary>
/// 列家2
/// </summary>
public IPlayer Plyer2
{
get { return _plyer2; }
set { _plyer2 = value; }
} /// <summary>
/// 当前玩家
/// </summary>
public IPlayer CurrentPlayer
{
get { return _currentPlayer; }
}
#endregion /// <summary>
/// 构造方法
/// </summary>
public ChessEngine()
{
_chessData = new ChessData();
_timer = new ChessTimer();
_timer.Elapsed += new ChessTimerElapsed(_timer_Elapsed);
} /// <summary>
/// 开始
/// </summary>
public void Start()
{
if (_plyer1 == null || _plyer2 == null)
{
return;
}
_chessData = new ChessData();
_chessLogic = new ChessLogic();
_plyer1.Init(ChessType.Black);
_plyer2.Init(ChessType.White);
_currentPlayer = _plyer1;
_plyer1.PutChess += new PutChessEventHandle(plyerPutChess);
_plyer2.PutChess += new PutChessEventHandle(plyerPutChess); _timer.Start(ChessType.Black);
_doChessThread = new Thread(new ThreadStart(StartDoChess));
_doChessThread.Start(); //DoChess(_plyer1);
} /// <summary>
/// 停止
/// </summary>
public void Stop()
{
StopTimer();
StopThread();
} /// <summary>
/// 停止计时器
/// </summary>
private void StopTimer()
{
if(_timer != null)
_timer.Stop();
} /// <summary>
/// 停止线程
/// </summary>
private void StopThread()
{
if (_doChessThread != null)
{
if (_doChessThread.ThreadState != ThreadState.Stopped)
{
try
{
_doChessThread.IsBackground = true;
_doChessThread.Abort();
}
catch (Exception ep)
{
string t = ep.Message;
}
finally
{
_doChessThread.Join(5000);
}
}
}
}
/// 当一家放下棋子事件处理程序
/// </summary>
/// <param name="sender"></param>
/// <param name="args"></param>
private void plyerPutChess(IPlayer sender, PutChessEventArgs args)
{
if (_currentPlayer != sender)
{
//没轮他该玩家,犯规
StopTimer();
FireEvents(EventType.Illegality);
StopThread();
return;
}
if (args.TheChessPosition.ColIndex < 0 || args.TheChessPosition.ColIndex >= 15 || args.TheChessPosition.RowIndex < 0 || args.TheChessPosition.RowIndex >= 15)
{
//不在范围内
StopTimer();
FireEvents(EventType.Illegality);
StopThread();
return;
}
if (_chessData.HasChess(args.TheChessPosition))
{
//这里已经有棋子了,犯规
StopTimer();
FireEvents(EventType.Illegality);
StopThread();
return;
}
//落子
_chessLogic.PutChess(ref _chessData, new ChessInfo(args.TheChessPosition, sender.ChessType));
if (DataChange != null)
{
DataChange(this, EventArgs.Empty);
}
//检查是否赢
ChessType whoWin = _chessLogic.TestWin(_chessData);
if (whoWin == ChessType.Black)
{
StopTimer();
FireEvents(EventType.BlackWin);
StopThread();
return;
}
if (whoWin == ChessType.White)
{
StopTimer();
FireEvents(EventType.WhiteWin);
StopThread();
return;
}
//检查是否是平局
if (_chessLogic.TestDogfall(_chessData))
{
StopTimer();
FireEvents(EventType.DataFull);
StopThread();
return;
} //对方下棋
try
{
DoChess(sender == _plyer1 ? _plyer2 : _plyer1);
}
catch (ThreadAbortException ep)
{
}
catch (Exception ep)
{
string t = ep.Message;
StopTimer();
StopThread();
FireEvents(EventType.Exceptions, ep.Message);
}
} /// <summary>
/// 下子
/// </summary>
/// <param name="player"></param>
private void DoChess(IPlayer player)
{
_currentPlayer = player;
if (PlayerChange != null)
PlayerChange(this, EventArgs.Empty);
_timer.Tick(_currentPlayer.ChessType);
_currentPlayer.DoChess(ChessData);
} /// <summary>
/// 开始下子
/// </summary>
private void StartDoChess()
{
DoChess(_plyer1);
} /// <summary>
/// 计时器事件处理程序
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void _timer_Elapsed(object sender, ChessTimerEventArgs e)
{
//判断是否超时
if (_timeLimit.Ticks > 0)
{
if (e.BlackPlayer > _timeLimit)
{
Stop();
FireEvents(EventType.WhiteWin);
}
if (e.WhitePlayer > _timeLimit)
{
Stop();
FireEvents(EventType.BlackWin);
}
}
} /// <summary>
/// 触发一个其他事件
/// </summary>
/// <param name="eventType"></param>
private void FireEvents(EventType eventType)
{
if (EventFire != null)
EventFire(this, new EngineEventArgs(this, eventType));
} /// <summary>
/// 触发一个其他事件
/// </summary>
/// <param name="eventType"></param>
/// <param name="message"></param>
private void FireEvents(EventType eventType, string message)
{
if (EventFire != null)
EventFire(this, new EngineEventArgs(this, eventType, message));
} protected virtual void Dispose(bool disposing)
{
if (_disposed)
return;
if (disposing)
{
// TODO: 此处释放受控资源
if (_timer != null)
{
_timer.Stop();
_timer.Dispose();
_timer = null;
StopThread();
}
}
// TODO: 此处释放所有受控资源 _disposed = true;
} ~ChessEngine()
{
Dispose(false);
} public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
}
using System;
using System.Collections.Generic;
using System.Text;namespace QiuQiu.ChessEngine
{
/// <summary>
/// 棋类游戏逻辑接口
/// </summary>
public interface IChessLogic
{
/// <summary>
/// 测试是否某一方赢棋
/// </summary>
/// <param name="chessData"></param>
/// <returns></returns>
ChessType TestWin(IChessData chessData); /// <summary>
/// 测试是否是平局
/// </summary>
/// <param name="chessData"></param>
/// <returns></returns>
bool TestDogfall(IChessData chessData); /// <summary>
/// 落子逻辑,在某一点落子后的逻辑
/// </summary>
/// <param name="chessData"></param>
/// <param name="chessInfo"></param>
void PutChess(ref IChessData chessData, ChessInfo chessInfo);
}
}
using System;
using System.Collections.Generic;
using System.Text;namespace QiuQiu.ChessEngine
{
/// <summary>
/// 棋类游戏逻辑
/// </summary>
public class ChessLogic : IChessLogic
{
/// <summary>
/// 判断是否是某一方赢棋
/// </summary>
/// <param name="chessData"></param>
/// <returns></returns>
public ChessType TestWin(IChessData chessData)
{
if (chessData.ChessCount < 9)
return ChessType.None;
int seriesNum = 0;//某个子连续出现的个数
ChessType nowChess = ChessType.None;
//遍历列
for (int rowIndex = 0; rowIndex < chessData.RowCount; rowIndex++)
{
for (int colIndex = 0; colIndex < chessData.ColCount; colIndex++)
{
ChessType currentChess = chessData.GetChess(new ChessPosition(rowIndex, colIndex));
if (currentChess == ChessType.None)
{
nowChess = currentChess;
seriesNum = 0;
}
else if (currentChess == nowChess)
{
seriesNum++;
if (seriesNum >= 5)
{
return currentChess;
}
}
else
{
nowChess = currentChess;
seriesNum = 1;
}
}
nowChess = ChessType.None;
seriesNum = 0;
}
//遍历行
for (int colIndex = 0; colIndex < chessData.ColCount; colIndex++)
{
for (int rowIndex = 0; rowIndex < chessData.RowCount; rowIndex++)
{
ChessType currentChess = chessData.GetChess(new ChessPosition(rowIndex, colIndex));
if (currentChess == ChessType.None)
{
nowChess = currentChess;
seriesNum = 0;
}
else if (currentChess == nowChess)
{
seriesNum++;
if (seriesNum >= 5)
{
return currentChess;
}
}
else
{
nowChess = currentChess;
seriesNum = 1;
}
}
nowChess = ChessType.None;
seriesNum = 0;
}
//遍历左上到右下
for (int scolIndex = 0; scolIndex < chessData.ColCount; scolIndex++)
{
int rowIndex = 0;
int colIndex = scolIndex;
while (rowIndex < chessData.RowCount && colIndex < chessData.ColCount)
{
ChessType currentChess = chessData.GetChess(new ChessPosition(rowIndex, colIndex));
if (currentChess == ChessType.None)
{
nowChess = currentChess;
seriesNum = 0;
}
else if (currentChess == nowChess)
{
seriesNum++;
if (seriesNum >= 5)
{
return currentChess;
}
}
else
{
nowChess = currentChess;
seriesNum = 1;
}
rowIndex++;
colIndex++;
}
nowChess = ChessType.None;
seriesNum = 0;
}
for (int srowIndex = 0; srowIndex < chessData.ColCount; srowIndex++)
{
int rowIndex = srowIndex;
int colIndex = 0;
while (rowIndex < chessData.RowCount && colIndex < chessData.ColCount)
{
ChessType currentChess = chessData.GetChess(new ChessPosition(rowIndex, colIndex));
if (currentChess == ChessType.None)
{
nowChess = currentChess;
seriesNum = 0;
}
else if (currentChess == nowChess)
{
seriesNum++;
if (seriesNum >= 5)
{
return currentChess;
}
}
else
{
nowChess = currentChess;
seriesNum = 1;
}
rowIndex++;
colIndex++;
}
nowChess = ChessType.None;
seriesNum = 0;
}
//遍历左下到右上
for (int scolIndex = 0; scolIndex < chessData.ColCount; scolIndex++)
{
int rowIndex = 0;
int colIndex = scolIndex;
while (rowIndex < chessData.RowCount && colIndex >= 0)
{
ChessType currentChess = chessData.GetChess(new ChessPosition(rowIndex, colIndex));
if (currentChess == ChessType.None)
{
nowChess = currentChess;
seriesNum = 0;
}
else if (currentChess == nowChess)
{
seriesNum++;
if (seriesNum >= 5)
{
return currentChess;
}
}
else
{
nowChess = currentChess;
seriesNum = 1;
}
rowIndex++;
colIndex--;
}
nowChess = ChessType.None;
seriesNum = 0;
}
for (int srowIndex = 0; srowIndex < chessData.RowCount; srowIndex++)
{
int rowIndex = srowIndex;
int colIndex = chessData.ColCount - 1;
while (rowIndex < chessData.RowCount && colIndex >= 0)
{
ChessType currentChess = chessData.GetChess(new ChessPosition(rowIndex, colIndex));
if (currentChess == ChessType.None)
{
nowChess = currentChess;
seriesNum = 0;
}
else if (currentChess == nowChess)
{
seriesNum++;
if (seriesNum >= 5)
{
return currentChess;
}
}
else
{
nowChess = currentChess;
seriesNum = 1;
}
rowIndex++;
colIndex--;
}
nowChess = ChessType.None;
seriesNum = 0;
} return ChessType.None;
}
/// 测试是否是平局
/// </summary>
/// <param name="chessData"></param>
/// <returns></returns>
public bool TestDogfall(IChessData chessData)
{
return chessData.IsFull;
} /// <summary>
/// 落子逻辑,在某一点落子后的逻辑
/// </summary>
/// <param name="chessData"></param>
/// <param name="chessInfo"></param>
public void PutChess(ref IChessData chessData,ChessInfo chessInfo)
{
chessData.SetChess(chessInfo.ChessPosition, chessInfo.TheChessType);
}
}
}
using System;namespace QiuQiu.ChessEngine
{
/// <summary>
/// 棋子信息
/// </summary>
public struct ChessInfo
{
public ChessPosition ChessPosition;
public ChessType TheChessType; public ChessInfo(ChessPosition chessPosition, ChessType chessType)
{
ChessPosition = chessPosition;
TheChessType = chessType;
}
} /// <summary>
/// 棋子位置
/// </summary>
public struct ChessPosition
{
public int RowIndex;
public int ColIndex; public ChessPosition(int rowIndex,int colIndex)
{
RowIndex = rowIndex;
ColIndex = colIndex;
} public static bool operator==(ChessPosition chessPosition1,ChessPosition chessPosition2)
{
return chessPosition1.ColIndex == chessPosition2.ColIndex && chessPosition1.RowIndex == chessPosition2.RowIndex;
} public static bool operator!=(ChessPosition chessPosition1,ChessPosition chessPosition2)
{
return chessPosition1.ColIndex != chessPosition2.ColIndex || chessPosition1.RowIndex != chessPosition2.RowIndex;
} public override int GetHashCode()
{
return base.GetHashCode ();
} public override bool Equals(object obj)
{
ChessPosition pos = (ChessPosition)obj;
return RowIndex == pos.RowIndex && ColIndex == pos.ColIndex;
}
}
}using System;namespace QiuQiu.ChessEngine
{
/// <summary>
/// 棋类
/// </summary>
public enum ChessType
{
None = 0,
Black = 1,
White = 2
}}using System;
using System.Collections.Generic;
using System.Text;namespace QiuQiu.ChessEngine
{
public enum EventType
{
Illegality,//犯规
DataFull,//数据满
BlackWin,//黑棋胜
WhiteWin,//白棋胜
Exceptions
}
}
using System;
using System.Collections.Generic;
using System.Text;namespace QiuQiu.ChessEngine
{
public class PlayerInfoAttribute : Attribute
{
public string PlayerName { get; set; }
public string Author { get; set; }
public string ModifyTime { get; set; }
}
}
{
/// <summary>
/// 计时类
/// </summary>
public sealed class ChessTimer : IDisposable
{
private TimeSpan _blackPlayer;
private TimeSpan _whitePlayer;
private DateTime _lastTickTime;
private ChessType _nowPlayer;
private System.Timers.Timer _timer; public event ChessTimerElapsed Elapsed; public TimeSpan BlackPlayer
{
get { return _blackPlayer; }
set { _blackPlayer = value; }
} public TimeSpan WhitePlayer
{
get { return _whitePlayer; }
set { _whitePlayer = value; }
} public ChessTimer()
{
_timer = new System.Timers.Timer(1000);
_timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
Reset();
} void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
switch (_nowPlayer)
{
case ChessType.Black:
_blackPlayer += DateTime.Now - _lastTickTime;
_lastTickTime = DateTime.Now;
break;
case ChessType.White:
_whitePlayer += DateTime.Now - _lastTickTime;
_lastTickTime = DateTime.Now;
break;
} if (Elapsed != null)
Elapsed(this,new ChessTimerEventArgs(_blackPlayer,_whitePlayer));
} //public TimeSpan BlackPlayer
//{
// get { return fBlackPlayer; }
// set { fBlackPlayer = value; }
//} //public TimeSpan WhitePlayer
//{
// get { return fWhitePlayer; }
// set { fWhitePlayer = value; }
//} public void Reset()
{
_blackPlayer = _whitePlayer = new TimeSpan(0);
_lastTickTime = DateTime.Now;
} public void Start(ChessType startPlayer)
{
Reset();
_nowPlayer = startPlayer;
_timer.Start();
} public void Stop()
{
_timer.Stop();
} public void Tick(ChessType chessType)
{
_nowPlayer = chessType;
switch (_nowPlayer)
{
case ChessType.Black:
_blackPlayer += DateTime.Now - _lastTickTime;
_lastTickTime = DateTime.Now;
break;
case ChessType.White:
_whitePlayer += DateTime.Now - _lastTickTime;
_lastTickTime = DateTime.Now;
break;
}
} public void Dispose()
{
if (_timer != null)
{
_timer.Dispose();
_timer = null;
}
}
} public class ChessTimerEventArgs : EventArgs
{
public TimeSpan BlackPlayer;
public TimeSpan WhitePlayer; public ChessTimerEventArgs(TimeSpan blackPlayer,TimeSpan whitePlayer)
{
BlackPlayer = blackPlayer;
WhitePlayer = whitePlayer;
}
} public delegate void ChessTimerElapsed(object sender, ChessTimerEventArgs e);
}
using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
using QiuQiu.ChessEngine;namespace QiuQiu.ChessEngine
{
/// <summary>
/// 棋盘
/// </summary>
public class Chessboard : System.Windows.Forms.UserControl
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.Container components = null; private int _rowCount;//表线行数
private int _colCount;//表线列数
private int _leftBlank;//左边空白像素
private int _rightBlank;//右边空白像素
private int _topBlank;//上边空白像素
private int _buttomBlank;//下边空白像素
private int _tableLineSpace;//线间间距像素
private int _chessRadius;//棋子半径
private Color _tableLineColor;//线颜色
private Color _focusColor;//焦点颜色
private IChessData _chessData;//棋子数据
private bool _canManChess;//是否是用户下棋 private ChessPosition fCurrentPosition; public event PutChessEventHandle PutChess; public Chessboard()
{
// 该调用是 Windows.Forms 窗体设计器所必需的。
InitializeComponent(); // TODO: 在 InitializeComponent 调用后添加任何初始化
_rowCount = 15;//棋盘行数
_colCount = 15;//棋盘列数
_leftBlank = 20;//左边留空
_rightBlank = 20;//右边留空
_topBlank = 20;//上边留空
_buttomBlank = 20;//下边留空
_tableLineSpace = 30;//格间距
_chessRadius = 10;//棋子半径
_tableLineColor = Color.Black;//棋盘线颜色
_focusColor = Color.Red;//焦点颜色 _chessData = new ChessData(_rowCount,_colCount); int width = _leftBlank + _rightBlank + _tableLineSpace * (_colCount - 1);
int hight = _topBlank + _buttomBlank + _tableLineSpace * (_rowCount - 1);
base.Size = new Size(width,hight);
} public bool CanManChess
{
get { return _canManChess; }
set { _canManChess = value; }
} protected override void OnMouseUp(MouseEventArgs e)
{
//鼠标左键弹起事件
if (_canManChess)
{
//如果用户下棋,则进行处理
ChessPosition chessPosotion = GetChessInfo(e.X, e.Y);
//鼠标弹出事件触发下子事件
if (PutChess != null)
{
if (!_chessData.HasChess(chessPosotion))
PutChess(null, new PutChessEventArgs(chessPosotion.RowIndex, chessPosotion.ColIndex));
}
Refresh();
}
base.OnMouseUp (e);
} protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove (e);
//鼠标移动事件处理焦点
ChessPosition nowPosotion = GetChessInfo(e.X,e.Y);
if(nowPosotion.RowIndex >= _rowCount || nowPosotion.ColIndex >= _colCount)
return;
if(nowPosotion != fCurrentPosition && !_chessData.HasChess(nowPosotion))
{
//当当前鼠标所在位置与原焦点位置不同且当前位置无棋子时更换显示位置
Graphics graphics = this.CreateGraphics();
if(!_chessData.HasChess(fCurrentPosition))
{
//原焦点不存在棋子则擦去原焦点
DrawFocus(fCurrentPosition,graphics,new SolidBrush(BackColor));
}
DrawFocus(nowPosotion,graphics,new SolidBrush(_focusColor));//绘制新焦点
fCurrentPosition = nowPosotion;
}
} protected override void OnPaint(PaintEventArgs e)
{
//重绘事件
DrawChessTable(e.Graphics);
DrawChess(_chessData,e.Graphics);
base.OnPaint (e);
} /// <summary>
/// 坐标转换成棋子位置
/// </summary>
/// <param name="X"></param>
/// <param name="Y"></param>
/// <param name="chessType"></param>
/// <returns></returns>
private ChessPosition GetChessInfo(int x,int y)
{
int rowIndex = (y - _topBlank + (_tableLineSpace >> 1)) / _tableLineSpace;
int colIndex = (x - _leftBlank + (_tableLineSpace >> 1)) / _tableLineSpace;
return new ChessPosition(colIndex,rowIndex);
} /// <summary>
/// 绘制棋盘
/// </summary>
/// <param name="graphics">绘图对象</param>
private void DrawChessTable(Graphics graphics)
{
Pen pen = new Pen(_tableLineColor,1); int rowStart = _leftBlank;
int rowEnd = _leftBlank + _tableLineSpace * (_colCount - 1);
int colStart = _topBlank;
int colEnd = _topBlank + _tableLineSpace * (_rowCount - 1);
for(int rowIndex = 0;rowIndex < _rowCount;rowIndex ++)
{
int top = _topBlank + _tableLineSpace * rowIndex;
graphics.DrawLine(pen,rowStart,top,rowEnd,top);
}
for(int colIndex = 0;colIndex < _colCount;colIndex ++)
{
int left = _topBlank + _tableLineSpace * colIndex;
graphics.DrawLine(pen,left,colStart,left,colEnd);
}
pen.Dispose();
}
/// 绘制棋子
/// </summary>
/// <param name="chessData">棋子数据</param>
/// <param name="graphics">绘图对象</param>
private void DrawChess(IChessData chessData,Graphics graphics)
{
if(chessData == null)
return;
Brush[] brush = new SolidBrush[3];
brush[1] = new SolidBrush(Color.Black);
brush[2] = new SolidBrush(Color.White);
Pen blackPen = new Pen(Color.Black,1);
Pen redPen = new Pen(Color.Red,(float)1.5);
for(int rowIndex = 0;rowIndex < _rowCount;rowIndex ++)
{
for(int colIndex = 0;colIndex < _colCount;colIndex ++)
{
ChessType chessType = chessData.GetChess(new ChessPosition(rowIndex,colIndex));
if(chessType != ChessType.None)
DrawAChess(rowIndex,colIndex,graphics,brush[(int)chessType],blackPen);
}
}
//对上一个子描红框
if(chessData.LastChess.TheChessType != ChessType.None)
DrawAChess(chessData.LastChess.ChessPosition.RowIndex,chessData.LastChess.ChessPosition.ColIndex,graphics,brush[(int)chessData.LastChess.TheChessType],redPen);
brush[1].Dispose();
brush[2].Dispose();
blackPen.Dispose();
redPen.Dispose();
} /// <summary>
/// 绘制一颗棋子
/// </summary>
/// <param name="rowIndex">行索引</param>
/// <param name="colIndex">列索引</param>
/// <param name="graphics">绘图对象</param>
/// <param name="brush">棋子笔刷</param>
/// <param name="blackPen">黑线笔</param>
private void DrawAChess(int rowIndex,int colIndex,Graphics graphics,Brush brush,Pen blackPen)
{
int x = _leftBlank + _tableLineSpace * rowIndex;
int y = _topBlank + _tableLineSpace * colIndex;
graphics.FillEllipse(brush,x - _chessRadius,y - _chessRadius,_chessRadius << 1,_chessRadius << 1);
graphics.DrawEllipse(blackPen,x - _chessRadius,y - _chessRadius,_chessRadius << 1,_chessRadius << 1);
} /// <summary>
/// 绘制焦点
/// </summary>
/// <param name="position">焦点位置</param>
/// <param name="graphics">绘图对象</param>
/// <param name="brush">绘制笔刷</param>
private void DrawFocus(ChessPosition position,Graphics graphics,Brush brush)
{
int x = _leftBlank + _tableLineSpace * position.RowIndex;
int y = _topBlank + _tableLineSpace * position.ColIndex;
Pen pen = new Pen(brush,2);
graphics.DrawLine(pen,x - 8,y - 8,x - 2,y - 8);
graphics.DrawLine(pen,x + 3,y - 8,x + 9,y - 8);
graphics.DrawLine(pen,x - 8,y + 9,x - 2,y + 9);
graphics.DrawLine(pen,x + 3,y + 9,x + 9,y + 9);
graphics.DrawLine(pen,x - 8,y - 8,x - 8,y - 2);
graphics.DrawLine(pen,x - 8,y + 3,x - 8,y + 9);
graphics.DrawLine(pen,x + 9,y - 8,x + 9,y - 2);
graphics.DrawLine(pen,x + 9,y + 3,x + 9,y + 9);
} public void SetChessData(IChessData chessData)
{
_chessData = chessData;
} /// <summary>
/// 清理所有正在使用的资源。
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
} #region 组件设计器生成的代码
/// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器
/// 修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
}
#endregion public override ISite Site
{
get
{
return base.Site;
}
} }
}
using System;
using System.Collections.Generic;
using System.Text;
using QiuQiu.ChessEngine;namespace QiuQiu.ChessForm
{
/// <summary>
/// 用户玩家类,依赖于棋盘界面
/// </summary>
[PlayerInfo(PlayerName = "ManPlayer", Author = "QiuQiu", ModifyTime = "2008-4-23")]
internal class ManPlayer : IPlayer
{
private ChessType _chessType;
private Chessboard _chessboard;
private PutChessEventHandle _putChessEventHandle; /// <summary>
/// 落子事件,当需要落子时触发该事件
/// </summary>
public event PutChessEventHandle PutChess; /// <summary>
/// 玩家所执的棋类型
/// </summary>
public ChessType ChessType { get { return _chessType; } } public ManPlayer(Chessboard chessboard)
{
_chessboard = chessboard;
_putChessEventHandle = new PutChessEventHandle(_chessboard_PutChess);
} void _chessboard_PutChess(IPlayer sender, PutChessEventArgs args)
{
_chessboard.CanManChess = false;
_chessboard.PutChess -= _putChessEventHandle;
if (PutChess != null)
{
PutChess(this, args);
} } /// <summary>
/// 初始化玩家
/// </summary>
/// <param name="chessData">棋盘数据</param>
/// <param name="chessType">所执棋类型</param>
public void Init(ChessType chessType)
{
_chessType = chessType;
} /// <summary>
/// 通知进行落子
/// </summary>
public void DoChess(IChessData chessData)
{
_chessboard.CanManChess = true;
_chessboard.PutChess += _putChessEventHandle;
} }
}
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.IO;
using QiuQiu.ChessEngine;namespace QiuQiu.ChessForm
{
public class ChessPlayers
{
private Dictionary<string, Type> _players;
private static string manPlayerName = "用户玩家"; public void LoadPlayer()
{
_players = new Dictionary<string, Type>();
_players.Add(manPlayerName, typeof(ManPlayer));
string localPath = Environment.CurrentDirectory;
string[] dlls = Directory.GetFiles(localPath, "*.dll", SearchOption.TopDirectoryOnly);
foreach(string dll in dlls)
{
Assembly asm = Assembly.LoadFrom(dll);
Type[] types = asm.GetTypes();
foreach(Type type in types)
{
if (type.IsClass && !type.IsAbstract)
{
Type interfaceType = type.GetInterface(typeof(IPlayer).Name);
if (interfaceType != null)
{
Attribute attr = Attribute.GetCustomAttribute(type, typeof(PlayerInfoAttribute));
PlayerInfoAttribute playerInfo = attr as PlayerInfoAttribute;
if (playerInfo != null)
{
_players.Add(playerInfo.PlayerName, type);
}
}
}
}
}
} public string[] GetPlayerNames()
{
if (_players == null)
{
return new string[] { };
}
string[] result = new string[_players.Count];
_players.Keys.CopyTo(result, 0);
return result;
} public IPlayer GetPlayer(string playerName,MainForm form)
{
if (playerName.Equals(manPlayerName))
{
return new ManPlayer(form.chessboard1);
}
if (_players == null)
{
return null;
}
if(!_players.ContainsKey(playerName))
{
return null;
}
Type playerType = _players[playerName];
if (playerType == null)
{
return null;
}
try
{
IPlayer player = Activator.CreateInstance(playerType) as IPlayer;
return player;
}
catch
{
return null;
}
}
}
}
namespace QiuQiu.ChessForm
{
partial class MainForm
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null; /// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
} #region Windows 窗体设计器生成的代码 /// <summary>
/// 设计器支持所需的方法 - 不要
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
this.chessboard1 = new QiuQiu.ChessEngine.Chessboard();
this.label1 = new System.Windows.Forms.Label();
this.lbNowPlaer = new System.Windows.Forms.Label();
this.label3 = new System.Windows.Forms.Label();
this.label4 = new System.Windows.Forms.Label();
this.lbBlackTime = new System.Windows.Forms.Label();
this.lbWhiteTime = new System.Windows.Forms.Label();
this.button2 = new System.Windows.Forms.Button();
this.label2 = new System.Windows.Forms.Label();
this.label5 = new System.Windows.Forms.Label();
this.player1ComboBox = new System.Windows.Forms.ComboBox();
this.player2ComboBox = new System.Windows.Forms.ComboBox();
this.SuspendLayout();
//
// button1
//
this.button1.Location = new System.Drawing.Point(457, 415);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(59, 23);
this.button1.TabIndex = 1;
this.button1.Text = "开始";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// chessboard1
//
this.chessboard1.CanManChess = false;
this.chessboard1.Location = new System.Drawing.Point(0, -2);
this.chessboard1.Name = "chessboard1";
this.chessboard1.Size = new System.Drawing.Size(460, 460);
this.chessboard1.TabIndex = 0;
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(466, 236);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(53, 12);
this.label1.TabIndex = 9;
this.label1.Text = "当前手:";
//
// lbNowPlaer
//
this.lbNowPlaer.AutoSize = true;
this.lbNowPlaer.Location = new System.Drawing.Point(524, 236);
this.lbNowPlaer.Name = "lbNowPlaer";
this.lbNowPlaer.Size = new System.Drawing.Size(29, 12);
this.lbNowPlaer.TabIndex = 10;
this.lbNowPlaer.Text = "黑棋";
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(466, 277);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(65, 12);
this.label3.TabIndex = 11;
this.label3.Text = "黑棋时间:";
//
// label4
//
this.label4.AutoSize = true;
this.label4.Location = new System.Drawing.Point(466, 328);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(65, 12);
this.label4.TabIndex = 6;
this.label4.Text = "白棋时间:";
//
// lbBlackTime
//
this.lbBlackTime.AutoSize = true;
this.lbBlackTime.Location = new System.Drawing.Point(492, 300);
this.lbBlackTime.Name = "lbBlackTime";
this.lbBlackTime.Size = new System.Drawing.Size(53, 12);
this.lbBlackTime.TabIndex = 7;
this.lbBlackTime.Text = "00:00:00";
//
// lbWhiteTime
//
this.lbWhiteTime.AutoSize = true;
this.lbWhiteTime.Location = new System.Drawing.Point(492, 354);
this.lbWhiteTime.Name = "lbWhiteTime";
this.lbWhiteTime.Size = new System.Drawing.Size(53, 12);
this.lbWhiteTime.TabIndex = 8;
this.lbWhiteTime.Text = "00:00:00";
//
// button2
//
this.button2.Location = new System.Drawing.Point(522, 415);
this.button2.Name = "button2";
this.button2.Size = new System.Drawing.Size(59, 23);
this.button2.TabIndex = 1;
this.button2.Text = "停止";
this.button2.UseVisualStyleBackColor = true;
this.button2.Click += new System.EventHandler(this.button2_Click);
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(463, 19);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(41, 12);
this.label2.TabIndex = 9;
this.label2.Text = "黑棋:";
//
// label5
//
this.label5.AutoSize = true;
this.label5.Location = new System.Drawing.Point(463, 97);
this.label5.Name = "label5";
this.label5.Size = new System.Drawing.Size(41, 12);
this.label5.TabIndex = 9;
this.label5.Text = "白棋:";
//
// player1ComboBox
//
this.player1ComboBox.FormattingEnabled = true;
this.player1ComboBox.Location = new System.Drawing.Point(465, 52);
this.player1ComboBox.Name = "player1ComboBox";
this.player1ComboBox.Size = new System.Drawing.Size(121, 20);
this.player1ComboBox.TabIndex = 12;
//
// player2ComboBox
//
this.player2ComboBox.FormattingEnabled = true;
this.player2ComboBox.Location = new System.Drawing.Point(465, 131);
this.player2ComboBox.Name = "player2ComboBox";
this.player2ComboBox.Size = new System.Drawing.Size(121, 20);
this.player2ComboBox.TabIndex = 13;
//
// MainForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(599, 467);
this.Controls.Add(this.player2ComboBox);
this.Controls.Add(this.player1ComboBox);
this.Controls.Add(this.label5);
this.Controls.Add(this.label2);
this.Controls.Add(this.label1);
this.Controls.Add(this.lbNowPlaer);
this.Controls.Add(this.label3);
this.Controls.Add(this.label4);
this.Controls.Add(this.lbBlackTime);
this.Controls.Add(this.lbWhiteTime);
this.Controls.Add(this.button2);
this.Controls.Add(this.button1);
this.Controls.Add(this.chessboard1);
this.Name = "MainForm";
this.Text = "五子棋";
this.Load += new System.EventHandler(this.MainForm_Load);
this.ResumeLayout(false);
this.PerformLayout(); } #endregion
private System.Windows.Forms.Button button1;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label lbNowPlaer;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.Label lbBlackTime;
private System.Windows.Forms.Label lbWhiteTime;
private System.Windows.Forms.Button button2;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label5;
private System.Windows.Forms.ComboBox player1ComboBox;
private System.Windows.Forms.ComboBox player2ComboBox;
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using QiuQiu.ChessEngine;
using QiuQiu.QChessPlayer;namespace QiuQiu.ChessForm
{
public partial class MainForm : Form
{
private IChessEngine _engine;
private ChessPlayers _chessPalyers; public MainForm()
{
InitializeComponent(); _chessPalyers = new ChessPlayers();
InitEngine();
} private void InitEngine()
{
if (_engine != null)
_engine.Dispose();
_engine = new ChessEngine.ChessEngine();
_engine.DataChange += new EventHandler(_engine_DataChange);
_engine.PlayerChange += new EventHandler(_engine_PlayerChange);
_engine.EventFire += new EngineEventHandle(_engine_EventFire);
_engine.Timer.Elapsed += new ChessTimerElapsed(Timer_Elapsed);
chessboard1.SetChessData(_engine.ChessData);
} /// <summary>
/// 计时器每秒触发
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Timer_Elapsed(object sender, ChessTimerEventArgs e)
{
//时间
try
{
Invoke(new EventHandler(timerAction), sender, e);
}
catch { }
} /// <summary>
/// 计时器触发动作
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void timerAction(object sender, EventArgs e)
{
this.lbBlackTime.Text = ((ChessTimerEventArgs)e).BlackPlayer.ToString().Substring(0, 8);
this.lbWhiteTime.Text = ((ChessTimerEventArgs)e).WhitePlayer.ToString().Substring(0, 8);
} void _engine_EventFire(IChessEngine sender, EngineEventArgs args)
{
switch (args.EventType)
{
case EventType.BlackWin:
MessageBox.Show("黑棋胜!" + args.Message);
break;
case EventType.WhiteWin:
MessageBox.Show("白棋胜!" + args.Message);
break;
case EventType.DataFull:
MessageBox.Show("平局!" + args.Message);
break;
case EventType.Illegality:
MessageBox.Show((sender.CurrentPlayer.ChessType == ChessType.Black?"黑棋":"白棋") + "犯规!" + args.Message);
break;
case EventType.Exceptions:
MessageBox.Show((sender.CurrentPlayer.ChessType == ChessType.Black ? "黑棋" : "白棋") + "异常!" + args.Message);
break;
} } private void _engine_DataChange(object sender, EventArgs e)
{
try
{
chessboard1.SetChessData(_engine.ChessData);
Invoke(new DeleGate(chessboard1.Refresh));
}
catch
{
}
} void _engine_PlayerChange(object sender, EventArgs e)
{
Invoke(new DeleGate(PlayerChang));
} private void PlayerChang()
{
lbNowPlaer.Text = _engine.CurrentPlayer.ChessType == ChessType.Black ? "黑棋" : "白棋";
} private void MainForm_Load(object sender, EventArgs e)
{
_chessPalyers.LoadPlayer();
player1ComboBox.DataSource = _chessPalyers.GetPlayerNames();
player2ComboBox.DataSource = _chessPalyers.GetPlayerNames();
} protected override void OnClosing(CancelEventArgs e)
{
_engine.Stop();
base.OnClosing(e);
} private void button1_Click(object sender, EventArgs e)
{
InitEngine();
_engine.Plyer1 = _chessPalyers.GetPlayer(player1ComboBox.SelectedItem.ToString(), this);// new QiuQiu.QChessPlayer.Player();
_engine.Plyer2 = _chessPalyers.GetPlayer(player2ComboBox.SelectedItem.ToString(), this);// new ManPlayer(chessboard1);
if (_engine.Plyer1 == null)
{
MessageBox.Show("黑棋玩家加载失败!");
return;
}
if (_engine.Plyer2 == null)
{
MessageBox.Show("白棋玩家加载失败!");
return;
}
chessboard1.Refresh();
_engine.Start();
} void button2_Click(object sender, System.EventArgs e)
{
_engine.Stop();
}
}
}
using System;
using System.Collections.Generic;
using System.Windows.Forms;namespace QiuQiu.ChessForm
{
static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
} }
}
是不是SimplePlayer太傻了,不屑一顾?
原理就是比较每个坐标落在后的综合指数,效率很快,但AI不高以前玩过一个叫“fiver6.exe”,智能五子棋,包括抓禁手,挺厉害的,高级一点的电脑基本下不过。
楼主可以继续完善一下比赛平台,界面不要有闪烁和假死状态、支持棋谱(建议xml格式)using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using QiuQiu.ChessEngine;namespace MyPlayers
{
/// <summary>
/// 一个最简单的玩家类,随机落子
/// </summary>
[PlayerInfo(PlayerName = "ZswangNo1", Author = "Zswang", ModifyTime = "2008-4-29")]
public class ZswangNo1 : 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 void Init(ChessType chessType)
{
_chessType = chessType;
} /// <summary>
/// 通知进行落子
/// </summary>
public void DoChess(IChessData chessData)
{
if (chessData == null) return;
if (PutChess == null) return;
if (chessData.IsFull) return; // 已经填满
CalcVantages(chessData); // 计算一下局势
if (vantages.Count <= 0)return;
Analyse(); // 分析一下局势
PutChess(this, new PutChessEventArgs(vantages[0].y, vantages[0].x));
} /// <summary>
/// 四个方向的趋势
/// </summary>
private Point[] offsetTide = new Point[] {
new Point(0, 1), //[|]
new Point(1, 1), //[/]
new Point(1, 0), //[-]
new Point(1, -1) //[\]
}; /// <summary>
/// 五子棋关系信息
/// </summary>
private struct GobangInfo
{
public int L5; // 连5
public int H4; // 连4
public int L4; // 连4
public int H3; // 活3
public int L3; // 连3
public int H2; // 活2
public int L2; // 连2
public int space; // 空间
} /// <summary>
/// 有利参数
/// </summary>
private class VantageInfo
{
public int x, y; //坐标
public GobangInfo black;
public GobangInfo white;
public VantageInfo(int x, int y)
{
this.x = x;
this.y = y;
black = new GobangInfo();
white = new GobangInfo();
}
} private List<VantageInfo> vantages = new List<VantageInfo>(); /// <summary>
/// 计算参数
/// </summary>
private void CalcVantages(IChessData chessData)
{
vantages.Clear();
for (int i = 0; i < chessData.ColCount; i++)
{
for (int j = 0; j < chessData.RowCount; j++)
{
ChessType ct = chessData.GetChess(new ChessPosition(j, i));
if (ct != ChessType.None) continue; // 已经有子
VantageInfo vantageInfo = new VantageInfo(i, j);
vantages.Add(vantageInfo);
for (int k = 0; k < offsetTide.Length; k++)
{
string blackString = "1";
string whiteString = "1"; #region 趋势判断
int x = i, y = j; // 正向
int _x = i, _y = j; // 逆向向
bool blackExists = false;
bool whiteExists = false;
bool _blackExists = false;
bool _whiteExists = false;
for (int step = 0; step < 6; step++)
{
x += offsetTide[k].X;
y += offsetTide[k].Y;
if (x >= 0 && x < chessData.ColCount &&
y >= 0 && y < chessData.RowCount)
{
switch (chessData.GetChess(new ChessPosition(y, x)))
{
case ChessType.Black:
blackExists = true;
blackString += "1";
whiteString += "#";
break;
case ChessType.White:
whiteExists = true;
whiteString += "1";
blackString += "#";
break;
case ChessType.None:
if (!blackExists) vantageInfo.white.space++;
if (!whiteExists) vantageInfo.black.space++;
whiteString += "0";
blackString += "0";
break;
}
}
else
{
blackString += "#";
whiteString += "#";
}
_x -= offsetTide[k].X;
_y -= offsetTide[k].Y;
if (_x >= 0 && _x < chessData.ColCount &&
_y >= 0 && _y < chessData.RowCount)
{
switch (chessData.GetChess(new ChessPosition(_y, _x)))
{
case ChessType.Black:
_blackExists = true;
blackString = "1" + blackString;
whiteString = "#" + whiteString;
break;
case ChessType.White:
_whiteExists = true;
whiteString = "1" + whiteString;
blackString = "#" + blackString;
break;
case ChessType.None:
if (!_blackExists) vantageInfo.white.space++;
if (!_whiteExists) vantageInfo.black.space++;
whiteString = "0" + whiteString;
blackString = "0" + blackString;
break;
}
}
else
{
blackString = "#" + blackString;
whiteString = "#" + whiteString;
}
}
#endregion 正向趋势判断
CalcGobangInfo(whiteString, ref vantageInfo.white);
CalcGobangInfo(blackString, ref vantageInfo.black);
}
}
}
}
{
if (text.IndexOf("11111") >= 0) //连5
gobangInfo.L5++;
else if (text.IndexOf("011110") >= 0 ||
text.IndexOf("110110110") >= 0 ||
text.IndexOf("110111011") >= 0) //活4
gobangInfo.H4++;
else if (text.IndexOf("11110") >= 0 ||
text.IndexOf("01111") >= 0 ||
text.IndexOf("11011") >= 0 ||
text.IndexOf("10111") >= 0 ||
text.IndexOf("11101") >= 0) //连4
gobangInfo.L4++;
else if (text.IndexOf("001110") >= 0 ||
text.IndexOf("011100") >= 0 ||
text.IndexOf("011010") >= 0 ||
text.IndexOf("010110") >= 0) //活3
gobangInfo.H3++;
else if (text.IndexOf("00111") >= 0 ||
text.IndexOf("11100") >= 0 ||
text.IndexOf("01110") >= 0 ||
text.IndexOf("10110") >= 0 ||
text.IndexOf("01101") >= 0 ||
text.IndexOf("11001") >= 0 ||
text.IndexOf("10011") >= 0) //连3
gobangInfo.L3++;
else if (text.IndexOf("001100") >= 0 ||
text.IndexOf("010100") >= 0 ||
text.IndexOf("001010") >= 0 ||
text.IndexOf("010010") >= 0) //活2
gobangInfo.H2++;
else if (text.IndexOf("11000") >= 0 ||
text.IndexOf("00011") >= 0 ||
text.IndexOf("10100") >= 0 ||
text.IndexOf("00101") >= 0 ||
text.IndexOf("10001") >= 0 ||
text.IndexOf("10010") >= 0 ||
text.IndexOf("01001") >= 0) //连2
gobangInfo.L2++;
}
private int CalcAttack(GobangInfo gobangInfo)
{
return gobangInfo.space +
gobangInfo.L2 * 10 +
gobangInfo.L3 * 100 +
gobangInfo.H2 * 1000 +
gobangInfo.L4 * 10000 +
gobangInfo.H3 * 100000 +
gobangInfo.H4 * 1000000 +
gobangInfo.L5 * 10000000;
} private int CompVantage(VantageInfo A, VantageInfo B)
{
if (A == B) return 0;
int ABlack = CalcAttack(A.black);
int AWhite = CalcAttack(A.white);
int BBlack = CalcAttack(B.black);
int BWhite = CalcAttack(B.white);
if (_chessType == ChessType.Black)
{
if (ABlack >= 10000000 || BBlack >= 10000000) return BBlack - ABlack;
if (AWhite >= 10000000 || BWhite >= 10000000) return BWhite - AWhite;
if (ABlack >= 110000 || BBlack >= 110000) return BBlack - ABlack;
if (AWhite >= 110000 || BWhite >= 110000) return BWhite - AWhite;
}
else
{
if (AWhite >= 10000000 || BWhite >= 10000000) return BWhite - AWhite;
if (ABlack >= 10000000 || BBlack >= 10000000) return BBlack - ABlack;
if (AWhite >= 110000 || BWhite >= 110000) return BWhite - AWhite;
if (ABlack >= 110000 || BBlack >= 110000) return BBlack - ABlack;
}
return (int)((BBlack + BWhite) - (ABlack + AWhite)); // 综合指数
} private void Analyse()
{
vantages.Sort(new Comparison<VantageInfo>(CompVantage));
}
}
}
[email protected]
[email protected] 辛苦楼主给我发下项目工程文件吧!
学习学习~
[email protected]
[email protected]
好贴!
我收藏了!
[email protected] 辛苦楼主给我发下项目工程文件吧!
MyMail::[email protected]
[email protected]
能不能再完整的发给我一份
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]以上已发送
[email protected]