C++项目:在线五子棋对战网页版--匹配对战模块开发

这篇具有很好参考价值的文章主要介绍了C++项目:在线五子棋对战网页版--匹配对战模块开发。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

玩家匹配是根据自己的天梯分数进行匹配的,而服务器中将玩家天梯分数分为三个档次:

1. 普通:天梯分数小于2000分
2. 高手:天梯分数介于2000~3000分之间
3. 大神:天梯分数大于3000分

当玩家进行对战匹配时,服务器会根据档次,将玩家送到不同档次的匹配队列当中。共有3个匹配队列,分别是普通队列、高手队列和大神队列,每一条队列由单独的线程去控制。因此,匹配对战模块,需要由两个类,一个类是匹配队列的类,另外一个是管理匹配队列的类。

匹配队列类

当玩家进行匹配对战的请求后,服务器会将玩家添加至相应的匹配队列当中,匹配成功后,会从匹配队列中移除该玩家,而在匹配成功前,玩家可能会中止匹配。因此,匹配队列应该包含的功能有入队、出队、和移除指定玩家,玩家处在的位置可能是队列的中间,因此,匹配队列采用的是双向循环链表。在匹配过程中,如果暂时为达到匹配玩家个数,该线程会进入阻塞等待状态,因此需要实现的功能还有阻塞等待的方法,获取队列元素个数、判断队列是否为空的方法。

template<class T>
class match_queue
{
private:
    /*由于可能要删除中间数据,因此使用双向链表,而不使用队列*/
    std::list<T> _list;
    //保证线程安全
    std::mutex _mutex;
    //使用条件变量实现阻塞,在队列中元素个数小于2的时候进行阻塞
    std::condition_variable _cond;
public:
    /*入队*/
    void push(T& data)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        _list.push_back(data);
        /*每次有玩家进入匹配队列后,唤醒线程*/
        _cond.notify_all();
    }

    /*出队*/
    bool pop(T& data)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        if(_list.empty()==true)
        {
            return false;
        }
        data = _list.front();
        _list.pop_front();
        return true;
    }

    /*移除指定元素*/
    void remove(T& data)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        _list.remove(data);
    }
    /*获取队列元素个数*/
    int size()
    {
        std::unique_lock<std::mutex> lock(_mutex);
        return _list.size();
    }

    /*判断队列是否为空*/
    bool empty()
    {
        std::unique_lock<std::mutex> lock(_mutex);
        return _list.empty();
    }

    /*阻塞等待*/
    void wait()
    {
        std::unique_lock<std::mutex> lock(_mutex);
        _cond.wait(lock);
    }

};

匹配队列管理类

在匹配队列管理类中,创建三个线程,每一个线程分别管理着每一条匹配队列:

普通线程管理普通队列,高手线程管理高手队列,大神线程管理大神队列。

而管理的方法是:实现匹配对战:当玩家数量小于2时,线程继续阻塞。大于2时,将两个玩家出队,然后将玩家添加到房间,最后对玩家进行一个匹配成功的响应。文章来源地址https://www.toymoban.com/news/detail-636197.html

#ifndef __M__MATCHER_H__
#define __M__MATCHER_H__
#include<list>
#include <mutex>
#include <condition_variable>
#include "room.hpp"

template<class T>
class match_queue
{
private:
    /*由于可能要删除中间数据,因此使用双向链表,而不使用队列*/
    std::list<T> _list;
    //保证线程安全
    std::mutex _mutex;
    //使用条件变量实现阻塞,在队列中元素个数小于2的时候进行阻塞
    std::condition_variable _cond;
public:
    /*入队*/
    void push(T& data)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        _list.push_back(data);
        /*每次有玩家进入匹配队列后,唤醒线程*/
        _cond.notify_all();
    }

    /*出队*/
    bool pop(T& data)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        if(_list.empty()==true)
        {
            return false;
        }
        data = _list.front();
        _list.pop_front();
        return true;
    }

    /*移除指定元素*/
    void remove(T& data)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        _list.remove(data);
    }
    /*获取队列元素个数*/
    int size()
    {
        std::unique_lock<std::mutex> lock(_mutex);
        return _list.size();
    }

    /*判断队列是否为空*/
    bool empty()
    {
        std::unique_lock<std::mutex> lock(_mutex);
        return _list.empty();
    }

    /*阻塞等待*/
    void wait()
    {
        std::unique_lock<std::mutex> lock(_mutex);
        _cond.wait(lock);
    }
};

class matcher
{
private:
    /*普通队列*/
    match_queue<uint64_t> _q_normal;
    /*高手队列*/
    match_queue<uint64_t> _q_hight;
    /*大神队列*/
    match_queue<uint64_t> _q_super;
    /*普通线程*/
    std::thread _th_normal;
    /*高手线程*/
    std::thread _th_hight;
    /*大神线程*/
    std::thread _th_super;
    room_manager *_rm;
    user_table *_ut;
    online_manager *_om;
private:
    void handle_match(match_queue<uint64_t>& mq)
    {
        while(1)
        {
            /*判断队列中玩家个数是否大于2*/
            while(mq.size()<2)
            {
                mq.wait();
            }
            /*大于2,将两个玩家出队*/
            uint64_t uid1,uid2;
            bool ret = mq.pop(uid1);
            if(ret==false)
            {
                continue;
            }
            ret = mq.pop(uid2);
            if(ret==false)
            {
                continue;
            }
            /*两个玩家出队后,获取对应的通信连接,然后判断是否依然连接在线*/
            wsserver_t::connection_ptr conn1 = _om->get_conn_from_hall(uid1);
            if(conn1.get()==nullptr)
            {
                this->add(uid1);
                continue;
            }
            wsserver_t::connection_ptr conn2 = _om->get_conn_from_hall(uid2);
            if(conn2.get()==nullptr)
            {
                this->add(uid2);
                continue;
            }
            /*获取连接后,为他们创建房间并且添加进房间*/
            room_ptr rp = _rm->create_room(uid1,uid2);
            if(rp.get()==nullptr)
            {
                this->add(uid1);
                this->add(uid2);
                continue;
            }
            /*将信息返回*/
            Json::Value resp;
            resp["optype"] = "match_success";
            resp["result"] = true;
            std::string body;
            json_util::serialize(resp,body);
            conn1->send(body);
            conn2->send(body);
        }
    }
    void _th_normal_entry(){return handle_match(_q_normal);}
    void _th_hight_entry(){return handle_match(_q_hight);}
    void _th_super_entry(){return handle_match(_q_super);}
public:
    matcher(room_manager *rm,user_table* ut,online_manager* om)
        :_rm(rm),_ut(ut),_om(om)
        ,_th_normal(std::thread(&matcher::_th_normal_entry,this))
        ,_th_hight(std::thread(&matcher::_th_hight_entry,this))
        ,_th_super(std::thread(&matcher::_th_super_entry,this))
    {
        DLOG("游戏匹配模块初始化完毕...");
    }

    bool add(uint64_t uid)
    {
        /*根据uid,获取到玩家的信息*/
        Json::Value user;
        bool ret = _ut->select_by_id(uid,user);
        if(ret==false)
        {
            DLOG("获取玩家:%d 信息失败",uid);
            return false;
        }
        int score = user["score"].asInt();
        if(score < 2000)
        {
            _q_normal.push(uid);
        }
        else if(score>=2000 && score < 3000)
        {
            _q_normal.push(uid);

        }
        else
        {
            _q_normal.push(uid);
        }
        return true;
    }

    bool del(uint64_t uid)
    {
        Json::Value user;
        bool ret = _ut->select_by_id(uid,user);
        if(ret==false)
        {
            DLOG("获取玩家:%d 信息失败",uid);
            return false;
        }
        int score = user["score"].asInt();
        if(score<2000)
        {
            _q_normal.remove(uid);
        }
        else if(score>=2000 && score<3000)
        {
            _q_hight.remove(uid);
        }
        else
        {
            _q_super.remove(uid);
        }
        return true;
    }

};

#endif

到了这里,关于C++项目:在线五子棋对战网页版--匹配对战模块开发的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 网页版Java(Spring/Spring Boot/Spring MVC)五子棋项目(四)对战模块

    匹配成功返回数据 1. message消息类别 2. ok 3. reson 4. 房间id 5. 双方id 6.白色玩家 一个类记录房间中的信息(房间id,两个用户id,是否为白棋) 信息提示框 处理匹配API 初始化游戏(棋盘,下一个棋子,接受棋子处理响应,判断是否结束) 1. 客户端连接到游戏房间后, 服务器返回

    2024年02月13日
    浏览(38)
  • 在线五子棋对战 --- 人机对战的实现

    要增添一个人机对战的模块, 最大的难点就是如何让人机知道下在什么位置是最好的, 不仅要具备进攻的能力, 还需要具备防守的能力. 这里当人机第一次走的时候, 采用标准开局, 下子在最中间. 当玩家走了之后, 人机就需要去判定下在什么位置合理. 这里采用的是评分表的方法

    2024年02月05日
    浏览(31)
  • C++ 实现对战AI五子棋

     个人主页: 日刷百题 系列专栏 : 〖C/C++小游戏〗 〖Linux〗 〖数据结构〗   〖 C语言 〗 🌎 欢迎各位 → 点赞 👍+ 收藏 ⭐️+ 留言 📝  ​ ​      为了能够快速上手一门语言,我们往往在学习了基本语法后,采用写一个小项目的方式来加深理解语言的语法及运用,本文采

    2024年02月03日
    浏览(43)
  • 【项目设计】网络对战五子棋(上)

    想回家过年… 1.1 http1.0/1.1和websocket协议 1. a. http协议在Linux的学习部分我们就已经学习过了,当时http和https是一块学的,我们当时其实已经了解了http的大部分知识内容,比如http请求和响应的格式,各自的报头字段都有哪些,cookie和session机制,http1.1的长连接策略keep-alive,还有

    2024年02月07日
    浏览(35)
  • Linux项目实战——五子棋(单机人人对战版)

    Linux操作系统项目实战——五子棋 GIF: 目录            Linux操作系统项目——五子棋 一、问题导引: 二、实现要求: 三、五子棋原理: 1.落子数据信息保存载体: 2.落子思路: 3.判断“五子连珠” 四、项目实现步骤: Ⅰ.创建目录及文件: 1.在Linux环境下创建名为Gobang的文

    2024年02月03日
    浏览(38)
  • 基于FPGA(basys3)的双人对战人机对战五子棋(vivado)课程设计项目

    目录 主界面显示与选择模式 双人对战 人机对战 胜利界面显示 部分源码 VGA显示器显示图片,显示图片利用Block Memory Generator将图片像素点储存在RAM里面。 效果图:(防止侵权打了马赛克)  通过开发板上的按键进行模式选择,模式确定 双人对战就是采用简单的存数组的办法

    2024年01月18日
    浏览(31)
  • 2.6.C++项目:网络版五子棋对战之数据管理模块-游戏房间管理模块的设计

    对匹配成功的玩家创建房间,建立起一个小范围的玩家之间的关联关系! 房间里一个玩家产生的动作将会广播给房间里的其他用户。 将这些房间管理起来,以便于进行房间生命周期的控制! 游戏房间类: // 实现两个部分: // 1. 房间的设计 // 2. 房间管理的设置 // 游戏房间的

    2024年02月08日
    浏览(33)
  • 基于Python的五子棋人机对战

    在之前的博文基于tkinter的五子棋游戏中使用tkinter做了一个简单的五子棋游戏,只能实现人人对战,后来想着加上人机对战的功能。 不过,最初想想还是挺麻烦的,计算机怎么评估当前的棋局,找到最佳或者较佳的落子点呢,脑子真是越来越不灵光了。站在巨人的肩膀上,科

    2024年02月04日
    浏览(30)
  • python实现五子棋-人机对战/人人对战(动图演示+源码分享)

    大家好,我是梦执,对梦执着。希望能和大家共同进步!   五子棋对战-所有文件文末自取 前言 人人对战 动态演示 源码分享 cheackboard.py 人人对战.py 导入模块 设置棋盘和棋子参数 局内字体设置 落子循坏体 画棋盘 画棋子 运行框返回落子坐标 执行文件 人机对战 动态演示

    2023年04月08日
    浏览(42)
  • JAVA五子棋手机网络对战游戏的设计与实现(源代码+论文)

    在现代社会中,手机及其它无线设备越来越多的走进普通老百姓的工作和生活。 随着3G技术的普及与应用,基于Java开发的软件在手机上的使用非常的广泛,手机增值服务的内容也是越来越多,对丰富人们的生活内容、提供快捷的资讯起着不可忽视的作用。 本文基于J2ME技术,以

    2024年02月09日
    浏览(28)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包