井字棋源码(网络线程池版)

源码链接:game

效果可能没有那么好,大家可以给点建议。

效果展示 

game.h

#include <stdio.h>
#include <stdlib.h>
#include <time.h>#define ROW 3
#define COL 3void InitBoard(char board[ROW][COL], int row, int col)
{int i = 0;for (i = 0; i < row; i++){int j = 0;for (j = 0; j < col; j++){board[i][j] = ' ';}}
}void DisplayBoard(char board[ROW][COL], int row, int col)
{int i = 0;for (i = 0; i < row; i++){//打印数据int j = 0;for (j = 0; j < col; j++){printf(" %c ", board[i][j]);if (j < col - 1)printf("|");}printf("\n");//打印分割的行if (i < row - 1){for (j = 0; j < col; j++){printf("---");if (j < col - 1)printf("|");}printf("\n");}}
}void player_move(char board[ROW][COL], int row, int col)
{int x = 0;int y = 0;printf("玩家下棋\n");while (1){printf("请输入坐标:>");scanf("%d %d", &x, &y);if (x >= 1 && x <= row && y >= 1 && y <= col){//下棋if (board[x - 1][y - 1] == ' '){board[x - 1][y - 1] = '*';break;}else{printf("该坐标被占用,请重新输入\n");}}else{printf("坐标非法,请重新输入\n");}}
}void computer_move(char board[ROW][COL], int row, int col)
{int x = 0;int y = 0;printf("电脑下棋:>\n");while (1){x = rand() % row;//0~2y = rand() % col;//0~2if (board[x][y] == ' '){board[x][y] = '#';break;}}
}static int if_full(char board[ROW][COL], int row, int col)
{int i = 0;for (i = 0; i < row; i++){int j = 0;for (j = 0; j < col; j++){if (board[i][j] == ' '){return 0;//没满}}}return 1;//满了
}char is_win(char board[ROW][COL], int row, int col)
{int i = 0;//判断行for (i = 0; i < row; i++){if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][1] != ' '){return board[i][1];}}//判断列for (i = 0; i < col; i++){if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != ' '){return board[1][i];}}//对角线if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' '){return board[1][1];}if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' '){return board[1][1];}//判断平局if (if_full(board, row, col) == 1){return 'Q';}//继续return 'C';
}

tcp_client.cc

#include <iostream>
#include <string>
#include <cstring>
#include <cstdio>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include "game.h"void menu()
{printf("********************************\n");printf("*********  1. play     *********\n");printf("*********  0. exit     *********\n");printf("********************************\n");
}void game()
{char ret = 0;// 存放下棋的数据char board[ROW][COL] = {0};// 初始化棋盘为全空格InitBoard(board, ROW, COL);// 打印棋盘DisplayBoard(board, ROW, COL);while (1){// 玩家下棋player_move(board, ROW, COL);DisplayBoard(board, ROW, COL);// 判断输赢ret = is_win(board, ROW, COL);if (ret != 'C'){break;}// 电脑下棋computer_move(board, ROW, COL);// 随机下棋DisplayBoard(board, ROW, COL);ret = is_win(board, ROW, COL);if (ret != 'C'){break;}}if (ret == '*'){printf("恭喜你赢了\n");}else if (ret == '#'){printf("很遗憾你输了\n");}else{printf("平局\n");}
}void Usage(std::string proc)
{std::cout << "\nUsage: " << proc << " serverIp serverPort\n"<< std::endl;
}void Print(int &sock, std::string &line)
{ssize_t s = send(sock, line.c_str(), line.size(), 0);if (s > 0){char buffer[1024];ssize_t s = recv(sock, buffer, sizeof(buffer) - 1, 0);if (s > 0){buffer[s] = 0;std::cout << "server 回应# " << buffer << std::endl;}else if (s == 0){close(sock);}}else{close(sock);}
}int main(int argc, char *argv[])
{if (argc != 3){Usage(argv[0]);exit(1);}std::string serverip = argv[1];uint16_t serverport = atoi(argv[2]);int sock = 0;std::string line;sock = socket(AF_INET, SOCK_STREAM, 0);if (sock < 0){std::cerr << "socket error" << std::endl;exit(2);}struct sockaddr_in server;memset(&server, 0, sizeof(server));server.sin_family = AF_INET;server.sin_port = htons(serverport);server.sin_addr.s_addr = inet_addr(serverip.c_str());if (connect(sock, (struct sockaddr *)&server, sizeof(server)) < 0) // 连接服务器{std::cerr << "connect error" << std::endl;exit(3);}std::cout << "connect success" << std::endl;int input = 0;srand((unsigned int)time(NULL));do{menu();printf("请选择:>");scanf("%d", &input);switch (input){case 1:line = "start";Print(sock, line);game(); // 游戏break;case 0:line = "quit";Print(sock, line);break;default:printf("选择错误\n");break;}} while (input);if (line == "quit"){exit(0);}return 0;
}

tcp_server.cc

#include "tcp_server.hpp"
#include <memory>static void Usage(std::string proc)
{std::cout << "\nUsage" << proc << " port\n" << std::endl;
}int main(int argc, char* argv[])
{if(argc != 2){Usage(argv[0]);exit(1);}uint16_t port = atoi(argv[1]);std::unique_ptr<Tcp_Server> svr(new Tcp_Server(port));svr->InitServer();svr->Start();return 0;
}

tcp_server.hpp

#pragma once#include <iostream>
#include <string>
#include <cstring>
#include <strings.h>
#include <assert.h>
#include <unistd.h>
#include <signal.h>
#include <memory>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <pthread.h>
#include <sys/wait.h>
#include "threadPool/log.hpp"
#include "threadPool/thread.hpp"
#include "threadPool/threadPool.hpp"
#include "threadPool/Task.hpp"
#include "game.h"static void play(int sock, const std::string &clientip, const uint16_t &clientport, const std::string &thread_name)
{char buffer[1024];while (true){ssize_t s = read(sock, buffer, sizeof(buffer) - 1);std::string message;if (s > 0){buffer[s] = 0;std::cout << thread_name << "|" << clientip << ":" << clientport << "# " << buffer << std::endl;if (strcmp(buffer, "start") == 0){message = "玩家请开始游戏";}if (strcmp(buffer, "quit") == 0){message = "玩家退出游戏成功";}write(sock, message.c_str(), message.size());}else if (s == 0) // 对端关闭连接{logMessage(NORMAL, "%s:%d 玩家已退出游戏,我也退出", clientip.c_str(), clientport);break;}else{logMessage(ERROR, "read socket error, %d:%s", errno, strerror(errno));break;}}close(sock);
}class Tcp_Server
{
private:const static int gbacklog = 20;public:Tcp_Server(uint16_t port, std::string ip = ""): _port(port), _ip(ip), listensock(-1), _threadpool_ptr(ThreadPool<Task>::getThreadPool()){}~Tcp_Server(){}void InitServer(){// 1.创建socketlistensock = socket(AF_INET, SOCK_STREAM, 0);if (listensock < 0){// 创建socket失败logMessage(FATAL, "create socket error, %d:%S", errno, strerror(errno));exit(2);}logMessage(NORMAL, "create socket success, listensock:%d", listensock);// 2.bindstruct sockaddr_in local;memset(&local, 0, sizeof local);local.sin_family = AF_INET;local.sin_port = htons(_port);local.sin_addr.s_addr = _ip.empty() ? INADDR_ANY : inet_addr(_ip.c_str()); // INADDR_ANY:任意IPif (bind(listensock, (struct sockaddr *)&local, sizeof(local)) < 0){// bind失败logMessage(FATAL, "bind error, %d:%s", errno, strerror(errno));exit(3);}// 3.建立连接if (listen(listensock, gbacklog) < 0){// 建立连接失败logMessage(FATAL, "listen error, %d:%s", errno, strerror(errno));exit(4);}logMessage(NORMAL, "init server success");}void Start(){_threadpool_ptr->run();while (true){// 4.获取连接struct sockaddr_in src;socklen_t len = sizeof(src);int servicesock = accept(listensock, (struct sockaddr *)&src, &len);// 获取连接失败if (servicesock < 0){logMessage(ERROR, "accept error, %d:%s", errno, strerror(errno));continue;}// 获取连接成功uint16_t client_port = ntohs(src.sin_port);std::string client_ip = inet_ntoa(src.sin_addr);logMessage(NORMAL, "link success, servicesock: %d | %s : %d |\n", servicesock, client_ip.c_str(), client_port);// 5.开始通信// 线程池版Task t(servicesock, client_ip, client_port, play);_threadpool_ptr->pushTask(t);}}private:uint16_t _port;std::string _ip;int listensock;std::unique_ptr<ThreadPool<Task>> _threadpool_ptr;
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/3211.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

企业数字化转型,“业务”先行

在当今时代&#xff0c;数字化转型已经成为企业发展的必经之路。数字化转型&#xff0c;简而言之&#xff0c;就是运用数字技术&#xff0c;对企业运营管理的各个环节进行深度改造&#xff0c;以提升企业的运营效率和市场竞争力。据有关机构研究测算&#xff0c;数字化转型可使…

丈母娘眼中“靠谱女婿”职业榜曝光,公务员跌落榜首,新兴职业成宠儿!

正如婆婆和媳妇相处很复杂&#xff0c;丈母娘和女婿亦有着微妙关系&#xff0c;看对眼是“半个儿”&#xff0c;不对付则会成为小两口婚姻的“地雷”&#xff0c;甚至是恋爱路上的“拦路虎”。 近来&#xff0c;最新丈母娘认可的“靠谱女婿”职业榜排行新鲜出炉&#xff0c;备受…

R语言 数据的整理与清洗(Data Frame 篇下)

《Cookbook for R》 Manipulating Data ~ Dataframe Comparing data frames 比较数据框 当你想比较两个或多个数据框&#xff0c;并从中找到&#xff1a; 1、重复出现在多个数据框中的行 2、或仅出现在一个数据框中的行 先构建三个示例数据框 dfA <- data.frame(Subjectc…

5g工业数采网关是什么?-天拓四方

随着工业4.0时代的到来&#xff0c;数字化、网络化、智能化成为工业发展的新趋势。在这个过程中&#xff0c;5G工业数采网关作为一种关键设备&#xff0c;发挥着越来越重要的作用。本文将详细解析5G工业数采网关是什么&#xff0c;以及它在工业领域中的应用和重要性。 一、5G工…

MySql CPU激增原因分析

QPS激增会导致CPU占用升高 分析 可以使用监控工具&#xff0c;查看CPU利用率曲线图和QPS曲线图进行对比。如果CPU曲线图波动情况跟QPS曲线图波动情况基本保持一致&#xff0c;可以明确明确CPU升高时QPS上升导致。反之&#xff0c;CPU曲线图对比QPS曲线图有不同步的峰值抖动&am…

socket套接字在tcp客户端与tcp服务器之间的通信,以及socket中常用的高效工具epoll

1.socket&#xff08;套接字&#xff09;的概念 Socket是对TCP/IP协议的封装&#xff0c;Socket本身并不是协议&#xff0c;而是一个调用接口&#xff08;API&#xff09;&#xff0c;通过Socket&#xff0c;我们才能使用TCP/IP协议,主要利用三元组【ip地址&#xff0c;协议&am…

【芯片科普】运算放大器用作比较器的注意事项

运算放大器和比较器 比较器和运算放大器电气符号非常相像&#xff0c;都是有反相、同相两个输入端和一个输出端的器件&#xff0c;输出端的输出电压范围一般在供电的轨到轨之间&#xff1b;同时比较器和运算放大器都具有低偏置电压、高增益和高共模抑制比的特点。 图1 运算放…

自由场、半自由场、扩散场

按声场性质可以将声场分为三类&#xff1a;自由声场、半自由声场、扩散声场 分别对应着全消声室&#xff0c;半消声室&#xff0c;混响室 自由声场&#xff1a; 声源在均匀、各向同性媒介中传播时&#xff0c;不计边界影响的声场&#xff0c;此时声场中只有直达声没有反射声。…

测试工程师面试准备(软硬件)

您好&#xff0c;我叫XXX。学历XX&#xff0c;XXX专业毕业。X年X月份毕业&#xff0c;但是去年二月份已经找到工作开始实习了&#xff0c;目前工作一年了&#xff0c;这一年的过程中我主要负责软件的开发和测试和软硬件联调测试工作。具体来说就是&#xff0c;在软件开发完成后…

在Linux系统中炫酷的输出命令可以让终端看起来更有趣

在Linux系统中,有许多炫酷的输出命令可以让终端看起来更有趣。 以下是一些流行的命令,以及它们的描述和安装方法: cmatrix:这个命令会在终端中显示一个类似于《黑客帝国》中的绿色代码雨效果。安装命令为`sudo apt-get install cmatrix`.sl:当你错误地输入`ls`为`sl`时,…

华为 2024 届实习校园招聘-硬件通⽤/单板开发——第八套

华为 2024 届实习校园招聘-硬件通⽤/单板开发——第八套 部分题目分享&#xff0c;完整版带答案(有答案和解析&#xff0c;答案非官方&#xff0c;未仔细校正&#xff0c;仅供参考&#xff09;&#xff08;共十套&#xff09;获取&#xff08;WX:didadidadidida313&#xff0c…

Qwen1.5微调

引子 由于工作上需要&#xff0c;一直在用Qwen做大模型推理&#xff0c;有个再训练的需求&#xff0c;特此琢磨下Qwen的训练。OK&#xff0c;我们开始吧。 一、安装环境 查看显卡驱动版本 根据官网推荐 OK&#xff0c;docker在手&#xff0c;天下我有。 docker pull qwenll…

rancher-rke2 修改--service-cluster-ip-range

一、场景 因为需要部署新版本的ingress-nginx&#xff0c;而部署ingress-nginx的时候需要使用hostnetowrk以及nodeport的端口为80和443&#xff0c;service-node-port-range 默认为30000开始,部署会报错。 二、产生修改的需求 1、api-servier的配置文件位置 默认是没有的&…

LabVIEW学习记录 - 实时显示时间

LabVIEW操作 - 实时显示时间 在程序框图&#xff0c;选择函数->定时->格式化日期/时间字符串 该函数的使用手册说明&#xff1a; 鼠标选择“格式化日期/时间字符串”->创建->输入控件->输入格式 查看时间代码格式&#xff1a; 编程->定时->获取时间日…

Ali-Sentinel-入口控制

​ 归档 GitHub: Ali-Sentinel-入口控制 测试 // 在 demo-spring-webmvc 里新建测试类public class TestMain {public static void main(String[] args) throws InterruptedException {initFlowRules(); // 初始化规则while (true) {// 1.5.0 版本开始可以直接利用 try-with…

Stream流入门

Stream流:操作集合和数组的工具。 Stream的三类方法&#xff1a; 获取Stream流&#xff1a;创建一条流水线&#xff0c;并把数据放上去。中间方法&#xff1a;流水线上的操作&#xff0c;可以进行多次操作。终结方法&#xff1a;一个Stream流只能有一个终结方法&#xff0c;是…

Linux交换空间的创建使用

交换空间&#xff1a; 换出&#xff1a;将内存中不常用&#xff08;冷数据&#xff09;的放去硬盘里 换出&#xff1a;内存要使用这部分数据时&#xff0c;将硬盘的这部分数据放入内存 在内存和硬盘上用来交换数据的空间就是交换空间 创建交换空间的步骤 1.去磁盘上创建一个分…

想进大厂,请先想清楚这几个问题

今天被一个小伙伴问&#xff1a;“进大厂难吗&#xff1f;” 我想都不想回答&#xff1a;“简单啊~ 从北京郎家园&#xff0c;坐817或者816&#xff0c;终点站就是大厂。” 小伙伴翻了一个大大的白眼... “我是说工作上的事&#xff01;” 瞬间懂了&#xff0c;工作场所&…

C语言 | Leetcode C语言题解之第47题全排列II

题目&#xff1a; 题解&#xff1a; int* vis;void backtrack(int* nums, int numSize, int** ans, int* ansSize, int idx, int* perm) {if (idx numSize) {int* tmp malloc(sizeof(int) * numSize);memcpy(tmp, perm, sizeof(int) * numSize);ans[(*ansSize)] tmp;return…

OssUtil工具上传文件

安装、上传、下载 1. 安装ossutil sudo -v ; curl https://gosspublic.alicdn.com/ossutil/install.sh | sudo bash2. 配置ossutil ossutil config3. 验证是否已成功安装ossutil ossutil 如果屏幕中输出ossutil所有支持的命令&#xff0c;表明已成功安装ossutil。# 完整上传 os…