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”) ,獲取最新動態,?? 讓信息傳遞更加迅速。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/66641.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/66641.shtml
英文地址,請注明出處:http://en.pswp.cn/web/66641.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

python編程-OpenCV(圖像讀寫-圖像處理-圖像濾波-角點檢測-邊緣檢測)圖像變換

形態變換 圖像處理中的形態學操作是處理圖像結構的有效方法。以下是一些常見的形態學操作的介紹及其在 OpenCV 中的實現示例。 1. 腐蝕&#xff08;Erosion&#xff09; 腐蝕操作通過消除圖像邊界來減少圖像中的白色區域&#xff08;前景&#xff09;&#xff0c;使物體的邊…

【Prometheus】PromQL進階用法

?? 歡迎大家來到景天科技苑?? &#x1f388;&#x1f388; 養成好習慣&#xff0c;先贊后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者簡介&#xff1a;景天科技苑 &#x1f3c6;《頭銜》&#xff1a;大廠架構師&#xff0c;華為云開發者社區專家博主&#xff0c;…

SiamCAR(2019CVPR):用于視覺跟蹤的Siamese全卷積分類和回歸網絡

原文標題:SiamCAR: Siamese Fully Convolutional Classification and Regression for Visual Tracking 中文標題:SiamCAR:用于視覺跟蹤的Siamese全卷積分類和回歸 代碼地址: https://github.com/ohhhyeahhh/SiamCAR Abstract 通過將視覺跟蹤任務分解為兩個子問題,…

計算機網絡介質訪問控制全攻略:從信道劃分到協議詳解!!!

一、信道劃分介質訪問控制 介質訪問控制&#xff1a;多個節點共享同一個“總線型”廣播信道時&#xff0c;可能發生“信號沖突” 應該怎么控制各節點對傳輸介質的訪問&#xff0c;才能減少沖突&#xff0c;甚至避免沖突? 時分復用(TDM) 時分復用&#xff1a;將時間分為等長的“…

Prometheus部署及linux、mysql、monog、redis、RocketMQ、java_jvm監控配置

Prometheus部署及linux、mysql、monog、redis、RocketMQ、java_jvm監控配置 1.Prometheus部署1.2.Prometheus修改默認端口 2.grafana可視化頁面部署3.alertmanager部署4.監控配置4.1.主機監控node-exporter4.2.監控mysql數據庫mysqld_exporter4.3.監控mongod數據庫mongodb_expo…

基于tldextract提取URL里的子域名、主域名、頂級域

TLD是TopLevel Domain的縮寫。?tldextract? 是一個用于從URL中提取子域、主域名和頂級域&#xff08;TLD&#xff09;的Python庫。它利用公共后綴列表&#xff08;Public Suffix List&#xff09;來確保即使是復雜或不常見的URL結構也能被正確解析。tldextract能夠處理包括IC…

常見Arthas命令與實踐

Arthas 官網&#xff1a;https://arthas.aliyun.com/doc/&#xff0c;官方文檔對 Arthas 的每個命令都做出了介紹和解釋&#xff0c;并且還有在線教程&#xff0c;方便學習和熟悉命令。 Arthas Idea 的 IDEA 插件。 這是一款能快速生成 Arthas命令的插件&#xff0c;可快速生成…

Mellanox ConnectX 系列網卡的雙驅動架構:以太網與 InfiniBand 的協同設計

在現代數據中心和高性能計算(HPC)環境中,網絡硬件的性能和功能至關重要。Mellanox ConnectX 系列網卡以其卓越的性能和多功能性而聞名,支持從傳統的以太網到高性能的 InfiniBand 網絡協議。這種多功能性使得 Mellanox 網卡能夠滿足不同應用場景的需求,從常規的數據中心網絡…

win32匯編環境,對多行編輯框添加或刪除文本

;運行效果 ;win32匯編環境,對多行編輯框添加或刪除文本 ;主要要先設置文本的開始點與結束點&#xff0c;然后把一段文本頂替上去。沒有添加文本或刪除文本的概念&#xff0c;只有頂替。如果開始點與結束點都是前面文本的長度值&#xff0c;則成了從后面添加文本的效果。如果結束…

CSDN年度回顧:技術征途上的堅實步伐

嘿&#xff0c;時光過得可真快呀&#xff0c;就像那匹跑得飛快的白馬&#xff0c;嗖的一下&#xff0c;2024 年的日歷就這么悄無聲息地翻到了最后一頁。這會兒我回頭看看在 CSDN 上度過的這一年&#xff0c;心里那叫一個感慨萬千&#xff0c;滿滿的都是喜悅&#xff0c;就像心里…

泛型子類使用Builder提示:both methods have same erasure, yet neither hides the other

父類 Data Builder AllArgsConstructor NoArgsConstructor public class ParentClass {public String name; } 子類 AllArgsConstructor NoArgsConstructor Data SuperBuilder public class ChildClass<T> extends ParentClass {private T value; } 提示錯誤 builde…

Springboot集成Elasticsearch8.0(ES)版本,采用JAVA Client方式進行連接和實現CRUD操作

本文章介紹了 springboot t集成Elasticsearch8.0(ES)版本,如何通過 AVA Client方式進行連接和實現CRUD操作 在ES7.15版本之后,ES官方將高級客戶端 RestHighLevelClient標記為棄用狀態。同時推出了全新的 Java API客戶端 Elasticsearch Java API Client,該客戶端也將在 Ela…

人臉識別打卡系統--基于QT(附源碼)

逃離舒適區 項目源代碼放在我的倉庫中&#xff0c;有需要自取 項目地址 https://gitcode.com/hujiahangdewa/Face_recognition.git 文章目錄 一、項目結構分析二、服務器的搭建三、客戶端的搭建四、人臉識別庫的申請五、基于人臉識別庫的識別判斷六、QT人臉識別----調用百度ai…

人工智能在數字化轉型中的角色:從數據分析到智能決策

引言 在數字化轉型浪潮中&#xff0c;人工智能&#xff08;AI&#xff09;正迅速崛起&#xff0c;成為推動企業創新和變革的關鍵力量。面對日益復雜的市場環境和激烈的行業競爭&#xff0c;企業亟需借助技術手段提高運營效率、優化決策過程&#xff0c;并增強市場競爭力。而AI…

react install

react 安裝 React 是一個用于構建用戶界面的 JavaScript 庫。以下是安裝 React 的步驟&#xff1a; 使用 Create React App Create React App 是一個官方支持的命令行工具&#xff0c;用于快速搭建 React 應用。 安裝 Node.js 和 npm 確保你的計算機上安裝了 Node.js 和 npm…

Android系統開發(二十):字體活起來,安卓自定義字體改造指南

為什么要寫這篇文章&#xff1f; 你是否厭倦了千篇一律的安卓默認字體&#xff1f;想讓你的設備從“乏味的配角”變成“炫酷的主角”&#xff1f;好消息&#xff01;從Android 12到Android 15&#xff0c;自定義字體變得更簡單、更強大。尤其是表情字體的更新&#xff0c;不僅…

django使用踩坑經歷

DRF 使用drf獲取序列化后的id visitor_serializer VisitorSaveSerializer(data{…}) if visitor_serializer.is_valid():visitor visitor_serializer.save() visitor_id visitor.pkpostgrepsql踩坑 django使用postgrepsql&#xff0c;使用聚合函數如:sum 等&#xff0c;被…

ASP.NET Core中 JWT 實現無感刷新Token

在 Web 應用開發中&#xff0c;用戶登錄狀態的管理至關重要。為了避免用戶頻繁遇到登錄過期的問題&#xff0c;我們可以通過實現 JWT&#xff08;JSON Web Token&#xff09;刷新機制來提升用戶體驗 推薦: 使用 Refresh Token&#xff08;雙 Token 機制&#xff09; 1. 生成和…

將 AzureBlob 的日志通過 Azure Event Hubs 發給 Elasticsearch(3.純python的實惠版)

前情&#xff1a; 將 AzureBlob 的日志通過 Azure Event Hubs 發給 Elasticsearch&#xff08;1.標準版&#xff09;-CSDN博客 將 AzureBlob 的日志通過 Azure Event Hubs 發給 Elasticsearch&#xff08;2.換掉付費的Event Hubs&#xff09;-CSDN博客 python腳本實現 厲害的…

python學opencv|讀取圖像(四十)掩模:三通道圖像的局部覆蓋

【1】引言 前序學習了使用numpy創建單通道的灰色圖像&#xff0c;并對灰色圖像的局部進行了顏色更改&#xff0c;相關鏈接為&#xff1a; python學opencv|讀取圖像&#xff08;九&#xff09;用numpy創建黑白相間灰度圖_numpy生成全黑圖片-CSDN博客 之后又學習了使用numpy創…