基于socket的联机五子棋

基于socket的联机五子棋

一、团队介绍

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

二、前期调查

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2I9rR4uI-1673262926455)(E:\桌面\新建文件夹\1.jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RzyswbZY-1673262926456)(E:\桌面\新建文件夹\2.jpg)]

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

1.绘制一个五子棋窗口

2.创建游戏,开始游戏

3.落子

4.判断五子棋的胜利

5.两个客户端联机

三、主要功能流程图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tuze19pD-1673262926821)(null)]

四、UML图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kI1aPvxc-1673262926457)(E:\桌面\新建文件夹\4.png)]

五、项目运行截图

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

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KZ9KE7uN-1673262926458)(E:\桌面\新建文件夹\5.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4ejCCa8j-1673262926458)(E:\桌面\新建文件夹\6.png)]

创建游戏以及加入游戏

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TtDvuraE-1673262926458)(E:\桌面\新建文件夹\7.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-q3SDpjPL-1673262926458)(E:\桌面\新建文件夹\8.png)]

游戏进行中

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-P1b3yqSE-1673262926459)(E:\桌面\新建文件夹\9.png)]

赢下小局

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-swiUzwDF-1673262926459)(E:\桌面\新建文件夹\10.png)]

六、项目关键代码

判断五子连线的情况

    /**
    * 五子棋核心算法
    * */
    public boolean checkVicStatus(int xPos, int yPos, int chessColor) {
        //连接的棋子数
        int chessLinkedCount;
        //用于比较是否要继续遍历一个棋子的相邻网格
        int chessLinkedCompare = 1;
        //要比较的棋子在数组中的索引位置
        int chessToCompareIndex;
        //相邻网格的位置
        int closeGrid;

        //当落子为黑棋时
        if(chessColor == 1) {
            //将该棋子自身算入的话,初始连接数为1
            chessLinkedCount = 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])) {
                        //连接数加1
                        chessLinkedCount = 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)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-f0Jx8AZ9-1673262926459)(E:\桌面\新建文件夹\11.png)]

  • 2
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要在Dev-C++中进行联机编程,可以按照以下步骤操作: 1. 在代码中包含必要的头文件,如 `<iostream>` 和 `<winsock2.h>`。 2. 使用 `WSAStartup` 函数初始化 Winsock 库。 3. 创建一个套接字,使用 `socket` 函数指定协议簇、套接字类型和协议。 4. 设置服务器的地址信息,包括 IP 地址和端口号。 5. 使用 `connect` 函数连接到服务器。 6. 接收来自服务器的消息,使用 `recv` 函数将消息存储到一个字符数组中。 7. 使用 `cout` 输出接收到的消息。 8. 使用 `system("pause")` 使程序在接收完消息后暂停,防止程序立即退出。 9. 在程序末尾,使用 `WSACleanup` 函数清理并释放 Winsock 库所使用的资源。 要注意的是,将代码中的 IP 地址改为运行服务器端的电脑的 IP。另外,如果使用 Dev-C++,还需要进行一些额外的设置才能编译成功。可以按照以下步骤进行设置: 1. 打开 Dev-C++,点击菜单中的 "工具"。 2. 选择 "编译选项"。 3. 在 "编译时加入以下命令" 中,将内容改为 `-std=c11`。 4. 勾选 "在连接器命令行加入以下命令"。 5. 在 "连接器命令行加入以下命令" 中,将内容改为 `-static-libgcc -l wsock32`。 6. 点击 "确定" 保存设置。 这样就完成了在 Dev-C++ 中进行联机编程的设置和操作。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [科技系列 - 2 更新第二期 >:DEV - C++ 不同主机下的同局域网联机 更新 第 2 期](https://blog.csdn.net/Hox_5/article/details/120355064)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [C++ Winsock进行联机通信](https://blog.csdn.net/tyx159357/article/details/125122721)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值