summaryrefslogtreecommitdiff
path: root/extractor
diff options
context:
space:
mode:
authorpommicket <pommicket@gmail.com>2025-09-18 11:39:35 -0400
committerpommicket <pommicket@gmail.com>2025-09-18 11:39:35 -0400
commitc728aae2527221032f47fded2fb697d95661977d (patch)
treea971c528ebd8b69758275d05b7ae6ddd747ce1c7 /extractor
parent6662ff6460bfe3a963564adb8fbe0d52370f882c (diff)
Keep track of solution
Diffstat (limited to 'extractor')
-rw-r--r--extractor/extractor.py81
1 files changed, 51 insertions, 30 deletions
diff --git a/extractor/extractor.py b/extractor/extractor.py
index 8fac3bf..da16717 100644
--- a/extractor/extractor.py
+++ b/extractor/extractor.py
@@ -1,16 +1,27 @@
+#!/usr/bin/env python3
+
import sys
import os
import shutil
+import argparse
+
+parser = argparse.ArgumentParser(description='''BlankPlays challenge extractor.
+Extracts challenges from log files generated by Macondo's autoplay command.''')
+parser.add_argument('-w', '--word-list', required=True, help='File containing list of words, separated by newlines.')
+parser.add_argument('-o', '--output', required=True, help='Directory to put challenges in (will be created if does not exist).')
+parser.add_argument('--start-idx', default=0, help='Number of first challenge (default: 0)')
+parser.add_argument('log_files', nargs='*', help='Macondo log files')
+args = parser.parse_args()
-if len(sys.argv) < 4:
- print('Usage: extractor.py <MACONDO LOG FILE> <WORD LIST> <START IDX>')
+if not args.log_files:
+ print('At least one log file must be specified.')
sys.exit(1)
alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
# board size
N = 15
-word_list = set(line.strip().upper() for line in open(sys.argv[2], encoding='utf-8'))
+word_list = set(line.strip().upper() for line in open(args.word_list, encoding='utf-8'))
# can change these to implement non-ASCII tiles
def encode(tile: str) -> int:
@@ -103,40 +114,50 @@ class GameState:
def output(self, filename: str) -> None:
if os.path.exists(filename):
- print(filename, 'already exists')
+ print(filename, 'already exists. Aborting.')
sys.exit(1)
with open('challenge.tmp', 'wb') as out:
out.write(self.board_string().encode())
for square, letter, _ in self.blank_plays():
out.write(f'{square} {letter}\n'.encode())
os.rename('challenge.tmp', filename)
-games_file = open(sys.argv[1], encoding='utf-8')
+
+def is_nice(play: tuple[int, str, list[str]]) -> bool:
+ _square, letter, words = play
+ # we want 5+-letter words that aren't just S hooks
+ return any(len(w) >= 5 and not (letter == 'S' and w.endswith('S')) for w in words)
+
+output_dir = args.output
+game_idx = args.start_idx
+count = 0
+
try:
- os.mkdir('challenges')
+ os.mkdir(output_dir)
except FileExistsError:
pass
-lines = iter(games_file)
-next(lines) # skip header
-games = {}
-count = 0
-game_idx = int(sys.argv[3])
-for line in lines:
- line = line.strip()
- fields = line.split(',')
- game_id = fields[1]
- if game_id not in games:
- games[game_id] = GameState()
- play = fields[4]
- games[game_id].make_play(play)
- if fields[3] == '?':
- game = games[game_id]
- plays = game.blank_plays()
- nice_plays = [play for play in plays if any(len(w) > 4 for w in play[2])]
- # require at least 3 plays that make 5+-letter words
- if len(nice_plays) >= 3:
- game.output(f'challenges/{game_idx:05}.txt')
- print(game.board_string())
- print(len(plays), 'plays')
- count += 1
- game_idx += 1
+
+for filename in args.log_files:
+ games_file = open(filename, encoding='utf-8')
+ lines = iter(games_file)
+ next(lines) # skip header
+ games = {}
+ for line in lines:
+ line = line.strip()
+ fields = line.split(',')
+ game_id = fields[1]
+ if game_id not in games:
+ games[game_id] = GameState()
+ play = fields[4]
+ games[game_id].make_play(play)
+ if fields[3] == '?':
+ game = games[game_id]
+ plays = game.blank_plays()
+ nice_plays = [play for play in plays if is_nice(play)]
+ # require at least 3 plays that make 5+-letter words
+ if len(nice_plays) >= 3:
+ game.output(f'{output_dir}/{game_idx:05}.txt')
+ print(game.board_string())
+ print(len(plays), 'plays')
+ count += 1
+ game_idx += 1
print(count, 'challenges made.')