当前位置: 首页 > news >正文

C语言之斗地主游戏


🌟 嗨,我是LucianaiB!

🌍 总有人间一两风,填我十万八千梦。

🚀 路漫漫其修远兮,吾将上下而求索。


C语言之斗地主游戏

目录

  1. 程序概述
  2. 程序设计
    1. Card类
    2. CardGroup类
    3. Player类
    4. LastCards类
    5. Landlords类
  3. 游戏流程
  4. 特点与功能
    1. 牌型判断
    2. AI提示
    3. 交互性
    4. 随机性
  5. 测试与运行
  6. 总体评价
  7. 附录代码

本文介绍了一个基于C++实现的简单斗地主游戏程序。该程序模拟了斗地主的基本规则和流程,包括发牌、抢地主、出牌以及胜负判定等功能。程序的核心由多个类组成,包括Card(表示单张牌)、CardGroup(表示一组牌)、Player(表示玩家)、LastCards(用于记录上家出的牌)和Landlords(用于管理整个游戏流程)。

程序设计

程序通过Card类定义了牌的基本属性,如牌面值、花色和显示方法。CardGroup类用于管理一组牌,并提供牌型判断和大小比较的功能。Player类则管理玩家手中的牌,并提供出牌和提示功能。LastCards类用于记录上家出的牌,并提供查找可打得过的牌的功能。Landlords类作为游戏的核心,负责初始化游戏、发牌、抢地主、轮流出牌以及判断游戏结束等逻辑。

游戏流程

游戏开始时,程序通过洗牌和分牌将54张牌随机分配给三个玩家,并通过抢地主环节确定地主玩家。地主玩家获得额外的三张底牌后,游戏正式开始。玩家按顺序出牌,每次出牌需要比上家的牌大,或者选择不出。当某个玩家手中的牌全部出完时,游戏结束,程序会判断地主是否获胜。

特点与功能
  1. 牌型判断:程序能够准确判断牌型,如单牌、对子、三带一、炸弹等,并根据牌型和牌的大小进行比较。
  2. AI提示:非地主玩家在出牌时,程序会自动提示可打得过的牌,提高了游戏的流畅性。
  3. 交互性:程序通过控制台输入输出与用户交互,用户可以选择是否抢地主、出牌以及是否继续游戏。
  4. 随机性:通过随机洗牌和抢地主环节,增加了游戏的趣味性和不确定性。
测试与运行

程序在测试中表现出了良好的稳定性和正确性。玩家可以自由选择出牌策略,程序会根据规则判断出牌是否合法,并在游戏结束后输出胜负结果。用户可以通过简单的命令行交互体验完整的斗地主游戏流程。
在这里插入图片描述

总体评价

本文介绍了一个基于C++实现的斗地主游戏程序,模拟了斗地主的基本规则和流程,包括发牌、抢地主、出牌和胜负判定等功能。程序的核心由多个类组成,如Card、CardGroup、Player、LastCards和Landlords,通过面向对象编程的方式实现了游戏的完整逻辑。

在程序设计中,Card类用于定义单张牌的基本属性,如牌面值、花色和显示方法。CardGroup类管理一组牌,并提供牌型判断和大小比较的功能。Player类管理玩家手中的牌,并提供出牌和提示功能。LastCards类用于记录上家出的牌,并提供查找可打得过的牌的功能。Landlords类作为游戏的核心,负责初始化游戏、发牌、抢地主、轮流出牌以及判断游戏结束等逻辑。

游戏流程从洗牌和分牌开始,通过抢地主环节确定地主玩家。地主获得额外三张底牌后,游戏正式开始。玩家按顺序出牌,每次出牌需要比上家的牌大,或者选择不出。当某个玩家手中的牌全部出完时,游戏结束,程序会判断地主是否获胜。
该程序具有以下特点:

牌型判断:能够准确判断牌型,如单牌、对子、三带一、炸弹等,并根据牌型和牌的大小进行比较。

AI提示:非地主玩家在出牌时,程序会自动提示可打得过的牌,提高了游戏的流畅性。

交互性:通过控制台输入输出与用户交互,用户可以选择是否抢地主、出牌以及是否继续游戏。

随机性:通过随机洗牌和抢地主环节,增加了游戏的趣味性和不确定性。

在测试中,程序表现出良好的稳定性和正确性,用户可以通过简单的命令行交互体验完整的斗地主游戏流程。该程序不仅实现了斗地主的基本规则,还通过类的设计和封装展示了面向对象编程的思想。代码结构清晰,易于理解和扩展,适合用于学习和研究C++编程以及游戏开发。

附录代码:
#include <iostream>
#include<vector>
#include<assert.h>
#include<string>
#include<stdio.h>
#include<algorithm>
#include<time.h>using namespace std;#define PLAYERCOUNT 3
#define CARDSCOUNT 54
#define CURRENTPLAYER 0
#define VALUECOUNT 17
#define ERROR -1
using namespace std;
int scnt=0;
const char toFigure[]="34567890JQKA 2YZ";enum COLOR{  //花色显示ASCII: 3~6
eHEART=3,//红桃
eDIAMOND=4,//方片
eCLUB=5,   //草花
eSPADE=6   //黑桃
};class Card;
class CardsType;
class CardGroup;
class Player;
class Landlords;
class LastCards;
bool makeChoice(string tip);
bool cmp(Card* a,Card* b);
class Card{
public:
char figure;
COLOR color;
int value;
Card(char _figure,COLOR _color){figure=_figure;color=_color;value=calValue();
}
int calValue(){for(int i=0;toFigure[i];i++){if(toFigure[i]==figure){return i;}}return ERROR;
}void print() {assert(value != ERROR);switch (color) {case eHEART:cout << "♥"; // 红桃break;case eDIAMOND:cout << "♦"; // 方片break;case eCLUB:cout << "♣"; // 草花break;case eSPADE:cout << "♠"; // 黑桃break;default:cout << "?"; // 未知花色break;}cout << figure << ' ';}
};
class CardsType{
public:
//为了规范查找对应牌的方法
//统一为3个参数cnt1、isContinuous、cnt2
int typeId;
string typeStr;
int cnt1,cnt2;
bool isContinuous;
CardsType(){typeId=ERROR;
}
bool operator ==(const CardsType& other)const{return this->typeId==other.typeId;
}
void init(char* _typeStr,int _typeId,int _cnt1,bool _isContinuous,int _cnt2){cnt1=_cnt1;isContinuous=_isContinuous;cnt2=_cnt2;typeStr=_typeStr;typeId=_typeId;
}
};
class CardGroup{
public:
vector<Card*> cards;
CardsType type;
void calType(){int i,n=cards.size();//init(typeStr,typeId,cnt1,isContinuous,cnt2)if(n==0){type.init("不出",14,0,0,0);return;}if(n==2&&cards[0]->value==15&&cards[1]->value==14){type.init("王炸",0,0,0,0);return;}//统计同点数牌有多少张int cntFlag[VALUECOUNT]={0};for(i=0;i<n;i++){cntFlag[cards[i]->value]++;}//统计点数最多和最少的牌int maxCnt=0,minCnt=4;for(i=0;i<VALUECOUNT;i++){if(maxCnt<cntFlag[i]){maxCnt=cntFlag[i];}if(cntFlag[i]&&minCnt>cntFlag[i]){minCnt=cntFlag[i];}}if(n==4&&maxCnt==4){type.init("炸弹",1,4,0,0);return;}if(n==1){type.init("单牌",2,1,0,0);return;}if(n==2&&maxCnt==2){type.init("对子",3,2,0,0);return;}if(n==3&&maxCnt==3){type.init("三张 ",4,3,0,0);return;}if(n==4&&maxCnt==3){type.init("三带一",5,3,0,1);return;}if(n==5&&maxCnt==3&&minCnt==2){type.init("三带一对",6,3,0,2);return;}if(n==6&&maxCnt==4){type.init("四带二",7,4,0,1);return;}if(n==8&&maxCnt==4&&minCnt==2){type.init("四带二",8,4,0,2);return;}if(n>=5&&maxCnt==1&&cards[0]->value==cards[n-1]->value+n-1){type.init("顺子",9,1,1,0);return;}if(n>=6&&maxCnt==2&&minCnt==2&&cards[0]->value==cards[n-1]->value+n/2-1){type.init("连对",10,2,1,0);return;}int fjCnt;//统计连续且大于3三张的牌for(i=0;i<VALUECOUNT &&cntFlag[i]<3;i++);for(fjCnt=0;i<VALUECOUNT &&cntFlag[i]>=3;i++,fjCnt++);if(fjCnt>1){if(n==fjCnt*3)type.init("飞机",11,3,1,0);else if(n==fjCnt*4)type.init("飞机",12,3,1,1);else if(n==fjCnt*5&&minCnt==2)type.init("飞机",13,3,1,2);}
}
void init(string inputStr, vector<Card*> &cardsHolded){this->cards.clear();//不出if(inputStr=="N"){this->calType();return;}int i,j;//输入合法性判断for(i=0;i<inputStr.size();i++){bool find=false;for(j=0;toFigure[j];j++){if(inputStr[i]==toFigure[j]){find=true;break;}}if(find==false){//输入字符不在toFigure中return;}}//查找手中有没有这些牌int visitFlag[20]={0};for(i=0;i<inputStr.size();i++){Card *find=NULL;for(j=0;j<cardsHolded.size();j++){if(!visitFlag[j]&&cardsHolded[j]->figure==inputStr[i]){visitFlag[j]=1;find=cardsHolded[j];break;}}if(find){this->cards.push_back(find);}else{cout<<inputStr[i];cout<<"没有找到\t";this->cards.clear();return;}}//end for(i=0;i<inputStr.size();i++)this->arrange();
}
void init(vector<Card*> newCards){this->cards=newCards;this->arrange();
}
bool isCanBeat(CardGroup &cardGroup){if(cardGroup.type.typeStr=="王炸"){return false;}else if(this->type.typeStr=="王炸"){return true;}else if(cardGroup.type==this->type &&this->type.typeStr=="炸弹"){return value()>cardGroup.value();}else if(cardGroup.type.typeStr=="炸弹"){return false;}else if(this->type.typeStr=="炸弹"){return true;}else if(cardGroup.type==this->type &&this->cards.size()==cardGroup.cards.size()){return this->value()>cardGroup.value();}else{return false;}
}
int value(){//计算牌组权值int i;if(type.typeStr=="三带一"||type.typeStr=="三带一对"||type.typeStr=="飞机"){for(i=2;i<cards.size();i++){if(cards[i]->value==cards[i-2]->value){return cards[i]->value;}}}if(type.typeStr=="四带二"){for(i=3;i<cards.size();i++){if(cards[i]->value==cards[i-3]->value){return cards[i]->value;}}}return cards[0]->value;
}
void arrange(){//整理:排序、计算类型// sort(this->cards.begin(),this->cards.end(),cmp);this->calType();
}
};
class LastCards{
static LastCards *lastCards;
public:
Player *player;
CardGroup cardGroup;
static LastCards* inst(){//单例模式if(lastCards==NULL){lastCards=new LastCards();}return lastCards;
}
vector<Card*> findCanBeatFrom(vector<Card*> &cardsHolded){//查找能打得过的牌int i,j,k,n=cardsHolded.size(),m=cardGroup.cards.size();string typeStr=cardGroup.type.typeStr;vector<Card*> ret;if(typeStr=="王炸"||n<m){//打不过,返回空数组return ret;}int value=cardGroup.value();//统计各点牌出现的次数int cntFlag[VALUECOUNT]={0};for(i=0;i<n;i++){cntFlag[cardsHolded[i]->value]++;}int continuousCount=1;if(cardGroup.type.isContinuous){continuousCount=m/(cardGroup.type.cnt1+cardGroup.type.cnt2);}bool findFirstFigure;//cout<<"continuousCount="<<continuousCount<<endl;for(i=value+1;i<VALUECOUNT;i++){findFirstFigure=true;for(j=0;j<continuousCount;j++){if(cntFlag[i-j]<cardGroup.type.cnt1){findFirstFigure=false;break;}}if(findFirstFigure){ret.clear();int firstFigure=i;//cout<<"查找"<<cardGroup.type.cnt1<<"个"<<firstFigure+3<<endl;for(k=0,j=0;k<cardsHolded.size() &&j<continuousCount;k++){if(cardsHolded[k]->value==firstFigure-j){for(int kk=0;j>=0&&kk<cardGroup.type.cnt1;kk++){ret.push_back(cardsHolded[k+kk]);}j++;}}if(cardGroup.type.cnt2>0){int SecondFigures[5];int SecondCount=continuousCount;if(cardGroup.type.typeStr=="四带二")SecondCount=2;bool findSecondFigure=true;for(j=0,k=-1;j<SecondCount &&findSecondFigure;j++){findSecondFigure=false;for(k++;k<VALUECOUNT;k++){SecondFigures[j]=k;if(cntFlag[k]>=cardGroup.type.cnt2 &&cntFlag[k]<cardGroup.type.cnt1){findSecondFigure=true;break;}}}if(findSecondFigure){//cout<<"查找SecondFigure "<<cardGroup.type.cnt2<<"个"<<SecondFigures[0]+3<<endl;//cout<<"SecondCount= "<<SecondCount<<endl;//for(i=0;i<SecondCount;i++)cout<<"SecondFigures["<<i<<"]="<<SecondFigures[i]<<endl;for(i=0;i<SecondCount;i++){for(j=0;j<cardsHolded.size();){if(cardsHolded[j]->value==SecondFigures[i]){for(k=0;k<cardGroup.type.cnt2;k++){//cout<<"添加"<<cardsHolded[j]->value+3<<endl;ret.push_back(cardsHolded[j+k]);}do{j++;}while(j<cardsHolded.size()&&cardsHolded[j]->value==SecondFigures[i]);}else{j++;}}}return ret;}//if(findSecondFigure)}//end if(cardGroup.type.cnt2>0)else{return ret;}}//end if(findFirstFigure)}//end for(i=value+1;i<VALUECOUNT;i++)ret.clear();//没牌打得过时查找有没有炸弹if(typeStr!="炸弹"){for(i=cardsHolded.size()-1;i>=3;i--){if(cardsHolded[i]->value==cardsHolded[i-3]->value){for(j=0;j<4;j++){ret.push_back(cardsHolded[i-j]);}break;}}}return ret;
}//end vector<Card*> findCanBeatFrom()
};
LastCards* LastCards::lastCards = NULL;
class Player{
public:
string name;
vector<Card*> cards;
void arrange(){sort(cards.begin(),cards.end(),cmp);
}
void print(){cout<<this->name<<":\t";for(int i=0;i<cards.size();i++){cards[i]->print();}cout<<"["<<cards.size()<<"]\n";
}
vector<Card*> tip(){//提示功能,使自己最小一张连最长CardGroup ret;string temp;int j,k,m=cards.size();for(j=0;j<m;j++){temp="";for(k=j;k<m;k++){temp+=cards[k]->figure;}ret.init(temp,cards);if(ret.type.typeId!=ERROR){return ret.cards;}}ret.cards.clear();return ret.cards;
}
void chupai(CardGroup &cardGroup){//出牌cout<<this->name<<":\t";cout<<cardGroup.type.typeStr<<' ';for(int i=0;i<cardGroup.cards.size();i++){cardGroup.cards[i]->print();this->cards.erase(find(this->cards.begin(),this->cards.end(),cardGroup.cards[i]));}cout<<"\t["<<this->cards.size()<<"]\n";if(cardGroup.type.typeStr!="不出"){//记录到 LastCards 中LastCards::inst()->player=this;LastCards::inst()->cardGroup.init(cardGroup.cards);}
}
};
class Landlords{
Player *player[PLAYERCOUNT];
bool finished,youWin,landlordWin;
int landlordIndex;
Card *cards[CARDSCOUNT];
public:
Landlords(){int i=0,j=0,k=0;for(i=0;i<PLAYERCOUNT;i++){this->player[i]=new Player();}//54张牌初始化for(k=i=0;i<14;i++){if(toFigure[i]==' '){continue;}for(COLOR color=eHEART;color<=eSPADE;color=(COLOR)(color+1)){this->cards[k++]=new Card(toFigure[i],color);}}this->cards[k++]=new Card('Y',eSPADE);this->cards[k]=new Card('Z',eHEART);
}
~Landlords(){for(int i=0;i<PLAYERCOUNT;i++){delete this->player[i];}for(int i1=0;i1<CARDSCOUNT;i1++){delete this->cards[i1];}
}
void init(){player[CURRENTPLAYER]->name="Bice";player[1]->name="玩家2";player[2]->name="玩家3";finished=false;youWin=false;landlordWin=false;//抢地主landlordIndex=ERROR;while(landlordIndex==ERROR){srand((int)time(0));shuffle();landlordIndex=chooseLandlord();}cout<<player[landlordIndex]->name<<"\t成为地主\n\n";this->add3Cards();LastCards::inst()->player=player[landlordIndex];
}
void startGame(){string inputSrt;CardGroup inputCards;for(int iTurns=landlordIndex;!finished;iTurns++){if(iTurns>=PLAYERCOUNT){iTurns=0;}if(iTurns==CURRENTPLAYER){cout<<endl;player[iTurns]->print();cout<<"输入提示:Z=大王 Y=小王 0=10 N=不要 输入可无序 例如:JKQ0A9\n请出牌:\t";do{cin>>inputSrt;inputCards.init(inputSrt,player[iTurns]->cards);}while(check(&inputCards)==false);}else{if(player[iTurns]==LastCards::inst()->player){//若是上次出牌的是自己,启用提示功能inputCards.init(player[iTurns]->tip());}else{//查找能打得过上家的牌inputCards.init(LastCards::inst()->findCanBeatFrom(player[iTurns]->cards));}}player[iTurns]->chupai(inputCards);//出牌if(player[iTurns]->cards.size()==0){//玩家手中没牌了,游戏结束finished=true;landlordWin=iTurns==landlordIndex;if(landlordWin){youWin=landlordIndex==CURRENTPLAYER;}else{youWin=landlordIndex!=CURRENTPLAYER;}}}cout<<"\n_________________________ "<<(youWin?"You Win!":"You Lose!")<<" _________________________\n\n";
}
void add3Cards(){cout<<"地主3张牌:\t";for(int i=PLAYERCOUNT*17;i<CARDSCOUNT;i++){this->cards[i]->print();player[landlordIndex]->cards.push_back(cards[i]);}cout<<endl;player[landlordIndex]->arrange();
}
int chooseLandlord(){cout<<"\n_________________________ 抢地主 _________________________\n\n";int first=-1,last,cnt=0,i,j=rand()%PLAYERCOUNT;bool decision;for(i=0;i<PLAYERCOUNT;i++,j==2?j=0:j++){if(j==CURRENTPLAYER){decision=makeChoice("是否抢地主?(Y=抢/N=不抢):");}else{decision=rand()%2;}if(decision){cnt++;last=j;if(first==-1){first=j;}cout<<this->player[j]->name<<"\t抢地主\n";}else{cout<<this->player[j]->name<<"\t没有抢\n";}}if(cnt==0){cout<<"没人抢,重新发牌\n";return ERROR;}if(cnt==1){//第一轮只有一人抢地主return first;}else{//最后一次争抢if(first==CURRENTPLAYER){decision=makeChoice("是否抢地主?(Y=抢/N=不抢):");}else{decision=rand()%2;}if(decision){cout<<this->player[first]->name<<"\t抢地主\n";return first;}else{cout<<this->player[first]->name<<"\t没有抢\n";return last;}}
}
void shuffle(){int i,j,k;//洗牌for(i=0;i<CARDSCOUNT;i++){swap(this->cards[i],this->cards[rand()%CARDSCOUNT]);}//分牌for(k=i=0;i<PLAYERCOUNT;i++){this->player[i]->cards.clear();for(j=0;j<17;j++){this->player[i]->cards.push_back(this->cards[k++]);}this->player[i]->arrange();//整理this->player[i]->print();}
}
bool check(CardGroup *cardGroup){if(cardGroup->type.typeId==ERROR){cout<<"出牌错误,重新输入\n";return false;}else if(cardGroup->type.typeStr=="不出"){return true;}else if(LastCards::inst()->player!=player[CURRENTPLAYER]&&!cardGroup->isCanBeat(LastCards::inst()->cardGroup)){cout<<"打不过,重新输入\n";return false;}else{return true;}
}
};
int main(){
Landlords *landlords=new Landlords();
do{landlords->init();//发牌、抢地主landlords->startGame();//游戏开始
}while(makeChoice("\n是否继续游戏?(Y=继续/N=结束): "));
delete landlords;
return 0;
}
bool makeChoice(string tip){
cout<<tip;
string input;
cin>>input;
return input=="Y"||input=="y";
}
bool cmp(Card* a,Card* b){
if(a->value==b->value){return a->color>b->color;
}else{return a->value>b->value;
}
}

嗨,我是[LucianaiB](https://lucianaib.blog.csdn.net/ “LucianaiB”)。如果你觉得我的分享有价值,不妨通过以下方式表达你的支持:👍 点赞来表达你的喜爱,📁 关注以获取我的最新消息,💬 评论与我交流你的见解。我会继续努力,为你带来更多精彩和实用的内容。

点击这里👉[LucianaiB](https://lucianaib.blog.csdn.net/ “LucianaiB”) ,获取最新动态,⚡️ 让信息传递更加迅速。

相关文章:

C语言之斗地主游戏

&#x1f31f; 嗨&#xff0c;我是LucianaiB&#xff01; &#x1f30d; 总有人间一两风&#xff0c;填我十万八千梦。 &#x1f680; 路漫漫其修远兮&#xff0c;吾将上下而求索。 ​ C语言之斗地主游戏 目录 程序概述程序设计 Card类CardGroup类Player类LastCards类Land…...

【玩转全栈】----Django制作部门管理页面

目录 大致效果 BootStrap BootStrap简介 BootStrap配置 BootStrap使用 基本配置 部分代码解释及注意&#xff1a; 用户编辑&#xff1a; 新添数据&#xff1a; 删除数据&#xff1a; 大致效果 我先给个大致效果&#xff0c;基本融合了Django、Bootstrap、css、html等等。 基于D…...

Unreal Engine 5 C++ Advanced Action RPG 十章笔记

第十章 Survival Game Mode 2-Game Mode Test Map 设置游戏规则进行游戏玩法 生成敌人玩家是否死亡敌人死亡是否需要刷出更多 肯定:难度增加否定:玩家胜利 流程 新的游戏模式类游戏状态新的数据表来指定总共有多少波敌人生成逻辑UI告诉当前玩家的敌人波数 3-Survival Game M…...

学习ASP.NET Core的身份认证(基于JwtBearer的身份认证9)

测试数据库中只有之前记录温湿度及烟雾值的表中数据较多&#xff0c;在该数据库中增加AppUser表&#xff0c;用于登录用户身份查询&#xff0c;数据库表如下所示&#xff1a;   项目中安装SqlSugarCore包&#xff0c;然后修改控制器类的登录函数及分页查询数据函数&#xff…...

缓存之美:万文详解 Caffeine 实现原理(上)

由于社区最大字数限制&#xff0c;本文章将分为两篇&#xff0c;第二篇文章为缓存之美&#xff1a;万文详解 Caffeine 实现原理&#xff08;下&#xff09; 大家好&#xff0c;我是 方圆。文章将采用“总-分-总”的结构对配置固定大小元素驱逐策略的 Caffeine 缓存进行介绍&…...

Spark/Kafka

文章目录 项目地址一、Spark1. RDD1.1 五大核心属性1.2 执行原理1.3 四种创建方式二、Kafka2.1 生产者(1)分区器(2)生产者提高吞吐量(3) 生产者数据可靠性数据传递语义幂等性和事务数据有序2.2 Broker(1)Broker工作流程(2)节点服役和退役2.3 副本(1)Follower故障细…...

深入浅出:Go语言中的Unicode与字符编码详解

深入浅出:Go语言中的Unicode与字符编码详解 引言 在当今的编程世界中,字符编码和Unicode是不可或缺的技术基础。Go语言作为一种强大的编程语言,其对Unicode的支持和字符编码的处理方式,对于开发者来说至关重要。本文将从Unicode的基础知识入手,逐步深入探讨Go语言中字符编…...

什么是SSL及SSL的工作流程

什么是 SSL SSL(Secure Sockets Layer,安全套接层)是一种保护互联网通信安全的加密协议,用于确保数据在客户端和服务器之间传输时的保密性、完整性和身份验证。它已被TLS(Transport Layer Security,传输层安全协议)取代,但很多场景仍习惯称其为SSL。 SSL/TLS 的主要目…...

.Net Core微服务入门全纪录(二)——Consul-服务注册与发现(上)

系列文章目录 1、.Net Core微服务入门系列&#xff08;一&#xff09;——项目搭建 2、.Net Core微服务入门全纪录&#xff08;二&#xff09;——Consul-服务注册与发现&#xff08;上&#xff09; 3、.Net Core微服务入门全纪录&#xff08;三&#xff09;——Consul-服务注…...

AD7606, 逐次逼近型ADC以及一次被GPT坑了的过程.

首先, 我的项目中, 已有的一个ADC芯片, 8通道, 并行, Analog家的ad7606, 在采集高速的正弦信号的时候, 我发现采集到的值怎么都不太对. 但是宏观来看, 并没有太大问题, 首先我怀疑的是量程问题, 接入一个5伏直流, 得到的读数确实是接近16bit的正半量程的读数, 32xxx. 接着我用信…...

抬手、放手识别算法

在一款智能手表中&#xff0c; 平时手表处于息屏的状态&#xff0c; 用于节省功耗&#xff0c;延长使用时间。 在用户进行抬手的时候&#xff0c;其实是希望能够及时看一下时间、消息通知等信息的。这时手表应该能够检测到用户的抬手动作&#xff0c;自动进行屏幕的点亮。当用户…...

深度学习篇---AnacondaLabelImg

文章目录 前言第一部分&#xff1a;Anaconda是什么&#xff1f;1.简介2.特点&#xff08;1&#xff09;包管理器Conda&#xff08;2&#xff09;环境管理&#xff08;3&#xff09;预装包&#xff08;4&#xff09;跨平台&#xff08;5&#xff09;社区支持 3.安装WindowsLinux…...

探索云原生可观测性:技术与团队协作的深度结合

TheNewStack 出品的电子书《Cloud Native Observability for DevOps Teams》读后感&#xff0c;老书新读&#xff0c;还是另有一番领悟。 阅读原文请转到&#xff1a;https://jimmysong.io/blog/cloud-native-observability-devops/ 最近读了 TheNewStack 发布的电子书《Cloud …...

解决 Django 5.1 中的 TemplateSyntaxError 错误

解决 Django 5.1 中的 TemplateSyntaxError 错误 在 Django 开发过程中&#xff0c;我们经常会遇到 TemplateSyntaxError 错误&#xff0c;尤其是在模板文件中使用不被支持或错误的模板标签时。最近&#xff0c;我们遇到的一个常见错误是&#xff1a; Invalid block tag on l…...

基于SSM的自助购药小程序设计与实现(LW+源码+讲解)

专注于大学生项目实战开发,讲解,毕业答疑辅导&#xff0c;欢迎高校老师/同行前辈交流合作✌。 技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;…...

04JavaWeb——Maven-SpringBootWeb入门

Maven 课程内容 初识Maven Maven概述 Maven模型介绍 Maven仓库介绍 Maven安装与配置 IDEA集成Maven 依赖管理 01. Maven课程介绍 1.1 课程安排 学习完前端Web开发技术后&#xff0c;我们即将开始学习后端Web开发技术。做为一名Java开发工程师&#xff0c;后端Web开发…...

场馆预定平台高并发时间段预定实现V2

&#x1f3af; 本文档介绍了场馆预订系统接口V2的设计与实现&#xff0c;旨在解决V1版本中库存数据不一致及性能瓶颈的问题。通过引入令牌机制确保缓存和数据库库存的最终一致性&#xff0c;避免因服务器故障导致的库存错误占用问题。同时&#xff0c;采用消息队列异步处理库存…...

如何利用边缘节点服务打造极致用户体验?

随着互联网和数字化技术的飞速发展&#xff0c;用户对网络访问速度和服务体验的要求也在不断提高。在一个信息快速传播的时代&#xff0c;延迟过高或访问卡顿的问题会直接影响用户体验&#xff0c;甚至导致用户流失。因此&#xff0c;企业如何优化网络性能、提升用户访问速度&a…...

C语言之小型成绩管理系统

&#x1f31f; 嗨&#xff0c;我是LucianaiB&#xff01; &#x1f30d; 总有人间一两风&#xff0c;填我十万八千梦。 &#x1f680; 路漫漫其修远兮&#xff0c;吾将上下而求索。 C语言之小型成绩管理系统 目录 设计题目设计目的设计任务描述设计要求输入和输出要求验收要…...

ASP.NET Core 中基于 Cookie 的身份鉴权实现

在 ASP.NET Core 应用中&#xff0c;基于 Cookie 的身份鉴权是一种常见的身份验证方式&#xff0c;特别适用于传统的 Web 应用程序。Cookie 能够在用户的浏览器中存储身份验证数据&#xff0c;从而在用户访问应用的不同页面时保持登录状态。 一、配置 Cookie 身份验证 首先&a…...

解锁数据库简洁之道:FastAPI与SQLModel实战指南

在构建现代Web应用程序时&#xff0c;与数据库的交互无疑是核心环节。虽然传统的数据库操作方式&#xff08;如直接编写SQL语句与psycopg2交互&#xff09;赋予了我们精细的控制权&#xff0c;但在面对日益复杂的业务逻辑和快速迭代的需求时&#xff0c;这种方式的开发效率和可…...

论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)

笔记整理&#xff1a;刘治强&#xff0c;浙江大学硕士生&#xff0c;研究方向为知识图谱表示学习&#xff0c;大语言模型 论文链接&#xff1a;http://arxiv.org/abs/2407.16127 发表会议&#xff1a;ISWC 2024 1. 动机 传统的知识图谱补全&#xff08;KGC&#xff09;模型通过…...

今日科技热点速览

&#x1f525; 今日科技热点速览 &#x1f3ae; 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售&#xff0c;主打更强图形性能与沉浸式体验&#xff0c;支持多模态交互&#xff0c;受到全球玩家热捧 。 &#x1f916; 人工智能持续突破 DeepSeek-R1&…...

JS设计模式(4):观察者模式

JS设计模式(4):观察者模式 一、引入 在开发中&#xff0c;我们经常会遇到这样的场景&#xff1a;一个对象的状态变化需要自动通知其他对象&#xff0c;比如&#xff1a; 电商平台中&#xff0c;商品库存变化时需要通知所有订阅该商品的用户&#xff1b;新闻网站中&#xff0…...

Linux 内存管理实战精讲:核心原理与面试常考点全解析

Linux 内存管理实战精讲&#xff1a;核心原理与面试常考点全解析 Linux 内核内存管理是系统设计中最复杂但也最核心的模块之一。它不仅支撑着虚拟内存机制、物理内存分配、进程隔离与资源复用&#xff0c;还直接决定系统运行的性能与稳定性。无论你是嵌入式开发者、内核调试工…...

排序算法总结(C++)

目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指&#xff1a;同样大小的样本 **&#xff08;同样大小的数据&#xff09;**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...

MySQL 知识小结(一)

一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库&#xff0c;分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷&#xff0c;但是文件存放起来数据比较冗余&#xff0c;用二进制能够更好管理咱们M…...

离线语音识别方案分析

随着人工智能技术的不断发展&#xff0c;语音识别技术也得到了广泛的应用&#xff0c;从智能家居到车载系统&#xff0c;语音识别正在改变我们与设备的交互方式。尤其是离线语音识别&#xff0c;由于其在没有网络连接的情况下仍然能提供稳定、准确的语音处理能力&#xff0c;广…...

数据结构:递归的种类(Types of Recursion)

目录 尾递归&#xff08;Tail Recursion&#xff09; 什么是 Loop&#xff08;循环&#xff09;&#xff1f; 复杂度分析 头递归&#xff08;Head Recursion&#xff09; 树形递归&#xff08;Tree Recursion&#xff09; 线性递归&#xff08;Linear Recursion&#xff09;…...

相关类相关的可视化图像总结

目录 一、散点图 二、气泡图 三、相关图 四、热力图 五、二维密度图 六、多模态二维密度图 七、雷达图 八、桑基图 九、总结 一、散点图 特点 通过点的位置展示两个连续变量之间的关系&#xff0c;可直观判断线性相关、非线性相关或无相关关系&#xff0c;点的分布密…...