《炉石传说台服》【讨论】前两回合时,手上同时抽到两张龙鳗、一张学徒、和一张镜像的机率?
更新时间:1603438656 | 来源:巴哈姆特
于是乎,这就是学校教的C++能派上用场的时候啦!因为写程式能力有点生疏,所以花了一整个晚上才写好。
但是!!!非常令人惊讶,机率竟然不到1%!
以下是执行结果:
举例来说:
0 1 1 0
0.015873 1201
是指:“没换牌前,龙鳗0张、学徒至少1张、镜像至少1张”的情况— 在总共的27405个组合中,一共出现了1201次。
而在这种特定的情况下,前两回合就有抽齐“两张龙鳗、一张学徒、和一张镜像”的条件机率是0.015873。
那幺,就只好把程式码贴上来,和大家讨论实际的机率啦~
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <array>
#include <vector>
using namespace std;
//returns all (-1) if having no other ways to choose
void selection_changeToNextState(int numOfThingsToChooseFrom, int numOfThingsChosen, int nowState[]);
int main(int argc, const char * argv[]) {
const int MaxCards = 30;
int rounds = 2;
array<int,MaxCards> cards={};
cards[0]=2;
cards[1]=2;
cards[2]=2;
cards[3]=24;
array<int,MaxCards> goal={};
goal[0]=2;
goal[1]=1;
goal[2]=1;
goal[3]=0;
array<int,MaxCards> deck={};
int nowCard=0;
int importantTypes=0;
for(int nowType=0; nowType<MaxCards; ++nowType){
if(cards[nowType]>0){
importantTypes = nowType+1;
for(int j=nowCard; j< nowCard+cards[nowType]; ++j){
deck[j]=nowType;
}
nowCard+=cards[nowType];
}
}
int totalCards = nowCard;
cout<<"totalCards:\t"<<totalCards<<"\n";
cout<<"importantTypes:\t"<<importantTypes<<"\n";
//for testing: show the entire deck
/*for(int i=0;i<totalCards;++i){
cout<<i<<":\t"<<deck[i]<<"\n";
}*/
bool isFirst = false;
int firstDrawNum;
if(isFirst)
firstDrawNum=3;
else
firstDrawNum=4;
//hand starts from "choosing the first <firstDrawNum> number of cards"
array<int,MaxCards> hand = {};
for(int i=0;i<firstDrawNum;++i){
hand[i]=i;
}
bool testShow_cardTypeDrawn = false;
bool testShow_possible_hands = false;
bool testShow_possible_afterHands = false;
bool testShow_unfulfilledGoal = false;
bool testShow_finalGoal = false;
bool testShow_cardsLaterDrawn = false;
bool testShow_count = true;
bool testShow_finishProbability = false;
int count=1;
struct cardTypesKept_to_probability{
array<int,MaxCards> cardTypesKept;
double probability;
int count;
};
vector<cardTypesKept_to_probability> record;
while(true){
int cardsKept = 0;
int cardsToRedraw = 0;
array<int,MaxCards> unfulfilledGoal = goal;
array<int,MaxCards> cardTypesKept = {};
array<bool,MaxCards> cardIsKept = {};
for(int j=0;j<firstDrawNum;++j){
int cardDrawn = deck[hand[j]];
// for testing: show card type drawn
if(testShow_cardTypeDrawn)
cout<<cardDrawn<<"\n";
if(unfulfilledGoal[ cardDrawn ]>0){
unfulfilledGoal[ cardDrawn ]--;
cardTypesKept[ cardDrawn ]++;
cardIsKept[ hand[j] ] = true;
++cardsKept;
}
else{
++cardsToRedraw;
}
}
// for testing: show card type drawn
if(testShow_cardTypeDrawn){
cout<<"\n";
for(int j=0;j<importantTypes;++j){
cout<<cardTypesKept[j]<<"\t";
}
cout<<"\n";
}
bool inRecord = false;
for(int j=0;j<record.size();++j){
if(cardTypesKept == record[j].cardTypesKept){
++record[j].count;
inRecord = true;
}
}
if(!inRecord){
int cardsLaterDrawn = cardsToRedraw + (rounds-1) +1;
array<int,MaxCards> calcHandsAfter = {};
for(int i=0;i<cardsLaterDrawn;++i){
calcHandsAfter[i]=i;
}
int afterCount = 1;
int finishCount = 0;
while(true){
// for testing: show all the possible hands after drawing again
if(testShow_possible_afterHands){
cout<<"\t\t";
cout<<afterCount<<"~ ";
for(int j=0;j<cardsLaterDrawn;++j){
cout<<calcHandsAfter[j]<<" ";
}
cout<<"\n";
}
array<int,MaxCards> finalGoal = unfulfilledGoal;
bool goalFinished = true;
int nowPlace=0;
int nowAfterCode=0;
for(int stepsMoved=0; nowPlace<totalCards;++nowPlace){
if(cardIsKept[nowPlace]){
if(testShow_possible_afterHands)
cout<<nowPlace<<" ";
}
else{
if(stepsMoved == calcHandsAfter[nowAfterCode]){
if(testShow_possible_afterHands)
cout<<nowPlace<<" ";
int cardDrawnAfter = deck[nowPlace];
if(finalGoal[ cardDrawnAfter ]>0){
finalGoal[ cardDrawnAfter ]--;
}
++nowAfterCode;
}
++stepsMoved;
}
}
if(testShow_possible_afterHands)
cout<<"\n";
for(int j=0;j<importantTypes;++j){
if(finalGoal[j]>0){
goalFinished=false;
}
}
if(goalFinished)
++finishCount;
// for testing: show finalGoal
if(testShow_finalGoal){
for(int j=0;j<importantTypes;++j){
cout<<finalGoal[j]<<" ";
}
cout<<"\n";
}
selection_changeToNextState(totalCards-cardsKept, cardsLaterDrawn, calcHandsAfter.data());
//if having no other ways to choose
if(calcHandsAfter[0]<0)
break;
++afterCount;
}
double finishProbability = (finishCount * 1.0)/afterCount;
struct cardTypesKept_to_probability c_p={cardTypesKept,finishProbability,1};
record.push_back(c_p);
//cout<<finishProbability<<"\n";
}
// for testing: show all the possible hands
if(testShow_possible_hands){
cout<<count<<": ";
for(int j=0;j<firstDrawNum;++j){
cout<<hand[j]<<" ";
}
cout<<"\n";
}
// for testing: show unfulfilledGoal
if(testShow_unfulfilledGoal){
cout<<count<<"– ";
for(int j=0;j<importantTypes;++j){
cout<<unfulfilledGoal[j]<<" ";
}
}
selection_changeToNextState(totalCards, firstDrawNum, hand.data());
//if having no other ways to choose
if(hand[0]<0)
break;
++count;
}
//for testing
if(testShow_count)
cout<<count<<"\n";
double sumOfProbability = 0.0;
for(int i=0;i<record.size();++i){
sumOfProbability += (record[i].probability)*(record[i].count);
for(int j=0;j<importantTypes;++j){
cout<<record[i].cardTypesKept[j]<<"\t";
}
cout<<"\n";
cout<<record[i].probability<<"\t"<< record[i].count <<"\n";
cout<<"\n";
}
cout<<"\n"<< sumOfProbability/count <<"\n";
return 0;
}
//returns all (-1) if having no other ways to choose
void selection_changeToNextState(int numOfThingsToChooseFrom, int numOfThingsChosen, int nowState[]){
int lastDigit = numOfThingsChosen-1;
int lastNum = numOfThingsToChooseFrom-1;
int carryDigits = 0;
while(nowState[lastDigit - carryDigits] >= lastNum-carryDigits){
++carryDigits;
if(lastDigit - carryDigits<0)
break;
}
//return all (-1) if having no other ways to choose
if(lastDigit - carryDigits<0){
for(int j= 0; j<=lastDigit; ++j){
nowState[j]= -1;
}
return;
}
nowState[lastDigit - carryDigits]++;
for(int j= lastDigit - carryDigits+1; j<=lastDigit; ++j){
nowState[j]=nowState[j-1]+1;
}
}
跑出来的结果比我预期中小很多。大家觉得,这一种情况的机率是多少呢?
后手 ,1费有龙鳗—
换牌前没有的机率:
p = C(28,4)/C(30,4)=
(28*27*26*25)/(30*29*28*27)=
(26*25)/(30*29)=0.747
全换后也没有的机率:
C(28,4)/C(30,4) = 0.747
后手多抽的那张也没有的机率:
(30-4-2)/(30-4)=24/26=0.923
第一回合没有龙鳗的总机率:以上三个相乘 = 0.747*0.747*0.923 = 0.515
第一回合有龙鳗的总机率:
1 - 0.515 = 0.485
另外,由程式得出,前两回合同时有龙鳗+学徒的机率是0.245,约为1/4。
totalCards:30
importantTypes:3
27405
110
11405
100
0.3201975525
010
0.3201975525
000
0.11877414950
0.245169
Program ended with exit code: 0
L=学徒
T2有法术的话问题变成10回合内抽出SSLF,F是法术
可以帮我算一下术T1小鬼 硬币 巫医双食尸鬼 的机率吗XD
回到主题
首先是 为什幺要算这个机率呀?
就算让你2张龙鳗+学徒+镜像出了
那也只是你在前两回合就把所有手牌都打玩了
也就是我有东西清场 你就什幺都没了
遇到快攻还怕你铺场比他快吗~
对吧!?
如果只是无聊想算机率的话..
帮我算一下我出生的机率吧XD
2亿的竞争 还不能有缺陷 不然去医院照胎看到缺手缺脚
父母又要是正常夫妻或情侣想生小孩
怀胎10个月还不能有意外
这样看起来 我应该是人生胜利组 对吧XD
有跟没有阿
不然对面怎幺可能动不动就天胡==
空气感奈里( *´◒`*):
10-23 11:31
[tommy014012:ヽ(́◕◞౪◟◕‵)ノ] [tommy014012:ヽ(́◕◞౪◟◕‵)ノ]体感 别人都是神起手100% 我都是高费0%
-
相关文章
- Related articles
更多
-
热门资讯
- Hot News
更多
- 1 《炉石传说》【教学】竞技场选牌教学网站 - HearthArena
- 2 《炉石传说台服》【攻略】标準模式-复活牧
- 3 《炉石传说》【讨论】IOS玩家退费教学
- 4 《炉石传说台服》【问题】炉石卡登问题求解!
- 5 《炉石传说》【问题】请问有加快战场动画的方法吗
- 6 《炉石传说台服》【问题】最近常遇到对方玩家没显示ID,只显示: 你的对手
- 7 《炉石传说台服》【密技】卡铜小技巧 快速启用规则!启用规则! 卡痛!卡痛!
- 8 《炉石传说》【情报】HSREPLAY 最新的Tier list
- 9 《炉石传说台服》【讨论】浅谈暗月马戏团卡包(别在买暗月卡包了!)
- 10 《炉石传说》【其他】蓝龙实体化计画-马里苟斯的模型製作
-
热游推荐
- Hot Game
更多
-
游戏视频
- Game Videos
更多
-
- 《黑色沙漠》【黑色沙漠台服】觉醒女拳码率录制测试bilibili(视频)
- 时间:2021-11-12
-
- 《黑色沙漠》【黑色沙漠】2021年万圣节活动 我遇见了阴间莎亦_网络游戏热门视频(视频)
- 时间:2021-11-12
-
- 《黑色沙漠》【黑色沙漠】降生 10代梦想马bilibili(视频)
- 时间:2021-11-12
-
- 《黑色沙漠》【黑色沙漠】万圣节前夜 韩服城战 天马攻城bilibili(视频)
- 时间:2021-11-12