简单的西洋双陆棋,无计算机人工智能
最编程
2024-06-26 12:20:57
...
刚学了C#委托,做了个五子棋练习,把前台绘制和后台逻辑分开,前台绘制方法用委托传给后台逻辑。
界面好简单。。。
先看类图
控制类控制整个游戏的逻辑,包括调用棋盘类的属性初始化棋盘、初始化两个棋手、轮流落子。棋盘里有一个二维数组保存整个棋盘的落子情况,棋手里也有一个二维数组保存自己的落子情况。方向类是为了方便判断输赢的。
下面是代码:注释很详细就不说明了:
主要控制类:
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 }
棋手类:
上一篇: Java 的数组