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

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

  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,55enum 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,最大的牌是22100int 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 Areturn 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-48if(a/4 == 1 && c/4 == 13){//Q K Aret += 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 * 13const 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;elseret += (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];//minb = 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 posfor(int i = 0;i < mSelectList.size();++i){auto* card = mSelectList[i];if(!card) continue;moveCardWithAnimation(card,card->pos(),card->originalPos());}//clear recordmSelectList.clear();mInfo->clear();}//move cardint x = mSelectList.size() * (gCardW+gCardGap);moveCardWithAnimation(w,w->originalPos(),QPointF(x,0));//recordmSelectList.push_back(w);if(mSelectList.size() == 3){//calculateHand 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.rhkb.cn/news/274575.html

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

相关文章

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的常见车型识别系统(Python+PySide6界面+训练代码)

摘要&#xff1a;本文深入探讨了如何应用深度学习技术开发一个先进的常见车型识别系统。该系统核心采用最新的YOLOv8算法&#xff0c;并与早期的YOLOv7、YOLOv6、YOLOv5等版本进行性能比较&#xff0c;主要评估指标包括mAP和F1 Score等。详细解析了YOLOv8的工作机制&#xff0c…

Qt/QML编程之路:openglwidget和倒车影像的切换(43)

关于如何实现一个基于OpenGL的3d 图形,这个有很多专门的介绍,我在开发中遇到了这么一个问题: 如何实现一个倒车影像的video显示与一个3D物体显示的切换,因为开窗在同样的一个位置,如果车子倒车启动,则需要将原本显示3D的地方切换为视频图像的显示。 class testOpenGl : …

SpringMVC04、Controller 及 RestFul

4、Controller 及 RestFul 4.1、控制器Controller 控制器复杂提供访问应用程序的行为&#xff0c;通常通过接口定义或注解定义两种方法实现。控制器负责解析用户的请求并将其转换为一个模型。在Spring MVC中一个控制器类可以包含多个方法在Spring MVC中&#xff0c;对于Contr…

【嵌入式】嵌入式系统稳定性建设:最后的防线

&#x1f9d1; 作者简介&#xff1a;阿里巴巴嵌入式技术专家&#xff0c;深耕嵌入式人工智能领域&#xff0c;具备多年的嵌入式硬件产品研发管理经验。 &#x1f4d2; 博客介绍&#xff1a;分享嵌入式开发领域的相关知识、经验、思考和感悟。提供嵌入式方向的学习指导、简历面…

ChatGPT 结合实际地图实现问答式地图检索功能基于Function calling

ChatGPT 结合实际地图实现问答式地图检索功能基于Function calling ChatGPT结合实际业务&#xff0c;主要是研发多函数调用&#xff08;Function Calling&#xff09;功能模块&#xff0c;将自定义函数通过ChatGPT 问答结果&#xff0c;实现对应函数执行&#xff0c;再次将结果…

k8s-生产级的k8s高可用(2) 25

部署containerd k8s2、k8s3、k8s4在配置前需要重置节点&#xff08;reset&#xff09;在上一章已完成 禁用所有节点docker和cri-docker服务 所有节点清除iptables规则 重置后全部节点重启 由于之前部署过docker&#xff0c;因此containerd默认已安装 修改配置 启动containe…

vue 总结

1.vue 的生命周期 1. es6 2. vue 基本属性指令 <template><div><!--<h1>vue基本指令的使用方式</h1><a :href"url">v-bind使用链接</a><img :src"srcUrl" /><div>解决闪烁问题<p v-cloak>{{…

安装zabbix

部署Zabbix监控平台 部署一台Zabbix监控服务器&#xff0c;一台被监控主机&#xff0c;为进一步执行具体的监控任务做准备&#xff1a; 安装LNMP环境源码安装Zabbix安装监控端主机&#xff0c;修改基本配置初始化Zabbix监控Web页面修改PHP配置文件&#xff0c;满足Zabbix需求…

Vue3全家桶 - Pinia - 【1】(安装与使用 + Store + State + Getters + Actions)

Pinia pinia 是 Vue 的专属状态管理库&#xff0c;它允许你跨组件或跨页面共享状态&#xff1b; 一、 安装与使用 pinia 安装语法&#xff1a;yarn add pinia npm install pinia创建一个 pinia &#xff08;根存储&#xff09;并将其传递给应用程序&#xff1a; 目标文件&am…

PaddlePaddle----基于paddlehub的OCR识别

Paddlehub介绍 PaddleHub是一个基于PaddlePaddle深度学习框架开发的预训练模型库和工具集&#xff0c;提供了丰富的功能和模型&#xff0c;包括但不限于以下几种&#xff1a; 1.文本相关功能&#xff1a;包括文本分类、情感分析、文本生成、文本相似度计算等预训练模型和工具。…

【力扣hot100】刷题笔记Day25

前言 这几天搞工作处理数据真是类似我也&#xff0c;还被老板打电话push压力有点大的&#xff0c;还好搞的差不多了&#xff0c;明天再汇报&#xff0c;赶紧偷闲再刷几道题&#xff08;可恶&#xff0c;被打破连更记录了&#xff09;这几天刷的是动态规划&#xff0c;由于很成…

共基法律考点大默写

法是由国家制定或认可的&#xff0c;&#xff0c;能够反应统治阶级意志&#xff0c;反映着被一定物质生活条件决定的统治阶级&#xff08;在社会主义社会是工人阶级为首的广大人民&#xff09;的意志。 指引作用。法律为人们提供既定的行为模式&#xff0c;指引人们在法律范围内…

Qt插件之输入法插件的构建和使用(一)

文章目录 输入法概述输入法插件实现及调用输入键盘搭建定义样式自定义按钮实现自定义可拖动标签数字符号键盘候选显示控件滑动控件手绘输入控件输入法概述 常见的输入法有三种形式: 1.系统级输入法 2.普通程序输入法 3.程序自带的输入法 系统级输入法就是咱们通常意义上的输入…

Vue3全家桶 - Vue3 - 【8】模板引用【ref】(访问模板引用 + v-for中的模板引用 + 组件上的ref)

模板引用【ref】 Vue3官网-模板引用&#xff1b;如果我们需要直接访问组件中的底层DOM元素&#xff0c;可使用vue提供特殊的ref属性来访问&#xff1b; 一、 访问模板引用 在视图元素上采用ref属性来设置需要访问的DOM元素&#xff1a; 该 ref 属性可采用 字符串 值的执行设…

蝙蝠避障:我生活中的一道光

盲人的世界&#xff0c;是无尽的黑暗。看不见光&#xff0c;看不见色彩&#xff0c;甚至看不见自己的手。但在这个黑暗的世界里&#xff0c;我找到了一个光明的出口&#xff1a;一款可以障碍物实时检测的名为蝙蝠避障的盲人软件。 这款软件就像是我的一双眼睛。它通过先进的激光…

第五十六回 徐宁教使钩镰枪 宋江大破连环马-飞桨图像分类套件PaddleClas初探

宋江等人学会了钩镰枪&#xff0c;大胜呼延灼。呼延灼损失了很多人马&#xff0c;不敢回京&#xff0c;一个人去青州找慕容知府。一天在路上住店&#xff0c;马被桃花山的人偷走了&#xff0c;于是到了青州&#xff0c;带领官兵去打莲花山。 莲花山的周通打不过呼延灼&#xf…

【日常记录】【工具】随机生成图片的网站 Lorem Picsum

文章目录 1、介绍2、获取固定宽高的图片3、处理图片缓存4、 Emmet 缩写语法 1、介绍 Lorem Picsum 是一个免费的图片占位符服务&#xff0c;可以用于网站、应用程序或任何需要占位符图片的地方。它提供了一个简单的 API&#xff0c;可以通过 HTTP 请求获取随机图片&#xff0c;…

安信可IDE(AiThinker_IDE)编译ESP8266工程方法

0 工具准备 AiThinker_IDE.exe ESP8266工程源码 1 安信可IDE&#xff08;AiThinker_IDE&#xff09;编译ESP8266工程方法 1.1 解压ESP8266工程文件夹 我们这里使用的是NON-OS_SDK&#xff0c;将NON-OS_SDK中的1_UART文件夹解压到工作目录即可 我这里解压到了桌面&#xff0c…

软考73-上午题-【面向对象技术2-UML】-UML中的图4

一、构件图&#xff08;组件图&#xff09; 1-1、构件图的定义 展现了&#xff0c;一组构件之间的组织和依赖。 构件图专注于系统的静态实现图。 构件图与类图相关&#xff0c;通常把构件映射为一个、多个类、接口、协作。 【回顾】&#xff1a; 类图展示了一组对象、接口、…

加速 Webpack 构建:提升效率的秘诀

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