Add python script to check sprite masterlist

This commit is contained in:
Sirz Benjie 2025-02-14 14:14:40 -06:00
parent 3fd5414f5c
commit 3d9e0a93ec
No known key found for this signature in database
GPG Key ID: 4A524B4D196C759E
2 changed files with 100 additions and 0 deletions

4
.gitignore vendored
View File

@ -41,3 +41,7 @@ coverage
/dependency-graph.svg
/.vs
# Script outputs
./*.csv

View File

@ -0,0 +1,96 @@
"""
Validates the contents of the variant's masterlist file and identifies
any mismatched entries for the sprite of the same key between front, back, exp, and female.
This will create a csv file that contains all of the entries with mismatches.
An empty entry means that there was not a mismatch for that version of the sprite (meaning it matches front).
"""
import sys
if sys.version_info < (3, 7):
msg = "This script requires Python 3.7+"
raise RuntimeError(msg)
import json
import os
import csv
from dataclasses import dataclass, field
from typing import Literal as L
MASTERLIST_PATH = os.path.join(
os.path.dirname(os.path.dirname(__file__)), "public", "images", "pokemon", "variant", "_masterlist.json"
)
DEFAULT_OUTPUT_PATH = "sprite-mismatches.csv"
@dataclass(order=True)
class Sprite:
key: str = field(compare=False)
front: list[int] = field(default_factory=list, compare=False)
back: list[int] = field(default_factory=list, compare=False)
female: list[int] = field(default_factory=list, compare=False)
exp: list[int] = field(default_factory=list, compare=False)
sortedKey: tuple[int] | tuple[int, str] = field(init=False, repr=False, compare=True)
def as_row(self) -> tuple[str, list[int] | L[""], list[int] | L[""], list[int] | L[""], list[int] | L[""]]:
"""return sprite information as a tuple for csv writing"""
return (self.key, self.front or "", self.back or "", self.exp or "", self.female or "")
def is_mismatch(self) -> bool:
"""return True if the front, back, or exp sprites do not match the front"""
for val in [self.back, self.exp, self.female]:
if val != [] and val != self.front:
return True
return False
def __post_init__(self):
split = self.key.split("-", maxsplit=1)
self.sortedKey = (int(split[0]), split[1]) if len(split) == 2 else (int(split[0]),)
def make_mismatch_sprite_list(path):
with open(path, "r") as f:
masterlist: dict = json.load(f)
# Go through the keys in "front" and "back" and make sure they match the masterlist
back_data: dict[str, list[int]] = masterlist.pop("back", {})
exp_data: dict[str, list[int]] = masterlist.pop("exp", {})
female_data: dict[str, list[int]] = masterlist.pop("female", {})
sprites: list[Sprite] = []
for key, item in masterlist.items():
sprite = Sprite(
key, front=item, back=back_data.get(key, []), exp=exp_data.get(key, []), female=female_data.get(key, [])
)
if sprite.is_mismatch():
sprites.append(sprite)
return sprites
def write_mismatch_csv(filename: str, mismatches: list[Sprite]):
with open(filename, "w", newline="") as csvfile:
writer = csv.writer(csvfile)
writer.writerow(["key", "front", "back", "exp", "female"])
for sprite in sorted(mismatches):
writer.writerow(sprite.as_row())
if __name__ == "__main__":
import argparse
p = argparse.ArgumentParser("find_sprite_variant_mismatches", description=__doc__)
p.add_argument(
"-o",
"--output",
default=DEFAULT_OUTPUT_PATH,
help=f"The path to a file to save the output file. If not specified, will write to {DEFAULT_OUTPUT_PATH}.",
)
p.add_argument("--masterlist", default=MASTERLIST_PATH, help=f"The path to the masterlist file to validate. Defaults to {MASTERLIST_PATH}.")
args = p.parse_args()
mismatches = make_mismatch_sprite_list(args.masterlist)
write_mismatch_csv(args.output, mismatches)