Juego de gato ¿invensible? en Ruby

Recientemente me he interesado en Ruby, así que para ir practicando decidí programar el juego de gato (tres en raya, tic-tac-toe, etc.) utilizando Ruby 1.9.

Debo aclarar que es lo primero que desarrollo en Ruby y seguramente el código se puede optimizar mucho, ya que no dudo que haya cosas que se puedan hacer de una mejor forma, así que desde ahora ofrezco una disculpa a los expertos en Ruby que pudieran leer este post, espero ir mejorando en Ruby conforme vaya adquiriendo más experiencia con este lenguaje de programación.

Aquí el código

#       gato.rb
#       
#       Copyright 2010 SALOMON RINCON TORRES <rtmex@yahoo.com>
#       
#       This program is free software; you can redistribute it and/or modify
#       it under the terms of the GNU General Public License as published by
#       the Free Software Foundation; either version 2 of the License, or
#       (at your option) any later version.
#       
#       This program is distributed in the hope that it will be useful,
#       but WITHOUT ANY WARRANTY; without even the implied warranty of
#       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#       GNU General Public License for more details.
#       
#       You should have received a copy of the GNU General Public License
#       along with this program; if not, write to the Free Software
#       Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
#       MA 02110-1301, USA.


#!/usr/bin/ruby1.9

tablero = Array.new(3){Array.new(3)}
opcion = "-1"
caracter_usuario = nil
caracter_prog = nil
tira_usuario = 1
casillas_disponibles = (1..9).to_a
gana_programa = 0
opcion_programa = 0

def imprime_tablero(t)
    num = 1
    for i in 0..2 do
        print "#{num}|#{num+1}|#{num+2}   "
        for j in 0..2 do
            if j < 2 then
               if t[j][i]==nil then
                  print " "+"|"
               else
                   print t[j][i].to_s+"|"
               end
            else 
                print t[j][i]         
            end
        end
        puts
        num = num+3
        if i < 2 then
           5.times { |linea| print "-" }
           3.times { |linea| print " " }
           5.times { |linea| print "-" }
        end
        puts
    end
    
    return 
end

# Tira al azar en una esquina disponible
def tira_esquina(disp)
    opcion = 0
    esquina_seleccionada = 0
    # Tira al azar en una esquina, se basa en cuatro opciones:
    # opcion 1 será la esquina superior izquierda
    # opcion 2 será la esquina superior derecha
    # opcion 3 será la esquina inferior izquierda
    # opcion 4 será la esquina inferior derecha
    while not disp.include?(esquina_seleccionada)
          opcion = rand(4)+1
          case opcion
               when 1 then esquina_seleccionada = 1
               when 2 then esquina_seleccionada = 3
               when 3 then esquina_seleccionada = 7
               when 4 then esquina_seleccionada = 9
          end          
    end    
    
    return esquina_seleccionada
end

# Verifica en que casilla debe tirar quién este jugando con el caracter que recibe como parámetro
# para ganar horizontalmente
def gana_horizontal(caracter, t)
    tiros_hechos = 0
    contador = 0
    columna = -1
    fila = 0
    ganador_en = 0
        
    # El siguiente ciclo termina cuando se hayan recorrido todos los renglónes o se haya encontrado
    # un renglón en donde se han hecho dos tiros
    while contador <= 2 and tiros_hechos < 2
        for j in 0..2 do            
            if t[j][contador]==caracter then 
               tiros_hechos = tiros_hechos+1            
            elsif t[j][contador]==nil
                  columna = j
            end
        end
        # Si en el renglón actual había dos tiros y una casilla vacía, ahi se debe tirar para ganar
        if tiros_hechos == 2 and columna >= 0 then
           fila = contador           
        else
            tiros_hechos = 0
            columna = -1
            contador = contador + 1
        end
    end
        
    if tiros_hechos == 2 then
       case fila
            when 0 then
                   # Significa que se encontró un tiro ganador en el primer renglón
                   ganador_en = columna + 1                
            when 1 then
                   # Significa que se encontró un tiro ganador en el segundo renglón
                   ganador_en = columna + 4
            when 2 then
                   # Significa que se encontró un tiro ganador en el tercer renglón
                   ganador_en = columna + 7
       end       
    end
        
    return ganador_en
end

# Verifica en que casilla debe tirar quién este jugando con el caracter que recibe como parámetro
# para ganar verticalmente
def gana_vertical(caracter, t)
    tiros_hechos = 0
    contador = 0
    columna = 0
    fila = -1
    ganador_en = 0
        
    # El siguiente ciclo termina cuando se hayan recorrido todos los renglónes o se haya encontrado
    # un renglón en donde se han hecho dos tiros
    while contador <= 2 and tiros_hechos < 2
        for j in 0..2 do            
            if t[contador][j]==caracter then 
               tiros_hechos = tiros_hechos+1            
            elsif t[contador][j]==nil
                  fila = j
            end
        end
        # Si en la columna actual había dos tiros y una casilla vacía, ahi se debe tirar para ganar
        if tiros_hechos == 2 and fila >= 0 then
           columna = contador
        else
            tiros_hechos = 0
            fila = -1
            contador = contador + 1
        end
    end
        
    if tiros_hechos == 2 then
       case fila
            when 0 then
                   # Significa que se encontró un tiro ganador en el primer renglón
                   ganador_en = columna + 1                
            when 1 then
                   # Significa que se encontró un tiro ganador en el segundo renglón
                   ganador_en = columna + 4
            when 2 then
                   # Significa que se encontró un tiro ganador en el tercer renglón
                   ganador_en = columna + 7
       end
    end
        
    return ganador_en
end

# Verifica en que casilla debe tirar quién este jugando con el caracter que recibe como parámetro
# para ganar diagonalmente
def gana_diagonal(caracter, t)
    tirosd1 = 0
    tirosd2 = 0
    contador = 0    
    fila1 = -1
    fila2 = -1
    ganador_en = 0
    diagonal_1 = [0,1,2]
    diagonal_2 = [2,1,0]
        
    # El siguiente ciclo termina cuando se hayan recorrido todos los renglónes o se haya encontrado
    # que se han hecho dos tiros en una de las 2 diagonales diagonal
    while contador <= 2
          # Checa si hay un tiro a la casilla correspondiente en la diagonal 1
          if t[diagonal_1.at(contador)][contador]==caracter then 
             tirosd1 = tirosd1+1            
          elsif t[diagonal_1.at(contador)][contador]==nil
                fila1 = contador
          end
          
          # Checa si hay un tiro a la casilla correspondiente en la diagonal 2
          if t[diagonal_2.at(contador)][contador]==caracter then 
             tirosd2 = tirosd2+1            
          elsif t[diagonal_2.at(contador)][contador]==nil
                fila2 = contador
          end
          
          contador = contador+1
    end
        
    if tirosd1 == 2 and fila1>=0 then
       # Significa que se encontró el tiro ganador en la diagonal 1       
       case fila1
            when 0 then
                   # Significa que se encontró el tiro ganador en el primer renglón
                   ganador_en = 1                
            when 1 then
                   # Significa que se encontró el tiro ganador en el segundo renglón
                   ganador_en = 5
            when 2 then
                   # Significa que se encontró el tiro ganador en el tercer renglón
                   ganador_en = 9
       end
    elsif tirosd2 == 2 and fila2>=0 then
          # Significa que se encontró el tiro ganador en la diagonal 2          
          case fila2
               when 0 then
                    # Significa que se encontró el tiro ganador en el primer renglón
                    ganador_en = 3                
               when 1 then
                    # Significa que se encontró el tiro ganador en el segundo renglón
                    ganador_en = 5
               when 2 then
                    # Significa que se encontró el tiro ganador en el tercer renglón
                    ganador_en = 7
          end          
    end
    
    return ganador_en
end

def renglon_tirou(t, c_usuario)
    conta = 0
    renglones = Array.new
    
    for i in 0..2 do
        conta = 0
        for j in 0..2 do
            if t[j][i]==c_usuario then 
               conta = conta+1
            end            
        end
        if conta > 0 then
           renglones << i
        end
    end
    
    return renglones
end

# Ejecuta el tiro del programa
def tiro_programa(disp, c_programa, t, c_usuario)
    veces_tiradas = 0
    espacios = 0
    renglon_seleccionado = -1
    columna = -1
    tiro = 0
    gana = 0
    tiros_en_renglon = 0
    tiros_en_columna = 0
    tiros_usario = 0
    esquina_opuesta_ocupada = 1    
    # Crea un array con las 4 esquinas en que puede intentar tirar
    esquinas_intentadas = [1,3,7,9]
    # Elimina del array las esquinas que no están disponibles
    esquinas_intentadas.delete_if {|elemento| not disp.include?(elemento)}    
        
    # Verifica cuántas veces ha tirado el programa
    for i in 0..2 do        
        for j in 0..2 do
            if t[j][i]==c_programa then 
               veces_tiradas = veces_tiradas+1
            end            
        end
    end
        
    if veces_tiradas == 0 then
       # Primero intenta tirar al centro
       if disp.include?(5) then
          tiro = 5
       else
           # Tira al azar en una esquina         
           tiro = tira_esquina(disp)
       end
    else
        # Verifica si hay una casilla en la cual el programa gana horizontalmente y si es asi tira en ella
        tiro = gana_horizontal(c_programa, t)
        if tiro == 0 then
           # Significa que el programa no gana horizontalmente tirando en alguna casilla           
           # Verifica si hay una casilla en la cual el programa gana verticalmente y si es asi tira en ella
           tiro = gana_vertical(c_programa, t)
           if tiro == 0 then
              # Significa que el programa no gana verticalmente tirando en alguna casilla
              # Verifica si hay una casilla en la cual el programa gana diagonalmente y si es asi tira en ella
              tiro = gana_diagonal(c_programa, t)
              if tiro == 0 then
                 # Significa que el programa no gana diagonalmente tirando en alguna casilla
                 # Entónces checa si el usuario gana diagonalmente tirando en alguna casilla y si es asi lo bloquea
                 tiro = gana_diagonal(c_usuario, t)
                 if tiro == 0
                    # Significa que el usuario no gana diagonalmente tirando en alguna casilla
                    # Entónces checa si el usuario gana horizontalmente tirando en alguna casilla y si es asi lo bloquea
                    tiro = gana_horizontal(c_usuario, t)
                    if tiro == 0 then
                       # Significa que el usuario no gana horizontalmente tirando en alguna casilla
                       # Entónces checa si el usuario gana verticalmente tirando en alguna casilla y si es asi lo bloquea
                       tiro = gana_vertical(c_usuario, t)
                       if tiro == 0 then
                          # Significa que el usuario no gana verticalmente tirando en alguna casilla
                          # Si todas las esquinas están disponibles, tira en alguna de ellas
                          if esquinas_intentadas.length==4 then
                             tiro = tira_esquina(disp)
                          end
                          # Si hay 3 esquinas disponibles,
                          # busca tirar en una esquina correspondiente a un renglón y columna
                          # en donde el usuario ya había tirado y que la esquina opuesta esté vacía
                          if esquinas_intentadas.length==3 and disp.count<7  then
                             begin
                                 tiro = tira_esquina(disp)
                                 case tiro
                                      when 1,3 then
                                           if renglon_tirou(t, c_usuario).include?(0) then
                                              if tiro == 1 then
                                                 if disp.include?(9) and t[0].index(c_usuario) then
                                                    renglon_seleccionado=0
                                                 end
                                              else
                                                  if disp.include?(7) and t[2].index(c_usuario) then
                                                     renglon_seleccionado=0
                                                  end
                                              end
                                           end
                                      when 7,9 then
                                           if renglon_tirou(t, c_usuario).include?(2) then
                                              if tiro == 7 then
                                                 if disp.include?(3) and t[0].index(c_usuario) then
                                                    renglon_seleccionado=2
                                                 end
                                              else
                                                  if disp.include?(1) and t[2].index(c_usuario) then
                                                     renglon_seleccionado=2
                                                  end
                                              end
                                           end
                                 end
                             end until renglon_seleccionado>=0  
                          elsif tiro==0 then
                                # Entónces busca tirar en el renglón en donde el programa haya tirado el mayor número de veces
                                # o el renglón con el mayor número de casillas disponibles
                                casillas_disponibles = []
                                tiros_programa = []
                                max_disponibles = nil
                                max_tiros_programa = nil
                                 
                                # Guarda en el arreglo casillas_disponibles, el número de casillas disponibles
                                # para cada renglón, primero el número de casillas disponibles para el renglón 0
                                # después el número de casillas disponibles para el renglón 1 y al final
                                # el número de casillas disponibles para el renglón 2
                                # Guarda en el arreglo tiros_programa, el número de veces que el programa ha tirado
                                # en cada renglón, primero el número de veces en el renglón 0
                                # después el número de veces en el renglón 1 y al final
                                # el número de veces en el renglón 2
                                for i in 0..2 do
                                    espacios = 0
                                    veces_tiradas = 0
                                    for j in 0..2 do
                                        case t[j][i]
                                             when nil then espacios = espacios+1
                                             when c_programa then veces_tiradas = veces_tiradas+1
                                        end
                                    end
                                    casillas_disponibles.push(espacios)
                                    tiros_programa.push(veces_tiradas)
                                end
                                
                                # Guarda en la variable nmax_casillas_disp el número máximo de casillas disponibles
                                nmax_casillas_disp = casillas_disponibles.max
                                # Guarda en la variable max_disponibles el renglón en donde hay más casillas disponibles
                                max_disponibles = casillas_disponibles.index(casillas_disponibles.max)
                                # Busca si hay otro renglón que tenga el mismo número de casillas disponibles
                                # y que además el programa ya haya tirado en ese renglón previamente
                                max_disponibles_preferido = nil
                                for i in 0..2 do
                                    if casillas_disponibles[i] == nmax_casillas_disp then
                                       for j in 0..2 do
                                           if t[j][i] == c_programa then
                                              max_disponibles_preferido = i
                                              break
                                           end
                                       end
                                    end
                                end
                                
                                # Guarda en la variable max_tiros_programa el renglón en donde el programa ha tirado más veces
                                max_tiros_programa = tiros_programa.index(tiros_programa.max)
                                
                                if max_disponibles_preferido then
                                   renglon_seleccionado = max_disponibles_preferido
                                   for i in 0..2 do
                                       if t[i][renglon_seleccionado] == nil then
                                          columna = i
                                          break
                                       end
                                   end
                                else
                                    # Entónces busca tirar en la columna en donde el programa haya tirado el mayor número de veces
                                    # o la columna con el mayor número de casillas disponibles
                                    casillas_disponibles = []
                                    tiros_programa = []
                                    max_disponibles = nil
                                    max_tiros_programa = nil
                                    
                                    # Guarda en el arreglo casillas_disponibles, el número de casillas disponibles
                                    # para cada columna, primero el número de casillas disponibles para la columna 0
                                    # después el número de casillas disponibles para la columna 1 y al final
                                    # el número de casillas disponibles para la columna 2
                                    for i in 0..2 do
                                        casillas_disponibles.push(t[i].count(nil))
                                    end
                                    # Guarda en la variable max_disponibles la columna en donde hay más casillas disponibles
                                    max_disponibles = casillas_disponibles.index(casillas_disponibles.max)
                                    
                                    # Guarda en el arreglo tiros_programa, el número de veces que el programa ha tirado
                                    # en cada columna, primero el número de veces en la columna 0
                                    # después el número de veces en la columna 1 y al final
                                    # el número de veces en la columna 2
                                    for i in 0..2 do
                                        tiros_programa.push(t[i].count(c_programa))
                                    end
                                    # Guarda en la variable max_tiros_programa la columna en donde el programa ha tirado más veces
                                    max_tiros_programa = tiros_programa.index(tiros_programa.max)
                                      
                                    if t[max_tiros_programa].index(nil) and tiros_programa.uniq.count>1 then
                                       # Selecciona la columna en donde el programa ha tirado más veces
                                       columna = max_tiros_programa
                                    else
                                        # Como en todas las columnas el programa ha tirado igual número de veces
                                        # selecciona la columna con mas casillas disponibles
                                        columna = max_disponibles
                                    end                                 
                                    
                                    renglon_seleccionado = t[columna].index(nil)
                                end
                                
                                case renglon_seleccionado
                                     when 0 then tiro = columna+1
                                     when 1 then tiro = columna+4
                                     when 2 then tiro = columna+7
                                end
                          end
                       end
                    end
                 end
              else
                  gana = 1
              end
           else
               gana = 1
           end
        else
            gana = 1
        end
    end
    return tiro, gana
end

# Mientras que la opción seleccionada por el usuario no esté en el rango de 0 a 2,
# el programa seguirá pidiendo que seleccione un aopción
while not (0..2).include?(opcion.to_i)
   # Pregunta al usuario que caracter desea usar (X ó O)
   puts "Seleccione el caracter que desea usar para jugar o pulse [0] para salir."
   puts "[1] = X, [2] = O"
   
   opcion = gets.chomp    
   if opcion == "1" then
      caracter_usuario = "X"
      caracter_prog = "O"
   elsif opcion == "2"
       caracter_usuario = "O"
       caracter_prog = "X"
   end
end

if opcion != "0" then
   puts
   opcion = "-1"
   # Pregunta al usuario si quiere tirar primero
   while not (0..2).include?(opcion.to_i)
         puts "Indique quien debe tirar primero o pulse [0] para salir."
         puts "[1] = Tira primero Ud., [2] = Tira primero el programa"
   
         opcion = gets.chomp    
         tira_usuario = opcion == "1" ? 1: 0
   end
   
   while opcion != "0"
         if tira_usuario == 0 and not casillas_disponibles.empty? then
            opcion_programa, gana_programa = tiro_programa(casillas_disponibles, caracter_prog, tablero, caracter_usuario)
            case opcion_programa
                 when 1 then tablero[0][0] = caracter_prog
                 when 2 then tablero[1][0] = caracter_prog
                 when 3 then tablero[2][0] = caracter_prog
                 when 4 then tablero[0][1] = caracter_prog
                 when 5 then tablero[1][1] = caracter_prog
                 when 6 then tablero[2][1] = caracter_prog
                 when 7 then tablero[0][2] = caracter_prog
                 when 8 then tablero[1][2] = caracter_prog
                 when 9 then tablero[2][2] = caracter_prog
            end 
            # Elimina del array casillas_disponibles la posición en donde tiró el programa
            casillas_disponibles.delete(opcion_programa)            
            # Indica que le toca tirar al usuario
            tira_usuario = 1
         end
         puts imprime_tablero(tablero)
         
         if casillas_disponibles.empty? or gana_programa == 1 then
            # Como ya no hay casillas disponibles para tirar o ya ganó el progama, termina el programa
            if gana_programa == 1 then
               print "Gana el programa!"
            else
                print "No hay ganador!"
            end
            puts
            opcion = "0"
         else
             print "Pulse el numero en donde desea tirar o [0] para salir"
             puts
             # Espera a que el usuario seleccione en donde desea tirar         
             opcion = gets.chomp
             if opcion != "0" then            
                # Verifica que el usuaruo haya indicado una casilla vacia
                if casillas_disponibles.include?(opcion.to_i) then
                   case opcion
                        when "1" then tablero[0][0] = caracter_usuario
                        when "2" then tablero[1][0] = caracter_usuario
                        when "3" then tablero[2][0] = caracter_usuario
                        when "4" then tablero[0][1] = caracter_usuario
                        when "5" then tablero[1][1] = caracter_usuario
                        when "6" then tablero[2][1] = caracter_usuario
                        when "7" then tablero[0][2] = caracter_usuario
                        when "8" then tablero[1][2] = caracter_usuario
                        when "9" then tablero[2][2] = caracter_usuario
                   end
                   # Elimina del array casillas_disponibles la posición en donde tiró el usuario
                   casillas_disponibles.delete(opcion.to_i)
                   # Indica que le toca tirar al programa
                   tira_usuario = 0
                end
             end
         end
   end
end

Etiquetas: , ,

7 comentarios to “Juego de gato ¿invensible? en Ruby”

  1. Juego de gato ¿invensible? en Ruby | GNU/Linux Puebla Says:

    […] https://salomonrt.wordpress.com/2010/04/03/juego-de-gato-%C2%BFinvensible-en-ruby/ blog comments powered by Disqus var disqus_url = […]

  2. oscar Says:

    aaaaaa

  3. El juego de gato en Ruby ahora para Web « Código Fuente Says:

    […] un post anterior (https://salomonrt.wordpress.com/2010/04/03/juego-de-gato-%C2%BFinvensible-en-ruby/) puse el código fuente del juego de gato en Ruby, dicho programa hay que ejecutarlo desde la […]

  4. Douglas Says:

    No se si esto continue viviendo pero tiene un bug….

    De echo, he conseguido ganar pero en realidad gana el programa gracias a este bug

    Te comento…

    Llega el momento en el que tengo 2 posibilidades de completar el tercio con 1 movimiento o jugada al mismo tiempo asi que la maquina no podra impedir el tercio… a esto le llamo doble filo

    En el turno del programa impide mi tercio con su jugada, liberando mi tecnica maxima

    Es mi turno y como mencione tenia 2 posiblidades y al perder 1 me quede con mi movimiento final.

    Pero en vez de ganar, el programa sigue su curso y es el turno del programa que, en vez de impedir mi jugada final, hace su jugada y gana el juego, ESTANDO MI TERCIO YA COMPLETADO…

    Es como si no hiciera el calculo de que ya tengo el tercio completado y siguiera su curso normalmente…

    Ahora entiendo por que dice ¿invensible?.

    Quisiera que lo arreglaras por favor….

    Te muestro el proceso.

    “Seleccione el caracter que desea usar para jugar o pulse [0] para salir.
    [1] = X, [2] = O
    1

    Indique quien debe tirar primero o pulse [0] para salir.
    [1] = Tira primero Ud., [2] = Tira primero el programa
    1
    1|2|3 | |
    —– —–
    4|5|6 | |
    —– —–
    7|8|9 | |

    Pulse el numero en donde desea tirar o [0] para salir
    5
    1|2|3 | |O
    —– —–
    4|5|6 |X|
    —– —–
    7|8|9 | |

    Pulse el numero en donde desea tirar o [0] para salir
    7
    1|2|3 |O|O
    —– —–
    4|5|6 |X|
    —– —–
    7|8|9 X| |

    Pulse el numero en donde desea tirar o [0] para salir
    1
    1|2|3 X|O|O
    —– —–
    4|5|6 |X|
    —– —–
    7|8|9 X| |O

    Pulse el numero en donde desea tirar o [0] para salir
    4
    1|2|3 X|O|O
    —– —–
    4|5|6 X|X|O
    —– —–
    7|8|9 X| |O

    Gana el programa!
    => nil

    • rtmex Says:

      En cuanto tenga tiempo lo reviso, para poder reproducir el error y arreglarlo, Gracias

    • rtmex Says:

      Efectivamente pude reproducir el caso que mencionas, el error estaba en que antes de checar el caso en que el programa debe buscar tirar en una esquina que no sea diagonalmente opuesta a una esquina en la que haya tirado el usuario y además verificar que la esquina seleccionada se encuentre en un renglón en donde ya haya tirado el usuario (si existe este caso y no se tira en esta esquina, el usuario gana en el próximo tiro) se estaba buscando tirar en una casilla disponible en el renglón en donde el programa hubiera ejecutado más tiros, si no se encontraba, entónces buscaba una casilla disponible en una columna en dónde el programa hubiera ejecutado más tiros.

      Ya quedó en el orden correcto, es decir:
      1. Checar si hay una casilla en donde el programa puede tirar para ganar, si la encuentra, tira ahí
      2. Si no hay una casilla en donde el usuario pueda ganar, checa si hay una casilla en donde el usuario puede tirar para ganar
      3. Si se encuentra una casilla en donde el usuario puede tirar para ganar, entónces el programa lo bloquea
      4. El programa debe buscar tirar en una esquina que no sea diagonalmente opuesta a una esquina en la que haya tirado el usuario y además verificar que la esquina seleccionada se encuentre en un renglón en donde ya haya tirado el usuario (si existe este caso y no se tira en esta esquina, el usuario gana en el próximo tiro)
      5. Busca tirar en el renglón que cumpla lo siguiente:
      – Haya mayor número de casillas disponibles
      – El usuario no ha tirado en ese renglón
      – El programa ya había tirado previamente en ese renglón
      6. Busca tirar en la columna que cumpla lo siguiente:
      – Haya mayor número de casillas disponibles
      – El usuario no ha tirado en esa columna
      – El programa ya había tirado previamente en esa columna

      El error estaba en que se estaban ejecutando los pasos 5 y 6 antes que el 4
      Tendré que corregir también la versión para web, ya que seguramente tiene el mismo error, espero tener tiempo la próxima semana

      Saludos y gracias por detectar el bug.

  5. rtmex Says:

    He modificado el código, ahora tiene menos líneas, así que en algunos comentarios anteriores aparece código que ya no está en esta nueva versión.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s


A %d blogueros les gusta esto: