else/BaseGame/basegame.py
2015-08-02 21:28:40 -07:00

118 lines
No EOL
3.6 KiB
Python

import random
import shutil
DEFAULT_FROMBASE = 10
DEFAULT_TOBASE = 16
DEFAULT_LOWER = 0
DEFAULT_UPPER = 1000
TERMINALWIDTH = shutil.get_terminal_size().columns
def basex(number, base, alphabet='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'):
"""Converts an integer to a different base string."""
if base > len(alphabet):
raise Exception('alphabet %s does not support base %d' % (
repr(alphabet), base))
alphabet = alphabet[:base]
if not isinstance(number, (int, str)):
raise TypeError('number must be an integer')
number = int(number)
based = ''
sign = ''
if number < 0:
sign = '-'
number = -number
if 0 <= number < len(alphabet):
return sign + alphabet[number]
while number != 0:
number, i = divmod(number, len(alphabet))
based = alphabet[i] + based
return sign + based
def changebase(number, frombase, tobase):
number = str(number)
result = int(number, frombase)
return basex(result, tobase)
def intinput(prompt, greaterthan=None, notequal=None):
''' Prompt for input until the user enters an int '''
while True:
result = input(prompt)
try:
i = int(result)
if isinstance(notequal, int) and i == notequal:
continue
if isinstance(greaterthan, int) and i < greaterthan:
continue
return i
except ValueError:
pass
def configuration():
frombase = intinput(' From base: ', 1)
tobase = intinput(' To base: ', 1, frombase)
lower = intinput('Lower bound: ')
upper = intinput('Upper bound: ', lower)
return {
'frombase': frombase,
'tobase': tobase,
'lower': lower,
'upper': upper,
}
def calcpoints(solution, lower, upper, maxpoints):
'''
1/2 of the maxpoints are granted automatically.
The other 1/2 points depends on how large the number
you had to guess was.
'''
basescore = int(maxpoints / 2) + 1
bonus = (solution - lower) / (upper - lower)
bonus *= basescore
bonus = int(bonus)
return basescore + bonus
def playgame():
c= {
'frombase': DEFAULT_FROMBASE,
'tobase': DEFAULT_TOBASE,
'lower': DEFAULT_LOWER,
'upper': DEFAULT_UPPER,
}
print('\n"!" to reconfigure, "?" to give up')
score = 0
while True:
number = random.randint(c['lower'], c['upper'])
prompt = changebase(number, 10, c['frombase'])
solution = changebase(number, 10, c['tobase']).lower()
prompt = 'b%d -> b%d : %s = ' % (c['frombase'], c['tobase'], prompt)
cursor = len(prompt) + 1
scoretext = '(score: %d)' % score
spacer = ' ' * (TERMINALWIDTH - (len(scoretext) + cursor))
prompt = prompt + spacer + scoretext
prompt += '\b' * (TERMINALWIDTH - cursor)
correctness = False
while not correctness:
guess = input(prompt).lower()
guess = guess.lstrip('0')
if guess == '!':
c = configuration()
correctness = True
print()
if guess == '?':
if c['frombase'] != 10 and c['tobase'] != 10:
b10 = ' (b10= %d)' % number
else:
b10 = ''
print('%s= %s%s'% (' '*(cursor-3), solution, b10))
correctness = True
if guess == solution:
maxpoints = int((c['upper'] - c['lower']) ** 0.5)
score += calcpoints(number, c['lower'],c['upper'],maxpoints)
correctness = True
if __name__ == '__main__':
playgame()