summaryrefslogtreecommitdiff
path: root/src/scenes/hungry_partner.tsx
blob: 5198dafe187f9da1bc986fee8c7c845aa3600f5c (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
import { Layout, Txt, makeScene2D } from "@motion-canvas/2d";
import {
  Direction,
  beginSlide,
  range,
  all,
  makeRef,
  slideTransition,
} from "@motion-canvas/core";

import { FunctionBox } from "../components/function_box";
import { theme } from "../theme";

const hungryValentine = `(
  savoryCravingRatio: number, sweetCravingRatio: number,
  acidityCravingRatio: number, spiceCravingRatio: number,
): string => {
  const foods = {
    "🍕": {savory: 0.8, sweet: 0.1, acidity: 0.5, spice: 0.5},
    "🧁": {savory: 0.2, sweet: 0.9, acidity: 0.1, spice: 0.1},
    "🍋🍰": {savory: 0.1, sweet: 0.8, acidity: 0.9, spice: 0.1},
    "🌮🔥": {savory: 0.6, sweet: 0.2, acidity: 0.5, spice: 0.8},
  };

  const weight = (foodProfile: Record<string, number>) =>
    foodProfile["savory"] * savoryCravingRatio
    + foodProfile["sweet"] * sweetCravingRatio
    + foodProfile["acidity"] * acidityCravingRatio
    + foodProfile["spice"] * spiceCravingRatio;

  const bestFood = Object.keys(foods).reduce((a, b) =>
    weight(foods[a]) > weight(foods[b]) ? a : b
  );

  const foodNames = Array.from(Object.keys(foods));
  const shouldChooseRandom = Math.random() > 0.7; // side effect
  return shouldChooseRandom
    ? foodNames[Math.floor(Math.random() * foodNames.length)]
    : bestFood;
};`;

export default makeScene2D(function* (view) {
  const functionBoxes: FunctionBox[] = [];

  view.add(
    <Layout direction={"column"} gap={20} layout>
      {range(3).map((i) => (
        <FunctionBox
          arity={4}
          idlingText={"😴"}
          workingText={"😋💭"}
          source={hungryValentine}
          ref={makeRef(functionBoxes, i)}
        />
      ))}
    </Layout>,
  );

  yield* slideTransition(Direction.Right);

  yield* beginSlide("Get Best Food For Partner");

  const order = ["savory", "sweet", "acidic", "spice"];

  for (const [[a, b, c, d], i] of [
    [0.7, 0.1, 0.4, 0.1],
    [0.7, 0.1, 0.4, 0.1],
  ].map((x, i) => [x, i]) as [[number, number, number, number], number][]) {
    const inputId = "(" + [a, b, c, d, i].join(",") + ")";

    yield* all(...functionBoxes.map((box) => box.reset(0.5)));

    yield* all(
      ...functionBoxes.map((box) =>
        box.setInputs(
          [a, b, c, d].map((ratio, i) => ({
            val: ratio,
            node: (
              <Txt fontFamily={theme.font} fill={theme.text.hex}>
                {order[i]}:{" "}
                <Txt
                  fontFamily={theme.font}
                  fill={
                    ratio > 0.6
                      ? theme.red.hex
                      : ratio < 0.3
                        ? theme.green.hex
                        : theme.lavender.hex
                  }
                >
                  {ratio.toString()}
                </Txt>
              </Txt>
            ),
          })),
          0.5,
        ),
      ),
    );

    yield* beginSlide("Add Inputs " + inputId);
    yield* all(...functionBoxes.map((box) => box.propogateInput(0.5)));

    yield* beginSlide("Propogate Inputs " + inputId);

    yield* all(...functionBoxes.map((box) => box.propogateOutput(0.5)));
    yield* beginSlide("Propogate Outputs of " + inputId);
  }

  yield* all(...functionBoxes.map((box) => box.reset(0.5)));

  functionBoxes.slice(1).map((box) => box.remove());

  const [root] = functionBoxes;
  yield* root.showCode(0.85);
  yield* beginSlide("Show Code");

  yield* root.hideCode(0.85);
  yield* beginSlide("Hide Code");
});