C#版智能五子棋游戏(3)


C#版智能五子棋游戏(3)
其他的一些结构、枚举

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



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


还有一个,计时器类
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);
}



下面是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();
      }
      /// <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;
         }
      }
      
   }
}



用户玩家类,实现 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;
      }
      
   }
}



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



 

本文来源:
版权声明:本文为开发框架文库发布内容,转载请附上原文出处连接
C/S框架网
上一篇:C#版智能五子棋游戏(2)
下一篇:C#版智能五子棋游戏(4)-主窗体
评论列表

发表评论

评论内容
昵称:
关联文章

C#智能五子棋游戏(3)
C#智能五子棋游戏(1)
C#智能五子棋游戏(2)
C#智能五子棋游戏(4)-主窗体
C#贪吃蛇小游戏的源代码
C#积木游戏(改编自DevExpress GridTetris)
.Net Core SignalR简介-用SignalR撸个游戏
C#网络版中国象棋游戏源代码(VS2005)
SQL智能提示插件 SQL Prompt 破解
智能语音播报音箱收款播报机|收钱音箱|收款盒子4GWifi(支持微信、支付宝)
C/S系统快速开发框架-高级3.0
MES - 比亚迪智能制造执行系统
WMS - 北京某公司智能仓储管理系统 - CSFrameworkV5旗舰成功案例
关于C/S系统开发框架高级V3.x停止软件升级的公告
C# C/S系统开发框架高级V3.0正式发布!
C# Winform CS结构快速开发框架高级V3.0 - 视频介绍
C/S系统快速开发框架 - 标准V2.3
软件开发与设计 - CMS内容管理系统-KesionICMS智能建站系统 6.0
即将发布企业V4.3.3,敬请期待!
快速开发框架标准V2.3-钢铁贸易进销存(ERP系统)

热门标签
.NET5 .NET6 .NET7 APP Auth-软件授权注册系统 Axios B/S B/S开发框架 Bug Bug记录 C#加密解密 C#源码 C/S CHATGPT CMS系统 CodeGenerator CSFramework.DB CSFramework.EF CSFrameworkV1学习版 CSFrameworkV2标准版 CSFrameworkV3高级版 CSFrameworkV4企业版 CSFrameworkV5旗舰版 CSFrameworkV6.0 DAL数据访问层 Database datalock DbFramework Demo教学 Demo下载 DevExpress教程 DOM EF框架 Element-UI EntityFramework ERP ES6 Excel FastReport GIT HR IDatabase IIS JavaScript LINQ MES MiniFramework MIS NavBarControl Node.JS NPM OMS ORM PaaS POS Promise API Redis SAP SEO SQL SQLConnector TMS系统 Token令牌 VS2022 VSCode VUE WCF WebApi WebApi NETCore WebApi框架 WEB开发框架 Windows服务 Winform 开发框架 Winform 开发平台 WinFramework Workflow工作流 Workflow流程引擎 版本区别 报表 踩坑日记 操作手册 代码生成器 迭代开发记录 基础资料窗体 架构设计 角色权限 开发sce 开发技巧 开发教程 开发框架 开发平台 开发指南 客户案例 快速搭站系统 快速开发平台 秘钥 密钥 权限设计 软件报价 软件测试报告 软件简介 软件开发框架 软件开发平台 软件开发文档 软件体系架构 软件下载 软著证书 三层架构 设计模式 生成代码 实用小技巧 收钱音箱 数据锁 数据同步 微信小程序 未解决问题 文档下载 喜鹊ERP 喜鹊软件 系统对接 详细设计说明书 行政区域数据库 需求分析 疑难杂症 蝇量级框架 蝇量框架 用户管理 用户开发手册 用户控件 在线支付 纸箱ERP 智能语音收款机 自定义窗体 自定义组件 自动升级程序