Python - Problema de las 8 reinas

 
Vista:

Problema de las 8 reinas

Publicado por Anonimo (1 intervención) el 08/06/2018 22:13:31
De que se trata el reto:
Hola gente, no se si conocen el reto de las 8 reinas. Si no lo conocen se los explico en breve.
Tenemos un tablero de ajedrez como cualquier otro y se tiene que colocar 8 reinas en el tablero sin que se ataquen. Si quieres ver más a fondo de que se trata este reto aqui te dejo un enlace:https://es.wikipedia.org/wiki/Problema_de_las_ocho_reinas

Bueno lo que quería hacer era un programa que dará una solución a este problema.
Ya tengo el código pero me ha surgido un error en la linea 58:
Excepción:
1
'NoneType' has no atribute 'reina'

Código fuente
Este es el código fuente:
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
class Casilla: #Cada casilla del tablero de ajedrez 
	afectado = False #Afectacion de la casilla por otra casillas
	reina = False #Si la casilla tiene reina o no
 
	def __init__(self,afectado,reina): #Constructor de la clase
		self.afectado = afectado
		self.reina = reina
 
	def setAfectado(self,estado):
		self.estado = estado
 
	def getAfectado(self):
		return self.estado
	#(retorno)
	def setReina(self,reina):
		self.reina = reina
	def getReina(self):
		return self.reina
 
tablero = [] #Creacion de la matriz
for i in range(0,8):
	tablero.append([None])
	for j in range(0,8):
		tablero[i].append(None)
 
#Inicializacion de objetos casillas
def reinicializacionTablero():
	global tablero #Dando permisos de modificacion de la matriz tablero a las funciones
	for i in range(0,len(tablero)):
		for j in range(0,len(tablero)):
			tablero[i][j] = Casilla(False,False)
def casillasLibres():
	libres = 0
	for i in range(len(tablero)):
		for i in range(len(tablero)):
			#Casilla vacia
			if tablero[i][j].afectado == False and tablero[i][j].reina == False:
				libres += 1 #Significa que la casilla esta libre y se aumenta la variable que indica cuantas lo estan
	return libres #Retorna el numero de casillas libres				
def primeraReina():
	pos = ""
	for i in range(8):
		for j in range(8):
			if(tablero[i][j].getReina()):
				pos = str(i) + str(j)
				return pos
def solucionado():
	num_reinas = 0
	for i in range(8):
		for j in range(8):
			if(tablero[i][j].reina != False):
				num_reinas +=1
	if(num_reinas == 8):
		return False
	else:
		return True
 
reinas = 8
primerPos = ""
 
def afectarCasillas(row,column):
	b = False
	referenceRow = 0; referenceColumn = 0 #Variables locales de indice
	#up (afect)
	referenceRow = row; referenceColumn = column #Asignacion de los indices
	while(b == False):
		referenceRow -=1 #Se decrementa los indices
		try:
			tablero[referenceRow][referenceColumn].afectado = True
		except IndexError as e:
			b = True
			break
	b = False
	#down (afect)
	referenceRow = row; referenceColumn = column #Asignacion de los indices
	while(b == False):
		referenceRow -=1 #Se decrementa los indices
		try:
			tablero[referenceRow][referenceColumn].afectado = True
		except IndexError as e:
			b = True
			break
	b = False
	#left (afect)
	referenceRow = row; referenceColumn = column #Asignacion de los indices
	while(b == False):
		referenceColumn -= 1 #Se decrementa los indices
		try:
			tablero[referenceRow][referenceColumn].afectado = True
		except IndexError as e:
			b = True
			break
	b = False
	#rigth (afect)
	referenceRow = row;#Asignacion de los indices
	while(b == False):
		referenceColumn += 1 #Se decrementa las los indices
		try:
			tablero[referenceRow][referenceColumn].afectado = True
		except IndexError as e:
			b = True
	b = False
	#up-left (afect)
	referenceRow = row; referenceColumn = column #Asignacion de los indices
	while(b == False):
		referenceRow -=1; referenceColumn -= 1 #Se decrementa las los indices
		try:
			tablero[referenceRow][referenceColumn].afectado = True
		except IndexError as e:
			b = True
	b = False
	#up-rigth (afect)
	referenceRow = row; referenceColumn = column #Asignacion de los indices
	while(b == False):
		referenceRow +=1; referenceColumn += 1 #Se decrementa las los indices
		try:
			tablero[referenceRow][referenceColumn].afectado = True
		except IndexError as e:
			b = True
			break
	b = False
	#down-left (afect)
	referenceRow = row; referenceColumn = column #Asignacion de los indices
	while(b == False):
		referenceRow +=1; referenceColumn -= 1 #Se incrementan las los indices
		try:
			tablero[referenceRow][referenceColumn].afectado = True
		except IndexError as e:
			b = True
			break
	b = False
	#down-rigth (afect)
	referenceRow = row; referenceColumn = column #Asignacion de los indices
	while(b == False):
		referenceRow +=1; referenceColumn += 1 #Se decrementa las los indices
		try:
			tablero[referenceRow][referenceColumn].afectado = True
		except IndexError as e:
			b = True
			break
 
#Bucle principal
while(solucionado()):
	num_libres = casillasLibres() #Asigna a num_libres el numero de casillas vacias que hay en el tablero
	bel = 't'
	while(reinas > 0):
		for i in range(8):
			for j in range(8):
				#Caso de casilla libre
				if(tablero[i][j].getAfectado()==False and tablero[i][j].getReina()==False):
					tablero[i][j].setReina(True) #Se pone una reina en la casilla
					afectarCasillas(i,j) #Afecta todas las casillas relacionadas con la casilla actual
					reinas -= 1 #Disminuye el numero de reinas que faltan
				else:
					num_libres = casillasLibres() #Asigna el numero de casillas libres
					if(num_libres > reinas):
						bel = 'f'
						primerPos = primeraReina() #Asigna en un string los indices en el que se encuentra la primera reina
						break
			if(bel == 'f'):
				break
		if(bel == 'f'):
			break
	if(bel == 'f'):
		reinicializacionTablero()
		fil = int(primerPos[0])
		col = int(primerPos[1])
		tablero[fil][col].setAfectado(True);
		reinas = 8
	else:
		continue
 
def imprimiendoSolucion():
	print("SOLUCION: ")
	for i in range(0,8):
		for j in range(0,8):
			if(tablero[i][j].getReina()):
				print(" [R] ",end="")
			else:
				print(" [ ] ",end="")
		print(""); print("")
imprimiendoSolucion() #Imprime toda la solcion de la matriz

Un resumen de lo que hace el programa:
Lo que hace el programa es crear una clase casilla que va contener la variable booleana 'afectado' que indica si la casilla está amenazada por una reina, otra variable también booleana llamada 'reina' que indica si hay una reina en el objeto 'casilla' que la contiene.
Después revisa casilla por casilla mirando si no esta afectada por una reina y si no tiene una reina para poder poner una. Cuando pone una, afecta(cambia el valor 'afectado' del objeto casilla a 'True') todas las casillas que están involucradas con esa casilla que contiene la reina para que en esas casillas no se pueda poner una reina.
Bueno ya saben, así hasta que ya allá puesto todas las reinas. Ah! bueno una cosa, si el numero de casillas libres es menor al numero de reinas que faltan por poner, significa que la estructura de reinas que hay ahora en el tablero esta mal, entonces lo que hace es afectar(cambia el valor 'afectado' del objeto casilla a 'True') la primera casilla con una reina que tiene esa estructura y después reinicia todas las casillas al los valores por defecto false, exceptuando la casilla ya explicada anteriormente para que la siguiente estructura de reinas que se coloque no sea igual a la anterior y así puedo ir probando todos los casos hasta encontrar la solución.
Si no lo entendieron, estudien un poco más mi código así podrán entenderlo un poquito mejor. ¡Saludos!
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