Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
320 commits
Select commit Hold shift + click to select a range
00692aa
Update ollama_voice_assistant.py
js3888-shunshun Sep 27, 2025
30996ac
Update ollama_voice_assistant.py
js3888-shunshun Sep 27, 2025
7bf1a78
Update ollama_voice_assistant.py
js3888-shunshun Sep 27, 2025
5da1fd1
Update ollama_voice_assistant.py
js3888-shunshun Sep 27, 2025
f9c87d6
Update ollama_voice_assistant.py
js3888-shunshun Sep 27, 2025
6101e11
Update ollama_voice_assistant.py
js3888-shunshun Sep 27, 2025
433f3ae
Update ollama_voice_assistant.py
js3888-shunshun Sep 27, 2025
e500517
Update ollama_voice_assistant.py
js3888-shunshun Sep 27, 2025
4c51104
Update ollama_voice_assistant.py
js3888-shunshun Sep 27, 2025
795d40c
Update ollama_voice_assistant.py
js3888-shunshun Sep 27, 2025
0e92920
Update README.md
js3888-shunshun Sep 27, 2025
7c5dd06
Add files via upload
js3888-shunshun Sep 27, 2025
2e263c9
Update README.md
js3888-shunshun Sep 27, 2025
590e44d
Create greet_joy.sh
js3888-shunshun Sep 27, 2025
50bd632
Add files via upload
js3888-shunshun Sep 27, 2025
b72d648
Update README.md
js3888-shunshun Sep 27, 2025
ea39c43
Update README.md
js3888-shunshun Sep 27, 2025
6129320
Merge branch 'IRL-CT:Fall2025' into Fall2025
js3888-shunshun Oct 4, 2025
12ae6b1
Update requirements.txt
js3888-shunshun Oct 4, 2025
680cab1
Update app.py
js3888-shunshun Oct 4, 2025
24fa3d5
Update index.html
js3888-shunshun Oct 4, 2025
28dfa67
Update app.py
js3888-shunshun Oct 4, 2025
fc7d31e
Update app.py
js3888-shunshun Oct 4, 2025
def7cc7
Update app.py
js3888-shunshun Oct 4, 2025
cccfa37
Update README.md
js3888-shunshun Oct 5, 2025
8b2e857
Add files via upload
js3888-shunshun Oct 5, 2025
3b31b4c
Update README.md
js3888-shunshun Oct 5, 2025
3d69eb5
Update README.md
js3888-shunshun Oct 6, 2025
c87b179
Update README.md
js3888-shunshun Oct 6, 2025
eb77000
Update README.md
js3888-shunshun Oct 6, 2025
372ce62
Update encoder_test.py
js3888-shunshun Oct 8, 2025
18508c4
Rename encoder_test.py to encoder_lights.py
js3888-shunshun Oct 8, 2025
c4b47f5
Update encoder_lights.py
js3888-shunshun Oct 8, 2025
cb36710
Create encoder_test.py
js3888-shunshun Oct 8, 2025
4e6d989
Create mcp_test.py
js3888-shunshun Oct 8, 2025
479fd26
Update encoder_lights.py
js3888-shunshun Oct 8, 2025
0870daa
Create test_mcp23017.py
js3888-shunshun Oct 8, 2025
7c1939a
Create gesture_game.py
js3888-shunshun Oct 9, 2025
1aa84e2
Update gesture_game.py
js3888-shunshun Oct 9, 2025
0dfd96d
Update gesture_game.py
js3888-shunshun Oct 9, 2025
835b91f
Update gesture_game.py
js3888-shunshun Oct 9, 2025
97fabde
Update gesture_game.py
js3888-shunshun Oct 9, 2025
fa0714f
Update gesture_game.py
js3888-shunshun Oct 9, 2025
4285e36
Create music_player.py
js3888-shunshun Oct 9, 2025
41cba20
Create music_player.py
js3888-shunshun Oct 9, 2025
8a3c57a
Create music1.mp3
js3888-shunshun Oct 9, 2025
3daaad3
Update music_player.py
js3888-shunshun Oct 9, 2025
528eb91
Update music_player.py
js3888-shunshun Oct 9, 2025
acb9832
Update music_player.py
js3888-shunshun Oct 9, 2025
3ca09a2
Add files via upload
js3888-shunshun Oct 9, 2025
2a880f8
Update music_player.py
js3888-shunshun Oct 9, 2025
7d6ad2c
Update music_player.py
js3888-shunshun Oct 9, 2025
2b432a0
Update music_player.py
js3888-shunshun Oct 9, 2025
e316294
Update music_player.py
js3888-shunshun Oct 9, 2025
a73d43d
Delete Lab 4/music/spring.mp3
js3888-shunshun Oct 9, 2025
9d35fb3
Delete music_player.py
js3888-shunshun Oct 9, 2025
7d4e013
Delete Lab 4/music/dawn.mp3
js3888-shunshun Oct 9, 2025
3c77f56
Delete Lab 4/music/main.mp3
js3888-shunshun Oct 9, 2025
6896d55
Add files via upload
js3888-shunshun Oct 9, 2025
a3f8234
Delete Lab 4/music/music1.mp3
js3888-shunshun Oct 9, 2025
25ce2b1
Update README.md
js3888-shunshun Oct 13, 2025
ec07666
Add files via upload
js3888-shunshun Oct 13, 2025
44d8738
Delete Design1.jpeg
js3888-shunshun Oct 13, 2025
f38f297
Delete Design2.jpeg
js3888-shunshun Oct 13, 2025
0e49e8f
Delete Design3.jpeg
js3888-shunshun Oct 13, 2025
3c6d082
Delete Design4.jpeg
js3888-shunshun Oct 13, 2025
d616938
Delete Design5.jpeg
js3888-shunshun Oct 13, 2025
7a4d012
Delete Handcraft1.jpeg
js3888-shunshun Oct 13, 2025
87919ed
Delete Handcraft2.jpeg
js3888-shunshun Oct 13, 2025
cac2d53
Add files via upload
js3888-shunshun Oct 13, 2025
d337dc4
Add files via upload
js3888-shunshun Oct 13, 2025
a9d8cfd
Update README.md
js3888-shunshun Oct 13, 2025
4962fab
Add files via upload
js3888-shunshun Oct 13, 2025
5d31e3c
Update README.md
js3888-shunshun Oct 13, 2025
21cf3f9
Add files via upload
js3888-shunshun Oct 19, 2025
14f4c0b
Add files via upload
js3888-shunshun Oct 19, 2025
cfbf177
Add files via upload
js3888-shunshun Oct 19, 2025
c0cc33c
Update music_player.py
js3888-shunshun Oct 19, 2025
5420de9
Update music_player.py
js3888-shunshun Oct 19, 2025
c152fad
Update music_player.py
js3888-shunshun Oct 19, 2025
0cf7d60
Update music_player.py
js3888-shunshun Oct 19, 2025
32ca05f
Update music_player.py
js3888-shunshun Oct 19, 2025
590821f
Update music_player.py
js3888-shunshun Oct 19, 2025
ebc2c65
Update music_player.py
js3888-shunshun Oct 19, 2025
ae23c46
Update music_player.py
js3888-shunshun Oct 19, 2025
c5fceb2
Update music_player.py
js3888-shunshun Oct 19, 2025
944ba49
Create music_player_seesaw.py
js3888-shunshun Oct 19, 2025
7a6f6a1
Update README.md
js3888-shunshun Oct 19, 2025
a16baa9
Add files via upload
js3888-shunshun Oct 19, 2025
5006730
Update README.md
js3888-shunshun Oct 19, 2025
f21a530
Merge branch 'IRL-CT:Fall2025' into Fall2025
js3888-shunshun Oct 22, 2025
a3e2cf8
Update infer.py
js3888-shunshun Oct 26, 2025
10f49c3
Update infer.py
js3888-shunshun Oct 27, 2025
cbbbc84
Update infer.py
js3888-shunshun Oct 27, 2025
ff9072e
Update infer.py
js3888-shunshun Oct 27, 2025
a0e5a0a
Update infer.py
js3888-shunshun Oct 27, 2025
558beb7
Update infer.py
js3888-shunshun Oct 27, 2025
f479f27
Update infer.py
js3888-shunshun Oct 27, 2025
bc1619a
Update infer.py
js3888-shunshun Oct 27, 2025
2e1da36
Update infer.py
js3888-shunshun Oct 27, 2025
09267ca
Update infer.py
js3888-shunshun Oct 27, 2025
d74ea1e
Update README.md
js3888-shunshun Oct 27, 2025
010d2be
Add files via upload
js3888-shunshun Oct 27, 2025
48dd381
Update README.md
js3888-shunshun Oct 27, 2025
1431b85
Update README.md
js3888-shunshun Oct 27, 2025
df009de
Create warm.wav
js3888-shunshun Nov 2, 2025
d87d901
Add files via upload
js3888-shunshun Nov 2, 2025
332101e
Delete Lab 5/sounds/warm.wav
js3888-shunshun Nov 2, 2025
707ad14
Add files via upload
js3888-shunshun Nov 2, 2025
9bcb175
Update infer.py
js3888-shunshun Nov 2, 2025
332afcf
Update infer.py
js3888-shunshun Nov 2, 2025
5b89f2f
Update infer.py
js3888-shunshun Nov 2, 2025
be4bb50
Update README.md
js3888-shunshun Nov 2, 2025
e866342
Merge branch 'IRL-CT:Fall2025' into Fall2025
js3888-shunshun Nov 4, 2025
c4988d0
Create game_master.py
js3888-shunshun Nov 8, 2025
0affd60
Update game_master.py
js3888-shunshun Nov 8, 2025
d5adc05
Create player_A.py
js3888-shunshun Nov 8, 2025
b0d566b
Update player_A.py
js3888-shunshun Nov 8, 2025
fdc0feb
Update player_A.py
js3888-shunshun Nov 8, 2025
f0357ab
Update player_A.py
js3888-shunshun Nov 8, 2025
22f0399
Update game_master.py
js3888-shunshun Nov 8, 2025
ceaf9c5
Update game_master.py
js3888-shunshun Nov 8, 2025
2f59fd4
Update player_A.py
js3888-shunshun Nov 8, 2025
9294d5b
Update game_master.py
js3888-shunshun Nov 8, 2025
1a6d000
Update game_master.py
js3888-shunshun Nov 8, 2025
37e056a
Update game_master.py
js3888-shunshun Nov 8, 2025
ecbc97b
Update game_master.py
js3888-shunshun Nov 8, 2025
559f4dc
Update game_master.py
js3888-shunshun Nov 8, 2025
900aa10
Update game_master.py
js3888-shunshun Nov 8, 2025
1f519b5
Update README.md
js3888-shunshun Nov 8, 2025
8dfd686
Update README.md
js3888-shunshun Nov 9, 2025
dabb108
Add files via upload
js3888-shunshun Nov 9, 2025
50ab8ba
Add files via upload
js3888-shunshun Nov 9, 2025
825d1e8
Update README.md
js3888-shunshun Nov 9, 2025
9eba9b8
Create Final Project.md
js3888-shunshun Nov 10, 2025
2c84fac
Update and rename Final Project.md to Final Project/readme.md
js3888-shunshun Nov 10, 2025
6533e74
Update readme.md
js3888-shunshun Nov 10, 2025
c455230
Add files via upload
js3888-shunshun Nov 10, 2025
6cc0e6f
Update readme.md
js3888-shunshun Nov 10, 2025
0c1e3aa
Update readme.md
js3888-shunshun Nov 10, 2025
83feece
Add files via upload
js3888-shunshun Dec 1, 2025
cd3c1b5
Create animation
js3888-shunshun Dec 1, 2025
f3a299c
Delete Final Project/animation
js3888-shunshun Dec 1, 2025
b343bb7
Create empty
js3888-shunshun Dec 1, 2025
962fc73
Add files via upload
js3888-shunshun Dec 1, 2025
2e0d448
Delete Final Project/animation/empty
js3888-shunshun Dec 1, 2025
e2d6431
Create empty
js3888-shunshun Dec 1, 2025
d4bc503
Add files via upload
js3888-shunshun Dec 1, 2025
06893ca
Delete Final Project/sensors/empty
js3888-shunshun Dec 1, 2025
4597f2d
Update animation_engine.py
js3888-shunshun Dec 1, 2025
8f805b9
Update animation_engine.py
js3888-shunshun Dec 1, 2025
64969f6
Update animation_engine.py
js3888-shunshun Dec 1, 2025
3e9ce78
Create requirements-pi.txt
js3888-shunshun Dec 1, 2025
592ff31
Update tft_display.py
js3888-shunshun Dec 2, 2025
6df12fa
Update tft_display.py
js3888-shunshun Dec 2, 2025
dd3e7d4
Update animation_engine.py
js3888-shunshun Dec 2, 2025
8f09576
Update camera_reflection.py
js3888-shunshun Dec 2, 2025
f5de1b4
Update sensor_manager.py
js3888-shunshun Dec 2, 2025
3cc10d9
Update tft_display.py
js3888-shunshun Dec 2, 2025
1f3b47d
Update tft_display.py
js3888-shunshun Dec 2, 2025
27f5013
Update sensor_manager.py
js3888-shunshun Dec 2, 2025
90b51d2
Update tft_display.py
js3888-shunshun Dec 2, 2025
291978f
Update tft_display.py
js3888-shunshun Dec 2, 2025
30748e8
Create set_profile.py
js3888-shunshun Dec 2, 2025
cb188f4
Update sensor_manager.py
js3888-shunshun Dec 2, 2025
9a0b934
Update touch_mpr121.py
js3888-shunshun Dec 2, 2025
e328307
Create touch_mpr121_selector.py
js3888-shunshun Dec 2, 2025
8dc8797
Update tft_display.py
js3888-shunshun Dec 2, 2025
ae0c468
Update touch_mpr121_selector.py
js3888-shunshun Dec 2, 2025
aebdc29
Update requirements-pi.txt
js3888-shunshun Dec 2, 2025
80fa9d5
Update main.py
js3888-shunshun Dec 2, 2025
a219f0a
Update sensor_manager.py
js3888-shunshun Dec 2, 2025
5139f5f
Update animation_engine.py
js3888-shunshun Dec 2, 2025
7a2bdf2
Update animation_engine.py
js3888-shunshun Dec 2, 2025
d038df6
Update animation_engine.py
js3888-shunshun Dec 3, 2025
9e69e36
Update animation_engine.py
js3888-shunshun Dec 3, 2025
e64a5d4
Update animation_engine.py
js3888-shunshun Dec 3, 2025
4c57f9b
Update animation_engine.py
js3888-shunshun Dec 3, 2025
a4cbce4
Update set_profile.py
js3888-shunshun Dec 3, 2025
98a0ae8
Update gesture_apds9960.py
js3888-shunshun Dec 3, 2025
feb3fc3
Update sensor_manager.py
js3888-shunshun Dec 3, 2025
2fbd5b1
Update main.py
js3888-shunshun Dec 3, 2025
3aea80a
Update animation_engine.py
js3888-shunshun Dec 3, 2025
527eb1b
Update animation_engine.py
js3888-shunshun Dec 3, 2025
3531f7f
Update set_profile.py
js3888-shunshun Dec 3, 2025
f1e0530
Update animation_engine.py
js3888-shunshun Dec 3, 2025
bba292e
Update set_profile.py
js3888-shunshun Dec 3, 2025
bc39654
Update animation_engine.py
js3888-shunshun Dec 3, 2025
d1b047a
Update touch_mpr121_selector.py
js3888-shunshun Dec 3, 2025
152d6f0
Update sensor_manager.py
js3888-shunshun Dec 3, 2025
316f5c8
Update animation_engine.py
js3888-shunshun Dec 3, 2025
61ed74f
Update main.py
js3888-shunshun Dec 3, 2025
714abc0
Update main.py
js3888-shunshun Dec 3, 2025
a858581
Update gesture_apds9960.py
js3888-shunshun Dec 3, 2025
ee1a604
Update gesture_apds9960.py
js3888-shunshun Dec 3, 2025
e73dd4b
Update gesture_apds9960.py
js3888-shunshun Dec 3, 2025
ea837f6
Update animation_engine.py
js3888-shunshun Dec 3, 2025
9fc8563
Update animation_engine.py
js3888-shunshun Dec 3, 2025
5c7c657
Update animation_engine.py
js3888-shunshun Dec 5, 2025
9708787
Update animation_engine.py
js3888-shunshun Dec 5, 2025
77a7809
Update sensor_manager.py
js3888-shunshun Dec 5, 2025
9f6ac34
Update animation_engine.py
js3888-shunshun Dec 5, 2025
1bd3846
Update animation_engine.py
js3888-shunshun Dec 5, 2025
a5a0a09
Update set_profile.py
js3888-shunshun Dec 5, 2025
df23f88
Update sensor_manager.py
js3888-shunshun Dec 5, 2025
4424126
Update tft_display.py
js3888-shunshun Dec 5, 2025
f789f7c
Update tft_display.py
js3888-shunshun Dec 5, 2025
c2b1603
Update animation_engine.py
js3888-shunshun Dec 5, 2025
949ac3a
Create index.html
js3888-shunshun Dec 5, 2025
3fa61e4
Create server.py
js3888-shunshun Dec 5, 2025
f4d5c4e
Update animation_engine.py
js3888-shunshun Dec 5, 2025
fd368e7
Update animation_engine.py
js3888-shunshun Dec 5, 2025
00d6987
Update animation_engine.py
js3888-shunshun Dec 5, 2025
ab17d90
Update animation_engine.py
js3888-shunshun Dec 5, 2025
4f9be4a
Update requirements-pi.txt
js3888-shunshun Dec 5, 2025
46e6d8a
Update animation_engine.py
js3888-shunshun Dec 5, 2025
8e9cb48
Update server.py
js3888-shunshun Dec 5, 2025
fdc2fc5
Update server.py
js3888-shunshun Dec 5, 2025
d75e1de
Update server.py
js3888-shunshun Dec 5, 2025
69440d6
Update index.html
js3888-shunshun Dec 5, 2025
6ac2fe6
Update index.html
js3888-shunshun Dec 5, 2025
ae2bb88
Update server.py
js3888-shunshun Dec 5, 2025
629d9ac
Update animation_engine.py
js3888-shunshun Dec 5, 2025
c593b16
Update animation_engine.py
js3888-shunshun Dec 5, 2025
2165532
Update server.py
js3888-shunshun Dec 5, 2025
d1167df
Update index.html
js3888-shunshun Dec 5, 2025
65e7529
Update set_profile.py
js3888-shunshun Dec 6, 2025
b1c02ae
Update animation_engine.py
js3888-shunshun Dec 6, 2025
40381bc
Update animation_engine.py
js3888-shunshun Dec 6, 2025
22ba295
Update server.py
js3888-shunshun Dec 8, 2025
3352192
Update animation_engine.py
js3888-shunshun Dec 8, 2025
9df3f9e
Update animation_engine.py
js3888-shunshun Dec 8, 2025
bfaeda8
Update animation_engine.py
js3888-shunshun Dec 8, 2025
8dae300
Update animation_engine.py
js3888-shunshun Dec 8, 2025
b8bfad7
Update server.py
js3888-shunshun Dec 8, 2025
03b687d
Update server.py
js3888-shunshun Dec 8, 2025
0fb33c5
Update server.py
js3888-shunshun Dec 8, 2025
e17398b
Update animation_engine.py
js3888-shunshun Dec 8, 2025
231f870
Update animation_engine.py
js3888-shunshun Dec 8, 2025
5583c99
Update animation_engine.py
js3888-shunshun Dec 8, 2025
7d9df14
Create 1
js3888-shunshun Dec 12, 2025
0676482
Add files via upload
js3888-shunshun Dec 12, 2025
e6282d9
Add files via upload
js3888-shunshun Dec 12, 2025
7917372
Delete Final Project/images/1
js3888-shunshun Dec 12, 2025
2dc666f
Update readme.md
js3888-shunshun Dec 12, 2025
65f5113
Update readme.md
js3888-shunshun Dec 12, 2025
77d0064
Update readme.md
js3888-shunshun Dec 12, 2025
b8e7831
Update readme.md
js3888-shunshun Dec 12, 2025
f89498b
Update readme.md
js3888-shunshun Dec 12, 2025
fc00947
Update readme.md
js3888-shunshun Dec 12, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,048 changes: 1,048 additions & 0 deletions Final Project/animation/animation_engine.py

Large diffs are not rendered by default.

388 changes: 388 additions & 0 deletions Final Project/animation/set_profile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,388 @@
from typing import List, Dict, Tuple

Color = Tuple[int, int, int]
Style = Dict[str, object]

# ----------------------------------------------------------------------
# Base element color palette (primary hues)
# ----------------------------------------------------------------------

ELEMENT_MAIN_COLOR: Dict[str, Color] = {
"Fire": (255, 130, 70),
"Water": (80, 160, 255),
"Wind": (190, 230, 255),
"Earth": (110, 180, 110),
"Light": (255, 255, 230),
"Shadow": (150, 110, 200),
}

ELEMENT_SECONDARY_COLOR: Dict[str, Color] = {
"Fire": (255, 210, 120),
"Water": (120, 220, 255),
"Wind": (150, 210, 255),
"Earth": (170, 220, 150),
"Light": (255, 245, 210),
"Shadow": (90, 60, 140),
}

# Slightly different dark backgrounds to give each profile a distinct
# "night atmosphere" while still looking consistent.
BASE_BACKGROUNDS: Dict[str, Color] = {
"Fire": (10, 4, 8),
"Water": (3, 8, 16),
"Wind": (3, 10, 18),
"Earth": (5, 10, 6),
"Light": (8, 8, 18),
"Shadow": (6, 4, 10),
}

# Global default background if nothing else is set
DEFAULT_BG: Color = (5, 7, 18)


def make_style(
name: str,
pattern_type: str,
base_colors: List[Color],
background_color: Color = DEFAULT_BG,
**kwargs,
) -> Style:
"""Helper to create a style dict."""
style: Style = {
"name": name,
"pattern_type": pattern_type,
"base_colors": base_colors,
"background_color": background_color,
}
style.update(kwargs)
return style


def element_pair_palette(elem: str) -> List[Color]:
"""Return a simple 2-color palette for a single element."""
c1 = ELEMENT_MAIN_COLOR.get(elem, (255, 255, 255))
c2 = ELEMENT_SECONDARY_COLOR.get(elem, c1)
return [c1, c2]


def combo_palette(elems: List[str]) -> List[Color]:
"""
Return a 3-color palette for a 3-element combination.
The order of elems is already sorted by caller.
"""
colors: List[Color] = []
for e in elems:
colors.append(ELEMENT_MAIN_COLOR.get(e, (255, 255, 255)))
return colors


# ----------------------------------------------------------------------
# Single-element styles (fallback before 3-element profile is locked)
# ----------------------------------------------------------------------

SINGLE_ELEMENT_STYLES: Dict[str, Style] = {
"Fire": make_style(
name="Inner Flame",
pattern_type="pillar_orbs",
base_colors=element_pair_palette("Fire"),
background_color=BASE_BACKGROUNDS["Fire"],
pillar_width_factor=1.1,
halo_scale=1.3,
orb_count=40,
),
"Water": make_style(
name="Tidal Heart",
pattern_type="ring_waves",
base_colors=element_pair_palette("Water"),
background_color=BASE_BACKGROUNDS["Water"],
),
"Wind": make_style(
name="Sky Drift",
pattern_type="vortex",
base_colors=element_pair_palette("Wind"),
background_color=BASE_BACKGROUNDS["Wind"],
),
"Earth": make_style(
name="Root Pulse",
pattern_type="double_pillar",
base_colors=element_pair_palette("Earth"),
background_color=BASE_BACKGROUNDS["Earth"],
),
"Light": make_style(
name="Stellar Bloom",
pattern_type="starfield",
base_colors=element_pair_palette("Light"),
background_color=BASE_BACKGROUNDS["Light"],
),
"Shadow": make_style(
name="Night Current",
pattern_type="galaxy",
base_colors=element_pair_palette("Shadow"),
background_color=BASE_BACKGROUNDS["Shadow"],
),
}

# ----------------------------------------------------------------------
# 3-element combination styles (20 total)
#
# Key (always sorted): ("Earth", "Fire", "Light"), etc.
# ----------------------------------------------------------------------

COMBO_STYLES: Dict[Tuple[str, str, str], Style] = {}

# 1. Earth, Fire, Light
COMBO_STYLES[("Earth", "Fire", "Light")] = make_style(
name="Solar Grove",
pattern_type="double_pillar",
base_colors=combo_palette(["Earth", "Fire", "Light"]),
background_color=(12, 6, 8),
pillar_width_factor=1.2,
pillar_height_factor=1.1,
halo_scale=1.4,
)

# 2. Earth, Fire, Shadow
COMBO_STYLES[("Earth", "Fire", "Shadow")] = make_style(
name="Magma Veil",
pattern_type="vortex",
base_colors=combo_palette(["Fire", "Earth", "Shadow"]),
background_color=(10, 3, 10),
)

# 3. Earth, Fire, Water
COMBO_STYLES[("Earth", "Fire", "Water")] = make_style(
name="Molten Delta",
pattern_type="cross_waves",
base_colors=combo_palette(["Fire", "Water", "Earth"]),
background_color=(6, 9, 12),
)

# 4. Earth, Fire, Wind
COMBO_STYLES[("Earth", "Fire", "Wind")] = make_style(
name="Blazing Gale",
pattern_type="comet_trails",
base_colors=combo_palette(["Fire", "Wind", "Earth"]),
background_color=(10, 5, 8),
)

# 5. Earth, Light, Shadow
COMBO_STYLES[("Earth", "Light", "Shadow")] = make_style(
name="Twilight Garden",
pattern_type="blooming_orbs",
base_colors=combo_palette(["Light", "Earth", "Shadow"]),
background_color=(6, 6, 12),
)

# 6. Earth, Light, Water
COMBO_STYLES[("Earth", "Light", "Water")] = make_style(
name="Crystal Spring",
pattern_type="ring_waves",
base_colors=combo_palette(["Water", "Light", "Earth"]),
background_color=(4, 8, 14),
)

# 7. Earth, Light, Wind
COMBO_STYLES[("Earth", "Light", "Wind")] = make_style(
name="Daybreak Breeze",
pattern_type="vertical_ribbons",
base_colors=combo_palette(["Wind", "Light", "Earth"]),
background_color=(6, 9, 16),
)

# 8. Earth, Shadow, Water
COMBO_STYLES[("Earth", "Shadow", "Water")] = make_style(
name="Deep Moss",
pattern_type="grid_pulse",
base_colors=combo_palette(["Earth", "Water", "Shadow"]),
background_color=(4, 7, 9),
)

# 9. Earth, Shadow, Wind
COMBO_STYLES[("Earth", "Shadow", "Wind")] = make_style(
name="Fogbound Roots",
pattern_type="aurora",
base_colors=combo_palette(["Shadow", "Wind", "Earth"]),
background_color=(5, 6, 10),
)

# 10. Earth, Water, Wind
COMBO_STYLES[("Earth", "Water", "Wind")] = make_style(
name="Mist Valley",
pattern_type="spiral_rings",
base_colors=combo_palette(["Water", "Wind", "Earth"]),
background_color=(3, 8, 12),
)

# 11. Fire, Light, Shadow
COMBO_STYLES[("Fire", "Light", "Shadow")] = make_style(
name="Lunar Flame",
pattern_type="galaxy",
base_colors=combo_palette(["Fire", "Light", "Shadow"]),
background_color=(10, 5, 12),
)

# 12. Fire, Light, Water
COMBO_STYLES[("Fire", "Light", "Water")] = make_style(
name="Radiant Tide",
pattern_type="ring_waves",
base_colors=combo_palette(["Fire", "Water", "Light"]),
background_color=(5, 8, 13),
)

# 13. Fire, Light, Wind
COMBO_STYLES[("Fire", "Light", "Wind")] = make_style(
name="Solar Storm",
pattern_type="radial_rays",
base_colors=combo_palette(["Fire", "Light", "Wind"]),
background_color=(12, 7, 10),
)

# 14. Fire, Shadow, Water
COMBO_STYLES[("Fire", "Shadow", "Water")] = make_style(
name="Abyss Ember",
pattern_type="vortex",
base_colors=combo_palette(["Shadow", "Fire", "Water"]),
background_color=(6, 4, 10),
)

# 15. Fire, Shadow, Wind
COMBO_STYLES[("Fire", "Shadow", "Wind")] = make_style(
name="Nocturne Blaze",
pattern_type="comet_trails",
base_colors=combo_palette(["Shadow", "Fire", "Wind"]),
background_color=(8, 5, 11),
)

# 16. Fire, Water, Wind
COMBO_STYLES[("Fire", "Water", "Wind")] = make_style(
name="Storm Current",
pattern_type="pillar_orbs",
base_colors=combo_palette(["Fire", "Wind", "Water"]),
background_color=(5, 9, 14),
pillar_width_factor=0.9,
halo_scale=1.6,
orb_count=50,
)

# 17. Light, Shadow, Water
COMBO_STYLES[("Light", "Shadow", "Water")] = make_style(
name="Moonlit Lake",
pattern_type="starfield",
base_colors=combo_palette(["Light", "Water", "Shadow"]),
background_color=(3, 7, 13),
)

# 18. Light, Shadow, Wind
COMBO_STYLES[("Light", "Shadow", "Wind")] = make_style(
name="Veil of Dawn",
pattern_type="aurora",
base_colors=combo_palette(["Light", "Shadow", "Wind"]),
background_color=(6, 6, 12),
)

# 19. Light, Water, Wind
COMBO_STYLES[("Light", "Water", "Wind")] = make_style(
name="Crystal Sky",
pattern_type="spiral_rings",
base_colors=combo_palette(["Light", "Wind", "Water"]),
background_color=(4, 9, 16),
)

# 20. Shadow, Water, Wind
COMBO_STYLES[("Shadow", "Water", "Wind")] = make_style(
name="Midnight Surge",
pattern_type="blooming_orbs",
base_colors=combo_palette(["Shadow", "Water", "Wind"]),
background_color=(4, 5, 10),
)


# ----------------------------------------------------------------------
# Default / fallback style
# ----------------------------------------------------------------------

DEFAULT_STYLE: Style = make_style(
name="Idle Constellation",
pattern_type="pillar_orbs",
base_colors=[(200, 200, 220), (150, 180, 220)],
background_color=DEFAULT_BG,
pillar_width_factor=1.0,
halo_scale=1.0,
orb_count=30,
)


# ----------------------------------------------------------------------
# Public API
# ----------------------------------------------------------------------

def _normalize_profile(profile: List[str]) -> List[str]:
"""Return a sorted list of unique element names."""
unique = sorted(set(profile))
return unique


def get_spectrum_style(profile: List[str] | None) -> Style:
"""
Map a list of elements (length 0–3) to a style dict.

Cases:
- [] or None → neutral default style
- [E] → single-element style
- [E1, E2] → blended 2-element style (uses DEFAULT_STYLE-like pattern)
- [E1, E2, E3] → 3-element combination, one of 20 styles
"""
if profile is None:
profile = []

if len(profile) == 0:
return DEFAULT_STYLE

profile = _normalize_profile(profile)

# Single element
if len(profile) == 1:
elem = profile[0]
return SINGLE_ELEMENT_STYLES.get(elem, DEFAULT_STYLE)

# Three elements → check combo table
if len(profile) >= 3:
key = tuple(profile[:3])
style = COMBO_STYLES.get(key)
if style:
return style
# Fallback if not found for any reason:
return make_style(
name="Unknown Constellation",
pattern_type="pillar_orbs",
base_colors=combo_palette(list(key)),
background_color=DEFAULT_BG,
)

# Exactly 2 elements → simple blended style
if len(profile) == 2:
e1, e2 = profile
colors = [
ELEMENT_MAIN_COLOR.get(e1, (255, 255, 255)),
ELEMENT_MAIN_COLOR.get(e2, (220, 220, 255)),
]
return make_style(
name=f"{e1} · {e2} Field",
pattern_type="ring_waves",
base_colors=colors,
background_color=DEFAULT_BG,
)

# Should never reach here, but keep a safe fallback
return DEFAULT_STYLE

def combo_palette(elems: List[str]) -> List[Color]:
colors: List[Color] = []
for e in elems:
r, g, b = ELEMENT_MAIN_COLOR.get(e, (255, 255, 255))
r = min(int(r * 2), 255)
g = min(int(g * 2), 255)
b = min(int(b * 2), 255)
colors.append((r, g, b))
return colors

Binary file added Final Project/images/16651762814138_.pic_hd.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Final Project/images/3D_printed.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Final Project/images/Eneergy_setting.JPG
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Final Project/images/Energy_Card.JPG
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Final Project/images/Overall_Setup.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Final Project/images/Scenario_1.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Final Project/images/Scenario_2.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Final Project/images/Scenario_3.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Final Project/images/Verplank_Diagram.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Final Project/images/Wire_Setting.JPG
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Final Project/images/Wiring_Diagram.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Final Project/images/board_decoration.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Final Project/images/elements.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading