Qt 实现诈金花的牌面值分析工具

news2025/6/13 19:37:39

诈金花是很多男人最爱的卡牌游戏 , 每当你拿到三张牌的时候, 生活重新充满了期待和鸟语花香. 那么我们如果判断手中的牌在所有可能出现的牌中占据的百分比位置呢.
这是最终效果:
在这里插入图片描述
这是更多的结果:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在此做些简单的说明:

  1. 炸弹(有些地方叫豹子) > 同花顺 > 同花 > 顺子 > 对子 > 散牌
  2. 同类型的组合先比较最大的牌的点数. 然后是第二大的点数, 然后是第三大的点数, 最后才是比较花色,同样也是从最大牌开始
  3. 最大的顺子是A K Q , 最小的顺子是 A 2 3 , 同花顺也是同样道理
  4. 对子先比较的成对的点数,其次是散牌的点数,然后是成对的花色,最后是散牌的花色
  5. 这两个百分比的意思是这样的, 第一个百分比是指这三张牌的组合在所有可能的组合中所超过的比例. 第二个百分比的意思是实际牌局中, 他超过的所有不含有这三张牌之外的所有场景的个数. 这两个百分比相差很小.
  6. 主要的判断逻辑在Hand类中,界面代码非常简单 , 一共六个文件,可以直接编译运行
//Hand.h
#ifndef CARD_H
#define CARD_H
#include <QDebug>
#include <qglobal.h>

class Hand{
public:
    //最小的点是Ace , 对应的点数是4, 5 ,6 ,7
    //最大的点是K   , 对应的点数是52,53,54,55
    enum class BaseType{
        Junk5 = 0,//最大点数是5的散牌
        Junk6,Junk7,Junk8,Junk9,Junk10,JunkJ,JunkQ,JunkK,JunkA,
        Pair , Sequence,Suit,Flush,Bomb
    };

    Hand(char card1,char card2 ,char card3);
    Hand(const Hand& that);
    Hand& operator=(const Hand& that) = delete;
    bool operator<(const Hand& that)const;

    //这手牌的战斗值,最小的牌是1,最大的牌是22100
    int value()const;
    //是炸弹
    bool isBomb()const;
    //是同花顺
    bool isFlush()const;
    //是同花
    bool isSuitedOnly()const;
    //是顺子
    bool isSequenceOnly()const;
    //是对子
    bool isPair()const;
    //是垃圾牌
    bool isJunk()const;

    QString toString()const;           //不重要
    QString card1()const;              //不重要
    char card1Color()const;            //不重要
    QString card2()const;              //不重要
    char card2Color()const;            //不重要
    QString card3()const;              //不重要
    char card3Color()const;            //不重要
    bool clash(const Hand* that)const; //不重要
private:
    BaseType baseType()const;
    int sumColor()const;    //三张牌的花色值的简单相加
    char pairPoint()const;// 在对子中成对的点数
    char singlePoint()const;//在对子中,散牌的点数
    char pairColorValue()const;//对子的花色带来的加分,0到5之间
    int fragmentValue(BaseType t)const;//基本类型确定后的剩余分数
    int baseValue(BaseType t)const;//基本类型的加分
    bool isSuited()const;   //是同花 包含同花顺
    bool isSequence()const; //是顺子 包含同花顺
    QString strPoint(char c)const;//不重要
    QString strColor(char c)const;//不重要
    void sortCard(char* arr)const;//不重要
    char a;
    char b;
    char c;
};

#endif // CARD_H

//Hand.cpp
#include "Hand.h"

int Hand::sumColor()const{
    return a%4 + b%4 + c%4;
}
char Hand::pairPoint()const{// 在对子中成对的点数
    if(a/4 == b/4) return a;
    return b;
}
char Hand::singlePoint()const{//在对子中,散牌的点数
    if(a/4 == b/4) return c;
    return a;
}
char Hand::pairColorValue()const{//对子的花色带来的加分,0到5之间
    char max,min;
    if(a/4 == b/4){
        max = b%4;
        min = a%4;
    }
    else{
        max = c%4;
        min = b%4;
    }
    if(max == 3){
        if(2 == min) return 5;
        if(1 == min) return 4;
        if(0 == min) return 3;
    }
    else if(2 == max){
        if(1 == min) return 2;
        if(0 == min) return 1;
    }
    return 0;
}
int Hand::fragmentValue(BaseType t)const{
    int ret = 0;
    static const char colorCombinationValueList[4][4][4] = {
        {{0, 1, 2, 3} ,    {4, 5, 6,7}  ,   {8,9,10,11}  ,    {12,13,14,15}},
        {{16,17,18,19}  ,  {20,0, 21,22}  , {23,24,25,26}  ,  {27,28,29,30}},
        {{31,32,33,34}  ,  {35,36,37,38}  , {39,40,0 ,41}  ,  {42,43,44,45}},
        {{46,47,48,49}  ,  {50,51,52,53}  , {54,55,56,57}  ,  {58,59,60,0 }}
    };
    static const char midPointListA[14] = {0,0,0,0,0,2,5,9,14,20,27,35,44,54};
    static const char midPointList[13] =  {0,0,0,0,1,3,6,10,15,21,28,36,45};
    if(t == BaseType::Bomb){
        if(a/4 == 1){
            return 48 + sumColor() - 2;
        }
        else{
            return (a/4-2) * 4 + sumColor() - 2;
        }
    }
    else if(t == BaseType::Flush){
        if(a/4 == 1 && c/4 == 13){//Q K A
            return 44 + sumColor() / 3 + 1;
        }
        else{
            return (a/4 - 1)*4 + sumColor() /3 + 1;
        }
    }
    else if(t == BaseType::Suit){
        if(a/4 == 1){
            ret += 840;//(12*11*10/6-10)*4 Ace带来的加分
            ret += midPointListA[c/4] * 4;   //第二大的牌带来的加分
            ret += (b/4-2)*4;       //最小牌带来的加分
            ret += a%4+1;           //花色带来的加分
        }
        else {
            const auto max = c/4;
            ret += ((max-2)*(max-3)*(max-4)/6-(max-4))*4;   //最大牌带来的加分 624(K) 448 308 200 120 64 28 8(6)
            const auto mid = b/4;
            const auto min = a/4;
            ret += midPointList[mid] * 4;   //第二大的牌带来的加分
            ret += (min - 2) * 4;
            ret += a%4 + 1;
        }
    }
    else if(t == BaseType::Sequence){//共720个情况; 4*4*4*12-48

        if(a/4 == 1 && c/4 == 13){//Q K A
            ret += 660;//组合带来的加分
            ret += colorCombinationValueList[a%4][c%4][b%4];
        }
        else{
            ret += (c/4-3) * 60;
            ret += colorCombinationValueList[c%4][b%4][a%4];
        }
    }
    else if(t == BaseType::Pair){//6 * 48 * 13
        const auto pair = pairPoint();
        const auto single = singlePoint();
        if(pair/4 == 1){//A A ?
            ret += 6*48*12;//对子点数带来的分数
            ret += (single/4-2)*24;//散牌点数带来的分数
        }
        else{
            ret += 6*48*(pair/4-2); //对子点数带来的分数
            if(single/4 == 1){//Ace是散牌
                ret += 11*24;//散牌点数带来的分数
            }
            else{
                if(single / 4 < pair /4)
                    ret += (single/4-2)*24;
                else
                    ret += (single/4-3)*24;
            }
        }
        ret += pairColorValue() * 4;//对子花色带来的分数
        ret += single%4 + 1;//散牌的花色带来的分数
    }
    else if(t == BaseType::JunkA){//3840;// ((14-2)*(14-3)/2-2)*(4*4*4-4)
        auto mid = c/4;
        auto min = b/4;

        ret += midPointListA[mid] * 60;//中间点数带来的加分
        ret += (min-2)*60;//最小点数带来的加分
        ret += colorCombinationValueList[a%4][c%4][b%4];
    }
    else {//3240; (11*10/2-1)*(4*4*4-4)
        auto mid = b/4;
        auto min = a/4;

        ret += midPointList[mid] * 60;
        ret += (min-2) * 60;
        ret += colorCombinationValueList[c%4][b%4][a%4];
    }
    return ret;
}
Hand::BaseType Hand::baseType()const{
    if(isBomb()) return BaseType::Bomb;
    if(isFlush()) return BaseType::Flush;
    if(isSuitedOnly()) return BaseType::Suit;
    if(isSequenceOnly()) return BaseType::Sequence;
    if(isPair()) return BaseType::Pair;
    if(isJunk()){
        if(a/4 == 1 ) return BaseType::JunkA;
        if(c/4 == 13) return BaseType::JunkK;
        if(c/4 == 12) return BaseType::JunkQ;
        if(c/4 == 11) return BaseType::JunkJ;
        if(c/4 == 10) return BaseType::Junk10;
        if(c/4 == 9 ) return BaseType::Junk9;
        if(c/4 == 8 ) return BaseType::Junk8;
        if(c/4 == 7 ) return BaseType::Junk7;
        if(c/4 == 6 ) return BaseType::Junk6;
        if(c/4 == 5 ) return BaseType::Junk5;
        Q_ASSERT(c/4 > 4);
    }
    Q_ASSERT(false);
}
Hand::Hand(char card1,char card2 ,char card3){
    Q_ASSERT(card1 != card2 && card1 != card3 && card2 != card3);
    Q_ASSERT(card1>=4 && card1<56 && card2>=4 && card2<56 && card3>=4 && card3<56);
    char arr[3] = {card1,card2,card3};
    std::sort(arr,arr+3);
    a = arr[0];//min
    b = arr[1];
    c = arr[2];//max
}
Hand::Hand(const Hand& that):a(that.a),b(that.b),c(that.c){}
bool Hand::operator<(const Hand& that)const{
    return value() < that.value();
}
int Hand::value()const{
    const auto type = baseType();
    const int base = baseValue(type);
    const int fragment = fragmentValue(type);
    return base + fragment;
}

bool Hand::isBomb()const{//炸弹
    return a/4 == c/4;
}
bool Hand::isFlush()const{//同花顺
    return isSuited() && isSequence();
}
bool Hand::isSuitedOnly()const{//只是同花
    return isSuited() && !isSequence();
}

bool Hand::isSequenceOnly()const{//只是顺子
    return isSequence() && !isSuited();
}

bool Hand::isPair()const{//对子
    return (a/4 == b/4 || b/4 == c/4) && a/4 != c/4;
}
bool Hand::isJunk()const{//散牌
    return !isBomb() && !isSuited() && !isSequence() && !isPair();
}

QString Hand::toString()const{
    return card1() + "-" + card1Color() + " , " +
           card2() + "-" + card2Color() + " , " +
           card3() + "-" + card3Color();
}
void Hand::sortCard(char* arr)const{
    auto _a = a;
    auto _b = b;
    auto _c = c;
    if(_a/4 == 1) _a += 52;
    if(_b/4 == 1) _b += 52;
    if(_c/4 == 1) _c += 52;
    arr[0] = _a;
    arr[1] = _b;
    arr[2] = _c;
    std::sort(arr,arr+3,[](char _1,char _2){
        return _1 > _2;
    });
}
static const char* strList[15] = {
    "","","2","3","4","5","6","7","8","9","10","J","Q","K","A"
};
QString Hand::card1()const{
    char arr[3];
    sortCard(arr);
    return strList[arr[0] / 4];
}
char    Hand::card1Color()const{
    char arr[3];
    sortCard(arr);
    return arr[0] % 4;
}
QString Hand::card2()const{
    char arr[3];
    sortCard(arr);
    return strList[arr[1] / 4];
}
char    Hand::card2Color()const{
    char arr[3];
    sortCard(arr);
    return arr[1] % 4;
}
QString Hand::card3()const{
    char arr[3];
    sortCard(arr);
    return strList[arr[2] / 4];
}
char Hand::card3Color()const{
    char arr[3];
    sortCard(arr);
    return arr[2] % 4;
}
bool Hand::clash(const Hand* that)const{
    if(a == that->a || a == that->b || a == that->c ||
       b == that->a || b == that->b || b == that->c ||
       c == that->a || c == that->b || c == that->c) return true;
    return false;
}
int Hand::baseValue(Hand::BaseType t)const{
    static constexpr int mNodeList[15] = {//每种场景的数量
          120,300,540,840,1200,1620,2100,2640,3240,3840,3744, 720,  1096,   48,    52
        //5   6   7   8   9    10   J    Q    K    A    对子   顺子   同花    同花顺  炸弹
    };
    int idx = (int)t;
    int ret = 0;
    for(int i = 0;i < idx;++i) ret += mNodeList[i];
    return ret;
}

bool Hand::isSuited()const{//同花
    return a%4 == b%4 && a%4 == c%4;
}
bool Hand::isSequence()const{//顺子
    if(a/4 == 1){
        if(b/4 == 2 && c/4 == 3) return true;
        if(b/4 == 12 && c/4 == 13) return true;
        return false;
    }
    return (b/4-a/4)==1 && (c/4-b/4)==1;
}
QString Hand::strPoint(char c)const{
    const auto p = c / 4;
    if(p == 1) return "Ace";
    if(p == 11) return "J";
    if(p == 12) return "Q";
    if(p == 13) return "K";
    return QString::number(p);
}
QString Hand::strColor(char c)const{
    const auto spade = c % 4;
    if(spade == 0) return "0";
    if(spade == 1) return "1";
    if(spade == 2) return "2";
    if(spade == 3) return "3";
    return "null";
}

//CardWidget.h
#ifndef CARDWIDGET_H
#define CARDWIDGET_H

#include <QWidget>

class CardWidget : public QWidget
{
    Q_OBJECT
public:
    explicit CardWidget(char card,QWidget *parent = nullptr);
    inline void recordOriginalPos(const QPointF& p){ mOriginalPos = p; }
    inline QPointF originalPos()const{return mOriginalPos;}
    const char mCard;
private:
    QPointF mOriginalPos;
protected:
    void mousePressEvent(QMouseEvent*);
    void paintEvent(QPaintEvent* e);
signals:
    void cardClicked(CardWidget*);
public slots:
};

#endif // CARDWIDGET_H

//CardWidget.cpp
#include "CardWidget.h"
#include <QPainter>
#include <QDebug>
CardWidget::CardWidget(char c,QWidget *parent) : QWidget(parent),mCard(c) {}
void CardWidget::mousePressEvent(QMouseEvent*){
    emit cardClicked(this);
}
void CardWidget::paintEvent(QPaintEvent* e){
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.setPen(Qt::NoPen);
    painter.setBrush(QBrush("lightgray"));
    painter.drawRoundedRect(rect(),8,8);

    static const QFont font("Microsoft YaHei",16,2);
    static const QFont fontIcon("Microsoft YaHei",32,2);
    static const char* pointList[14] = {"","A","2","3","4","5","6","7","8","9","10","J","Q","K"};
    static const char* colorList[4] = {"♦","♣","♥","♠"};
    static const QPen penList[4] = {QPen("lightpink") , QPen("hotpink") , QPen("orangered") ,QPen("red")};

    const qreal x = width();
    const qreal y = height();
    painter.setFont(font);
    painter.setPen("black");
    painter.drawText(QRectF(0,0,x*0.5,x/2),Qt::AlignCenter,pointList[mCard/4]);
    painter.setFont(fontIcon);
    painter.setPen(penList[mCard%4]);
    painter.drawText(QRect(0,x/2,x,y-x/2),Qt::AlignCenter,colorList[mCard%4]);
}

//DemoCardTable.h
#ifndef DEMOCARDTABLE_H
#define DEMOCARDTABLE_H

#include <QWidget>
#include "CardWidget.h"
#include <QLabel>
#include "Hand.h"
class DemoCardTable : public QWidget
{
    Q_OBJECT
public:
    explicit DemoCardTable(QWidget *parent = nullptr);
private:
    QLabel* mInfo;
    QList<CardWidget*> mSelectList;
    QList<Hand*> mHandList;
    void moveCardWithAnimation(CardWidget* w,const QPointF& start,const QPointF& end);
signals:

public slots:
    void onCardClicked(CardWidget*);
};

#endif // DEMOCARDTABLE_H

//DemoCardTable.cpp
#include "DemoCardTable.h"
#include <QPropertyAnimation>
#include <QApplication>
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    DemoCardTable t;
    t.setWindowTitle("炸金花牌面值分析");
    t.show();
    return a.exec();
}
const int gCardW = 50;
const int gCardH = 75;
const int gCardGap = 4;
static bool compareHands(const Hand* a,const Hand* b){
    return a->value() < b->value();
}
DemoCardTable::DemoCardTable(QWidget *parent) : QWidget(parent)
{
    for(char i = 0;i < 4;++i){
        for(char j = 1;j < 14;++j){
            auto* card = new CardWidget(j*4+i,this);
            connect(card,&CardWidget::cardClicked,this,&DemoCardTable::onCardClicked);
            card->setFixedSize(gCardW,gCardH);
            QPointF pos( (j-1)*(gCardW+gCardGap),(i+1)*(gCardH+gCardGap));
            card->recordOriginalPos(pos);
            card->move(pos.toPoint());
        }
    }
    mInfo = new QLabel(this);
    mInfo->setFixedSize(10*(gCardW+gCardGap)-gCardGap,gCardH);
    mInfo->setFont(QFont("Microsoft YaHei",16,2));
    mInfo->setWordWrap(true);
    mInfo->move(3*(gCardW+gCardGap),0);
    setFixedSize(13*(gCardW+gCardGap)-gCardGap,5*(gCardH+gCardGap));

    for(char a = 55;a>=6;--a){
        for(char b = a-1;b >= 5;--b){
            for(char c = b-1;c >= 4;--c){
                mHandList.push_back(new Hand(a,b,c));
            }
        }
    }
    std::sort(mHandList.begin(),mHandList.end(),compareHands);
}
void DemoCardTable::moveCardWithAnimation(CardWidget* w,const QPointF& start,const QPointF& end){
    auto* anim = new QPropertyAnimation(w,"pos");
    anim->setStartValue(start);
    anim->setEndValue(end);
    anim->setDuration(400);
    connect(anim,&QPropertyAnimation::finished,anim,&QObject::deleteLater);
    anim->start();
}
void DemoCardTable::onCardClicked(CardWidget* w){
    if(!w) return;
    if(mSelectList.size() >= 3) {
        //reset pos
        for(int i = 0;i < mSelectList.size();++i){
            auto* card = mSelectList[i];
            if(!card) continue;
            moveCardWithAnimation(card,card->pos(),card->originalPos());
        }
        //clear record
        mSelectList.clear();
        mInfo->clear();
    }

    //move card
    int x = mSelectList.size() * (gCardW+gCardGap);
    moveCardWithAnimation(w,w->originalPos(),QPointF(x,0));
    //record
    mSelectList.push_back(w);
    if(mSelectList.size() == 3){
        //calculate
        Hand hand(mSelectList[0]->mCard,mSelectList[1]->mCard,mSelectList[2]->mCard);
        const int v =hand.value();
        const int index = v-1;
        float percent = index / 22100.0*100;
        int cnt1 = 0;
        int cnt2 = 0;
        for(int i = 0;i < index;++i){
            if(mHandList[i]->clash(&hand)) cnt1++;
        }
        for(int i = index+1;i< 22100;++i){
            if(mHandList[i]->clash(&hand)) cnt2++;
        }
        float percent2 = (index - cnt1)*1.0/(22100-cnt1-cnt2-1)*100;
        QString info = "当前牌面值超过了 " + QString::number(percent,'g',5) + "% 的理论场景\n"+
                       "实际牌局中,它超过了 " + QString::number(percent2,'g',5) +"% 的场景";
        mInfo->setText(info);
    }

}

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

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

相关文章

【Web】浅聊Java反序列化之Rome——关于其他利用链

目录 前言 JdbcRowSetImpl利用链 BasicDataSource利用链 Hashtable利用链 BadAttributeValueExpException利用链 HotSwappableTargetSource利用链 前文&#xff1a;【Web】浅聊Java反序列化之Rome——EqualsBean&ObjectBean-CSDN博客 前言 Rome中ToStringBean的利用…

ElasticSearch 底层读写原理

ElasticSearch 底层读写原理 ​ 写请求是写入 primary shard&#xff0c;然后同步给所有的 replica shard&#xff1b;读请求可以从 primary shard 或 replica shard 读取&#xff0c;采用的是随机轮询算法。 1、ES写入数据的过程 1.选择任意一个DataNode发送请求&#xff0c…

山泉还可以申请商标不,现阶段通过率如何!

在32类类别啤酒饮料是许多生产水企业主要申请注册的类别&#xff0c;那现在山泉在这个类别还可以申请注册商标不&#xff0c;山泉在这个类别基本上是通用词&#xff0c;首先是需要前面词具有显著性&#xff0c;没的相同或近似才可以。 经普推知产老杨检索发现&#xff0c;在32…

数据分析-Pandas数据画箱线图

数据分析-Pandas数据画箱线图 数据分析和处理中&#xff0c;难免会遇到各种数据&#xff0c;那么数据呈现怎样的规律呢&#xff1f;不管金融数据&#xff0c;风控数据&#xff0c;营销数据等等&#xff0c;莫不如此。如何通过图示展示数据的规律&#xff1f; 数据表&#xff…

全网最最最详细centos7如何安装docker教程

在CentOS 7上安装Docker主要包括以下步骤&#xff1a; 1. 卸载旧版本的Docker 首先&#xff0c;需要确保系统上没有安装旧版本的Docker。可以通过以下命令来卸载它们&#xff1a; sudo yum remove docker \docker-client \docker-client-latest \docker-common \docker-late…

阿珊详解Vue Router的守卫机制

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

nginx代理minio客户端

错误方式 在点击桶名查看文件时, 会一直处于loading加载中 worker_processes 1; #设置 Nginx 启动的工作进程数为 1。events {worker_connections 1024; ##设置每个工作进程的最大并发连接数为 1024。 }http {include mime.types; #该文件定义了文件扩展名和 MIME 类型…

AJAX学习(一)

版权声明 本文章来源于B站上的某马课程&#xff0c;由本人整理&#xff0c;仅供学习交流使用。如涉及侵权问题&#xff0c;请立即与本人联系&#xff0c;本人将积极配合删除相关内容。感谢理解和支持&#xff0c;本人致力于维护原创作品的权益&#xff0c;共同营造一个尊重知识…

全网最新最全的Jmeter接口测试:jmeter_定时器

固定定时器 如果你需要让每个线程在请求之前按相同的指定时间停顿&#xff0c;那么可以使用这个定时器&#xff1b;需要注意的是&#xff0c;固定定时器的延时不会计入单个sampler的响应时间&#xff0c;但会计入事务控制器的时间 1、使用固定定时器位置在http请求中&#xf…

CVHub | 初识langchain,3分钟快速了解!

本文来源公众号“CVHub”&#xff0c;仅用于学术分享&#xff0c;侵权删&#xff0c;干货满满。 原文链接&#xff1a;初识langchain 1 什么是langchain langchain[1]是一个用于构建LLM-Based应用的框架&#xff0c;提供以下能力: 上下文感知&#xff1a;可以为LLM链接上下文…

汽车零部件制造中的信息抽取技术:提升效率与质量的关键

一、引言 在汽车制造业中&#xff0c;零部件的生产是整个制造流程的关键一环。这些零部件&#xff0c;包括但不限于制动系统、转向系统和传动系统&#xff0c;是确保汽车安全、可靠运行的基础。为了满足现代汽车工业对效率和质量的严格要求&#xff0c;制造商们纷纷投入到高度…

jvm堆概述

《java虚拟机规范》中对java堆的描述是&#xff1a;所有的对象实例以及数组都应当在运行时分配在堆上。 一个JVM实例只存在一个堆内存(就是new 出来一个对象)&#xff0c;java内存管理的核心区域 java堆区在jvm启动的时候就被创建&#xff0c;空间大小确定。是jvm管理的最大一…

探索代理服务器:保护您的网络安全与隐私

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a;Linux ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 前言 正文 隐藏真实IP地址&#xff1a; 访问控制&#xff1a; 加速访问速度&#xff1a; 过滤内容&#xff1a; 突破访问限制&#xff1…

深入浅出计算机网络 day.1 概论③ 电路交换、分组交换和报文交换

人无法同时拥有青春和对青春的感受 —— 04.3.9 内容概述 01.电路交换、分组交换和报文交换 02.三种交换方式的对比 一、电路交换、分组交换和报文交换 1.电路交换 计算机之间的数据传送是突发式的&#xff0c;当使用电路交换来传送计算机数据时&#xff0c;其线路的传输效率一…

MUMU模拟器12连logcat的方法

大家好&#xff0c;我是阿赵。   在开发手机游戏的时候&#xff0c;在真机上会出现各种问题&#xff0c;在查询问题的时候&#xff0c;安卓手机需要用adb连接来连接手机看logcat输出分析问题。但由于连接手机比较麻烦&#xff0c;所以我都习惯在电脑用安卓模拟器来测试。   …

启动项目报502怎么处理呢?

您好&#xff0c;我是码农飞哥&#xff08;wei158556&#xff09;&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f4aa;&#x1f3fb; 1. Python基础专栏&#xff0c;基础知识一网打尽&#xff0c;9.9元买不了吃亏&#xff0c;买不了上当。 Python从入门到精…

C#中对象的相等性与同一性的判断方法总结

C#对象的相等性与同一性 1. 概述与准备1.1 概述1.2 准备 2. Equals(Object)2.1 功能&#xff1a;2.2 实例&#xff1a;2.3 扩展&#xff1a;2.4 重写此方法 3. Equals(Object, Object)3.1 功能3.2 实例 4. ReferenceEquals(Object, Object)4.1 功能4.2 使用场景&#xff1a;4.3…

成人商务英语,外贸英语纺织英语日常交流口语柯桥学外语

大家好&#xff0c;今天我们要说的这个短语&#xff0c;跟香蕉Banana有关&#xff0c;它就是top banana。 不过它可不是字面上的“顶级香蕉”的意思哦~ Top banana是一个俚语&#xff0c;常见的意思有两个&#xff1a; 1. the most important person in any group 一群人中最…

第14章 西瓜书——概率图模型

概率图模型 概率图模型&#xff08;Probabilistic Graphical Model&#xff09;是用图结构来表示多元随机变量之间条件依赖关系的模型。在图模型中&#xff0c;节点表示随机变量&#xff0c;边表示变量之间的依赖关系。概率图模型可以分为有向图模型&#xff08;如贝叶斯网络&a…

C#与欧姆龙PLC实现CIP通讯

参考文档&#xff1a; 欧姆龙PLC使用-CSDN博客 CIP通讯介绍&#xff08;欧姆龙PLC&#xff09;-CSDN博客 使用NuGet添加引用&#xff1a;CIPCompolet 基础参考我的CIP协议介绍&#xff0c;默认TCP端口为&#xff1a;44818 类NXCompolet 类的功能可以在安装PLC开发软件后帮…