Skip to content

Instantly share code, notes, and snippets.

@trysdyn
Created September 30, 2017 23:20
Show Gist options
  • Save trysdyn/134f890a9fa4426c2616f2ae4f496865 to your computer and use it in GitHub Desktop.
Save trysdyn/134f890a9fa4426c2616f2ae4f496865 to your computer and use it in GitHub Desktop.
A simplified version of my retro roulette script
#! /usr/bin/env python3
import os
import random
import subprocess
# The path to the emu, configured for single instance mode
# So each invocation just opens the rom in the current instance
launch = "D:/Emulators/Bizhawk/EmuHawk.exe"
# Roms dir. This assumes a specific dir layout such as:
# D:/ROMs/SNES/Cool Spot/Cool Spot.sfc
roms_dir = "D:/ROMs/"
# List of systems to peruse. Must be sub-dirs of roms_dir
systems = ["SNES", "GBA", "NES", "FDS", "TG16", "GB", "GEN", "GG",
"SWAN", "SMS"]
def get_dir_list(d):
"""Gets a list of sub-dirs in the given dir.
This is used to get a list of systems in roms_dir and to get a list of
rom dirs within each system sub-dir."""
# This is a list comprehension. The logic breaks down to...
# For every item in dir 'd', check if that item is not a file (a dir)
# if it is, add it to a list that gets returned.
return [f for f in os.listdir(d)
if not os.path.isfile(os.path.join(d, f))]
# These functions that only do random.choice() are broken out because they
# used to be more complicated before I refactored things. I keep them broken
# out in case these calls end up becoming more complicated again in the future
def choose_game(l):
"""Returns a random rom from a given list of roms. This is called to pick
a random surviving candidate from a list of ROMs pared down by
choose_file()"""
return random.choice(l)
def choose_system(l):
"""Returns a random system from a given list of systems. This is called to
pick a system from the list provided in 'systems' global above."""
return random.choice(l)
def format_filename(n):
"""Some light cleanup to remove leading "A" and "The" from titles, and
also strip dumper tags like [!], [o0], etc. Makes a printable, clean game
name we inject into our output."""
# Strip floating "The" and "A"
n = n.replace(', The', '')
n = n.replace(', A', '')
# Strip file extension
# We have to do this despite the next strip making it redundant because
# sometimes on badly formatted dump filenames the next strip fails
n = n.rsplit('.', 1)[0]
# Strip parenthetical and dumper tags by splitting at the first (
n = n.split('(', 1)[0]
return n
def launch_emu(rom):
"""Calls choose_file() on the system and directory chosen by do_choice()
then calls Bizhawk with the given ROM filename."""
if launch:
# Get our full filename
filename = choose_file(rom)
# And call Bizhawk with it
subprocess.Popen([launch, filename])
def choose_file(rom):
"""Given a directory of ROMs, attempts to pick the ROM most likely to be
playable. This follows this specific order of preference:
1.) Any file with [!] which means "canonical good room"
2.) Any file with (U) which means "NA port/English"
3.) Any file with T+Eng or T-Eng which means "English Translated"
4.) Any file with (E) which means "EU port, likely to be English"
5.) Any file
This compiles a list of valid candidates, then one is randomly chosen.
"""
# Piece together the full path for the ROM dir in question
d = roms_dir + rom[0] + "/" + rom[1]
# Get a list of all files in the dir (each file should be a ROM)
files = os.listdir(d)
# Define the strings we want to search for, in order of preference
matches = ["[!]", "(u)", "(ue)", "t+eng", "t-eng", "(e)"]
# Loop through the list and make a list of ROM candidates for selection
for m in matches:
candidates = []
# If our search string is in the filename, add the ROM to the
# candidate list
for f in files:
if m in f.lower():
candidates.append(f)
# If we scored any candidates, discard all non-candidates by replacing
# our list of files with our list of candidates.
if len(candidates):
files = candidates[:]
# Pick a random ROM from candidates and return the full absolute path of it
return d + "/" + random.choice(files)
def do_choice():
"""Chooses a system, then chooses a game from that system. Returns the
system and dirname of the game."""
# Choose a system
system = choose_system(systems)
# Choose a game
f = choose_game(get_dir_list("D:/ROMs/%s" % system))
# Return the choice and the system it runs on
return (system, f)
if __name__ == "__main__":
print("Retro Roulette, scaled down version. Press return for a new game. ^C to quit")
while True:
input()
# Call do_choice() and get back (system, ROM) frex
# ("SNES", "D:/ROMs/SNES/Cool Spot/Cool Spot (U).sfc")
selection = do_choice()
# Format our print string for the game
game = format_filename("[%s] %s" % selection)
# Print our selection frex "[SNES] Cool Spot"
print(game, end="")
# Launch emu with the given ROM
launch_emu(selection)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment