So I was watching some memes on r/formuladank (the only good thing reddit is good for anyway), and I stumbled upon this little gem:

This made me think: what would happen if we’d have actually a D20 roll for each championship?

So without further ado, while I was waiting in the airport for my plane, I started to write the code. I turned to Wikipedia to get the list of the drivers enlisted by the teams this year and then also wrote a small piece of code to exclude various driver line-up changes.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
<table><thead><tr><th>Race</th><th>Driver</th><th>Wins</th></tr></thead><tbody><?php
$startdrivers = array(
	10 => 'Pierre Gasly',
	14 => 'Fernando Alonso',
	16 => 'Charles Leclerc',
	20 => 'Kevin Magnussen',
	24 => 'Zhou Guanyu',
	4  => 'Lando Norris',
	44 => 'Lewis Hamilton',
	3  => 'Daniel Ricciardo',
	1  => 'Max Verstappen',
	2  => 'Logan Sargeant',
	31 => 'Esteban Ocon',
	18 => 'Lance Stroll',
	55 => 'Carlos Sainz Jr.',
	77 => 'Valtteri Bottas',
	81 => 'Oscar Piastri',
	63 => 'George Russell',
	11 => 'Sergio PĂ©rez',
	43 => 'Franco Colapinto',
	27 => 'Nico HĂŒlkenberg',
	22 => 'Yuki Tsunoda',
	23 => 'Alexander Albon',	
);
$races = array(
	1  => 'Bahrain Grand Prix',
	2  => 'Saudi Arabian Grand Prix',
	3  => 'Australian Grand Prix',
	4  => 'Japanese Grand Prix',
	5  => 'Chinese Grand Prix',
	6  => 'Miami Grand Prix',
	7  => 'Emilia Romagna Grand Prix',
	8  => 'Monaco Grand Prix',
	9  => 'Canadian Grand Prix',
	10 => 'Spanish Grand Prix',
	11 => 'Austrian Grand Prix',
	12 => 'British Grand Prix',
	13 => 'Hungarian Grand Prix',
	14 => 'Belgian Grand Prix',
	15 => 'Dutch Grand Prix',
	16 => 'Italian Grand Prix',
	17 => 'Azerbaijan Grand Prix',
	18 => 'Singapore Grand Prix',
	19 => 'United States Grand Prix',
	20 => 'Mexico City Grand Prix',
	21 => 'SĂŁo Paulo Grand Prix',
	22 => 'Las Vegas Grand Prix',
	23 => 'Qatar Grand Prix',
	24 => 'Abu Dhabi Grand Prix',
);
foreach($races as $key=>$value) {
	$drivers = $startdrivers; // reset driver list
	if($key == '2') {
		// Carlos Sainz's appendicectomy
		unset($drivers['55']);
		$drivers['50'] = 'Oliver Bearman';
	}
	if($key >= 16) {
		// Logan Sargeant is replaced by Colapinto
		unset($drivers['2']);
		$drivers['43'] = 'Franco Colapinto';
	}
	if( ($key == '17') || ($key == '22') ) {
		// Kevin Magnussen penalty  and KMag sick
		unset($drivers['55']);
		$drivers['50'] = 'Oliver Bearman';
	}
	if($key >= 19) {
		// Danny Ricciardo is dropped by RB
		unset($drivers['2']);
		$drivers['30'] = 'Liam Lawson';
	}
	
	echo '<tr><td><strong>'.$value.'</strong></td>';
	$winner = array_rand($drivers);
	$winners[] = $winner;
	$standings = array_count_values($winners);
	echo '<td>'. $drivers[$winner] . '</td>';
	echo '<td>('. $standings[$winner] . ')</td>';
	echo '</tr>';
}

?></tbody></table>

This piece of code creates a simple table and pulls one random driver which it deems the winner of said race and puts it into a table along with how many wins he has. It’s all random (as much as PHP randomness is random) and it doesn’t take into account chaos events like weather, crashes, etc, because that would be a lot of statistic data that I don’t want to process. The result looks like this:

RaceDriverWins
Bahrain Grand PrixNico HĂŒlkenberg(1)
Saudi Arabian Grand PrixDaniel Ricciardo(1)
Australian Grand PrixKevin Magnussen(1)
Japanese Grand PrixZhou Guanyu(1)
Chinese Grand PrixLance Stroll(1)
Miami Grand PrixSergio PĂ©rez(1)
Emilia Romagna Grand PrixZhou Guanyu(2)
Monaco Grand PrixZhou Guanyu(3)
Canadian Grand PrixOscar Piastri(1)
Spanish Grand PrixMax Verstappen(1)
Austrian Grand PrixPierre Gasly(1)
British Grand PrixYuki Tsunoda(1)
Hungarian Grand PrixValtteri Bottas(1)
Belgian Grand PrixLando Norris(1)
Dutch Grand PrixEsteban Ocon(1)
Italian Grand PrixFranco Colapinto(1)
Azerbaijan Grand PrixMax Verstappen(2)
Singapore Grand PrixZhou Guanyu(4)
United States Grand PrixNico HĂŒlkenberg(2)
Mexico City Grand PrixFranco Colapinto(2)
SĂŁo Paulo Grand PrixKevin Magnussen(2)
Las Vegas Grand PrixSergio PĂ©rez(2)
Qatar Grand PrixEsteban Ocon(2)
Abu Dhabi Grand PrixFernando Alonso(1)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
<?php 
// Resetting the list and adding replacement drivers to the drivers list
$drivers = $startdrivers; // reset driver list
$drivers['43'] = 'Franco Colapinto';
$drivers['50'] = 'Oliver Bearman';
$drivers['30'] = 'Liam Lawson';

echo '<h3>Number of winners: ' . count($standings)."</h3>";
arsort($standings); // sorting the final standings
echo '<table>';
	echo '<tr><th>Driver</td><td>Wins</td></tr>';
foreach($standings as $key=>$value){
	echo '<tr><th>'.$key.'. '. $drivers[$key] . '</th><td>'. $value . '</td></tr>';
}
echo '</table>';
?>

After all this process, I add the replacement drivers to the list, and then I sort the winners total table so we can see which driver had the most wins over the 24 races and place it in a table next to the number of winners.

Number of winners: 15

DriverWins
24. Zhou Guanyu4
27. Nico HĂŒlkenberg2
20. Kevin Magnussen2
11. Sergio PĂ©rez2
1. Max Verstappen2
31. Esteban Ocon2
43. Franco Colapinto2
3. Daniel Ricciardo1
18. Lance Stroll1
81. Oscar Piastri1
10. Pierre Gasly1
22. Yuki Tsunoda1
77. Valtteri Bottas1
4. Lando Norris1
14. Fernando Alonso1

Jumping to conclusions

Using the meme as a starting point for this small project, it seems that on my test, we’re having about 12-16 winners every run of the script, and sometimes the championship is tied in number of victories. Funny enough, in a batch of 10 tests, Zhou Guanyu won the championship twice, Oscar Piastri once and Lando Norris once as well (but after Oscar, lmao).

If you want to play yourself with this, you can follow the tool available here: Formula 1 Season Simple Random Simulator

The Advanced Formula 1 Random Simulator

Having so many ties (I had one run with 17 winners and a six-way championship tie!) quickly prompted me to develop more this script and make it take into account points awarded for running the entire race. There are some less points awarded if the race has to be shorter (many red flags, bad weather, etc), but these situation happen so rarely, I’m not taking them into account. As Formula 1 states:

The scoring system awards championship points for the first ten finishers at each Grand Prix, with 25 points for the winner, before scaling down to 18, 15, 12, 10, 8, 6, 4, 2, and a single point for the 10th-placed driver. There’s an additional point available for the driver with the fastest lap of the race (if they finish in the top ten), plus more points available for success in F1 Sprint races. The driver with the most points at the end of the year wins the title. No end of season play-offs.

Also for the sake of simplifying the code, I will not take into account neither sprints nor fastest lap, and the championship will be decided only by the race points.

Converting the code of the simple generator to the new one, was fairly simple, instead of using a random pull from the drivers array to decide the winner, I had to iterate over an array of points assignment

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
$points = array(
	1 => 25,
	2 => 18,
	3 => 15,
	4 => 12,
	5 => 10,
	6 => 8,
	7 => 6,
	8 => 4,
	9 => 2,
	10=> 1,
);

foreach($races as $key=>$value) {
	// ..... pilots reassignment code here .....
	
	echo '<tr><td rowspan="10"><strong>'.$value.'</strong></td>';	
	foreach($points as $key=>$value){
		$winner = array_rand($drivers);
		$totalpoints[$winner] = $totalpoints[$winner] + $value;
		if($key > 1) { echo '<tr>'; }
		echo '<td>'.$key.'. '. $drivers[$winner] . '</td><td> ('.$totalpoints[$winner].')</td></tr>';
		unset($drivers[$winner]);
	}
}

The results can be seen easily in the table below (you need to click on the plus sign to the right to expand the table), I’ve added in the brackets the total points of that driver after the respective race.

Year Races
RaceDriverWins
Bahrain Grand Prix1. Carlos Sainz Jr. (25)
2. Logan Sargeant (18)
3. Zhou Guanyu (15)
4. Kevin Magnussen (12)
5. Lewis Hamilton (10)
6. Alexander Albon (8)
7. Sergio PĂ©rez (6)
8. George Russell (4)
9. Daniel Ricciardo (2)
10. Yuki Tsunoda (1)
Saudi Arabian Grand Prix1. Pierre Gasly (25)
2. Daniel Ricciardo (20)
3. Logan Sargeant (33)
4. Max Verstappen (12)
5. Esteban Ocon (10)
6. Fernando Alonso (8)
7. Charles Leclerc (6)
8. Zhou Guanyu (19)
9. Alexander Albon (10)
10. George Russell (5)
Australian Grand Prix1. Valtteri Bottas (25)
2. Pierre Gasly (43)
3. Max Verstappen (27)
4. George Russell (17)
5. Yuki Tsunoda (11)
6. Lewis Hamilton (18)
7. Daniel Ricciardo (26)
8. Logan Sargeant (37)
9. Kevin Magnussen (14)
10. Fernando Alonso (9)
Japanese Grand Prix1. Kevin Magnussen (39)
2. Charles Leclerc (24)
3. Lando Norris (15)
4. Carlos Sainz Jr. (37)
5. Fernando Alonso (19)
6. Logan Sargeant (45)
7. Nico HĂŒlkenberg (6)
8. Max Verstappen (31)
9. Lance Stroll (2)
10. Zhou Guanyu (20)
Chinese Grand Prix1. Pierre Gasly (68)
2. Nico HĂŒlkenberg (24)
3. Yuki Tsunoda (26)
4. Zhou Guanyu (32)
5. Lance Stroll (12)
6. Valtteri Bottas (33)
7. Alexander Albon (16)
8. Esteban Ocon (14)
9. Charles Leclerc (26)
10. Daniel Ricciardo (27)
Miami Grand Prix1. Daniel Ricciardo (52)
2. Yuki Tsunoda (44)
3. Valtteri Bottas (48)
4. Kevin Magnussen (51)
5. Max Verstappen (41)
6. Lewis Hamilton (26)
7. Sergio PĂ©rez (12)
8. Lando Norris (19)
9. Alexander Albon (18)
10. Lance Stroll (13)
Emilia Romagna Grand Prix1. Lance Stroll (38)
2. George Russell (35)
3. Kevin Magnussen (66)
4. Max Verstappen (53)
5. Sergio PĂ©rez (22)
6. Lando Norris (27)
7. Fernando Alonso (25)
8. Daniel Ricciardo (56)
9. Logan Sargeant (47)
10. Lewis Hamilton (27)
Monaco Grand Prix1. Charles Leclerc (51)
2. Sergio PĂ©rez (40)
3. George Russell (50)
4. Franco Colapinto (12)
5. Max Verstappen (63)
6. Lewis Hamilton (35)
7. Esteban Ocon (20)
8. Valtteri Bottas (52)
9. Oscar Piastri (2)
10. Fernando Alonso (26)
Canadian Grand Prix1. Kevin Magnussen (91)
2. Sergio PĂ©rez (58)
3. Daniel Ricciardo (71)
4. Fernando Alonso (38)
5. Oscar Piastri (12)
6. Lando Norris (35)
7. Lance Stroll (44)
8. Alexander Albon (22)
9. George Russell (52)
10. Logan Sargeant (48)
Spanish Grand Prix1. Alexander Albon (47)
2. Carlos Sainz Jr. (55)
3. Franco Colapinto (27)
4. Logan Sargeant (60)
5. Charles Leclerc (61)
6. Fernando Alonso (46)
7. Lando Norris (41)
8. Pierre Gasly (72)
9. Sergio PĂ©rez (60)
10. Kevin Magnussen (92)
Austrian Grand Prix1. Fernando Alonso (71)
2. Pierre Gasly (90)
3. Oscar Piastri (27)
4. Carlos Sainz Jr. (67)
5. Zhou Guanyu (42)
6. Esteban Ocon (28)
7. Nico HĂŒlkenberg (30)
8. George Russell (56)
9. Valtteri Bottas (54)
10. Alexander Albon (48)
British Grand Prix1. Nico HĂŒlkenberg (55)
2. Valtteri Bottas (72)
3. Pierre Gasly (105)
4. Sergio PĂ©rez (72)
5. Lance Stroll (54)
6. Lewis Hamilton (43)
7. George Russell (62)
8. Logan Sargeant (64)
9. Max Verstappen (65)
10. Daniel Ricciardo (72)
Hungarian Grand Prix1. Lando Norris (66)
2. Sergio PĂ©rez (90)
3. Carlos Sainz Jr. (82)
4. Alexander Albon (60)
5. Zhou Guanyu (52)
6. Esteban Ocon (36)
7. Lewis Hamilton (49)
8. Charles Leclerc (65)
9. Yuki Tsunoda (46)
10. Fernando Alonso (72)
Belgian Grand Prix1. Esteban Ocon (61)
2. Max Verstappen (83)
3. Charles Leclerc (80)
4. Valtteri Bottas (84)
5. George Russell (72)
6. Lewis Hamilton (57)
7. Kevin Magnussen (98)
8. Yuki Tsunoda (50)
9. Carlos Sainz Jr. (84)
10. Sergio PĂ©rez (91)
Dutch Grand Prix1. Lewis Hamilton (82)
2. Carlos Sainz Jr. (102)
3. Kevin Magnussen (113)
4. Valtteri Bottas (96)
5. George Russell (82)
6. Nico HĂŒlkenberg (63)
7. Esteban Ocon (67)
8. Sergio PĂ©rez (95)
9. Oscar Piastri (29)
10. Zhou Guanyu (53)
Italian Grand Prix1. Kevin Magnussen (138)
2. Daniel Ricciardo (90)
3. Zhou Guanyu (68)
4. Valtteri Bottas (108)
5. Carlos Sainz Jr. (112)
6. Lance Stroll (62)
7. Oscar Piastri (35)
8. Lando Norris (70)
9. Esteban Ocon (69)
10. Pierre Gasly (106)
Azerbaijan Grand Prix1. Sergio PĂ©rez (120)
2. Pierre Gasly (124)
3. Esteban Ocon (84)
4. George Russell (94)
5. Zhou Guanyu (78)
6. Lando Norris (78)
7. Franco Colapinto (33)
8. Oliver Bearman (4)
9. Lewis Hamilton (84)
10. Alexander Albon (61)
Singapore Grand Prix1. Charles Leclerc (105)
2. Nico HĂŒlkenberg (81)
3. Franco Colapinto (48)
4. Valtteri Bottas (120)
5. Fernando Alonso (82)
6. Esteban Ocon (92)
7. Max Verstappen (89)
8. George Russell (98)
9. Carlos Sainz Jr. (114)
10. Sergio PĂ©rez (121)
United States Grand Prix1. Sergio PĂ©rez (146)
2. Alexander Albon (79)
3. Franco Colapinto (63)
4. Carlos Sainz Jr. (126)
5. Kevin Magnussen (148)
6. Oscar Piastri (43)
7. Esteban Ocon (98)
8. Max Verstappen (93)
9. Lando Norris (80)
10. Zhou Guanyu (79)
Mexico City Grand Prix1. Kevin Magnussen (173)
2. Sergio PĂ©rez (164)
3. Carlos Sainz Jr. (141)
4. Oscar Piastri (55)
5. Charles Leclerc (115)
6. Max Verstappen (101)
7. Nico HĂŒlkenberg (87)
8. Alexander Albon (83)
9. Yuki Tsunoda (52)
10. Daniel Ricciardo (91)
SĂŁo Paulo Grand Prix1. Zhou Guanyu (104)
2. Yuki Tsunoda (70)
3. Lewis Hamilton (99)
4. Pierre Gasly (136)
5. Esteban Ocon (108)
6. Fernando Alonso (90)
7. Kevin Magnussen (179)
8. Max Verstappen (105)
9. Charles Leclerc (117)
10. Nico HĂŒlkenberg (88)
Las Vegas Grand Prix1. Oliver Bearman (29)
2. Charles Leclerc (135)
3. Sergio PĂ©rez (179)
4. Fernando Alonso (102)
5. Max Verstappen (115)
6. Lance Stroll (70)
7. Esteban Ocon (114)
8. Nico HĂŒlkenberg (92)
9. Oscar Piastri (57)
10. Lewis Hamilton (100)
Qatar Grand Prix1. Lance Stroll (95)
2. Zhou Guanyu (122)
3. Pierre Gasly (151)
4. Charles Leclerc (147)
5. Valtteri Bottas (130)
6. Carlos Sainz Jr. (149)
7. Oscar Piastri (63)
8. Franco Colapinto (67)
9. Lando Norris (82)
10. Fernando Alonso (103)
Abu Dhabi Grand Prix1. Zhou Guanyu (147)
2. Yuki Tsunoda (88)
3. Kevin Magnussen (194)
4. Esteban Ocon (126)
5. Valtteri Bottas (140)
6. Alexander Albon (91)
7. Sergio PĂ©rez (185)
8. Charles Leclerc (151)
9. Lance Stroll (97)
10. Nico HĂŒlkenberg (93)

After doing this, it was fairly easy to sort and display the total points and display the grand champion.

1
2
3
4
5
6
7
8
9
arsort($totalpoints); // sorting the final standings
echo '<table>';
	echo '<tr><th>P</th><th>Driver</td><td>Points</td></tr>';
	$i = 1;
	foreach($totalpoints as $key=>$value){
		echo '<tr><th>'.$i.'</th><th>'.$key.'. '. $drivers[$key] . '</th><td>'. $value . '</td></tr>';
		$i++;
	}
echo '</table>';

And the result can be seen below:

PDriverPoints
120. Kevin Magnussen194
211. Sergio PĂ©rez185
310. Pierre Gasly151
416. Charles Leclerc151
555. Carlos Sainz Jr.149
624. Zhou Guanyu147
777. Valtteri Bottas140
831. Esteban Ocon126
91. Max Verstappen115
1014. Fernando Alonso103
1144. Lewis Hamilton100
1263. George Russell98
1318. Lance Stroll97
1427. Nico HĂŒlkenberg93
153. Daniel Ricciardo91
1623. Alexander Albon91
1722. Yuki Tsunoda88
184. Lando Norris82
1943. Franco Colapinto67
202. Logan Sargeant64
2181. Oscar Piastri63
2250. Oliver Bearman29

As a small observation, with only 3 races ran in this “Season”, Oliver Bearman scores points in about half of the runs. In the few runs I made, Checo Perez, Alexander Albon, Max Verstappen (twice!), and Yuki Tsunoda won the championship before Lando Norris did.

If you want to play with this generator yourself, you can find it available here: Formula 1 Season Advanced Random Simulator

This was a fun experiment and it was nice to brush a bit on my php code. Hope I’ll expand it more soon.