C#版智能五子棋游戏(2)
作者:C/S框架网  发布日期:2011/06/12 18:46:09
C#版智能五子棋游戏(2)

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



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




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



 

上一篇 下一篇