Overall this seems to benefit the first player, but it depends how you measure it.
I thought I would model this programatically as it will be a bit more flexible than using AnyDice. I've written a script which carries out the process a large number of times and averages the values for each player.
The main difficulty here is how you actually interpret the data: what makes one array of ability scores better than another one? There are multiple ways to judge this. I'll include some values for different methods.
Total of all ability scores
Player 1 has mean ability score value 72.95522.
Player 2 has mean ability score value 73.43975.
Player 3 has mean ability score value 73.64131.
Player 4 has mean ability score value 73.72761.
Verdict: Being later in the order is better
Total of all ability scores except the lowest one
Player 1 has mean ability score value 66.49585.
Player 2 has mean ability score value 65.71347.
Player 3 has mean ability score value 65.10333.
Player 4 has mean ability score value 64.57315.
Verdict: Being earlier in the order is better
Total points buy cost of all ability scores
(I've used invented points buy scores for numbers outside the normal allowed range: 18 = 19, 17 = 15, 16 = 12, 6-7 = -1, 4-5 = -2, 3 = -1)
Player 1 has mean ability score value 33.43838.
Player 2 has mean ability score value 31.80692.
Player 3 has mean ability score value 31.00389.
Player 4 has mean ability score value 30.64647.
Verdict: Being earlier in the order is better
Total points buy cost of all ability scores except the lowest one
Player 1 has mean ability score value 34.33727.
Player 2 has mean ability score value 31.88918.
Player 3 has mean ability score value 30.39722.
Player 4 has mean ability score value 29.45149.
Verdict: Being earlier in the order is much better
I've included my horrible amateur code here so you can try it out.
#!/usr/bin/perl
use strict;
use warnings;
use List::Util qw(sum);
use Data::Dumper;
use POSIX;
use 5.010;
my $die_size = 6;
my $number_of_dice = 4;
my $number_of_players = 4;
my $number_of_runs = 10000;
sub get_single_ability_score {
my @rolls;
for (1..$number_of_dice) {
my $roll = 1 + int rand($die_size);
push @rolls, $roll;
}
@rolls = sort {$a <=> $b} @rolls;
for (1..$number_of_dice - 3) {
shift @rolls;
}
my $ability_score = sum(@rolls);
return $ability_score;
}
sub get_total_values {
my @group_ability_scores;
for (1..$number_of_players * 6) {
push @group_ability_scores, get_single_ability_score();
}
@group_ability_scores = sort { $b <=> $a } @group_ability_scores;
my @player_order = (1..$number_of_players);
my @reverse_player_order = sort { $b <=> $a } @player_order;
@player_order = (@player_order, @reverse_player_order, @player_order, @reverse_player_order, @player_order, @reverse_player_order);
my @player_ability_scores;
foreach my $player (@player_order) {
my @ability_scores;
my $chosen_ability_score = shift @group_ability_scores;
push @ability_scores, $chosen_ability_score;
push @{ $player_ability_scores[$player-1] }, @ability_scores;
}
my @total_values;
foreach my $player (1..$number_of_players) {
my @ability_scores = sort { $a <=> $b } @{ $player_ability_scores[$player-1] };
my $total_value = 0;
shift @ability_scores; # One dump stat is fine so discard the lowest ability score
foreach my $ability_score (@ability_scores) {
#$total_value += $ability_score; # Uses the score as the value
#$total_value += floor(($ability_score - 10) / 2); # Uses the modifier as the value
given ($ability_score) {
when ($_ == 18) {$total_value += 19}
when ($_ == 17) {$total_value += 15}
when ($_ == 16) {$total_value += 12}
when ($_ == 15) {$total_value += 9}
when ($_ == 14) {$total_value += 7}
when ($_ == 13) {$total_value += 5}
when ($_ == 12) {$total_value += 4}
when ($_ == 11) {$total_value += 3}
when ($_ == 10) {$total_value += 2}
when ($_ == 9) {$total_value += 1}
when ($_ == 8) {$total_value += 0}
when ($_ == 7) {$total_value += -1}
when ($_ == 6) {$total_value += -2}
when ($_ == 5) {$total_value += -3}
when ($_ == 4) {$total_value += -4}
when ($_ == 3) {$total_value += -5}
}
}
push @total_values, $total_value;
}
return @total_values;
}
my @all_values;
for (1..$number_of_runs) {
my @total_values = get_total_values();
foreach my $player (1..$number_of_players) {
push @{ $all_values[$player-1] }, $total_values[$player-1];
}
}
for my $player (1..$number_of_players) {
my $total_value;
foreach my $value (@{ $all_values[$player-1] }) {
$total_value += $value;
}
my $mean_value = $total_value / $number_of_runs;
print "Player $player has mean ability score value $mean_value.\n";
}
Try it online!
Best Answer
If you actually get a standard distribution from the dice in the 3d6 x12 method, it will be slightly better than a standard distribution of results from the 4d6 method. The more samples you take, the more likely it is that you will get something approaching average or a standard distribution. The fewer samples you take, the more likely the results will just be random.