-
Notifications
You must be signed in to change notification settings - Fork 0
/
mastermind.py
189 lines (156 loc) · 4.34 KB
/
mastermind.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Fri Jun 2 22:40:25 2017
@author: Janna112358
mastermind
"""
from numpy.random import randint
def display(name):
"""
Display rules or credits on screen
Parameters
----------
name: {'rules', 'credits'}
what to display
"""
fname = name + '.txt'
f = open(fname, 'r')
text = f.read()
print(text)
f.close()
def get_guess(n):
"""
Allow user to input a guess
Parameters
----------
n: int
the length of the code in the game
Returns
-------
bool
if True, user indicated to quit the game
string
valid length n guess
"""
# loop allows to aks for input until we have something valid
while True:
quit_game = False
guess = input("guess >> ")
if guess == "quit" or guess == "q":
quit_game = True
guess = None
break
elif guess == "cheatycheat":
quit_game = False
guess = "cheat"
break
# check if guess has correct length and consists of integers
# (by trying to convert the guess to a single integer, which should work
# for any code of 4 digits)
if len(guess) == n:
try:
int(guess)
valid_guess = True
break
except:
valid_guess = False
else:
valid_guess = False
if not valid_guess:
print("Invalid input, guess needs to be a code of %d integers"%n)
# this ensures the loop continues
continue
return quit_game, guess
def get_n():
"""
Allows user to input a length for the code to use
Returns
-------
bool
if True, user indicated to quit the game
int
length of the code to generate
"""
# loop allows to aks for input until we have something valid
while True:
quit_game = False
n = input("Choose a code length >> ")
if n == "quit" or n == "q":
quit_game = True
n = None
break
# check wether the input is valid, i.e. an integer
try:
n = int(n)
valid_n = True
break
except:
valid_n = False
if not valid_n:
print("Invalid input, needs to be an integer")
continue
return quit_game, n
def get_score(n, code, guess):
"""
Score a guess given a code and the length
Parameters
----------
n: int
length of the code
code: string
n-digit code
guess: string
n-digit guess
Returns
-------
int
number of correct digits in the right place
int
number of correct digits in the wrong place
"""
score1 = 0 # number of correct digits in the right place
score2 = 0 # number of correct digits in the wrong place
for i in range(n):
if guess[i] == code[i]:
score1 += 1
# this allows for correct scoring of doubles
for j in set(guess):
score2 += min(code.count(j), guess.count(j))
return score1, score2 - score1
def game():
"""
Allow user to play a game
Returns
-------
int
0 if user quit the game
otherwise the number of turns it took to win
"""
print("play a game!")
print("Type quit anytime to quit the game \n")
quit_game, n = get_n()
if quit_game:
return 0
print("You have chosen a code length of %d \n"%n)
code = ''
for i in range(n):
code += str(randint(0, 9))
turn = 1
while True:
quit_game, guess = get_guess(n)
if quit_game:
break
elif guess == "cheat":
print("code: %s"%code)
continue
score1, score2 = get_score(n, code, guess)
# win condition is that all of the digits are correct and in the right
# place, so the first score should be equal to the number of digits
# in the code
if score1 == n:
print("you win! turns: %d"%turn)
print
return turn
print("turn %d, guess: %s, score: %d %d"%(turn, guess, score1, score2))
turn += 1