-
-
Save lambda-fairy/5033356 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
============================= | |
The Epic Fail Guessing Game | |
============================= | |
The Epic Fail Guessing Game (*efguess*) is a simple number guessing game. | |
Except you can't win it, of course. That would be silly. | |
""" | |
from __future__ import print_function | |
from collections import namedtuple | |
from functools import partial | |
from math import log | |
from random import randint | |
# Python 3 compatibility | |
try: | |
raw_input | |
except NameError: | |
raw_input = input | |
Game = namedtuple('Game', 'low high chances') | |
class SimpleChecker(object): | |
def __init__(self, game, secret=None): | |
self.game = game | |
if secret is None: | |
self.secret = randint(game.low, game.high) | |
else: | |
self.secret = secret | |
def check(self, guess): | |
return guess - self.secret | |
def answer(self): | |
return self.secret | |
class BisectingChecker(object): | |
def __init__(self, game, troll_mode=False): | |
if troll_mode and self.player_can_win(game): | |
raise ValueError("lol u fail n00b") | |
self.game = game | |
self.low = game.low | |
self.high = game.high | |
@staticmethod | |
def player_can_win(game): | |
"""Return True if, given those game parameters, it is possible | |
for the player to win.""" | |
return game.chances >= log(game.high-game.low, 2) | |
def check(self, guess): | |
if self.low == self.high == guess: | |
return 0 | |
middle = (self.low + self.high) // 2 | |
if guess <= middle: | |
self.low = max(self.low, guess + 1) | |
return 1 | |
else: | |
self.high = min(self.high, guess - 1) | |
return -1 | |
def answer(self): | |
return randint(self.low, self.high) | |
def read(prompt, parse): | |
while True: | |
try: | |
return parse(raw_input(prompt).strip()) | |
except ValueError as ex: | |
print(ex) | |
def int_from_to(low, high): | |
def parse(s): | |
number = int(s) | |
if number < low or number > high: | |
raise ValueError("number must be from {0} through {1}".format(low, high)) | |
return number | |
return parse | |
def play(game, checker): | |
print("Welcome to the Epic Fail Guessing Game!") | |
print("I'm thinking of a number from {low} to {high}.".format(**game._asdict())) | |
def loop(): | |
for guesses_left in range(game.chances, 0, -1): | |
print("\nYou have", guesses_left, "guesses left.") | |
guess = read("What is your guess? ", int_from_to(game.low, game.high)) | |
reply = checker.check(guess) | |
if reply < 0: | |
print("Lower") | |
elif reply > 0: | |
print("Higher") | |
else: | |
print("That's correct!") | |
return True | |
else: | |
# Ran out of guesses | |
return False | |
if loop(): | |
print("\nYou won!") | |
else: | |
print("\nThe number was actually:", checker.answer()) | |
print("Better luck next time!") | |
if __name__ == '__main__': | |
try: | |
game = Game(low=1, high=100, chances=5) | |
checker = BisectingChecker(game, troll_mode=True) | |
play(game, checker) | |
except KeyboardInterrupt: | |
pass |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment