简单五子棋,没有电脑AI

  刚学了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 }

棋手类:

  1 using System;
  2 using System.Drawing;
  3
  4 namespace 五子棋.Control
  5 {
  6     class QiShou
  7     {
  8         #region 字段
  9         /// <summary>
 10         /// 棋子图像
 11         /// </summary>
 12         /// /// <summary>
 13         /// 走棋棋盘
 14         /// </summary>
 15         byte[,] zouqiqipan;
 16         #endregion
 17         #region 属性
 18         public string PlayerName { get; set; }
 19         public Image ImagePlayer { get; set; }
 20         /// <summary>
 21         /// 棋子图像缩放比例
 22         /// </summary>
 23         public float ImageScale { get; set; }
 24
 25         /// <summary>
 26         /// 走棋棋盘
 27         /// </summary>
 28         public byte[,] ZouQiQiPan
 29         {
 30             get
 31             {
 32                 return zouqiqipan;
 33             }
 34             set
 35             {
 36                 zouqiqipan = value;
 37             }
 38         }
 39         /// <summary>
 40         /// 是否可以走棋
 41         /// </summary>
 42         public bool IsZouqi { get; set; }
 43         #endregion
 44         /// <summary>
 45         /// 构造函数
 46         /// </summary>
 47         /// <param name="image">棋子图像</param>
 48         /// <param name="imagescale">棋子缩放比例</param>
 49         /// /// <param name="zouqiqipan">走棋棋盘大小</param>
 50         public QiShou(Image image, float imagescale, byte[,] zouqiqipan)
 51         {
 52             this.zouqiqipan = zouqiqipan;
 53             ImagePlayer = image;
 54             ImageScale = imagescale;
 55             Init();
 56         }
 57         /// <summary>
 58         /// 初始化棋手
 59         /// </summary>
 60         private void Init()
 61         {
 62             for (int i = 0; i < zouqiqipan.GetLength(0); i++)
 63             {
 64                 for (int j = 0; j < zouqiqipan.GetLength(1); j++)
 65                 {
 66                     zouqiqipan[i, j] = 0;
 67                 }
 68             }
 69         }
 70
 71         /// <summary>
 72         /// 下棋落字
 73         /// </summary>
 74         /// <param name="x">棋盘X网格</param>
 75         /// <param name="y">棋盘Y网格</param>
 76         public void LuoZi(int x, int y)
 77         {
 78             ZouQiQiPan[x, y] = 1;
 79         }
 80         #region 绘制棋子
 81         /// <summary>
 82         /// 绘制所有棋子
 83         /// </summary>
 84         /// <param name="start"></param>
 85         /// <param name="grid"></param>
 86         public void Render(Point start, int grid,Action<Image, int,int,float> actionDrawImage)
 87         {
 88             for (int i = 0; i < ZouQiQiPan.GetLength(0); i++)
 89             {
 90                 for (int j = 0; j < ZouQiQiPan.GetLength(1); j++)
 91                 {
 92                     if (zouqiqipan[i, j] == 1)
 93                     {
 94                         Render(i * grid + start.X, i * grid + start.Y,actionDrawImage);
 95
 96                     }
 97                 }
 98             }
 99         }
100         public void Render(int x,int y, Action<Image, int, int, float> actionDrawImage)
101         {
102             actionDrawImage?.Invoke(ImagePlayer, x, y, ImageScale);
103         }
104         ///// <summary>
105         ///// 绘制棋子
106         ///// </summary>
107         ///// <param name="x">棋盘X网格坐标</param>
108         ///// <param name="y">棋盘Y网格坐标</param>
109         ///// <param name="g">画家对象</param>
110         //public void Render(int x, int y)
111         //{
112         //    //actionDrawimage(x, y, ImagePlayer, ImageScale);
113
114
115         //    //绘制棋子,绘制的坐标应该换算到中心
116         //    g.DrawImage(ImagePlayer, x - ImagePlayer.Width * ImageScale / 2, y - ImagePlayer.Height * ImageScale / 2,
117         //        ImagePlayer.Width * ImageScale, ImagePlayer.Height * ImageScale);
118         //}
119         #endregion
120
121
122     }
123
124 }

棋盘类:

  1 using System;
  2 using System.Drawing;
  3
  4 namespace 五子棋.Control
  5 {
  6     class QiPan
  7     {
  8
  9         /// <summary>
 10         /// 棋盘绘制起点坐标
 11         /// </summary>
 12         public readonly Point start;
 13         /// <summary>
 14         /// X缩放
 15         /// </summary>
 16         public int ScaleX { get; set; }
 17         /// <summary>
 18         /// Y缩放
 19         /// </summary>
 20         public int ScaleY { get; set; }
 21         /// <summary>
 22         /// 棋盘宽度
 23         /// </summary>
 24         public int Width { get; set; }
 25         /// <summary>
 26         /// 棋盘高度
 27         /// </summary>
 28         public int Heigth { get; set; }
 29         /// <summary>
 30         /// 网格大小
 31         /// </summary>
 32         public int Grid { get; set; }
 33         /// <summary>
 34         /// 棋盘棋子
 35         /// </summary>
 36         private byte[,] qipanQiZi;
 37         public byte this[int x, int y]
 38         {
 39             get
 40             {
 41                 if (x < qipanQiZi.GetLength(0) && y < qipanQiZi.GetLength(1))
 42                 {
 43                     return qipanQiZi[x, y];
 44                 }
 45                 else
 46                 {
 47                     return 0;
 48                 }
 49             }
 50             set
 51             {
 52                 if (x < qipanQiZi.GetLength(0) && y < qipanQiZi.GetLength(1))
 53                 {
 54                     qipanQiZi[x, y] = value;
 55                 }
 56             }
 57         }
 58
 59         /// <summary>
 60         /// 构造函数
 61         /// </summary>
 62         /// <param name="width">棋盘宽度</param>
 63         /// <param name="height">棋盘高度</param>
 64         /// <param name="grid">棋盘网格大小</param>
 65         public QiPan(Point start, int width, int height, int grid)
 66         {
 67             this.start = start;
 68             Width = width;
 69             Heigth = height;
 70             Grid = grid;
 71             Init();
 72
 73         }
 74
 75         private void Init()
 76         {
 77             qipanQiZi = new byte[Width / Grid + 1, Heigth / Grid + 1];
 78             for (int i = 0; i < qipanQiZi.GetLength(0); i++)
 79             {
 80                 for (int j = 0; j < qipanQiZi.GetLength(1); j++)
 81                 {
 82                     qipanQiZi[i, j] = 0;
 83                 }
 84             }
 85         }
 86
 87         /// <summary>
 88         /// 构造函数
 89         /// 默认棋盘大小为400*400,方格大小为40
 90         /// </summary>
 91         public QiPan() : this(new Point(50, 50), 400, 400, 40)
 92         {
 93         }
 94         #region Graphics绘制棋盘
 95
 96
 97         /// <summary>
 98         /// 绘制棋盘
 99         /// </summary>
100         /// <param name="g"></param>
101         //public void Render(Graphics g)
102         //{
103         //    for (int i = 0; i <= Width / Grid; i++)
104         //    {
105         //        g.DrawLine(Pens.Black, start.X + (Grid * i), start.Y, start.X + (Grid * i), start.Y + Heigth);
106
107         //    }
108         //    for (int i = 0; i <= Heigth / Grid; i++)
109         //    {
110         //        g.DrawLine(Pens.Black, start.X, start.Y + (Grid * i), start.X + Width, start.Y + (Grid * i));
111         //    }
112         //}
113         #endregion
114         public void Render(Action< Point, Point> actionDrawLine)
115         {
116             int row = Heigth / Grid + 1;
117             int cel = Width / Grid + 1;
118             for (int i = 0; i < row; i++)
119             {
120                 actionDrawLine?.Invoke( new Point(start.X, start.Y + Grid * i), new Point(start.X + Width, start.Y + Grid * i));
121             }
122             for (int i = 0; i < cel; i++)
123             {
124                 actionDrawLine?.Invoke( new Point(start.X + Grid * i, start.Y), new Point(start.X + Grid * i, start.Y + Heigth));
125             }
126         }
127     }
128 }

时间: 2024-10-14 03:18:54

简单五子棋,没有电脑AI的相关文章

控制台简单五子棋

1 import java.util.Scanner; 2 3 //控制台简单五子棋 4 public class wuziqi { 5 6 //二维数组作为棋盘 7 private static char[][] board=new char[16][16]; 8 //已下棋子数目 9 private static int cnt; 10 //分别代表玩家1,2的棋子 11 private static char[] qizi={'#','@'}; 12 //八方向搜索检测 13 privat

如何简单的识别电脑图片中的文字

相信很多人都和小编一样有这样的烦恼,经常需要将电脑中的图片或者扫描件中的文字提取出来应用到别的地方,但是使用了很多种方法效果都不是很理想,这就比较令人头疼了,那如何简单的识别电脑图片中的文字呢?接下来小编就带大家来了解下具体的操作方法. 使用工具:迅捷OCR文字识别软件 操作步骤: 1:打开电脑中的迅捷OCR文字识别软件,在软件左边导航栏中选择图片局部识别板块. 2:进入图片局部识别版块后就可以将所需识别的图片添加进来了,点击添加文件按钮添加. 3:接着鼠标点击框选工具,拖动鼠标在图片将所需识别

简单安全的电脑文件加密方案?如何控制数据文档随意外发?选择湖南风奥科技

网络技术的普及程度的提高,确实给该阶段时代的发展带来便利,也让人们享受到互联网发展带来的快捷!人们在享受互联网发展带来的快捷感的同时,大家是否思考过,互联网的发展又会给这个时代带来哪些危机? 为什么要加强对电脑文件加密的使用?相信不少的企业以及个人都在互联网新闻上看到了不少关于某某企业.某某机构等数据泄露,多少多少数据泄露为企业带来了什么样的影响等等诸如此类的相关报道!正是因为这些数据泄露事件在互联网上的公开,让现阶段的政府部门等等加强了对互联网市场安全监管,同时企事业单位也加强了对自身企业数据

控制台的简单五子棋

只实现了最基本的功能,玩家下棋和电脑随机下棋.缺乏输入检查,重复下棋检查,判断输赢,人工智能算法等等. 待完善. 1 import java.io.BufferedReader; 2 import java.io.InputStreamReader; 3 4 // GoBang(五子棋) 5 class GoBang { 6 // 二维数组来模拟一个棋盘 7 private String[][] board; 8 // 表示棋盘的长.宽度 9 private static int BOARD_S

简单实用的电脑视频录屏软件哪个好用?

电脑上面有很多不能下载的视频文件我想大家都是知道的,那么问题来了,如何去解决这件事情呢?这个时候就要用到桌面录屏软件了,其实录制电视视频特别简单,今天小编就来和你们一起探讨这款软件,说它简单实用一点毛病没有,快来和小编一起看看吧! 桌面录屏软件http://www.xunjieshipin.com/download-luping 屏幕录像工具http://www.onlinedown.net/soft/1152608.htm 软件介绍: 迅捷屏幕录像工具是一款即专业又好用的电脑录屏软件,支持教学

[收藏]C++简单五子棋

1 #include<iostream> 2 #include<iomanip> 3 using namespace std; 4 5 const int X = 21; //棋盘行数 6 const int Y = 21; //棋盘列数 7 char p[X][Y]; //定义棋盘 8 int m = 0;//定义临时点,保存输入坐标 9 int n = 0; 10 11 void display() //输出棋盘 12 { 13 for (int i = 0; i < X

C++的简单“五子棋”游戏,只是核心代码,资源代码未添加

ChessBoard.h 1 #ifndef __CHESS_BOARD_H__ 2 #define __CHESS_BOARD_H__ 3 4 #include "DataStruct.h" 5 6 #define COL_WIDTH 45 7 #define ROW_WIDTH 45 8 9 class CChessBoard : public CWnd 10 { 11 private: 12 CBitmap m_bitBlackChess, m_bitWhiteChess; 13

简单五子棋

#include<iostream> #include <vector> #include <windows.h> using namespace std; const int Max=19; ///该位置手否已被占用 bool PZ(vector<vector<int> > &aaa,int x,int y ); ///判断胜方 bool SF(vector<vector<int> > &aaa,int

简单五子棋实现

一.定义一个对手Rival类 package com.itwang.gonbang; public class Rival { private String color;//颜色 private String nickName;//昵称 public String getNickName() { return nickName; } public void setNickName(String nickName) { this.nickName = nickName; } public Stri