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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
|
# -*- coding: utf-8 -*-
import sys, os
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from manim import *
from tiktok import *
DOOR_Y, DW, DH = 4.0, 2.5, 3.7
XS = [-2.85, 0.0, 2.85]
class MontyHall(TikTok):
NAME = "montyhall"
def door(self, n, x):
face = RoundedRectangle(corner_radius=0.18, width=DW, height=DH,
stroke_color="#2E3A55", stroke_width=6,
fill_color="#16203A", fill_opacity=1)
num = Text(str(n), font=FONT, font_size=104, weight=BOLD, color="#5B6B8C")
knob = Dot(radius=0.1, color="#5B6B8C").move_to(face.get_right() + LEFT * 0.36)
d = VGroup(face, num, knob).move_to([x, DOOR_Y, 0])
d.face, d.num, d.knob = face, num, knob
return d
def badge(self, text, color, fs=30):
t = Text(text, font=FONT, font_size=fs, weight=BOLD, color="#0B0F1A")
box = RoundedRectangle(corner_radius=0.2, width=t.width + 0.5, height=t.height + 0.42,
stroke_width=0, fill_color=color, fill_opacity=1)
return VGroup(box, t)
def car_icon(self, color=VERDE):
body = RoundedRectangle(corner_radius=0.14, width=1.6, height=0.6,
stroke_width=0, fill_color=color, fill_opacity=1)
roof = RoundedRectangle(corner_radius=0.12, width=0.92, height=0.48,
stroke_width=0, fill_color=color, fill_opacity=1)
roof.next_to(body, UP, buff=-0.08)
w1 = Dot(radius=0.19, color="#0B0F1A").move_to(body.get_bottom() + LEFT * 0.48)
w2 = Dot(radius=0.19, color="#0B0F1A").move_to(body.get_bottom() + RIGHT * 0.48)
return VGroup(roof, body, w1, w2)
def goat_icon(self, color="#94A3B8"):
head = Ellipse(width=1.05, height=0.72, stroke_width=0, fill_color=color, fill_opacity=1)
snout = Ellipse(width=0.5, height=0.36, stroke_width=0, fill_color=color, fill_opacity=1)
snout.move_to(head.get_bottom() + DOWN * 0.1)
h1 = ArcBetweenPoints(head.get_top() + LEFT * 0.26, head.get_top() + LEFT * 0.62 + UP * 0.42,
angle=-1.1, stroke_width=8, color=color)
h2 = ArcBetweenPoints(head.get_top() + RIGHT * 0.26, head.get_top() + RIGHT * 0.62 + UP * 0.42,
angle=1.1, stroke_width=8, color=color)
e1 = Dot(radius=0.07, color="#0B0F1A").move_to(head.get_center() + LEFT * 0.22 + UP * 0.06)
e2 = Dot(radius=0.07, color="#0B0F1A").move_to(head.get_center() + RIGHT * 0.22 + UP * 0.06)
return VGroup(h1, h2, head, snout, e1, e2)
def prize(self, kind, x):
if kind == "auto":
g = VGroup(self.car_icon(), self.badge("AUTO", VERDE))
else:
g = VGroup(self.goat_icon(), self.badge("CABRA", "#94A3B8"))
g.arrange(DOWN, buff=0.3)
return g.move_to([x, DOOR_Y, 0])
def construct(self):
self.prepare()
chip = self.chip("¿Cambiarías de puerta?")
doors = VGroup(*[self.door(i + 1, XS[i]) for i in range(3)])
with self.beat(0) as b:
b.play(FadeIn(chip, shift=DOWN * 0.3), run_time=0.5)
b.play(LaggedStart(*[GrowFromCenter(d) for d in doors], lag_ratio=0.25), run_time=1.2)
h1 = VGroup(self.car_icon().scale(0.85),
Text("×1", font=FONT, font_size=46, weight=BOLD, color=VERDE)
).arrange(RIGHT, buff=0.35).move_to(UP * 1.3)
b.play(FadeIn(h1, shift=UP * 0.2), run_time=0.5)
with self.beat(1) as b:
h2 = VGroup(self.goat_icon().scale(0.85),
Text("×2", font=FONT, font_size=46, weight=BOLD, color="#94A3B8")
).arrange(RIGHT, buff=0.35)
h2.next_to(h1, DOWN, buff=0.55)
b.play(FadeIn(h2, shift=UP * 0.2), run_time=0.6)
b.wait(0.5)
b.play(FadeOut(VGroup(h1, h2)), run_time=0.4)
with self.beat(2) as b:
pick = Text("TU ELECCIÓN", font=FONT, font_size=38, weight=BOLD, color=AMBAR)
arrow = Arrow(doors[0].get_bottom() + DOWN * 1.3, doors[0].get_bottom() + DOWN * 0.12,
buff=0, color=AMBAR, stroke_width=10)
pick.next_to(arrow, DOWN, buff=0.18)
b.play(doors[0].face.animate.set_stroke(AMBAR, 11),
doors[0].num.animate.set_color(AMBAR), run_time=0.5)
b.play(GrowArrow(arrow), FadeIn(pick), run_time=0.5)
picked = VGroup(pick, arrow)
with self.beat(3) as b:
goat = self.prize("cabra", XS[2])
b.play(doors[2].face.animate.set_fill("#0E1526", 1).set_stroke("#2E3A55", 4),
FadeOut(doors[2].num), FadeOut(doors[2].knob), run_time=0.7)
b.play(FadeIn(goat, scale=0.75), run_time=0.7)
doors[2].remove(doors[2].num, doors[2].knob)
b.play(VGroup(doors[2], goat).animate.set_opacity(0.35), run_time=0.5)
with self.beat(4) as b:
q = Text("¿1 o 2?", font=FONT, font_size=82, weight=BOLD, color=WHITE).move_to(UP * 1.0)
b.play(FadeOut(picked), run_time=0.3)
b.play(Write(q), doors[1].face.animate.set_stroke(CELESTE, 10),
doors[1].num.animate.set_color(CELESTE), run_time=1.0)
with self.beat(5) as b:
fifty = Text("50% / 50%", font=FONT, font_size=68, weight=BOLD, color=GRIS)
fifty.move_to(DOWN * 1.5)
cross = VGroup(
Line(fifty.get_corner(UL), fifty.get_corner(DR), stroke_width=14, color=ROSA),
Line(fifty.get_corner(DL), fifty.get_corner(UR), stroke_width=14, color=ROSA),
)
b.play(FadeIn(fifty), run_time=0.5)
b.wait(0.6)
b.play(Create(cross), run_time=0.6)
b.play(FadeOut(VGroup(fifty, cross, q)), run_time=0.5)
with self.beat(6) as b:
f1 = MathTex(r"\tfrac{1}{3}", color=AMBAR).scale(2.6).next_to(doors[0], DOWN, buff=0.7)
cap1 = Text("lo que tenías al elegir", font=FONT, font_size=34, color=GRIS)
cap1.next_to(f1, DOWN, buff=0.45).set_x(0)
b.play(Write(f1), run_time=0.8)
b.play(FadeIn(cap1), run_time=0.5)
with self.beat(7) as b:
brace = Brace(VGroup(doors[1], doors[2]), DOWN, color=CELESTE, buff=0.28)
f2 = MathTex(r"\tfrac{2}{3}", color=CELESTE).scale(2.6).next_to(brace, DOWN, buff=0.25)
b.play(FadeOut(cap1), run_time=0.25)
b.play(GrowFromCenter(brace), run_time=0.5)
b.play(Write(f2), run_time=0.7)
with self.beat(8) as b:
dest = f1.get_center() + RIGHT * (XS[1] - XS[0])
b.play(FadeOut(brace), run_time=0.3)
b.play(f2.animate.move_to(dest), run_time=1.2)
b.play(Flash(f2, color=CELESTE, line_length=0.6, num_lines=18, flash_radius=1.4),
doors[1].face.animate.set_fill("#123A57", 1), run_time=0.9)
with self.beat(9) as b:
b.play(FadeOut(VGroup(doors, f1, f2, goat)), run_time=0.5)
rows = []
for lbl, pct, col in (("QUEDARSE", 0.333, ROSA), ("CAMBIAR", 0.667, VERDE)):
name = Text(lbl, font=FONT, font_size=46, weight=BOLD, color=col)
track = RoundedRectangle(corner_radius=0.12, width=7.0, height=0.85, stroke_width=0,
fill_color="#1B2233", fill_opacity=1)
fill = RoundedRectangle(corner_radius=0.12, width=7.0 * pct, height=0.85,
stroke_width=0, fill_color=col, fill_opacity=1)
fill.move_to(track.get_left(), LEFT)
val = Text(f"{round(pct*100)}%", font=FONT, font_size=58, weight=BOLD, color=col)
rows.append(VGroup(name, VGroup(track, fill), val).arrange(DOWN, buff=0.25))
board = VGroup(*rows).arrange(DOWN, buff=1.0).move_to(UP * 2.2)
b.play(*[FadeIn(r[0]) for r in rows], *[FadeIn(r[1][0]) for r in rows], run_time=0.5)
for r in rows:
f, w = r[1][1], r[1][1].width
f.stretch_to_fit_width(0.002).move_to(r[1
|