logo资料库

同步TCP网络五子棋-课程设计报告.doc

第1页 / 共42页
第2页 / 共42页
第3页 / 共42页
第4页 / 共42页
第5页 / 共42页
第6页 / 共42页
第7页 / 共42页
第8页 / 共42页
资料共42页,剩余部分请下载后查看
1.课程设计内容
2.课程设计目的
3.背景知识
4.工具/准备工作
5.设计步骤与方法
5.1.服务器端编程
5.1.1.服务器具体实现步骤如下:
5.1.1.1.玩家信息
5.1.1.2.游戏桌位信息
5.1.1.3.公用的方法
5.1.1.4.玩家房间状态信息
5.1.1.5.登录窗体事件
5.1.1.6.五子棋主要代码
5.2.客户端编程
5.2.1.客户端具体实现步骤如下:
5.2.1.1.游戏室
5.2.1.2.游戏界面及窗体事件
6.设计结果及分析
7.设计结论
8.问题及心得体会
9.对本设计过程及方法、手段的改进建议
10.参考文献
11.课程设计评价(教师)
网络五子棋 1. 课程设计内容 五子棋游戏以其优秀的传统知识跟智慧深受广大玩家的喜爱,编制五子棋程 序因其规则简单而大受编程者的欢迎,然而它却要求程序员对五子棋规则有相当 深入的了解。网络五子棋的主要内容是:根据五子棋的基本规则,要让对方客户 端知道该在哪一点下子,就要根据盘面的形势,并把棋盘棋子的重新绘制,也就 是更新该点的位置,然后再通过监听网络传递的消息,直到新的位置放在棋盘的 什么位置上,在进行修改,并通过计算,判定游戏的获胜方和游戏的结束与否.,因此 玩家就能反复的通过网络进行联机游戏。 2. 课程设计目的 为了更深入地理解 TCP 协议的具体应用编程技巧,本设计使用功能强大的 VS2008 开发工具和 C#开发语言,开发出一个拥有自己特色的五子棋程序,其中 VS2008 是一个能开放代码的开发工具,基本 C#的扩展平台。就该五子棋程序来 讲,它只是一个框架和一组服务,用于通过插件,组件,控件构建开发环境。 对于游戏,要求能够达到以下功能: (1).服务器可以同时服务多桌,每桌允许两个玩家通过 internet 对弈。 (2)允许玩家自由选择坐在哪里一桌的哪一方。如果两个玩家坐在同一桌,双 方老师应能看到对方的状态。两个玩家均单击开始按钮后,游戏才开始。 (3)游戏开始后,由黑色棋子的玩家先下棋。 (4)每当玩家走完一步棋子后,都检测相当颜色的棋子是否已经相邻的出现达 到五个,即游戏结束。 (5)同一桌的玩家可以聊天。 3. 背景知识 同步工作方式,利用 TCP 编写程序执行到发送,接收或监听语句时,在未完 成工作前是不会往下执行,即处于阻塞状态,这样的 TCP 协议有利于编写五子 棋这样的回合制游戏。采用 Socket 类编程,运用了系统提供相应的方法。逻辑 关系上,都会涉及服务器,客户端这两个概念。
课程设计报告 4. 工具/准备工作 资源方法有棋盘,黑白棋子,还有游戏室的位置头像如下图: 5. 设计步骤与方法 5.1. 服务器端编程 服务器启动后,需要创建一个线程专门用于监听玩家连接请求。在监听线程 中,服务器一旦接受一个连接,就创建一个线程与该玩家对应的线程,用于接收 该玩家发送的信息,并根据玩家发送的信息来提供相应的服务。有多少个玩家就 得创建多少个对应的线程。直到玩家退出游戏室,其对应的线程才终止。 服务器必须限制进入游戏室的玩家数量,具体多少,可以由服务器的启动来 设置。 5.1.1. 服务器具体实现步骤如下: 创建一个命名为 GameServer 的 Windows 应用程序,将 Form1.cs 改名为 FormServer.cs,界面设计如下: 第 2 页 共 42 页
课程设计报告 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 = client.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 bool Start {get{return start; } set{start = value; } } 第 3 页 共 42 页
课程设计报告 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 Service(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); listbox.SelectedIndex = listbox.Items.Count - 1; listbox.ClearSelected(); { } } } 第 4 页 共 42 页
课程设计报告 5.1.1.4. 玩家房间状态信息 在资源管理器中添加一个类文件 GameRoom.cs,用来保存玩家游戏的顺序分 配及判定输赢。代码如下: class GameRoom { private GobangBoard gameBoard = new GobangBoard(); public GobangBoard GameBoard { } get { } return gameBoard; /// /// 向listbox中添加显示信息以及向客户发送信息 /// private ListBox listbox; private Service service; //构造函数 public GameRoom(ListBox listbox) { } this.listbox = listbox; gamePlayer[0] = new Player(); gamePlayer[1] = new Player(); service = new Service(listbox); //将棋盘上的棋子全部清除 gameBoard.InitializeBoard(); public void SetChess(int i, int j, int chessColor) { //发送格式:SetChess,行,列,颜色 gameBoard.Grid[i, 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 { 第 5 页 共 42 页
课程设计报告 service.SendToRoom(this, "NextChess," + gameBoard.NextIndex); } } private void ShowWin(int chessColor) gamePlayer[0].Start = false; gamePlayer[1].Start = false; gameBoard.InitializeBoard(); //发送格式:Win,胜方棋子颜色 service.SendToRoom(this, string.Format("Win,{0}", chessColor)); { } } 5.1.1.5. 登录窗体事件 在 FormServer 的代码编辑下,添加对应的控件代码,源程序如下: public partial 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) { } listBoxStatus.HorizontalScrollbar = true; IPAddress[] addrIP = Dns.GetHostAddresses(Dns.GetHostName()); localAddress = addrIP[0]; buttonStop.Enabled = false; private void buttonStart_Click(object sender, EventArgs e) { if (int.TryParse(textBoxMaxTables.Text, out maxRoomNumbers) == false || int.TryParse(textBoxMaxUsers.Text, out maxUsers) == false) { } MessageBox.Show("请输入在规定范围内的正整数"); return; 第 6 页 共 42 页
课程设计报告 if (maxUsers < 1 || maxUsers > 500) { } MessageBox.Show("允许进入的人数只能在1-300之间"); return; if (maxRoomNumbers < 1 || maxRoomNumbers > 100) { } MessageBox.Show("允许开出的房间数只能在1-100之间"); return; textBoxMaxUsers.Enabled = false; textBoxMaxTables.Enabled = false; //初始化数组 gameRoom = new GameRoom[maxRoomNumbers]; for (int i = 0; i < maxRoomNumbers; i++) { } gameRoom[i] = new GameRoom(listBoxStatus); myListener = new TcpListener(localAddress, port); myListener.Start(); service.AddListBoxItem(string.Format( "{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 sender, 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.Enabled = true; textBoxMaxTables.Enabled = true; } private void StopCLientAndListener() 第 7 页 共 42 页
课程设计报告 { } for (int i = 0; i < userList.Count; i++) { } userList[i].client.Close(); myListener.Stop(); private void ListenClientConnect() { while (true) { TcpClient newClient = null; try { } newClient = myListener.AcceptTcpClient(); catch { } break; 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.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.ReadLine(); 第 8 页 共 42 页
分享到:
收藏