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


C#版智能五子棋游戏(1) 看到zswang大牛组织的擂台赛,觉得挺有意思,不过随机性太强,现在来个稍复杂一点的,五子棋

贴图图片

[比赛规则]
1、五子连珠,可长连,无禁手,10分钟快棋
2、犯规(落在已有子的位置或多次落子)判输
3、比赛先手后手共五局,比分多的赢,若比分相同看赢局的时间总和,少的赢
4、赢得比赛的成为擂主,擂主可更新自己的代码
5、选手可以用以前的代码与新擂主打擂,不可以用相同的代码连续请求打擂
6、请求打擂请跟帖,以“请求打擂”为标题,帖上自己的代码,若代码较长,请给出下载地址

[机器人编写方法]
1、下载五子棋框架 http://download.csdn.net/source/430083
2、查看编写说明readme.cs
3、编写自己的玩家代码,编译成DLL文件与框架程序放在同一目录下,启动游戏,选择自己与对方的玩家,开始即可


[框架说明]
1、自己写的玩家类中不推荐使用多线程,线程由框架控制
2、您下载的代码中已经包含了三个已经实现的玩家,用户玩家由用户鼠标控制,一个简单的玩家和一个AI玩家
3、要框架源码的请与本人联系
4、由于本人在上班,会不定期上来看并给出打擂结果,希望有热心网友能够帮我来做这个工作


您可以实现IPlayer接口来完成机器人玩家


/// <summary>
/// 棋类游戏玩家接口,所有玩家必须实现本接口
/// 定义了初始化、通知落子,落子完成事件
/// </summary>
public interface IPlayer
{
   /// <summary>
   /// 落子事件,当需要落子时触发该事件
   /// 当您认为需要进行落子时,您需要触发该事件,游戏引擎将设置该事件的处理程序,但在触发该事件时最好先判断是否为空
   /// 你可以随时触发任意次本事件,但只有当DoChess方法被调用后(即游戏通知您可以进行落子)触发本事件是合法的,否则您将犯规
   /// </summary>
   event PutChessEventHandle PutChess;
   
   /// <summary>
   /// 玩家所执的棋类型
   /// 您必须直接返回初始化时给您的棋类型
   /// </summary>
   ChessType ChessType { get; }
   
   /// <summary>
   /// 初始化玩家
   /// </summary>
   /// <param name="chessType">您所执的棋类型 </param>
   void Init(ChessType chessType);
   
   /// <summary>
   /// 通知进行落子
   /// 当对方玩家落子完成或由您开局等游戏引擎认为由您进行落子时将调用该方法
   /// </summary>
   /// <param name="chessData">通知您进行落子时的棋盘数据的副本 </param>
   void DoChess(IChessData chessData);
}


或者继承BasePlayer类,只要重写DoChess方法,在适当的时候调用OnPutChess即可

public abstract class BasePlayer : IPlayer
{
   private ChessType _chessType;
   
   /// <summary>
   /// 落子事件,当需要落子时触发该事件
   /// </summary>
   public event PutChessEventHandle PutChess;
   
   /// <summary>
   /// 玩家所执的棋类型
   /// </summary>
   public ChessType ChessType { get { return _chessType; } }
   
   /// <summary>
   /// 初始化玩家
   /// </summary>
   /// <param name="chessData">棋盘数据 </param>
   /// <param name="chessType">所执棋类型 </param>
   public virtual void Init(ChessType chessType)
   {
      _chessType = chessType;
   }
   
   /// <summary>
   /// 触发落子事件
   /// </summary>
   /// <param name="rowIndex">落子行位置 </param>
   /// <param name="colIndex">落子列位置 </param>
   protected void OnPutChess(int rowIndex, int colIndex)
   {
      if (PutChess != null)
      {
         PutChess(this, new PutChessEventArgs(new ChessPosition(rowIndex, colIndex)));
      }
   }
   
   /// <summary>
   /// 触发落子事件
   /// </summary>
   /// <param name="rowIndex">落子行位置 </param>
   /// <param name="colIndex">落子列位置 </param>
   protected void OnPutChess(ChessPosition chessPosition)
   {
      if (PutChess != null)
      {
         PutChess(this, new PutChessEventArgs(chessPosition));
      }
   }
   
   /// <summary>
   /// 通知进行落子
   /// </summary>
   public abstract void DoChess(IChessData chessData);
}


这是一个最简单的机器人,作为原始擂主,抛砖引玉吧


using System;
using System.Collections.Generic;
using System.Text;
using QiuQiu.ChessEngine;

namespace MyPlayers
{
   /// <summary>
   /// 一个最简单的玩家类,随机落子
   /// </summary>
   [PlayerInfo(PlayerName = "SimplePlayer", Author = "QiuQiu", ModifyTime = "2008-4-23")]
   public class SimplePlayer : BasePlayer
   {
      /// <summary>
      /// 通知进行落子
      /// </summary>
      public override void DoChess(IChessData chessData)
      {
         Random rd = new Random(GetHashCode() + (int)DateTime.Now.Ticks);
         int r = rd.Next(15);//随机行
         int c = rd.Next(15);//随机列
         if (!chessData.IsFull)
         {
            //棋盘未满
            while (chessData.HasChess(new ChessPosition(r, c)))
            {
               //直至取到未落子的点
               r = rd.Next(15);
               c = rd.Next(15);
            }
            //执行落子
            base.OnPutChess(r, c);
         }
      }
      
   }
}



首先是ChessEngine程序集

IChessData 接口代码

using System;
using System.Collections.Generic;
using System.Text;

namespace QiuQiu.ChessEngine
{
   /// <summary>
   /// 棋盘数据接口
   /// 定义了取得棋子,设置棋子,判断是否有棋子,是否已满等
   /// 适合用于二维落子型棋类数据,如果五子棋,黑白棋,围棋等
   /// </summary>
   public interface IChessData : ILookChessData
   {
      /// <summary>
      /// 清空棋子数据
      /// </summary>
      void Clear();
      /// <summary>
      /// 设置指定位置的棋子
      /// </summary>
      /// <param name="chessPosition">棋子位置</param>
      /// <param name="chessType">棋子类型</param>
      void SetChess(ChessPosition chessPosition, ChessType chessType);
      
      /// <summary>
      /// 拷贝棋子数据
      /// </summary>
      /// <returns></returns>
      IChessData Copy();
   }
   
   /// <summary>
   /// 提供棋子数据的观察接口,不允许修改
   /// </summary>
   public interface ILookChessData
   {
      /// <summary>
      /// 取得指定位置的棋子,不检查是否存在棋子
      /// </summary>
      /// <param name="chessPosition"></param>
      /// <returns></returns>
      ChessType GetChess(ChessPosition chessPosition);
      
      /// <summary>
      /// 取得指定位置的棋子
      /// </summary>
      /// <param name="chessPosition"></param>
      /// <returns></returns>
      ChessType GetChess(ChessPosition chessPosition, bool check);
      
      /// <summary>
      /// 取得指定位置是否存在棋子
      /// </summary>
      /// <param name="chessPosition"></param>
      /// <returns></returns>
      bool HasChess(ChessPosition chessPosition);
      
      /// <summary>
      /// 上一步棋
      /// </summary>
      ChessInfo LastChess { get; }
      
      /// <summary>
      /// 棋盘是否已满
      /// </summary>
      bool IsFull { get; }
      
      /// <summary>
      /// 棋盘行数
      /// </summary>
      int RowCount { get; }
      
      /// <summary>
      /// 棋盘列数
      /// </summary>
      int ColCount { get; }
      
      /// <summary>
      /// 棋子数量
      /// </summary>
      int ChessCount { get; }
   }
}



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



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




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




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




转自csdn:http://topic.csdn.net/u/20080425/12/4bbb0f82-f963-4743-ac0e-f806333ac5f9.html

本文来源:
版权声明:本文为开发框架文库发布内容,转载请附上原文出处连接
C/S框架网
上一篇:C#深入剖析事件(C# Event详解)
下一篇:C#版智能五子棋游戏(2)
评论列表

发表评论

评论内容
昵称:
关联文章

C#智能五子棋游戏(1)
C#智能五子棋游戏(2)
C#智能五子棋游戏(3)
C#智能五子棋游戏(4)-主窗体
C#贪吃蛇小游戏的源代码
SQL智能提示插件 SQL Prompt 破解
C#积木游戏(改编自DevExpress GridTetris)
.Net Core SignalR简介-用SignalR撸个游戏
C#网络版中国象棋游戏源代码(VS2005)
MES - 比亚迪智能制造执行系统
WMS - 北京某公司智能仓储管理系统 - CSFrameworkV5旗舰成功案例
C# Winform 三层架构代码生成器 V5.1正式发布
智能语音播报音箱收款播报机|收钱音箱|收款盒子4GWifi(支持微信、支付宝)
智能分词搜索引擎Lucent.NET
CSFrameworkV5.1旗舰代码生成器(Code Generator)
C/S架构软件快速开发平台-旗舰V5.1简介
CSFramework旗舰V5.1介绍
C/S快速开发框架旗舰V5.1 - 业务单据明细表字段命名规范
C/S快速开发框架旗舰V5.1 - 预览报表
C/S快速开发框架旗舰V5.1 - 预览报表

热门标签
.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 智能语音收款机 自定义窗体 自定义组件 自动升级程序