patternpythonMinor
Mastermind game in Python
Viewed 0 times
mastermindgamepython
Problem
I am a C#/.Net developer and have decided it is time to branch out and really learn Python. I started with a simple implementation of a Mastermind-esque game. Any comments about the code would be greatly appreciated. I already know the gameplay isn't perfect, but it was just a quick attempt. I also am aware that there isn't much user input checking, but again, quick attempt.
```
import random
class Game(object):
def run(self):
guesses = []
game_states = []
length = int(input("Choose length of code to break: "))
code = [random.randint(0, 9) for i in range(length)]
def take_guess():
correct_guess_length = False
while not correct_guess_length:
guess = input("Guess a number of length {0}: ".format(length))
if len(guess) != length:
print("Guesses must be a number of length {0}.".format(length))
else:
correct_guess_length = True
return guess
def check_guess(guess):
return all([x == y for x, y in zip(guess, code)])
def evaluate_guess(guess):
new_state = []
for pos, number in enumerate(guess):
if code[pos] == number:
new_state.append(str(number))
elif number in code:
new_state.append("O")
else:
new_state.append("X")
game_states.append(''.join([c for c in new_state]))
def print_game_state():
print()
for guess, state in zip(guesses, game_states):
print("{0}\t{1}".format(guess, state))
correct = False
while not correct:
guess = take_guess()
guesses.append(guess)
guess_as_ints = [int(c) for c in guess]
if not check_guess(guess_as_ints):
evaluate_guess(guess_as_ints)
print_game_state()
```
import random
class Game(object):
def run(self):
guesses = []
game_states = []
length = int(input("Choose length of code to break: "))
code = [random.randint(0, 9) for i in range(length)]
def take_guess():
correct_guess_length = False
while not correct_guess_length:
guess = input("Guess a number of length {0}: ".format(length))
if len(guess) != length:
print("Guesses must be a number of length {0}.".format(length))
else:
correct_guess_length = True
return guess
def check_guess(guess):
return all([x == y for x, y in zip(guess, code)])
def evaluate_guess(guess):
new_state = []
for pos, number in enumerate(guess):
if code[pos] == number:
new_state.append(str(number))
elif number in code:
new_state.append("O")
else:
new_state.append("X")
game_states.append(''.join([c for c in new_state]))
def print_game_state():
print()
for guess, state in zip(guesses, game_states):
print("{0}\t{1}".format(guess, state))
correct = False
while not correct:
guess = take_guess()
guesses.append(guess)
guess_as_ints = [int(c) for c in guess]
if not check_guess(guess_as_ints):
evaluate_guess(guess_as_ints)
print_game_state()
Solution
Organization
As Simon points out, you shouldn't put the list of functions inside of
Use
This:
Should be this:
(Also, I would keep
I would advise you look at how Python classes work.
You can replace
Furthermore, once you pull the functions out of
become:
Naming
I expect a varaible with the name of
You don't really need this anyway!
Can just be:
I would probably just get rid of that too and say:
Same thing goes for:
You can get rid of these and use a
Is pretty good except,
(Also, when you disregard a variable the convention is to use
Since you rap everything in a game object, maybe you should give it a string representation overloading the
As Simon points out, you shouldn't put the list of functions inside of
run. It doesn't make much sense. Move them out into the class.Use
selfself in python is equivalent to this in C# and many other languages.This:
guesses = []
game_states = []
length = int(input("Choose length of code to break: "))
code = [random.randint(0, 9) for i in range(length)]Should be this:
def __init__(self):
self.guesses = []
self.game_states = []
self.code = [] # Add this later when you define length.(Also, I would keep
length as a local variable defined in run and then refer to len(self.code) instead.)I would advise you look at how Python classes work.
You can replace
random.randint(0, 9) with random.randrange(10).Furthermore, once you pull the functions out of
run, things like:def take_guess():become:
def take_guess(self):Naming
correct_guess_length = FalseI expect a varaible with the name of
length have some sort of integer (maybe real?) value. A boolean? Not often.You don't really need this anyway!
else:
correct_guess_length = TrueCan just be:
else:
breakI would probably just get rid of that too and say:
else:
return guessSame thing goes for:
correct = False
while not correct:
...You can get rid of these and use a
break statement instead.randrangecode = [random.randint(0, 9) for i in range(length)]Is pretty good except,
randrange is a little more specialized for this:code = [random.randrange(10) for _ in range(length)](Also, when you disregard a variable the convention is to use
_, not i.)__str__Since you rap everything in a game object, maybe you should give it a string representation overloading the
__str__ function, and just print out the string representation of itself. Move print_game_state to __str__.Code Snippets
guesses = []
game_states = []
length = int(input("Choose length of code to break: "))
code = [random.randint(0, 9) for i in range(length)]def __init__(self):
self.guesses = []
self.game_states = []
self.code = [] # Add this later when you define length.def take_guess():def take_guess(self):correct_guess_length = FalseContext
StackExchange Code Review Q#150034, answer score: 7
Revisions (0)
No revisions yet.