2017-05-05 107 views
1

我目前正在写一个函数,会问你,你的甲板尺寸,你在甲板上有一个特定的卡,你最初的手掌大小,卡量的复印量你(我们正在将图形卡放在一边画图,然后将混合后的牌洗牌回来),以及你想要画什么牌。万智牌抽概率函数在C

从本质上讲,我乘不拉丝卡在一起(然后做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; 
} 

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

1.)不是在第一手牌中画出所需牌的概率 (total - numCopies)/(总数)是在第一次抽牌时不抽牌的概率。然后,例如,如果你画了7张牌,你会继续前进,并将概率乘以一致直到达到该项(总数 - 总数 - 7)

2.)不抽牌的概率在你修改了一个指定的金额后。

3)不领取该卡由指定的转概率。

谁能帮我设置这些for循环?我无法获得正确的增量。我没有在纸上的数学,并与10甲板的尺寸,卡我想,2手的大小,1·穆利根2份,和3选择转我得到不拉丝卡的16.66%%的机率=>大约83%的转3.

+0

为什么你的标题中使用C语言,而标签中使用C++?你在用哪个?例如,如果你使用的是C++,你应该使用'std :: string'代替文本,'std :: vector'代替数组。 –

+0

我正在使用C.我编辑了标签。感谢您的关注! – jzurks

+0

倾向于使用'fscanf'而不是[危险'scanf'](https://www.google.com/search?q=scanf+danger&ie=utf-8&oe=utf-8)。 –

回答

0

绘图卡所以,当你正在寻找的循环,为什么不递减一个额外的价值?

所以

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

首先,我们需要一个卡是不是在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% 

现货!