Created
November 22, 2019 07:04
Command Line Mastemind in Python
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
import sys | |
import random | |
SLOTS = 4 | |
class Colors: | |
G = 'g' # green | |
R = 'r' # red | |
B = 'b' # blue | |
Y = 'y' # yellow | |
C = 'c' # cyan | |
M = 'm' # magenta | |
all_colors = [Colors.G, Colors.R, Colors.B, Colors.Y, Colors.C, Colors.M] | |
class Game: | |
def __init__(self): | |
self._hidden = None | |
self.guesses = [] | |
def init(self): | |
self._hidden = random.choices(all_colors, k=SLOTS) | |
self.guesses = [] | |
@staticmethod | |
def rules(): | |
print("Guess should consist of 4 space separated colors") | |
print("There are 6 possible colors: g, r, b, y, c, m") | |
print("Feedback consists of 4 characters: - no match, " | |
"o match color but not position, * match color and position") | |
@property | |
def has_started(self): | |
return self._hidden is not None | |
@property | |
def is_finished(self): | |
if not self.has_started or not self.guesses: | |
return False | |
else: | |
return self._hidden == self.guesses[-1][0] | |
def guess(self, inp): | |
if self.has_started: | |
colors = inp.strip().split(' ') | |
if len(colors) != 4: | |
raise ValueError("Expected 4 colors, got {}".format(len(colors))) | |
else: | |
color_pos_match = 0 | |
for i, color in enumerate(colors): | |
if color not in all_colors: | |
raise ValueError("Color {} is not acceptable color " | |
"name.".format(color)) | |
if color == self._hidden[i]: | |
color_pos_match += 1 | |
color_match = 0 | |
for color in all_colors: | |
color_match += min(colors.count(color), | |
self._hidden.count(color)) | |
feedback = "*"*color_pos_match + "o"*(color_match-color_pos_match) \ | |
+ "-"*(4-color_match) | |
self.guesses.append((colors, feedback)) | |
return feedback | |
else: | |
return "Game is not initialized" | |
def cheat(self): | |
print(self._hidden) | |
def print_guesses(self): | |
for guess in self.guesses: | |
print(guess[0], guess[1]) | |
def start_game(game): | |
game.init() | |
continue_game(game) | |
def continue_game(game): | |
while not game.is_finished: | |
print("Guess the colors (input 'h' for help 'q' to quit)") | |
guess = input(">> ") | |
if guess == 'q': | |
return | |
elif guess == 'h': | |
Game.rules() | |
print("To see guess history input 'gh'.") | |
elif guess == "gh": | |
game.print_guesses() | |
elif guess == "cheat": | |
game.cheat() | |
else: | |
try: | |
feedback = game.guess(guess) | |
except ValueError as e: | |
print(e) | |
else: | |
print(feedback) | |
if feedback == "****": | |
print("Hidden pattern found!") | |
break | |
else: | |
print("Game is solved. Start a new one.") | |
game.print_guesses() | |
def print_usage(): | |
print("Write 'n' to start new game") | |
print("Write 'c' to continue saved game") | |
print("Write 'q' to quit") | |
def main(): | |
game = Game() | |
print_usage() | |
while True: | |
line_input = input("> ") | |
if line_input == 'q': | |
sys.exit(0) | |
elif line_input == 'n': | |
start_game(game) | |
elif line_input == 'c': | |
if not game.has_started: | |
start_new = \ | |
input('No saved game. Would you like to start a new one [Y/n]') | |
if start_new == 'Y': | |
start_game(game) | |
else: | |
print('Aborting') | |
else: | |
continue_game(game) | |
else: | |
print_usage() | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment