同步TCP网络五子棋-课程设计报告(共45页)_第1页
同步TCP网络五子棋-课程设计报告(共45页)_第2页
同步TCP网络五子棋-课程设计报告(共45页)_第3页
同步TCP网络五子棋-课程设计报告(共45页)_第4页
同步TCP网络五子棋-课程设计报告(共45页)_第5页
已阅读5页,还剩41页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、精选优质文档-倾情为你奉上电子科技大学中山学院课程设计说明书学生信息系别计算机工程系专业08数字媒体班级 A班姓名学号课程设计信息课程名称网络程序设计课程设计题目同步TCP网络五子棋课程设计时间2010.12.62010.12.24指导教师批改情况成绩评阅教师批改时间年 月 日20102011学年第 一 学期目 录网络五子棋1. 课程设计内容五子棋游戏以其优秀的传统知识跟智慧深受广大玩家的喜爱,编制五子棋程序因其规则简单而大受编程者的欢迎,然而它却要求程序员对五子棋规则有相当深入的了解。网络五子棋的主要内容是:根据五子棋的基本规则,要让对方客户端知道该在哪一点下子,就要根据盘面的形势,并把棋盘

2、棋子的重新绘制,也就是更新该点的位置,然后再通过监听网络传递的消息,直到新的位置放在棋盘的什么位置上,在进行修改,并通过计算,判定游戏的获胜方和游戏的结束与否.,因此玩家就能反复的通过网络进行联机游戏。2. 课程设计目的为了更深入地理解TCP协议的具体应用编程技巧,本设计使用功能强大的VS2008开发工具和C#开发语言,开发出一个拥有自己特色的五子棋程序,其中VS2008是一个能开放代码的开发工具,基本C#的扩展平台。就该五子棋程序来讲,它只是一个框架和一组服务,用于通过插件,组件,控件构建开发环境。对于游戏,要求能够达到以下功能:(1).服务器可以同时服务多桌,每桌允许两个玩家通过inter

3、net对弈。(2)允许玩家自由选择坐在哪里一桌的哪一方。如果两个玩家坐在同一桌,双方老师应能看到对方的状态。两个玩家均单击开始按钮后,游戏才开始。(3)游戏开始后,由黑色棋子的玩家先下棋。(4)每当玩家走完一步棋子后,都检测相当颜色的棋子是否已经相邻的出现达到五个,即游戏结束。(5)同一桌的玩家可以聊天。3. 背景知识同步工作方式,利用TCP编写程序执行到发送,接收或监听语句时,在未完成工作前是不会往下执行,即处于阻塞状态,这样的TCP协议有利于编写五子棋这样的回合制游戏。采用Socket类编程,运用了系统提供相应的方法。逻辑关系上,都会涉及服务器,客户端这两个概念。4. 工具/准备工作资源方

4、法有棋盘,黑白棋子,还有游戏室的位置头像如下图: 5. 设计步骤与方法5.1. 服务器端编程服务器启动后,需要创建一个线程专门用于监听玩家连接请求。在监听线程中,服务器一旦接受一个连接,就创建一个线程与该玩家对应的线程,用于接收该玩家发送的信息,并根据玩家发送的信息来提供相应的服务。有多少个玩家就得创建多少个对应的线程。直到玩家退出游戏室,其对应的线程才终止。服务器必须限制进入游戏室的玩家数量,具体多少,可以由服务器的启动来设置。5.1.1. 服务器具体实现步骤如下:创建一个命名为GameServer的Windows应用程序,将Form1.cs改名为FormServer.cs,界面设计如下:5

5、.1.1.1. 玩家信息在资源管理器中,添加User.cs,用于保存与该玩家的通信所需要的信息。代码如下:class User public readonly TcpClient client; public readonly StreamReader sr; public readonly StreamWriter sw; public string userName; public User(TcpClient client) this.client = client; this.userName = "" NetworkStream netStream = clien

6、t.GetStream(); sr = new StreamReader(netStream, System.Text.Encoding.Default); sw = new StreamWriter(netStream, System.Text.Encoding.Default); 5.1.1.2. 游戏桌位信息在资源管理器中,添加Player.cs,用于保存已经坐到游戏桌位上玩家的情况。代码如下: class Player private User user; public User GameUser get return user; set user = value; public bo

7、ol Start getreturn start; setstart = value; public Player() start = false; user = null; 5.1.1.3. 公用的方法在资源管理器中添加类文件Service.cs,用于提供公用的方法。代码如下:class Service private ListBox listbox; private delegate void AddListBoxItemCallback(string str); private AddListBoxItemCallback addListBoxItemCallback; public S

8、ervice(ListBox listbox) this.listbox = listbox; addListBoxItemCallback = new AddListBoxItemCallback(AddListBoxItem); public void AddListBoxItem(string str) if (listbox.InvokeRequired = true) listbox.Invoke(addListBoxItemCallback, str); else if (listbox.IsDisposed = false) listbox.Items.Add(str); lis

9、tbox.SelectedIndex = listbox.Items.Count - 1; listbox.ClearSelected(); 5.1.1.4. 玩家房间状态信息在资源管理器中添加一个类文件GameRoom.cs,用来保存玩家游戏的顺序分配及判定输赢。代码如下:class GameRoom private GobangBoard gameBoard = new GobangBoard(); public GobangBoard GameBoard get return gameBoard; / <summary> / 向listbox中添加显示信息以及向客户发送信息

10、/ </summary> private ListBox listbox; private Service service; /构造函数 public GameRoom(ListBox listbox) this.listbox = listbox; gamePlayer0 = new Player(); gamePlayer1 = new Player(); service = new Service(listbox); /将棋盘上的棋子全部清除 gameBoard.InitializeBoard(); public void SetChess(int i, int j, int

11、 chessColor) /发送格式:SetChess,行,列,颜色 gameBoard.Gridi, j = chessColor; gameBoard.NextIndex = gameBoard.NextIndex = 0 ? 1 : 0; service.SendToRoom(this, string.Format("SetChess,0,1,2", i, j, chessColor); if (gameBoard.IsWin(i, j) ShowWin(chessColor); else service.SendToRoom(this, "NextChes

12、s," + gameBoard.NextIndex); private void ShowWin(int chessColor) gamePlayer0.Start = false; gamePlayer1.Start = false; gameBoard.InitializeBoard(); /发送格式:Win,胜方棋子颜色 service.SendToRoom(this, string.Format("Win,0", chessColor); 5.1.1.5. 登录窗体事件在FormServer的代码编辑下,添加对应的控件代码,源程序如下:public par

13、tial class FormServer : Form private int port = 51888; private TcpListener myListener; private Service service; public FormServer() InitializeComponent(); listBoxStatus.HorizontalScrollbar = true; service = new Service(listBoxStatus); private void FormServer_Load(object sender, EventArgs e) listBoxS

14、tatus.HorizontalScrollbar = true; IPAddress addrIP = Dns.GetHostAddresses(Dns.GetHostName(); localAddress = addrIP0; buttonStop.Enabled = false; private void buttonStart_Click(object sender, EventArgs e) if (int.TryParse(textBoxMaxTables.Text, out maxRoomNumbers) = false | int.TryParse(textBoxMaxUse

15、rs.Text, out maxUsers) = false) MessageBox.Show("请输入在规定范围内的正整数"); return; if (maxUsers < 1 | maxUsers > 500) MessageBox.Show("允许进入的人数只能在1-300之间"); return; if (maxRoomNumbers < 1 | maxRoomNumbers > 100) MessageBox.Show("允许开出的房间数只能在1-100之间"); return; textBoxMa

16、xUsers.Enabled = false; textBoxMaxTables.Enabled = false; /初始化数组 gameRoom = new GameRoommaxRoomNumbers; for (int i = 0; i < maxRoomNumbers; i+) gameRoomi = new GameRoom(listBoxStatus); myListener = new TcpListener(localAddress, port); myListener.Start(); service.AddListBoxItem(string.Format( &quo

17、t;0:yyyy年M月d日(dddd)h点m分 开始在1:2监听客户连接", DateTime.Now, localAddress, port); /创建一个线程监听客户端连接请求 ThreadStart ts = new ThreadStart(ListenClientConnect); Thread myThread = new Thread(ts); myThread.Start(); buttonStart.Enabled = false; buttonStop.Enabled = true; private void buttonStop_Click(object send

18、er, EventArgs e) service.AddListBoxItem(string.Format("目前连接用户数:0", userList.Count); service.AddListBoxItem(string.Format( "0:yyyy年M月d日(dddd)h点m分 开始停止服务,并依次使用户退出。", DateTime.Now); StopCLientAndListener(); buttonStart.Enabled = true; buttonStop.Enabled = false; textBoxMaxUsers.Enab

19、led = true; textBoxMaxTables.Enabled = true; private void StopCLientAndListener() for (int i = 0; i < userList.Count; i+) userListi.client.Close(); myListener.Stop(); private void ListenClientConnect() while (true) TcpClient newClient = null; try newClient = myListener.AcceptTcpClient(); catch br

20、eak; ParameterizedThreadStart pts = new ParameterizedThreadStart(ReceiveData); Thread threadReceive = new Thread(pts); User user = new User(newClient); threadReceive.Start(user); userList.Add(user); service.AddListBoxItem(string.Format("0连接服务器成功。", newClient.Client.RemoteEndPoint); service

21、.AddListBoxItem(string.Format("当前连接用户数:0", userList.Count); private void ReceiveData(object obj) User user = (User)obj; TcpClient client = user.client; bool normalExit = false; bool exitWhile = false; while (exitWhile = false) string receiveString = null; try receiveString = user.sr.ReadLi

22、ne(); catch service.AddListBoxItem("接收数据失败"); RemovePlayerfromRoom(user); if (receiveString = null) if (normalExit = false) if (client.Connected = true) service.AddListBoxItem(string.Format( "与0失去联系,已终止接收该用户信息", client.Client.RemoteEndPoint); RemovePlayerfromRoom(user); break; st

23、ring splitString = receiveString.Split(','); int tableIndex = -1; /桌号 int side = -1; /座位号 int anotherSide = -1; /对方座位号 string sendString = "" / <summary> / 循环检测该用户是否坐到某游戏桌上 / </summary> private void RemovePlayerfromRoom(User user) for (int i = 0; i < gameRoom.Length;

24、 i+) if (gameRoomi.BlackPlayer.GameUser != null) if (gameRoomi.BlackPlayer.GameUser = user) StopPlayer(i, 0); return; if (gameRoomi.WhitePlayer.GameUser != null) if (gameRoomi.WhitePlayer.GameUser = user) StopPlayer(i, 1); return; for (int j = 0; j < gameRoomi.lookOnUser.Count; j+) if (gameRoomi.

25、lookOnUserj != null) if (gameRoomi.lookOnUserj = user) gameRoomi.lookOnUser.RemoveAt(j); return; / <summary> / 让第i个房间第j个座位的玩家退出房间 / </summary> private void StopPlayer(int i, int j) gameRoomi.gamePlayerj.Start = false; /gameRoomi.gamePlayerj.GameUser = null; /发送格式:Lost,座位号,用户名 service.Sen

26、dToRoom(gameRoomi, string.Format("LostPlayer,0,1,2", i, j, gameRoomi.gamePlayerj.GameUser.userName); / <summary> / 获取指定房间人员情况及昵称字符串,每人之间用/分隔。 / 格式:黑方昵称/白方昵称/旁观者昵称/旁观者昵称/ / </summary> private string GetRoomOnlineString(int tableIndex) /此处不能用string,否则效率会很低 StringBuilder strBuilde

27、r = new StringBuilder(); GameRoom room = gameRoomtableIndex; for (int i = 0; i < room.gamePlayer.Length; i+) if (room.gamePlayeri.GameUser != null) strBuilder.Append(room.gamePlayeri.GameUser.userName); strBuilder.Append("/"); for (int i = 0; i < room.lookOnUser.Count; i+) strBuilder

28、.Append(room.lookOnUseri.userName); strBuilder.Append("/"); /移除最后一个/符号 strBuilder = strBuilder.Remove(strBuilder.Length - 1, 1); return strBuilder.ToString(); / <summary> / 获取某桌棋盘上的落子情况 / </summary> / <param name="tableIndex">桌号(房间号)</param> / <returns&

29、gt;棋盘上各棋子的位置</returns> private string GetBoardGrid(int tableIndex) StringBuilder sb = new StringBuilder(); int, grid = gameRoomtableIndex.GameBoard.Grid; for (int i = 0; i <= grid.GetUpperBound(0); i+) for (int j = 0; j <= grid.GetUpperBound(1); j+) sb.Append(gridi, j.ToString(); sb.Appe

30、nd("/"); /移除最后一个"/"符号 sb = sb.Remove(sb.Length - 1, 1); return sb.ToString(); /关闭窗体时触发的事件 private void FormDDServer_FormClosing(object sender, FormClosingEventArgs e) /在没有单击开始服务就直接退出时,myListener为null if (myListener != null) StopCLientAndListener(); 5.1.1.6. 五子棋主要代码在资源管理器中生成一个类文件G

31、obangBoard.cs,用于刷新,重画棋盘,棋子,以及玩家的输赢判断。代码如下:class GobangBoard /无棋子 public const int None = -1; /黑色棋子 public const int Black = 0; /白色棋子 public const int White = 1; /15*15的方格 private int, grid = new int15, 15; / <summary> / 棋盘 / </summary> public int, Grid get return grid; private int nextIn

32、dex; / <summary> / 应该黑棋放子还是白棋放子 / </summary> public int NextIndex get return nextIndex; set nextIndex = value; /构造函数 public GobangBoard() InitializeBoard(); / <summary> / 将*15的方格中的每个交叉点均设置为无棋子 / </summary> public void InitializeBoard() for (int i = 0; i <= grid.GetUpperBou

33、nd(0); i+) for (int j = 0; j <= grid.GetUpperBound(1); j+) gridi, j = None; nextIndex = Black; / <summary> / 判断下棋位置是否有棋子 / </summary> public bool IsExist(int i, int j) if (gridi, j != None) return true; else return false; / <summary> / 获取棋子落下后是否获胜 / </summary> public bool

34、IsWin(int i, int j) /与方格的第i,j交叉点向四个方向的连子数,依次是水平,垂直,左上右下,左下右上 int numbers = new int4; numbers0 = GetRowNumber(i, j); numbers1 = GetColumnNumber(i, j); numbers2 = GetBacklashNumber(i, j); numbers3 = GetSlashNumber(i, j); /检查是否获胜 for (int k = 0; k < numbers.Length; k+) if (Math.Abs(numbersk) = 5) re

35、turn true; return false; / <summary> / 判断横向相同颜色的棋子个数 / </summary> / <returns>同色棋子个数</returns> private int GetRowNumber(int i, int j) /连子个数 int num = 1; /向右检查 int x = i + 1; while (x < 15) /前方棋子与i,j点不同时跳出循环 if (gridx, j = gridi, j) num+; x+; else break; /向左检查 x = i - 1; while (x >=

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论