基于socket的联机五子棋

一、团队介绍

团队名称:

团队成员 职务 负责部分 个人链接
林仕峰 组长 网络编程和多线程 (114条消息) 五子棋个人报告_林仕峰的博客-CSDN博客
吴双 组员 五子棋算法、棋盘棋子的GUI 五子棋个人报告
林伟涛 组员 部分客户端GUI界面

二、前期调查

根据微信小程序中的游戏调研,确定如下几步:

1.绘制一个五子棋窗口

2.创建游戏,开始游戏

3.落子

4.判断五子棋的胜利

5.两个客户端联机

三、主要功能流程图

四、UML图

五、项目运行截图

为了演示方便,该截图为一台电脑开启两个客户端进行联机

开启服务端,两个客户端连接:

创建游戏以及加入游戏

游戏进行中

赢下小局

六、项目关键代码

判断五子连线的情况

    /*** 五子棋核心算法* */public boolean checkVicStatus(int xPos, int yPos, int chessColor) {//连接的棋子数int chessLinkedCount;//用于比较是否要继续遍历一个棋子的相邻网格int chessLinkedCompare = 1;//要比较的棋子在数组中的索引位置int chessToCompareIndex;//相邻网格的位置int closeGrid;//当落子为黑棋时if(chessColor == 1) {//将该棋子自身算入的话,初始连接数为1chessLinkedCount = 1;//以下每对for循环语句为一组,因为下棋的位置能位于中间而非两端//遍历相邻4个网格//判断当前下的棋子的右边4个棋子是否都为黑棋for(closeGrid = 1; closeGrid <= 4; closeGrid++) {//遍历棋盘上所有黑棋子for(chessToCompareIndex = 0; chessToCompareIndex <= chessBlackCount; chessToCompareIndex++) {if(((xPos + closeGrid) * dis == chessBlack_XPOS[chessToCompareIndex])&& ((yPos * dis) == chessBlack_YPOS[chessToCompareIndex])) {//连接数加1chessLinkedCount = chessLinkedCount + 1;//五子相连时,胜利if (chessLinkedCount == 5) {return true;}}}if(chessLinkedCount == (chessLinkedCompare + 1)) {chessLinkedCompare++;//若中间有一个棋子非黑棋,则会进入此分支,此时无需再遍历} else {break;}}// 判断当前下的棋子的左边4个棋子是否都为黑棋for (closeGrid = 1; closeGrid <= 4; closeGrid++) {for (chessToCompareIndex = 0; chessToCompareIndex <= chessBlackCount; chessToCompareIndex++) {if (((xPos - closeGrid) * dis == chessBlack_XPOS[chessToCompareIndex])&& (yPos * dis == chessBlack_YPOS[chessToCompareIndex])) {chessLinkedCount++;if (chessLinkedCount == 5) {return true;}}}if (chessLinkedCount == (chessLinkedCompare + 1)) {chessLinkedCompare++;} else {break;}}// 进入新的一组for循环时要将连接数等重置chessLinkedCount = 1;chessLinkedCompare = 1;// 判断当前下的棋子的上边4个棋子是否都为黑棋for (closeGrid = 1; closeGrid <= 4; closeGrid++) {for (chessToCompareIndex = 0; chessToCompareIndex <= chessBlackCount; chessToCompareIndex++) {if ((xPos * dis == chessBlack_XPOS[chessToCompareIndex])&& ((yPos + closeGrid) * dis == chessBlack_YPOS[chessToCompareIndex])) {chessLinkedCount++;if (chessLinkedCount == 5) {return true;}}}if (chessLinkedCount == (chessLinkedCompare + 1)) {chessLinkedCompare++;} else {break;}}// 判断当前下的棋子的下边4个棋子是否都为黑棋for (closeGrid = 1; closeGrid <= 4; closeGrid++) {for (chessToCompareIndex = 0; chessToCompareIndex <= chessBlackCount; chessToCompareIndex++) {if ((xPos * dis == chessBlack_XPOS[chessToCompareIndex])&& ((yPos - closeGrid) * dis == chessBlack_YPOS[chessToCompareIndex])) {chessLinkedCount++;if (chessLinkedCount == 5) {return true;}}}if (chessLinkedCount == (chessLinkedCompare + 1)) {chessLinkedCompare++;} else {break;}}chessLinkedCount = 1;chessLinkedCompare = 1;for (closeGrid = 1; closeGrid <= 4; closeGrid++) {for (chessToCompareIndex = 0; chessToCompareIndex <= chessBlackCount; chessToCompareIndex++) {// 判断当前下的棋子的左上方向4个棋子是否都为黑棋if (((xPos - closeGrid) * dis == chessBlack_XPOS[chessToCompareIndex])&& ((yPos + closeGrid) * dis == chessBlack_YPOS[chessToCompareIndex])) {chessLinkedCount++;if (chessLinkedCount == 5) {return true;}}}if (chessLinkedCount == (chessLinkedCompare + 1)) {chessLinkedCompare++;} else {break;}}for (closeGrid = 1; closeGrid <= 4; closeGrid++) {for (chessToCompareIndex = 0; chessToCompareIndex <= chessBlackCount; chessToCompareIndex++) {// 判断当前下的棋子的右下方向4个棋子是否都为黑棋if (((xPos + closeGrid) * dis == chessBlack_XPOS[chessToCompareIndex])&& ((yPos - closeGrid) * dis == chessBlack_YPOS[chessToCompareIndex])) {chessLinkedCount++;if (chessLinkedCount == 5) {return true;}}}if (chessLinkedCount == (chessLinkedCompare + 1)) {chessLinkedCompare++;} else {break;}}chessLinkedCount = 1;chessLinkedCompare = 1;// 判断当前下的棋子的右上方向4个棋子是否都为黑棋for (closeGrid = 1; closeGrid <= 4; closeGrid++) {for (chessToCompareIndex = 0; chessToCompareIndex <= chessBlackCount; chessToCompareIndex++) {if (((xPos + closeGrid) * dis == chessBlack_XPOS[chessToCompareIndex])&& ((yPos + closeGrid) * dis == chessBlack_YPOS[chessToCompareIndex])) {chessLinkedCount++;if (chessLinkedCount == 5) {return true;}}}if (chessLinkedCount == (chessLinkedCompare + 1)) {chessLinkedCompare++;} else {break;}}// 判断当前下的棋子的左下方向4个棋子是否都为黑棋for (closeGrid = 1; closeGrid <= 4; closeGrid++) {for (chessToCompareIndex = 0; chessToCompareIndex <= chessBlackCount; chessToCompareIndex++) {if (((xPos - closeGrid) * dis == chessBlack_XPOS[chessToCompareIndex])&& ((yPos - closeGrid) * dis == chessBlack_YPOS[chessToCompareIndex])) {chessLinkedCount++;if (chessLinkedCount == 5) {return true;}}}if (chessLinkedCount == (chessLinkedCompare + 1)) {chessLinkedCompare++;} else {break;}}//当落子为白棋时} else if (chessColor == -1) {chessLinkedCount = 1;// 判断当前下的棋子的右边4个棋子是否都为白棋for (closeGrid = 1; closeGrid <= 4; closeGrid++) {for (chessToCompareIndex = 0; chessToCompareIndex <= chessWhiteCount; chessToCompareIndex++) {if (((xPos + closeGrid) * dis == chessWhite_XPOS[chessToCompareIndex])&& (yPos * dis == chessWhite_YPOS[chessToCompareIndex])) {chessLinkedCount++;if (chessLinkedCount == 5) {return true;}}}if (chessLinkedCount == (chessLinkedCompare + 1)) {chessLinkedCompare++;} else {break;}}// 判断当前下的棋子的左边4个棋子是否都为白棋for (closeGrid = 1; closeGrid <= 4; closeGrid++) {for (chessToCompareIndex = 0; chessToCompareIndex <= chessWhiteCount; chessToCompareIndex++) {if (((xPos - closeGrid) * dis == chessWhite_XPOS[chessToCompareIndex])&& (yPos * dis == chessWhite_YPOS[chessToCompareIndex])) {chessLinkedCount++;if (chessLinkedCount == 5) {return true;}}}if (chessLinkedCount == (chessLinkedCompare + 1)) {chessLinkedCompare++;} else {break;}}chessLinkedCount = 1;chessLinkedCompare = 1;// 判断当前下的棋子的上边4个棋子是否都为白棋for (closeGrid = 1; closeGrid <= 4; closeGrid++) {for (chessToCompareIndex = 0; chessToCompareIndex <= chessWhiteCount; chessToCompareIndex++) {if ((xPos * dis == chessWhite_XPOS[chessToCompareIndex])&& ((yPos + closeGrid) * dis == chessWhite_YPOS[chessToCompareIndex])) {chessLinkedCount++;if (chessLinkedCount == 5) {return true;}}}if (chessLinkedCount == (chessLinkedCompare + 1)) {chessLinkedCompare++;} else {break;}}// 判断当前下的棋子的下边4个棋子是否都为白棋for (closeGrid = 1; closeGrid <= 4; closeGrid++) {for (chessToCompareIndex = 0; chessToCompareIndex <= chessWhiteCount; chessToCompareIndex++) {if ((xPos * dis == chessWhite_XPOS[chessToCompareIndex])&& ((yPos - closeGrid) * dis == chessWhite_YPOS[chessToCompareIndex])) {chessLinkedCount++;if (chessLinkedCount == 5) {return true;}}}if (chessLinkedCount == (chessLinkedCompare + 1)) {chessLinkedCompare++;} else {break;}}chessLinkedCount = 1;chessLinkedCompare = 1;// 判断当前下的棋子的左上方向4个棋子是否都为白棋for (closeGrid = 1; closeGrid <= 4; closeGrid++) {for (chessToCompareIndex = 0; chessToCompareIndex <= chessWhiteCount; chessToCompareIndex++) {if (((xPos - closeGrid) * dis == chessWhite_XPOS[chessToCompareIndex])&& ((yPos + closeGrid) * dis == chessWhite_YPOS[chessToCompareIndex])) {chessLinkedCount++;if (chessLinkedCount == 5) {return true;}}}if (chessLinkedCount == (chessLinkedCompare + 1)) {chessLinkedCompare++;} else {break;}}// 判断当前下的棋子的右下方向4个棋子是否都为白棋for (closeGrid = 1; closeGrid <= 4; closeGrid++) {for (chessToCompareIndex = 0; chessToCompareIndex <= chessWhiteCount; chessToCompareIndex++) {if (((xPos + closeGrid) * dis == chessWhite_XPOS[chessToCompareIndex])&& ((yPos - closeGrid) * dis == chessWhite_YPOS[chessToCompareIndex])) {chessLinkedCount++;if (chessLinkedCount == 5) {return true;}}}if (chessLinkedCount == (chessLinkedCompare + 1)) {chessLinkedCompare++;} else {break;}}chessLinkedCount = 1;chessLinkedCompare = 1;// 判断当前下的棋子的右上方向4个棋子是否都为白棋for (closeGrid = 1; closeGrid <= 4; closeGrid++) {for (chessToCompareIndex = 0; chessToCompareIndex <= chessWhiteCount; chessToCompareIndex++) {if (((xPos + closeGrid) * dis == chessWhite_XPOS[chessToCompareIndex])&& ((yPos + closeGrid) * dis == chessWhite_YPOS[chessToCompareIndex])) {chessLinkedCount++;if (chessLinkedCount == 5) {return true;}}}if (chessLinkedCount == (chessLinkedCompare + 1)) {chessLinkedCompare++;} else {break;}}// 判断当前下的棋子的左下方向4个棋子是否都为白棋for (closeGrid = 1; closeGrid <= 4; closeGrid++) {for (chessToCompareIndex = 0; chessToCompareIndex <= chessWhiteCount; chessToCompareIndex++) {if (((xPos - closeGrid) * dis == chessWhite_XPOS[chessToCompareIndex])&& ((yPos - closeGrid) * dis == chessWhite_YPOS[chessToCompareIndex])) {chessLinkedCount++;if (chessLinkedCount == 5) {return (true);}}}if (chessLinkedCount == (chessLinkedCompare + 1)) {chessLinkedCompare++;} else {break;}}}return false;}

服务端多线程

public void dealWithMsg(String msgReceived){String peerName;if(msgReceived.startsWith("/")){//更新用户列表if(msgReceived.equals("/list")){Feedback(getUserList());//创建游戏}else if (msgReceived.startsWith("/creatgame [inchess]")){//获取服务器名String gameCreaterName = msgReceived.substring(20);//将用户端口放入用户列表中clientNameHash.put(clientSocket, msgReceived.substring(11));//将主机设置为等待状态chessPeerHash.put(gameCreaterName, "wait");Feedback("/yourname " + clientNameHash.get(clientSocket));sendGamePeerMsg(gameCreaterName, "/OK");sendPublicMsg(getUserList());//收到的信息为加入游戏}else if (msgReceived.startsWith("/joingame ")){//StringTokenizer用于分隔字符串StringTokenizer userTokens = new StringTokenizer(msgReceived," ");String userToken;String gameCreatorName;String gamePaticipantName;String[] playerNames = {"0","0"};int nameIndex = 0;while(userTokens.hasMoreTokens()){userToken =userTokens.nextToken(" ");if(nameIndex >= 1 && nameIndex <= 2){playerNames[nameIndex - 1] = userToken;}nameIndex++;}gameCreatorName = playerNames[0];gamePaticipantName = playerNames[1];//游戏已经创建if(chessPeerHash.containsKey(gameCreatorName)&& chessPeerHash.get(gameCreatorName).equals("wait")){//增加游戏加入者的接口与名称对应clientNameHash.put(clientSocket, ("[inchess]" + gamePaticipantName));// 增加或修改游戏创建者与游戏加入者的名称的对应chessPeerHash.put(gameCreatorName, gamePaticipantName);sendPublicMsg(getUserList());//发送信息给游戏加入者sendGamePeerMsg(gamePaticipantName,("/peer " + "[inchess]" + gameCreatorName));//发送游戏给游戏创建者sendGamePeerMsg(gameCreatorName,("/peer " + "[inchess]" + gamePaticipantName));//游戏未创建 则拒绝加入游戏}else{sendGamePeerMsg(gamePaticipantName,"/reject");try{closeClient();}catch (Exception e){e.printStackTrace();}}//游戏中} else if (msgReceived.startsWith("/[inchess]")) {int firstLocation = 0;int lastLocation = msgReceived.indexOf(" ",0);peerName = msgReceived.substring((firstLocation + 1),lastLocation);msgReceived = msgReceived.substring((lastLocation + 1));if(sendGamePeerMsg(peerName,msgReceived)){Feedback("/error");}//放弃游戏}else if(msgReceived.startsWith("/giveup ")){String chessClientName = msgReceived.substring(8);//胜利方为加入游戏者,发送胜利信息if(chessPeerHash.containsKey(chessClientName)&& !chessPeerHash.get(chessClientName).equals("wait")){sendGamePeerMsg((String) chessPeerHash.get(chessClientName),"/youwin");//删除退出游戏的用户chessPeerHash.remove(chessClientName);}//胜利方为游戏创建者,发送胜利信息if(chessPeerHash.containsValue(chessClientName)){sendGamePeerMsg((String) getHashKey(chessPeerHash,chessClientName),"/youwin");// 删除退出游戏的用户chessPeerHash.remove(getHashKey(chessPeerHash, chessClientName));}//收到其他信息}else{int lastLocation = msgReceived.indexOf(" ",0);if(lastLocation == -1){Feedback("无效命令");}}} else {msgReceived = clientNameHash.get(clientSocket) + ">" +msgReceived;serverMsgPanel.msgTextArea.append(msgReceived + "\n");sendPublicMsg(msgReceived);serverMsgPanel.msgTextArea.setCaretPosition(serverMsgPanel.msgTextArea.getText().length());}}

七、项目总结与感想

1.本次我们的项目编写的时间过程算是比较长,从老师布置课设任务的时候就在构思跟初步编写代码,可以说在时间充裕的情况下,本次项目的编写完成度还行(除了没有完成聊天功能以外)。

2.在本次项目编写中团队成员学会了如何用git管理我们的代码,也完善了许多知识点的不足。

3.可惜的是没有实现不同网络下的对局,仅仅只是在同一局域网下的对局。

4.界面还有待改进,应该再加入个登录界面,甚至想要加入个数据库,对局的胜利应该要加上相应分数,玩家之间可以进行排名(纯纯设想)

八、项目git地址,团队成员git提交记录截图

FiveChessGame: 五子棋 (gitee.com)

基于socket的联机五子棋相关推荐

  1. C# Winform基于socket编程的五子棋游戏(带聊天和发送文件功能)

    最近在做课设,题目是关于socket编程的一对一网络小游戏.期间遇到各种问题,也从中学到了很多.在此记录下课设中遇到的问题. 题目要求: 设计4 网络版小游戏 1 设计目的 1)熟悉开发工具(Visu ...

  2. 基于Socket的五子棋游戏

    仅自学记录用,侵删 基于Socket编写的五子棋项目,采用TCP/IP协议. 操作方法:先开启一个服务端,查看服务器连接状态,再启动两个客户端就可以实现双人下棋 游戏规则: (1)对局双方各执一色棋子 ...

  3. 用python做双人五子棋_基于python的socket实现单机五子棋到双人对战

    基于python的socket实现单机五子棋到双人对战,供大家参考,具体内容如下 本次实验使用python语言.通过socket进行不同机器见的通信,具体可以分为以下四步:1.创建ServerSock ...

  4. 基于python的socket实现单机五子棋到双人对战

    基于python的socket实现单机五子棋到双人对战 本次实验使用python语言.通过socket进行不同机器见的通信,具体可以分为以下四步:1.创建ServerSocket和Socket:2.打 ...

  5. 纯java编写的联机五子棋项目(附带开源链接)

    文章目录 说明 功能展示 客户端说明 服务端说明 总结 说明 这是用java写的一个联机五子棋项目,该项目是我大二上期的时候写的,那时候学完了java基础,想要把学的技术都综合使用一下,于是就在国庆节 ...

  6. Compose Multiplatform 实战:联机五子棋

    1. 认识 Compose Multiplatform Jetpack Compose 作为 Android 端的新一代UI开发工具,得益于 Kotlin 优秀的语法特性,代码写起来十分简洁,广受开发 ...

  7. 网络联机五子棋小游戏(C++)

    目录 项目简介 整体效果展示 菜单 本地游戏 网络游戏 游戏大厅 对局效果 部分代码 ending 项目简介 这是一个具备实时联机对局功能的五子棋游戏项目,该项目分为客户端与服务端两部分,客户端页面基 ...

  8. php读取西门子plc_基于Socket访问西门子PLC系列教程(二)

    本文是西门子开放式TCP通信的第2篇,上一篇我们讲了使用西门子1200PLC作为TCP服务器的程序编写,可以点击下方链接阅读:[公众号dotNet工控上位机:thinger_swj] 基于Socket ...

  9. php 基于socket的基本通信

    php 基于socket的基本通信 1.前言 Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口.在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐 ...

最新文章

  1. Away3d 骨骼动画优化
  2. backlight misc驱动范例 及应用程序范例
  3. c语言尖括号 注释,关于C语言include尖括号和双引号的对话
  4. Xilinx_ISE和ModelSim的联合使用方法 / 从Xilinx ISE 14.7启动ModelSim时遇到的问题
  5. POJ 2409 Let it Bead (Polya定理)
  6. Java笔记-对CountDownLatch的理解(对比Qt中的QSemaphore)含实例
  7. easyswoole事务mysql_easyswoole ORM 事务操作管理
  8. [CATARC_2017] 第八周
  9. 赛灵思推7nm加速平台:面向所有场景、所有开放者,AI推理性能提升8倍
  10. xp精简版安装iis
  11. 计算机重启命令编码,电脑倒计时重启代码是什么
  12. 小猪短租网requests库使用
  13. 最简示例 简介洗牌函数 之 __shfl_sync() cuda 之 shuffle
  14. js后代选择器_jQuery后代选择器用法实例
  15. Unity和AndroidStudio交互制作SDK并和其他的SDK合并(微信APP支付)
  16. three.js中jsm文件夹的使用
  17. HACKTHEBOX——Help
  18. 基于FPGA的FFT
  19. 电脑关闭休眠模式清理 C盘内存
  20. 辨别支付宝各种支付场景

热门文章

  1. Juniper JUNOS Commands (Tips and Tricks)
  2. 镜像网站 | 淘宝镜像网站
  3. 浙江工商大学20机试(oj复试)月利率
  4. 金蝶云苍穹轻量级环境搭建
  5. 从公众号跳转至小程序页面,页面链接发生变化?原因剖析解决方案
  6. 2022冬-DownKyi 辅助使用的小插件源码分享
  7. 湖北省2023年中级工程师职称评定条件及材料要求,伴德诚
  8. 防雷工程专业术语及雷电浪涌保护器名词解释
  9. 电脑没声音 小喇叭不见了怎么办
  10. 《Redis设计与实现》第十一章 AOF持久化