#!/usr/bin/env python ''' Generate reply to adventure's wizard challenge. The game prints five random letters. The correct reply depends on those letters, the secret magic number (-m), and current time (-t) of day to 10 minute resolution. This is the second half of the original Fortran WIZARD routine (labels 19 and following). The -m arg is only needed if you have changed the magic number from its default of 11111. -t is probably never needed and was helpful for debugging. It's a stretch but can possibly be useful if running on a machine whose clock is way off from the gaming machine. Yes, unlikely! Usage: answer.py LETTERS [-m N] [-t HH:MM] LETTERS The five letters the game printed, e.g. QBXMD. -m N Magic number (default 11111, the game's default; the hours file may have changed it). -t H:M Pretend it is this time (24-hour). Default: now. Mike Markowski, mike.ab3ap@gmail.com Oct 2026 ''' import argparse, datetime, sys def answer(challenge, magnm, mins): '''Return the 5 letter reply for challenge, given the magic number and minutes past midnight when the reply is read. Inputs: challenge (string): challenge output by adventure. magnm (int): magic number used by adventure and can be changed only in MAGIC MODE. mins (int): current number of minutes after midnight. Output: (string): 5 character string proving you are a wizard. ''' vals = [ord(c)-64 for c in challenge] # 'A'..'Z' -> 1..26 t = mins//60*40 + mins//10*10 # Same scrambling as the game. d = magnm reply = '' for i,v in enumerate(vals): nxt = vals[(i+1)%5] # Wraps around to first. x = (abs(v-nxt)*(d%10) + t%10)%26 + 1 t //= 10 # Next decimal digit of each. d //= 10 reply += chr(64+x) return reply def main(): ap = argparse.ArgumentParser( description='Answer adventure wizard challenge.') ap.add_argument('letters', help='five letters adventure printed') ap.add_argument('-m', type=int, default=11111, help='magic number') ap.add_argument('-t', help='current time as HH:MM') args = ap.parse_args() letters = args.letters.upper() if len(letters) != 5 or not all('A' <= c <= 'Z' for c in letters): sys.exit('The challenge is exactly five letters, A-Z.') if args.t: try: h,m = (int(x) for x in args.t.split(':')) assert 0 <= h < 24 and 0 <= m < 60 except (ValueError, AssertionError): sys.exit('-t must be HH:MM, 24-hour.') else: now = datetime.datetime.now() h,m = now.hour, now.minute minutes = 60*h + m # Answer now. print('%s now' % answer(letters, args.m, minutes)) # Answer in next 10 min block. Blocks start at :00, :10, etc. edge = (minutes//10 + 1)*10 # Minutes, start of next 10 minute block. a = answer(letters, args.m, edge%1440) # 1440==24*60, minutes in 24 hours. h = edge//60%24 # Hour of day. m = edge%60 # Minutes in hour. print('%s after %02d:%02d' % (a, h, m)) if __name__ == '__main__': main()