本帖最后由 Ivony 于 2008-05-04 11:13:36 编辑

解决方案 »

  1.   

    您可以实现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);
        }
      

  2.   

    或者继承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);
        }
      

  3.   

    这是一个最简单的机器人,作为原始擂主,抛砖引玉吧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);
                }
            }    }
    }
      

  4.   

    怎么没人来打擂呢,SimplePlayer 应该很容易打败吧
      

  5.   

    Mark一下
    有时间有能力的时候攻一下擂
      

  6.   

    能不能把源代码也给我一份,最近正在学习,thank you [email protected]
      

  7.   

    代码短的话直接帖上来就行了,如果比较长,可以放到一些网络硬盘或者CSDN的下载区,然后帖出下载地址
      

  8.   

    框架源码也发份,谢谢~
    [email protected]
      

  9.   

    提点意见!
    个人觉得这个贴人气高不起来,原因主要有两点
    第一个,这个程序难度教先的高,涉及算法问题。
    第二个,搂主没提供框架的源码,这个不合理,
    之前的擂台赛大家关注的理由就是开源,建立工程和实现接口简单,只用复制粘贴就可以了,这个接口比那个复杂,不是我们实现不了,而是不想那么麻烦。
    如果说提供一个完整的工程,直接打开那还可以,让我们自己弄,还是算了。而且最关键的,SimplePlayer 这个机器人更本就是一个傻子,对我们实现擂台没有实际价值。而另一个聪明的机器人你又不给源码,这不是明摆着下套儿吗!建议如同前一个项目,提供搂主的实现过程,否则便没有擂台的意义了
      

  10.   

    首先是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; }
        }
    }
      

  11.   

    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;
    }
    }
    }
    }
      

  12.   

    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);
        }
    }
      

  13.   

    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);
        }
    }
      

  14.   

    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();    }
    }
      

  15.   

    IChessEngine 五子棋实现 
    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);
                        }
                    }
                }
            }
      

  16.   

            /// <summary>
            /// 当一家放下棋子事件处理程序
            /// </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);
            }
        }
    }
      

  17.   

    IChessLogic 接口,封装部分逻辑
    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);
        }
    }
      

  18.   

    IChessLogic 五子棋实现 ChessLogic
    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;
            }
      

  19.   

            /// <summary>
            /// 测试是否是平局
            /// </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);
            }
        }
    }
      

  20.   

    其他的一些结构、枚举
    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
        }
    }
      

  21.   

    PlayerInfoAttribute 特性,用于运行时加载玩家类读取相关信息
    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; }
        }
    }
      

  22.   

    还有一个,计时器类using System;namespace QiuQiu.ChessEngine
    {
        /// <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);
    }
      

  23.   

    下面是ChessForm程序集,主是要主界面,棋盘控件,用户玩家的实现,动态加载玩家先是Chessboard控件,主要是绘制棋盘,用户鼠标事件
    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();
    }
      

  24.   

    /// <summary>
    /// 绘制棋子
    /// </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;
    }
    } }
    }
      

  25.   

    用户玩家类,实现 IPlayer接口,依赖于Chessboard类
    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;
            }    }
    }
      

  26.   

    ChessPlayers 类,反射运行时加载玩家类
    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;
                }
            }
        }
    }
      

  27.   

    然后是 MainForm 布局局部类,随便拉起来的,由VS生成
    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
      

  28.   

            internal QiuQiu.ChessEngine.Chessboard chessboard1;
            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;
        }
    }
      

  29.   

    MainForm类
    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();
            }
        }
    }
      

  30.   

    最后是程序入口点,ChessForm结束,框架也结束
    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());
            }    }
    }
      

  31.   

    赫赫,我也做过一个五子棋程序,是Web版的,用AJAX实现。没有AI,只能双人对战。(遗憾没时间弄AI)借楼主这个机会来写AI,找个时间来打擂。先标记一下。
      

  32.   

    应该说不是很复杂,接口也还算清晰,为什么没人来打擂呢
    是不是SimplePlayer太傻了,不屑一顾?
      

  33.   

    SimplePlayer没有挑战性,先抛一个“ZswangNo1”支持一下楼主
    原理就是比较每个坐标落在后的综合指数,效率很快,但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);
                        }
                    }
                }
            }
      

  34.   

            private void CalcGobangInfo(string text, ref GobangInfo gobangInfo)
            {
                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));
            }
        }
    }
      

  35.   

    楼主能不能把框架代码也发我一份啊,学习学习,可以的话连项目文件一起吧,谢啦
    [email protected]
      

  36.   

    前面留下Email的我已经把源码工程打包发过去了,注意查收
      

  37.   

    又是c#,我们VC6版咋就没这人才,.Net安装动辄两三个G真受不了啊,我搞算法,又不专攻这个语言,还是算了
      

  38.   

    这样的AI算法很好  支持楼主!
    [email protected] 辛苦楼主给我发下项目工程文件吧!
    学习学习~
      

  39.   

    支持,请发一份给我[email protected]
      

  40.   

    我也要一分,学习下..
    [email protected]
      

  41.   

    楼主,有空发份给我,谢谢
    [email protected]
      

  42.   

    Please me a copy source code,[email protected]
      

  43.   

    楼主辛苦了!
    好贴!
    我收藏了!
    [email protected] 辛苦楼主给我发下项目工程文件吧! 
      

  44.   

    Thanks for all
     
      

  45.   

    真是感谢啦!!
    MyMail::[email protected]
      

  46.   

    能发我一份源码吗
    [email protected]
      

  47.   

    恩,,不错不错,
    能不能再完整的发给我一份
    [email protected]
      

  48.   

    [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]以上已发送
      

  49.   

    发给我也研究研究吧!
    [email protected]