繁体   English   中英

魔术集合卡在C中绘制概率函数

[英]Magic The Gathering Card Draw Probability Function In C

我正在写一个函数,它会告诉你你的牌组大小,你在牌组中的特定牌的副本数量,你的初始手牌大小,你重新调整牌的数量(我们将mulliganed牌设置为绘图,然后将那些被淘汰的卡片拖回来),然后你要转向那张牌。

基本上我将所有NOT绘制卡的概率相乘(然后做1减去那个概率),以便给出我通过特定转弯绘制特定卡的概率。 到目前为止我的功能看起来像这样:

void card_probability() {

    int total;
    int numCopies;
    int n;
    int m;
    int turn;
    double initial_draw_prob;
    double mulligan_prob;
    double draw_prob;
    double neg_probability;
    double probability;

    printf("Enter how many total cards there are in the deck: ");
    scanf("%d", &total);

    printf("Enter how many copies of the card that you are looking for are 
    in the deck: ");
    scanf("%d", &numCopies);

    printf("Enter your initial hand size: ");
    scanf("%d", &n);

    printf("Enter how many cards you are mulliganing: ");
    scanf("%d", &m);

    printf("Enter what turn you want to draw the card by: ");
    scanf("%d", &turn);

    initial_draw_prob = ((total - numCopies) / total);

    //for loop{}

    mulligan_prob = ((total - numCopies - n) / (total - n));

    //for loop{}

    draw_prob = ((total - numCopies - n - m) / (total - n - m));

    //for loop{}

    neg_probability = initial_draw_prob * mulligan_prob * draw_prob;
    probability = 1 - neg_probability


    printf("The probability of drawing at least one of the cards by turn %d 
    given you mulliganed %d cards is %lf", turn, m, probability);

}

int main(){
card_probability();

return 0;
}

我在设置这些for循环时无法正常工作。 基本上发生的是三个不同的概率部分:

1.)不能在你的第一手牌中绘制所需牌的概率(总数 - numCopies)/(总数)是在第一次抽牌时不抽取该牌的概率。 然后,例如,如果你总共画了7张牌,你就会继续并将概率乘以一直到你达到这个词(总数 - numCopies - 7)/(总数 - 7)

2.)在您使用指定数量后,不绘制卡片的可能性。

3.)未按指定转弯绘制卡的可能性。

任何人都可以帮我设置这些for循环吗? 我不能让增量正确。 我在纸上做了数学计算,并且甲板大小为10,我想要的卡片副本为2,手的大小为2,重复1次,选择3转,我得到的概率为16.66%,不会拉卡=>大约83%的人在第3轮抽签。

那么,当你在看循环时,为什么不减少一个额外的值呢?

所以

int current_total = total;
for( int i = 0; i < opening_hand_size; i++)
{
  prob = prob * (( current_total - num_copies) / current_total) ;
  current_total--;
} 

首先,我们需要一张卡片不在n张牌中的赔率的公式。

P[Not found after n draws] 
= (deck_size - num_copies - 0) / (deck_size - 0)
* (deck_size - num_copies - 1) / (deck_size - 1)
...
* (deck_size - num_copies - (n-2)) / (deck_size - (n-2))
* (deck_size - num_copies - (n-1)) / (deck_size - (n-1))

在C中,这可以实现如下:

unsigned deck_size  = ...;
unsigned num_copies = ...;
unsigned num_draws  = ...;
float p = 1;
while (num_draws--) {
   p *= (float)(deck_size - num_copies - num_draws) / (float)(deck_size - num_draws);
}

要么

unsigned deck_size  = ...;
unsigned num_copies = ...;
unsigned num_draws  = ...;
float p = 1;
while (num_draws--) {
   p *= (float)(deck_size - num_copies) / (float)deck_size;
   --deck_size;
}

其余的可以由此构建。

#include <stdio.h>

float p_not_in(int deck_size, int num_draws, int num_copies) {
   float p = 1;
   while (num_draws--) {
      p *= (float)(deck_size - num_copies) / (float)deck_size;
      --deck_size;
   }

   return p;
}

int main() {
   unsigned deck_size          = ...;
   unsigned max_mulligans      = ...;
   unsigned draw_on_first_turn = ...;  // boolean
   unsigned max_turns          = ...;
   unsigned num_copies         = ...;

   float p = 1;

   unsigned starting_hand_size = 7;
   unsigned mulligans_taken = 0;
   while (1) {
      p *= p_not_in(deck_size, starting_hand_size, num_copies);
      deck_size -= starting_hand_size;
      printf("Chance found after %u mulligans: %.0f%%\n", mulligans_taken, (1-p)*100);
      if (mulligans_taken == max_mulligans)
         break;

      deck_size += starting_hand_size;
      --starting_hand_size;
      ++mulligans_taken;
   }

   for (unsigned turn_num = 1; turn_num <= max_turns; ++turn_num) {
      if (turn_num > 1 || draw_on_first_turn) {
         p *= (float)(deck_size - num_copies) / (float)deck_size;
         --deck_size;
      }

      printf("Chance found no later than turn %u: %.0f%%\n", turn_num, (1-p)*100);
   }

   return 0;
}

测试:

unsigned deck_size          = 60;
unsigned max_mulligans      = 2;
unsigned draw_on_first_turn = 1;  // boolean
unsigned max_turns          = 3;
unsigned num_copies         = 4;

输出:

$ gcc -Wall -Wextra -pedantic -std=c99 -o prob prob.c && prob
Chance found after 0 mulligans: 40%
Chance found after 1 mulligans: 61%
Chance found after 2 mulligans: 73%
Chance found no later than turn 1: 75%
Chance found no later than turn 2: 77%
Chance found no later than turn 3: 78%

让我们通过实验获得结果来验证:

#!/usr/bin/perl

use strict;
use warnings;

use List::Util qw( shuffle );

{
   my $num_trials = 10_000;
   my ($deck_size, $max_mulligans, $draw_on_first_turn, $max_turns, $num_copies) = @ARGV;

   my @counts;
   TRIAL:
   for (1..$num_trials) {
      my $i = 0;
      my @deck = shuffle(
         ( 0 ) x ( $deck_size - $num_copies ),
         ( 1 ) x $num_copies,
      );

      my $starting_hand_size = 7;
      my $mulligans_taken = 0;
      while (1) {
         my @hand = splice(@deck, 0, $starting_hand_size);
         next TRIAL if grep { $_ } @hand;

         ++$counts[$i++];
         last if $mulligans_taken == $max_mulligans;

         @deck = shuffle(@deck, @hand);
         --$starting_hand_size;
         ++$mulligans_taken;
      }

      for my $turn_num (1..$max_turns) {
         next TRIAL if ($turn_num > 1 || $draw_on_first_turn) && shift(@deck);
         ++$counts[$i++];
      }
   }

   printf("%.0f%%\n", (1 - $_/$num_trials)*100) for @counts;
}

输出:

$ verify 60 2 1 3 4
40%
61%
73%
75%
77%
78%

发现!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM