aboutsummaryrefslogtreecommitdiffstats
path: root/scenes/v1_montyhall.py
blob: 5e0ec9513789410cfe8e9c1ae20f9201cad67151 (plain)
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=C_GREEN):
        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", C_GREEN))
        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=C_GREEN)
                        ).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=AMBER)
            arrow = Arrow(doors[0].get_bottom() + DOWN * 1.3, doors[0].get_bottom() + DOWN * 0.12,
                          buff=0, color=AMBER, stroke_width=10)
            pick.next_to(arrow, DOWN, buff=0.18)
            b.play(doors[0].face.animate.set_stroke(AMBER, 11),
                   doors[0].num.animate.set_color(AMBER), 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(C_SKY, 10),
                   doors[1].num.animate.set_color(C_SKY), run_time=1.0)

        with self.beat(5) as b:
            fifty = Text("50%  /  50%", font=FONT, font_size=68, weight=BOLD, color=C_GRAY)
            fifty.move_to(DOWN * 1.5)
            cross = VGroup(
                Line(fifty.get_corner(UL), fifty.get_corner(DR), stroke_width=14, color=C_PINK),
                Line(fifty.get_corner(DL), fifty.get_corner(UR), stroke_width=14, color=C_PINK),
            )
            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=AMBER).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=C_GRAY)
            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=C_SKY, buff=0.28)
            f2 = MathTex(r"\tfrac{2}{3}", color=C_SKY).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=C_SKY, 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, C_PINK), ("CAMBIAR", 0.667, C_GREEN)):
                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][0].get_left(), LEFT)
                b.play(f.animate.stretch_to_fit_width(w)