-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathpalette.py
More file actions
87 lines (68 loc) · 2.58 KB
/
Copy pathpalette.py
File metadata and controls
87 lines (68 loc) · 2.58 KB
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
"""Game palette extracted from the supplied screenshots."""
import json
from dataclasses import dataclass
from datetime import datetime
from pathlib import Path
from typing import Sequence, Tuple
RGB = Tuple[int, int, int]
@dataclass(frozen=True)
class GameColor:
index: int
row: int
column: int
rgb: RGB
@property
def hex(self) -> str:
return "#{:02X}{:02X}{:02X}".format(*self.rgb)
DEFAULT_ROWS = (
("#222222", "#B5B5B5", "#E8E9DB", "#FFFFFF"),
("#D22F34", "#9C0901", "#D40948", "#E6968F"),
("#FE9773", "#F4CFBC", "#FAEDE4", "#F9F8E6"),
("#D9D1C6", "#DECFA8", "#D3641F", "#D38B41"),
("#F09800", "#F6C834", "#FAE498", "#B3B279"),
("#BFD872", "#686F00", "#AE9253", "#A78D74"),
("#A89326", "#3C2B11", "#72461F", "#524556"),
("#282343", "#394398", "#57449D", "#B9A1D7"),
("#B7BDE1", "#A8ABBE", "#62ACB7", "#B4D2DC"),
("#8DDAE4", "#48AD9F", "#B2D2C3", "#253862"),
)
PALETTE_CONFIG_PATH = Path(__file__).resolve().with_name("game_palette.json")
def _hex_to_rgb(value: str) -> RGB:
value = value.lstrip("#")
return tuple(int(value[i : i + 2], 16) for i in (0, 2, 4)) # type: ignore[return-value]
def _load_rows() -> Tuple[Tuple[str, ...], ...]:
if not PALETTE_CONFIG_PATH.exists():
return DEFAULT_ROWS
try:
data = json.loads(PALETTE_CONFIG_PATH.read_text(encoding="utf-8"))
colors = data["colors"]
if len(colors) != 40:
raise ValueError("colors must contain 40 entries")
normalized = []
for value in colors:
rgb = _hex_to_rgb(value)
normalized.append("#{:02X}{:02X}{:02X}".format(*rgb))
return tuple(tuple(normalized[row * 4 : row * 4 + 4]) for row in range(10))
except (KeyError, TypeError, ValueError, json.JSONDecodeError):
return DEFAULT_ROWS
def save_palette(colors: Sequence[RGB]) -> Path:
if len(colors) != 40:
raise ValueError(f"游戏色盘必须包含 40 个颜色,实际为 {len(colors)}")
values = ["#{:02X}{:02X}{:02X}".format(*color) for color in colors]
payload = {
"version": 1,
"captured_at": datetime.now().isoformat(timespec="seconds"),
"colors": values,
}
PALETTE_CONFIG_PATH.write_text(
json.dumps(payload, ensure_ascii=True, indent=2) + "\n",
encoding="utf-8",
)
return PALETTE_CONFIG_PATH
_ROWS = _load_rows()
PALETTE = tuple(
GameColor(row * 4 + column, row, column, _hex_to_rgb(value))
for row, values in enumerate(_ROWS)
for column, value in enumerate(values)
)
PALETTE_RGB = tuple(color.rgb for color in PALETTE)