! 8 - Reinas
! Resuelve el problema de colocar 8 reinas en un
! tablero de ajedrez sin que ninguna de ellas esté
! en jaque.
!
! jbgarcia@uvigo.es
object Resolutor8Reinas
attribute - vReinas = Nothing
method + setTablero ( v )
vReinas = v
return
endMethod
method + abs ( x )
x.isLessThan ( 0 )
jumpOnFalseTo fin
x = x.multiplyBy ( -1 )
:fin
return x
endMethod
method + estaBienPuesta ( reina )
reference i = 0
reference aux = 0
reference aux2 = 0
reference toret = False
reina.isEqualTo ( 0 )
jumpOnFalseTo Loop
toret = True
jumpOnTrueTo fin
:Loop
! Primera comparación v[i] == v[j]
aux = vReinas.get ( i )
aux2 = vReinas.get ( reina )
aux.isEqualTo ( aux2 )
jumpOnTrueTo fin
! Primer lado de la comparación i-j
aux = reina.substract ( i )
aux = __this.abs ( aux )
! Segundo lado de la comparación v[i]-v[j]
aux2 = vReinas.get ( reina )
aux2 = aux2.substract ( vReinas.get ( i ) )
aux2 = __this.abs ( aux2 )
! Segunda comparación |i-j| == |v[i]-v[j]|
aux2.isEqualTo ( aux )
jumpOnTrueTo fin
! Incrementar
i = i.sum ( 1 )
i.isLessThan ( reina )
jumpOnTrueTo Loop
toret = True
:fin
return toret
endMethod
method + resuelve ( lin )
reference col = 0
reference max = vReinas.size ( )
reference toret = False
max = max.substract ( 1 )
:Loop
! Poner la reina en esta columna
vReinas.put ( lin col )
__this.estaBienPuesta ( lin )
jumpOnFalseTo endif
lin.isEqualTo ( max )
jumpOnFalseTo else
toret = True
jumpOnTrueTo fin
:else
toret = __this.resuelve ( lin.sum ( 1 ) )
jumpOnTrueTo fin
:endif
col = col.sum ( 1 )
col.isGreaterThan ( max )
jumpOnFalseTo Loop
:fin
return toret
endMethod
method + toString ( )
reference i = 0
reference toret = ""
reference elem
! Resolver el juego
__this.resuelve ( 0 )
jumpOnTrueTo Loop
! No hay solución
toret = "No hay solución"
vReinas = Nothing
jumpOnTrueTo fin
:Loop
! Mostrar la solución
i = i.sum ( 1 )
toret = toret.concat ( "Reina en fila " )
toret = toret.concat ( i.toString ( ) )
toret = toret.concat ( " colocada en columna " )
elem = vReinas.get ( i.substract ( 1 ) )
toret = toret.concat ( elem.toString ( ) )
toret = toret.concat ( "\n" )
i.isEqualTo ( vReinas.size ( ) )
jumpOnFalseTo Loop
:fin
return toret
endMethod
endObject
object Reinas8App
method + doIt ( )
reference i = 0
reference reinas = VectorInstance.copy ( "" )
:Loop
reinas.add ( 0 )
i = i.sum ( 1 )
i.isLessThan ( 8 )
jumpOnTrueTo Loop
Resolutor8Reinas.setTablero ( reinas )
System.console.write ( "8 Reinas\n" )
System.console.write ( Resolutor8Reinas.toString ( ) )
System.console.lf ( )
return
endMethod
endObject