Python - Juego Mastermind: Problemilla con primer programa en python.

 
Vista:
sin imagen de perfil

Juego Mastermind: Problemilla con primer programa en python.

Publicado por BigfooTsp (12 intervenciones) el 12/10/2016 09:40:07
Hola. Estoy aprendiendo Python, no tengo experiencia como programador pero me parece muy interesante y tras algunos manuales y vídeos decidí hacer un programita para practicar basándome en el juego Mastermind.
Este consiste en tener que acertar antes de diez turnos una combinación aleatoria de cuatro dígitos con los valores 0 a 5 (No se repiten los números en la combinación aunque el usuario sí que puede hacerlo).
A cada turno se facilitan dos datos:
"Negras" son los números acertados por el usuario en una posición correcta.
"Blancas", coincide un número pero no en posición correcta.
Me funciona salvo en un pequeño problema al que le doy vueltas y vueltas pero no encuentro la solución... y sé que tiene que ser una tontería.

Bueno... aquí está el archivo "mastermind.py" en el que desarrollo la lógica, luego está menumind.py que me presenta el juego.

MASTERMIND:

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
import random
import re
 
class Mastermind:
	def __init__ (self):
 
		self.cont = 10 # Contador de 10 turnos para acertar.
		rango = [0, 1, 2, 3, 4, 5] #
		random.shuffle(rango)       # Creación de combinación aleatoria.
		self.comb = rango[0:4]     #
		self.respuestas= [] # listado de respuestas de cada turno
		self.blancas = [] #lista que contiene las variables blanc de cada turno.
		self.negras = [] #lista para las var. neg
		self.estado = "jugando" # Estado de la partida.
 
 
	def valores_correctos(self, entrada_user):
		''' Comprueba que la entrada del user es correcta.'''
 
		if re.match("^([0-5]\s){3}[0-5]$", entrada_user):
			return entrada_user
		else:
			print("Entrada incorrecta")
			self.acierta()
 
 
	def acierta(self):
		''' Inicia el juego'''
		entrada_user = self.valores_correctos(input(
			"Acierta la combinación de 4 dígitos entre 0 y 5 (x x x x)\n"))
 
		entrada_user = entrada_user.split( )
		self.compara(entrada_user)
 
 
	def compara(self, entrada_user):
		''' Compara combinación con entrada de usuario.
			si x - y = 0, x e y son iguales'''
 
		en_us = [] #resultado de la futura resta.
 
		for elemento in range(4):
			entrada_user[elemento] = int(entrada_user[elemento])
			en_us.append (self.comb[elemento] - entrada_user[elemento])
 
		# ¿Cuántos ceros (negras) hay?
		neg = (en_us.count(0))
 
		# ¿Cuántas blancas? 
		blanc = 0
		# entrada_user como conjunto por si user mete valores iguales.
		for element in (set(entrada_user)):
			if element in self.comb:
				blanc += 1
		# Y se eliminan las negras para que no cuenten como blancas.
		blanc = (blanc - neg)
 
		self.respuestas.append(entrada_user) #
		self.blancas.append(blanc)
		self.negras.append(neg)
 
		self.resuelve(neg)
 
 
	def resuelve(self, neg):
		''' Resuelve el resultado y lo devuelve como lista resultado[]'''
 
		if neg == 4:
			self.estado="ganaste"
		elif self.cont > 1:
	 		self.cont -= 1
	 		self.estado="jugando"
		else:
			self.estado="perdiste"


menumind.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
import os
from mastermind import Mastermind
 
clear = lambda: os.system('cls')
 
 
def representa():
 
	respuestas_menu = []
	negras_menu = []
	blancas_menu = []
 
	# Diseñando tablero.
	for e in range(len(juego.respuestas)):
		respuestas_menu.append(juego.respuestas[e])
		negras_menu.append(juego.negras[e])
		blancas_menu.append(juego.blancas[e])
	while (len(respuestas_menu)) < 10:
		respuestas_menu.append(" -  -  -  - ")
		negras_menu.append("-")
		blancas_menu.append("-")
 
	# Dibujando menú.
	clear()
	print ("\n--------- MASTERMIND ----------")
	print ("          [ {} ]\n".format(juego.estado))
 
	for element in range(10):
		print ("        {0}      negras {1}   blancas  {2} ".format(
			respuestas_menu[element], negras_menu[element], blancas_menu[element]))
	print ("")
 
 
def run():
	if juego.estado == 'jugando':
		representa()
		juego.acierta()
	elif juego.estado == "ganaste":
		representa()
		print("!!! GANASTE !!!")
		exit()
	else:
		representa()
		print ("La combinación era {} ...\n".format(juego.comb))
		print("!!! PERDISTE :(  !!!")
		exit()
 
 
if __name__ == '__main__':
 
	juego = Mastermind()
 
	while True:
		run()

EL juego funciona correctamente en consola hasta que introduzco un valor no permitido que intento controlar con la función valores_correctos() que comprueba cada entrada de usuario. Si esta no es del tipo "x x x x" donde x es de 0 a 5, te pide una entrada correcta volviendo a la función acierta() que es la que inicia el juego.
Si la entrada sigue siendo incorrecta te sigue pidiendo una correcta. Pero en cuanto introduces una correcta, te salta un error cuando antes funcionaba correctamente hasta el final del juego... No sé si me explico :)...
¡¡¡POR QUÉ, POR DIOS, POR QUÉ!!!

Aquí está el error...
-----------------------------------------------------------------------------------------------
Acierta la combinación de 4 dígitos entre 0 y 5 (x x x x)
DWECD
Entrada incorrecta
Acierta la combinación de 4 dígitos entre 0 y 5 (x x x x)
2 2 2 2 (#esta cumple el formato correcto)
Traceback (most recent call last):
File "menumind.py", line 54, in <module>
run()
File "menumind.py", line 37, in run
juego.acierta()
File "D:\Proyectos Phyton\MasterMind\mastermind.py", line 45, in acierta

File "D:\Proyectos Phyton\MasterMind\mastermind.py", line 39, in valores_correctos

File "D:\Proyectos Phyton\MasterMind\mastermind.py", line 45, in acierta

File "D:\Proyectos Phyton\MasterMind\mastermind.py", line 39, in valores_correctos

File "D:\Proyectos Phyton\MasterMind\mastermind.py", line 47, in acierta
self.compara(entrada_user)
AttributeError: 'NoneType' object has no attribute 'split'
-----------------------------------------------------------------------------------------------

Por otro lado, cualquier comentario sobre la forma de haber redactado el programa será bienvenido, que como he dicho, soy autodidacta, este es el primero y tengo en cuenta la opinión de gente más experimentada.
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
Imágen de perfil de xve
Val: 2.239
Plata
Ha mantenido su posición en Python (en relación al último mes)
Gráfica de Python

Juego Mastermind: Problemilla con primer programa en python.

Publicado por xve (1646 intervenciones) el 12/10/2016 19:04:12
Hola, te he modificado un poquito el archivo mastermind.py, para que cuando sea incorrecta la entrada, devuelva false simplemente!!!

haber si te sirve...
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
# -*- coding: UTF-8 -*-
 
import random
import re
 
class Mastermind:
	def __init__ (self):
 
		self.cont = 10 # Contador de 10 turnos para acertar.
		rango = [0, 1, 2, 3, 4, 5] #
		random.shuffle(rango)       # Creación de combinación aleatoria.
		self.comb = rango[0:4]     #
		self.respuestas= [] # listado de respuestas de cada turno
		self.blancas = [] #lista que contiene las variables blanc de cada turno.
		self.negras = [] #lista para las var. neg
		self.estado = "jugando" # Estado de la partida.
 
 
	def valores_correctos(self, entrada_user):
		''' Comprueba que la entrada del user es correcta.'''
 
		if re.match("^([0-5]\s){3}[0-5]$", entrada_user):
			return entrada_user
		else:
			print("Entrada incorrecta")
			return False
 
 
	def acierta(self):
		''' Inicia el juego'''
		entrada_user = self.valores_correctos(input(
			"Acierta la combinación de 4 dígitos entre 0 y 5 (x x x x)\n"))
		if entrada_user:
			entrada_user = entrada_user.split( )
			self.compara(entrada_user)
 
 
	def compara(self, entrada_user):
		''' Compara combinación con entrada de usuario.
			si x - y = 0, x e y son iguales'''
 
		en_us = [] #resultado de la futura resta.
 
		for elemento in range(4):
			entrada_user[elemento] = int(entrada_user[elemento])
			en_us.append (self.comb[elemento] - entrada_user[elemento])
 
		# ¿Cuántos ceros (negras) hay?
		neg = (en_us.count(0))
 
		# ¿Cuántas blancas? 
		blanc = 0
		# entrada_user como conjunto por si user mete valores iguales.
		for element in (set(entrada_user)):
			if element in self.comb:
				blanc += 1
		# Y se eliminan las negras para que no cuenten como blancas.
		blanc = (blanc - neg)
 
		self.respuestas.append(entrada_user) #
		self.blancas.append(blanc)
		self.negras.append(neg)
 
		self.resuelve(neg)
 
 
	def resuelve(self, neg):
		''' Resuelve el resultado y lo devuelve como lista resultado[]'''
 
		if neg == 4:
			self.estado="ganaste"
		elif self.cont > 1:
	 		self.cont -= 1
	 		self.estado="jugando"
		else:
			self.estado="perdiste"
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil

Juego Mastermind: Problemilla con primer programa en python.

Publicado por BigfooTsp (12 intervenciones) el 13/10/2016 06:39:25
Gracias pero no... Eso rompe el bucle que debería de volver a iniciar con el módulo acierta() en el que se vuelve a preguntar la entrada del usuario.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de xve
Val: 2.239
Plata
Ha mantenido su posición en Python (en relación al último mes)
Gráfica de Python

Juego Mastermind: Problemilla con primer programa en python.

Publicado por xve (1646 intervenciones) el 13/10/2016 09:06:02
Lo has probado??? no rompe el bucle, vuelve a pedirlo!!
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil

Juego Mastermind: Problemilla con primer programa en python.

Publicado por BigfooTsp (12 intervenciones) el 13/10/2016 07:45:42
Finalmente encontré el error.
En el módulo "valores_correctos", que comprueba que la entrada del usuario se corresponde con el formato correcto, cuando está era correcta, me mandaba un return al módulo inicial que pedía la entrada de usuario (acierta()) y desde aquí lo mandaba al otro módulo para compararla con la combinación aleatoria (compara()). Me he saltado el paso intermedio y mando la entrada de usuario directamente al módulo compara desde el módulo "valores_correctos" cuando esta es correcta... Aunque no entiendo demasiado bien porqué. Puede ver que desde el módulo acierta, tras la comprobación en valores_correctos si una entrada al menos hubiera sido incorrecta (lo que hace que vuelva a "acierta") posteriormente en el módulo compara aparecían dos valores para entrada_user que comprobé con un print(entrada_user) ahí en medio... un valor era la entrada correcta que me había llevado ahí, y salía otro entrada_user = None que no entiendo y que me marcaba el error al procesarlo como lista.
Imagino que esto solo lo entiendo yo y me ha tomado unos cuantos ratos encontrarlo... seguiré aprendiendo :). Gracias y hasta otra.

Así quedó el código:

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
import random
import re
 
class Mastermind:
	def __init__ (self):
 
		self.cont = 10 # Contador de 10 turnos para acertar.
		rango = [0, 1, 2, 3, 4, 5] #
		random.shuffle(rango)       # Creación de combinación aleatoria.
		self.comb = rango[0:4]     #
		self.respuestas= [] # listado de respuestas de cada turno
		self.blancas = [] #lista que contiene las variables blanc de cada turno.
		self.negras = [] #lista para las var. neg
		self.estado = "jugando" # Estado de la partida.
 
 
	def valores_correctos(self, entrada_user):
		''' Comprueba que la entrada del user es correcta.'''
 
		if re.match("^([0-5]\s){3}[0-5]$", entrada_user):
			self.compara(entrada_user)
		else:
			print("Entrada incorrecta")
			self.acierta()
 
 
	def acierta(self):
		''' Inicia el juego'''
 
		entrada_user = input("Acierta la combinación de 4 dígitos entre 0 y 5 (x x x x)\n")
		self.valores_correctos(entrada_user)
 
 
	def compara(self, entrada_user):
		''' Compara combinación con entrada de usuario.
			si x - y = 0, x e y son iguales'''
 
		entrada_user = entrada_user.split() # Convertimos el lista con 4 elementos
 
		en_us = [] #resultado de la futura resta.
 
		for elemento in range(4):
			entrada_user[elemento] = int(entrada_user[elemento])
			en_us.append (self.comb[elemento] - entrada_user[elemento])
 
		# ¿Cuántos ceros (negras) hay?
		neg = (en_us.count(0))
 
		# ¿Cuántas blancas? 
		blanc = 0
		# entrada_user como conjunto por si user mete valores iguales.
		for element in (set(entrada_user)):
			if element in self.comb:
				blanc += 1
		# Y se eliminan las negras para que no cuenten como blancas.
		blanc = (blanc - neg)
 
		self.respuestas.append(entrada_user) #
		self.blancas.append(blanc)
		self.negras.append(neg)
 
		self.resuelve(neg)
 
 
	def resuelve(self, neg):
		''' Resuelve el resultado y lo devuelve como lista resultado[]'''
 
		if neg == 4:
			self.estado="ganaste"
		elif self.cont > 1:
	 		self.cont -= 1
	 		self.estado="jugando"
		else:
			self.estado="perdiste"
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar
Imágen de perfil de xve
Val: 2.239
Plata
Ha mantenido su posición en Python (en relación al último mes)
Gráfica de Python

Juego Mastermind: Problemilla con primer programa en python.

Publicado por xve (1646 intervenciones) el 13/10/2016 09:08:36
Gracias por compartirlo!!!
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar