前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >简单五子棋,没有电脑AI

简单五子棋,没有电脑AI

作者头像
用户6362579
发布2019-09-29 17:06:22
4830
发布2019-09-29 17:06:22
举报
文章被收录于专栏:小神仙小神仙

  刚学了C#委托,做了个五子棋练习,把前台绘制和后台逻辑分开,前台绘制方法用委托传给后台逻辑。

界面好简单。。。

先看类图

控制类控制整个游戏的逻辑,包括调用棋盘类的属性初始化棋盘、初始化两个棋手、轮流落子。棋盘里有一个二维数组保存整个棋盘的落子情况,棋手里也有一个二维数组保存自己的落子情况。方向类是为了方便判断输赢的。

下面是代码:注释很详细就不说明了:

主要控制类:

代码语言:javascript
复制
  1 using System;
  2 using System.Collections.Generic;
  3 using System.Drawing;
  4 using 五子棋.Properties;
  5 
  6 namespace 五子棋.Control
  7 {
  8     class Controler
  9     {
 10         #region 字段
 11         ///// <summary>
 12         ///// 画家对象
 13         ///// </summary>
 14         //Graphics g;
 15         /// <summary>
 16         /// 棋盘对象
 17         /// </summary>
 18         QiPan qipan;
 19         /// <summary>
 20         /// 棋手列表
 21         /// </summary>
 22         List<QiShou> qishou;
 23         /// <summary>
 24         /// 游戏是否结束
 25         /// </summary>
 26         bool Gameover = false;
 27         /// <summary>
 28         /// 绘制直线委托
 29         /// </summary>
 30         Action<Point, Point> actionDrawLine;
 31         /// <summary>
 32         /// 绘制棋子图像委托
 33         /// </summary>
 34         Action<Image, int, int, float> actionDrawimage;
 35         /// <summary>
 36         /// 取得胜利事件,返回胜利选手的名称
 37         /// </summary>
 38         Action<string> actionWin;
 39         #endregion
 40 
 41         #region 构造函数
 42 
 43         /// <summary>
 44         /// 构造函数
 45         /// </summary>
 46         /// <param name="actionDrawLine">绘制直线委托</param>
 47         /// <param name="actionDrawimage">绘制棋子图像委托</param>
 48         public Controler(Action< Point, Point> actionDrawLine, Action<Image, int, int, float> actionDrawimage,Action<string> actionWin)
 49         {
 50             //开始游戏
 51             this.actionDrawLine = actionDrawLine;
 52             this.actionDrawimage = actionDrawimage;
 53             this.actionWin = actionWin;
 54             StartGame();
 55         }
 56         #endregion
 57 
 58         #region 方法
 59 
 60         /// <summary>
 61         /// 棋手轮流下棋
 62         /// </summary>
 63         /// <param name="x">棋子X坐标</param>
 64         /// <param name="y">棋子Y坐标</param>
 65         public void LuoZi(int x, int y)
 66         {
 67             if (Gameover)
 68             {
 69                 return;
 70             }
 71             //把不在棋盘交点上的坐标换算到最接近的棋盘交点上
 72 
 73             //x = (int)Math.Round((double)(x - qipan.start.X) / qipan.Grid)
 74             //    * qipan.Grid + qipan.start.X;
 75             //y = (int)Math.Round((double)(y - qipan.start.Y) / qipan.Grid)
 76             //    * qipan.Grid + qipan.start.Y;
 77             //换算到棋盘第几条线
 78             int qipanX = (int)Math.Round((double)(x - qipan.start.X) / qipan.Grid);
 79             int qipanY = (int)Math.Round((double)(y - qipan.start.Y) / qipan.Grid);
 80             if (qipan[qipanX, qipanY] == 0)
 81             {
 82                 for (int i = 0; i < qishou.Count; i++)
 83                 {
 84                     if (qishou[i].IsZouqi)
 85                     {
 86                         qipan[qipanX, qipanY] = 1;
 87                         qishou[i].LuoZi(qipanX, qipanY);
 88                         //换算到棋盘控件坐标并绘制棋子
 89                         qishou[i].Render(qipanX * qipan.Grid + qipan.start.X,
 90                             qipanY * qipan.Grid + qipan.start.Y, actionDrawimage);
 91 
 92                         //判断当前玩家是否获胜,获胜则游戏结束
 93                         Gameover = IsWin(qishou[i], new Point(qipanX, qipanY));
 94                         if (Gameover)
 95                         {
 96                             //if (actionWin!=null)
 97                             //{
 98                             //    actionWin.Invoke(qishou[i].PlayerName);
 99                             //}
100                             actionWin?.Invoke(qishou[i].PlayerName);
101                         }
102 
103                         //走棋后设置棋手不可走棋
104                         //qishou[i].LuoZi(x, y, g);
105                     }
106                     qishou[i].IsZouqi = !qishou[i].IsZouqi;
107                 }
108             }
109         }
110         /// <summary>
111         /// 刷新界面
112         /// </summary>
113         public void Render()
114         {
115             qipan.Render(actionDrawLine);
116             for (int i = 0; i < qishou.Count; i++)
117             {
118                 qishou[i].Render(qipan.start, qipan.Grid, actionDrawimage);
119             }
120         }
121         /// <summary>
122         /// 判断是否获胜
123         /// </summary>
124         /// <param name="qishou">棋手</param>
125         /// <param name="p">当前棋子坐标</param>
126         /// <returns></returns>
127         public bool IsWin(QiShou qishou, Point p)
128         {
129 
130             //如果点在连续直线上就累加,当sum=5时,表示连续5个棋子在一条直线上
131             int sum = 1;
132             for (int i = 0; i < 8; i++)
133             {
134                 Console.WriteLine(i);
135                 //下一个要检查的点
136                 Point nextP = p;
137                 Direction dr = (Direction)i;
138                 if (i % 2 == 0)
139                 {
140                     sum = 1;
141                 }
142                 for (int j = 0; j < 5; j++)
143                 {
144                     //根据当前方向判断设置下一个点
145                     #region switch
146                     switch (dr)
147                     {
148                         case Direction.Top:
149                             nextP.X = nextP.X;
150                             nextP.Y = nextP.Y - 1;
151                             break;
152                         case Direction.RightTop:
153                             nextP.X = nextP.X + 1;
154                             nextP.Y = nextP.Y - 1;
155                             break;
156                         case Direction.Rigth:
157                             nextP.X = nextP.X + 1;
158                             nextP.Y = nextP.Y;
159                             break;
160                         case Direction.RigthBotton:
161                             nextP.X = nextP.X + 1;
162                             nextP.Y = nextP.Y + 1;
163                             break;
164                         case Direction.Botton:
165                             nextP.X = nextP.X;
166                             nextP.Y = nextP.Y + 1;
167                             break;
168                         case Direction.LeftBotton:
169                             nextP.X = nextP.X - 1;
170                             nextP.Y = nextP.Y + 1;
171                             break;
172                         case Direction.Left:
173                             nextP.X = nextP.X - 1;
174                             nextP.Y = nextP.Y;
175                             break;
176                         case Direction.LeftTop:
177                             nextP.X = nextP.X - 1;
178                             nextP.Y = nextP.Y - 1;
179                             break;
180                         default:
181                             break;
182                     }
183                     #endregion
184 
185                     if (nextP.X >= 0 && nextP.X < qishou.ZouQiQiPan.GetLength(0)
186                         && nextP.Y >= 0 && nextP.Y < qishou.ZouQiQiPan.GetLength(1))
187                     {
188                         if (qishou.ZouQiQiPan[nextP.X, nextP.Y] == 0)
189                         {
190                             break;
191                         }
192                         else
193                         {
194                             sum += qishou.ZouQiQiPan[nextP.X, nextP.Y];
195                         }
196                     }
197                     else
198                     {
199                         break;
200                     }
201                 }
202                 if (sum == 5)
203                 {
204                     return true;
205                 }
206 
207             }
208 
209             return false;
210         }
211         /// <summary>
212         /// 开始游戏
213         /// </summary>
214         public void StartGame()
215         {
216             Gameover = false;
217             //初始化棋盘
218             qipan = new QiPan();
219             //初始化两种棋手:白棋和黑棋
220             qishou = new List<QiShou>()
221             {
222                 new QiShou(Resources.白棋,0.08f,new byte[qipan.Heigth/qipan.Grid+1,qipan.Width/qipan.Grid+1]) {IsZouqi=true,PlayerName="Bai" },
223 
224                 new QiShou(Resources.黑棋,0.08f,new byte[qipan.Heigth/qipan.Grid+1,qipan.Width/qipan.Grid+1]) { IsZouqi=false,PlayerName="Hei" }
225             };
226             Render();
227         }
228         #endregion
229 
230     }
231 }

棋手类:
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2016-07-15 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档