domingo, 1 de febrero de 2015

El viaje del caballo por mesoamérica

(es) El viaje del caballo por Mesoamérica

(eo) Ĉevalvojaĝo tra Mezameriko

El viaje del caballo por Mesoamérica

http://dx.doi.org/10.13140/RG.2.2.34092.90243

Descripción artística:

Es un tablero de ajedrez con una ruta del caballo escrita con números mayas.

Motivación:

El recuerdo de un programa desarrollado durante los años de juventud del autor... un programa que utiliza fuerza bruta para encontrar una ruta del caballo.

Descripción técnica:

Es una ruta del caballo escrita con números mayas, comenzando con se (uno) en la esquina inferior izquierda, luego ume (dos) dos casillas a la derecha y una arriba, luego yey (tres) dos casillas a la derecha y una abajo, … y así sucesivamente, hasta llegar a yey pual nawi (64) en la casilla abajo de la esquina superior derecha.

Archivos


Código de búsqueda de ruta (Python):

#!/usr/bin/env python
# coding: utf-8

# Copyright 2015 Eduardo Adam Navas López
# Este programa es Software Libre liberado bajo la licencia GNU GPLv3 o su versión más reciente:
# http://www.gnu.org/licenses/gpl.html

"""Búsqueda de una ruta de caballo válida.
"""

TAM = 8
#movimiento horario:
desplazamientos = [(1,-2),(2,-1),(2,1),(1,2),(-1,2),(-2,1),(-2,-1),(-1,-2)]

def imprimir():
 global matriz
 for i in range(TAM):
  for j in range(TAM):
   print "{: 3}".format(matriz[i][j]),
  print
 print "--------"
 #raw_input("Presione una tecla para continuar")

def buscarRuta(y,x,contador):
 """Busca recursivamente una ruta viable."""
 global matriz
 
 #imprimir()
 
 if contador==TAM*TAM+1:
  return True
 
 i=0
 while i < len(desplazamientos):
  dx,dy = desplazamientos[i]
  if x+dx>=0 and x+dx<TAM and y+dy>=0 and y+dy<TAM and matriz[y+dy][x+dx]==0:
   #Es viable
   matriz[y+dy][x+dx]=contador
   if buscarRuta(y+dy,x+dx,contador+1):
    break
   else:
    matriz[y+dy][x+dx]=0
  i = i+1
 if i == len(desplazamientos):
  return False
 return True
  

if __name__ == "__main__":
 global matriz
 
 matriz = []
 for i in range(TAM):
  L = []
  for j in range(TAM):
   L.append(0)
  matriz.append(L)
 
 i = 0
 j = 0
 matriz[i][j]=1
 if buscarRuta(i,j,2):
  f = open("ruta8.txt","w")
  for i in range(TAM):
   for j in range(TAM):
    f.write("{: 3}".format(matriz[i][j]))
   f.write("\n")
  f.close()
  print "Solución encontrada:"
  imprimir()
  f = open("ruta8.cfdg","w")
  f.write("#Archivo: ruta8.cfdg\n#Este archivo intermedio fue generado por el programa caballo.py\n")
  for i in range(TAM):
   for j in range(TAM):
    f.write("R{}x = {}\n".format(matriz[i][j],j))
    f.write("R{}y = {}\n".format(matriz[i][j],i))
  f.close()
  
 else:
  print "No hay solución"

Código intermedio (CFDG):

#Archivo: ruta8.cfdg
#Este archivo intermedio fue generado por el programa caballo.py
R1x = 0
R1y = 0
R38x = 1
R38y = 0
R55x = 2
R55y = 0
R34x = 3
R34y = 0
R3x = 4
R3y = 0
R36x = 5
R36y = 0
R19x = 6
R19y = 0
R22x = 7
R22y = 0
R54x = 0
R54y = 1
R47x = 1
R47y = 1
R2x = 2
R2y = 1
R37x = 3
R37y = 1
R20x = 4
R20y = 1
R23x = 5
R23y = 1
R4x = 6
R4y = 1
R17x = 7
R17y = 1
R39x = 0
R39y = 2
R56x = 1
R56y = 2
R33x = 2
R33y = 2
R46x = 3
R46y = 2
R35x = 4
R35y = 2
R18x = 5
R18y = 2
R21x = 6
R21y = 2
R10x = 7
R10y = 2
R48x = 0
R48y = 3
R53x = 1
R53y = 3
R40x = 2
R40y = 3
R57x = 3
R57y = 3
R24x = 4
R24y = 3
R11x = 5
R11y = 3
R16x = 6
R16y = 3
R5x = 7
R5y = 3
R59x = 0
R59y = 4
R32x = 1
R32y = 4
R45x = 2
R45y = 4
R52x = 3
R52y = 4
R41x = 4
R41y = 4
R26x = 5
R26y = 4
R9x = 6
R9y = 4
R12x = 7
R12y = 4
R44x = 0
R44y = 5
R49x = 1
R49y = 5
R58x = 2
R58y = 5
R25x = 3
R25y = 5
R62x = 4
R62y = 5
R15x = 5
R15y = 5
R6x = 6
R6y = 5
R27x = 7
R27y = 5
R31x = 0
R31y = 6
R60x = 1
R60y = 6
R51x = 2
R51y = 6
R42x = 3
R42y = 6
R29x = 4
R29y = 6
R8x = 5
R8y = 6
R13x = 6
R13y = 6
R64x = 7
R64y = 6
R50x = 0
R50y = 7
R43x = 1
R43y = 7
R30x = 2
R30y = 7
R61x = 3
R61y = 7
R14x = 4
R14y = 7
R63x = 5
R63y = 7
R28x = 6
R28y = 7
R7x = 7
R7y = 7

Código de dibujo (CFDG):

# Copyright 2015 Eduardo Adam Navas López
# Este archivo es Software Libre liberado bajo la licencia GNU GPLv3 o su versión más reciente:
# http://www.gnu.org/licenses/gpl.html

#Para generar la imagen:
#$ cfdg -b 0 -s 8000 caballo.cfdg caballo.png

TAMPUNTO = 0.15
TAMESPACIO = 0.2
NUMPUNTOSPORBARRA = 20

startshape caballo
CF::Impure = 1

#Aquí se encuentran las posiciones de cada uno de los números del viaje:
import@ruta ruta8.cfdg

shape caballo1{
 numero(20,1)[x 0 y 0]
 numero(40,0)[x 1 y 0]
 numero(60,1)[x 2 y 0]
}
shape caballo{
 numero( 1,mod(ruta::R1x  +ruta::R1y,2))[x ruta::R1x  y ruta::R1y]
 numero( 2,mod(ruta::R2x  +ruta::R2y,2))[x ruta::R2x  y ruta::R2y]
 numero( 3,mod(ruta::R3x  +ruta::R3y,2))[x ruta::R3x  y ruta::R3y]
 numero( 4,mod(ruta::R4x  +ruta::R4y,2))[x ruta::R4x  y ruta::R4y]
 numero( 5,mod(ruta::R5x  +ruta::R5y,2))[x ruta::R5x  y ruta::R5y]
 numero( 6,mod(ruta::R6x  +ruta::R6y,2))[x ruta::R6x  y ruta::R6y]
 numero( 7,mod(ruta::R7x  +ruta::R7y,2))[x ruta::R7x  y ruta::R7y]
 numero( 8,mod(ruta::R8x  +ruta::R8y,2))[x ruta::R8x  y ruta::R8y]
 numero( 9,mod(ruta::R9x  +ruta::R9y,2))[x ruta::R9x  y ruta::R9y]
 numero(10,mod(ruta::R10x+ruta::R10y,2))[x ruta::R10x y ruta::R10y]
 numero(11,mod(ruta::R11x+ruta::R11y,2))[x ruta::R11x y ruta::R11y]
 numero(12,mod(ruta::R12x+ruta::R12y,2))[x ruta::R12x y ruta::R12y]
 numero(13,mod(ruta::R13x+ruta::R13y,2))[x ruta::R13x y ruta::R13y]
 numero(14,mod(ruta::R14x+ruta::R14y,2))[x ruta::R14x y ruta::R14y]
 numero(15,mod(ruta::R15x+ruta::R15y,2))[x ruta::R15x y ruta::R15y]
 numero(16,mod(ruta::R16x+ruta::R16y,2))[x ruta::R16x y ruta::R16y]
 numero(17,mod(ruta::R17x+ruta::R17y,2))[x ruta::R17x y ruta::R17y]
 numero(18,mod(ruta::R18x+ruta::R18y,2))[x ruta::R18x y ruta::R18y]
 numero(19,mod(ruta::R19x+ruta::R19y,2))[x ruta::R19x y ruta::R19y]
 numero(20,mod(ruta::R20x+ruta::R20y,2))[x ruta::R20x y ruta::R20y]
 numero(21,mod(ruta::R21x+ruta::R21y,2))[x ruta::R21x y ruta::R21y]
 numero(22,mod(ruta::R22x+ruta::R22y,2))[x ruta::R22x y ruta::R22y]
 numero(23,mod(ruta::R23x+ruta::R23y,2))[x ruta::R23x y ruta::R23y]
 numero(24,mod(ruta::R24x+ruta::R24y,2))[x ruta::R24x y ruta::R24y]
 numero(25,mod(ruta::R25x+ruta::R25y,2))[x ruta::R25x y ruta::R25y]
 numero(26,mod(ruta::R26x+ruta::R26y,2))[x ruta::R26x y ruta::R26y]
 numero(27,mod(ruta::R27x+ruta::R27y,2))[x ruta::R27x y ruta::R27y]
 numero(28,mod(ruta::R28x+ruta::R28y,2))[x ruta::R28x y ruta::R28y]
 numero(29,mod(ruta::R29x+ruta::R29y,2))[x ruta::R29x y ruta::R29y]
 numero(30,mod(ruta::R30x+ruta::R30y,2))[x ruta::R30x y ruta::R30y]
 numero(31,mod(ruta::R31x+ruta::R31y,2))[x ruta::R31x y ruta::R31y]
 numero(32,mod(ruta::R32x+ruta::R32y,2))[x ruta::R32x y ruta::R32y]
 numero(33,mod(ruta::R33x+ruta::R33y,2))[x ruta::R33x y ruta::R33y]
 numero(34,mod(ruta::R34x+ruta::R34y,2))[x ruta::R34x y ruta::R34y]
 numero(35,mod(ruta::R35x+ruta::R35y,2))[x ruta::R35x y ruta::R35y]
 numero(36,mod(ruta::R36x+ruta::R36y,2))[x ruta::R36x y ruta::R36y]
 numero(37,mod(ruta::R37x+ruta::R37y,2))[x ruta::R37x y ruta::R37y]
 numero(38,mod(ruta::R38x+ruta::R38y,2))[x ruta::R38x y ruta::R38y]
 numero(39,mod(ruta::R39x+ruta::R39y,2))[x ruta::R39x y ruta::R39y]
 numero(40,mod(ruta::R40x+ruta::R40y,2))[x ruta::R40x y ruta::R40y]
 numero(41,mod(ruta::R41x+ruta::R41y,2))[x ruta::R41x y ruta::R41y]
 numero(42,mod(ruta::R42x+ruta::R42y,2))[x ruta::R42x y ruta::R42y]
 numero(43,mod(ruta::R43x+ruta::R43y,2))[x ruta::R43x y ruta::R43y]
 numero(44,mod(ruta::R44x+ruta::R44y,2))[x ruta::R44x y ruta::R44y]
 numero(45,mod(ruta::R45x+ruta::R45y,2))[x ruta::R45x y ruta::R45y]
 numero(46,mod(ruta::R46x+ruta::R46y,2))[x ruta::R46x y ruta::R46y]
 numero(47,mod(ruta::R47x+ruta::R47y,2))[x ruta::R47x y ruta::R47y]
 numero(48,mod(ruta::R48x+ruta::R48y,2))[x ruta::R48x y ruta::R48y]
 numero(49,mod(ruta::R49x+ruta::R49y,2))[x ruta::R49x y ruta::R49y]
 numero(50,mod(ruta::R50x+ruta::R50y,2))[x ruta::R50x y ruta::R50y]
 numero(51,mod(ruta::R51x+ruta::R51y,2))[x ruta::R51x y ruta::R51y]
 numero(52,mod(ruta::R52x+ruta::R52y,2))[x ruta::R52x y ruta::R52y]
 numero(53,mod(ruta::R53x+ruta::R53y,2))[x ruta::R53x y ruta::R53y]
 numero(54,mod(ruta::R54x+ruta::R54y,2))[x ruta::R54x y ruta::R54y]
 numero(55,mod(ruta::R55x+ruta::R55y,2))[x ruta::R55x y ruta::R55y]
 numero(56,mod(ruta::R56x+ruta::R56y,2))[x ruta::R56x y ruta::R56y]
 numero(57,mod(ruta::R57x+ruta::R57y,2))[x ruta::R57x y ruta::R57y]
 numero(58,mod(ruta::R58x+ruta::R58y,2))[x ruta::R58x y ruta::R58y]
 numero(59,mod(ruta::R59x+ruta::R59y,2))[x ruta::R59x y ruta::R59y]
 numero(60,mod(ruta::R60x+ruta::R60y,2))[x ruta::R60x y ruta::R60y]
 numero(61,mod(ruta::R61x+ruta::R61y,2))[x ruta::R61x y ruta::R61y]
 numero(62,mod(ruta::R62x+ruta::R62y,2))[x ruta::R62x y ruta::R62y]
 numero(63,mod(ruta::R63x+ruta::R63y,2))[x ruta::R63x y ruta::R63y]
 numero(64,mod(ruta::R64x+ruta::R64y,2))[x ruta::R64x y ruta::R64y]
}


shape numero(n,color){
 #color=0 : fondo blanco, frente negro
 #color=1 : fondo negro, frente blanco
 
 SQUARE[b color]
 
 if (n<20){
  numero20(n,color)[s 0.5]
 }else{
  if (n<400){
   numero20(floor(n/20),color)[y (TAMESPACIO*1.2) s 0.5]
   numero20(mod(n,20),color)[y (-TAMESPACIO*1.2) s 0.5]
  }else{
   cero(color)[b color]
  }
 }
}

shape numero20(n,color){
 #Caja:
 SQUARE[s (5*TAMESPACIO)      b (if(color,0,1))]
 SQUARE[s (5*TAMESPACIO*0.95) b color]
 
 
 if (n>=1 && n<5){
  numero_1_4(n)[b (if(color,0,1))]
 }else{
  if (n==5){
   numero_5[b (if(color,0,1))]
  }else{
   if (n>5 && n<10){
    numero_1_4(mod(n,5))[y (TAMESPACIO/2) b (if(color,0,1))]
    numero_5[y (-TAMESPACIO/2) b (if(color,0,1))]
   }else{
    if (n==10){
     numero_5[y (TAMESPACIO/2) b (if(color,0,1))]
     numero_5[y (-TAMESPACIO/2) b (if(color,0,1))]
    }else{
     if (n>10 && n<15){
      numero_1_4(mod(n,5))[y TAMESPACIO b (if(color,0,1))]
      numero_5[b (if(color,0,1))]
      numero_5[y (-TAMESPACIO) b (if(color,0,1))]
     }else{
      if (n==15){
       numero_5[y (TAMESPACIO) b (if(color,0,1))]
       numero_5[b (if(color,0,1))]
       numero_5[y (-TAMESPACIO) b (if(color,0,1))]
      }else{
       if (n>15 && n<20){
        numero_1_4(mod(n,5))[y (3*TAMESPACIO/2) b (if(color,0,1))]
        numero_5[y ( TAMESPACIO/2) b (if(color,0,1))]
        numero_5[y (-TAMESPACIO/2) b (if(color,0,1))]
        numero_5[y (-3*TAMESPACIO/2) b (if(color,0,1))]
       }else{ #Cero
        cero(color)[]
       }
      }
     }
    }
   }
  }
 }
}

fgrueso = 0.9

shape cero(color){
 CIRCLE[s (4*TAMESPACIO) (2*TAMESPACIO) b (if(color,0,1))]
 CIRCLE[s (4*TAMESPACIO*fgrueso) (2*TAMESPACIO*fgrueso) b color]
 
 transform[b (if(color,0,1)) s 0.5 ]{
  trazoCero1[]
  trazoCero2[y (0.1*TAMESPACIO)]
  trazoCero2[x (-1.5*TAMESPACIO) y (0.16*TAMESPACIO) s 1 0.85]
  trazoCero2[x (1.5*TAMESPACIO)  y (0.16*TAMESPACIO) s 1 0.85]
 }
}
path trazoCero1{
 MOVETO(-4*TAMESPACIO*fgrueso,0.5*TAMESPACIO*fgrueso)
 CURVETO(4*TAMESPACIO*fgrueso,0.5*TAMESPACIO*fgrueso, 0,-2*TAMESPACIO*fgrueso)
 STROKE(0.05,CF::RoundCap)[]
}
path trazoCero2{
 MOVETO(0,-0.8*TAMESPACIO*fgrueso)
 CURVETO(0,2*TAMESPACIO*fgrueso, -1.5*TAMESPACIO*fgrueso,0.5*TAMESPACIO*fgrueso)
 #STROKE(0.05,CF::SquareCap)[]
 STROKE(0.05,CF::ButtCap)[]
}

shape numero_1_4(n){
 if (mod(n,2)){
  punto[]
  loop i = n/2 []{
   punto[x (-TAMESPACIO*i)]
   punto[x ( TAMESPACIO*i)]
  }
 }else{
  loop i = n/2 []{
   punto[x (-TAMESPACIO/2-TAMESPACIO*i)]
   punto[x ( TAMESPACIO/2+TAMESPACIO*i)]
  }
 }
}

shape numero_5{
 loop i = NUMPUNTOSPORBARRA []{
  punto[x (-(3*TAMESPACIO/2)*i/(NUMPUNTOSPORBARRA-1))]
  punto[x ( (3*TAMESPACIO/2)*i/(NUMPUNTOSPORBARRA-1))]
 }
}

shape punto{
 CIRCLE[s TAMPUNTO]
}

No hay comentarios:

Publicar un comentario