¿Cómo entrenar una red neuronal artificial para jugar a Diablo 2 con entrada visual?

139

Actualmente estoy tratando de obtener un ANN para jugar un videojuego y esperaba obtener ayuda de la maravillosa comunidad aquí.

Me decidí por Diablo 2. El juego es en tiempo real y desde un punto de vista isométrico, con el jugador controlando un solo avatar en el que se centra la cámara.

Para hacer las cosas concretas, la tarea es conseguir que tu personaje x puntos de experiencia sin que su salud caiga a 0, donde el punto de experiencia se gana matando monstruos. Aquí hay un ejemplo de la jugabilidad:

aquí

Ahora, dado que quiero que la red opere basándose únicamente en la información que obtiene de los píxeles en la pantalla, debe aprender una representación muy rica para jugar de manera eficiente, ya que esto presumiblemente requeriría que supiera (al menos implícitamente) cómo divide el mundo del juego en objetos y cómo interactuar con ellos.

Y toda esta información debe enseñarse a la red de alguna manera. Por mi vida no puedo pensar en cómo entrenar a esta cosa. Mi única idea es tener un programa separado para extraer visualmente algo innatamente bueno / malo en el juego (por ejemplo, salud, oro, experiencia) de la pantalla, y luego usar esa estadística en un procedimiento de aprendizaje de refuerzo. Creo que eso será parte de la respuesta, pero no creo que sea suficiente; Hay demasiados niveles de abstracción desde la información visual sin procesar hasta el comportamiento orientado a objetivos para que una retroalimentación tan limitada entrene una red en mi vida.

Entonces, mi pregunta: ¿en qué otras formas se te ocurre entrenar una red para hacer al menos una parte de esta tarea? preferiblemente sin hacer miles de ejemplos etiquetados.

Solo por un poco más de dirección: estoy buscando otras fuentes de aprendizaje de refuerzo y / o cualquier método no supervisado para extraer información útil en este entorno. O un algoritmo supervisado si puede pensar en una forma de obtener datos etiquetados de un mundo de juegos sin tener que etiquetarlos manualmente.

ACTUALIZACIÓN (27/04/12):

Curiosamente, todavía estoy trabajando en esto y parece que estoy progresando. El mayor secreto para hacer que funcione un controlador ANN es utilizar las arquitecturas ANN más avanzadas apropiadas para la tarea. Por lo tanto, he estado usando una red de creencias profunda compuesta de máquinas de Boltzmann restringidas condicionadas y factorizadas que he entrenado de manera no supervisada (en un video de mí jugando el juego) antes de ajustar con propagación de diferencia temporal (es decir, aprendizaje de refuerzo con estándar ANNs de retroalimentación).

Sin embargo, todavía busco información más valiosa, especialmente sobre el problema de la selección de acciones en tiempo real y cómo codificar imágenes en color para el procesamiento de ANN :-)

ACTUALIZACIÓN (21/10/15):

Recién recuerdo que hice esta pregunta en el pasado, y pensé que debería mencionar que esto ya no es una idea loca. Desde mi última actualización, DeepMind publicó su artículo sobre cómo conseguir que las redes neuronales jueguen juegos de Atari desde entradas visuales . De hecho, lo único que me impide usar su arquitectura para jugar, un subconjunto limitado, de Diablo 2 es la falta de acceso al motor de juego subyacente. Renderizar a la pantalla y luego redirigirlo a la red es demasiado lento para entrenar en un período de tiempo razonable. Por lo tanto, probablemente no veremos este tipo de bot jugando Diablo 2 en el corto plazo, sino solo porque jugará algo de código abierto o con acceso API al destino de representación. (¿Temblor tal vez?)

zergylord
fuente
1
Mira este artículo. : D ri.cmu.edu/pub_files/pub2/pomerleau_dean_1992_1/…
zergylord
Una gran diferencia entre el problema de manejo en el periódico y un juego es que en el problema de manejo la entrada visual es una representación de estado suficientemente completa: si hay un obstáculo a la derecha - gire a la izquierda, si hay un obstáculo a la izquierda - gire Derecha. Sin embargo, en un juego, a menudo tienes que tomar decisiones basadas en cosas que no se muestran en la pantalla. Cada vez que ingresa a una tienda, puede verse igual, pero necesita comprar diferentes artículos.
Don Reba
1
Para ser lo mejor de mi recuerdo, Diablo 2 utiliza láminas de sprites fácilmente extraíbles. Debería ser bastante simple vincular objetos (jugador, enemigos, etc.) a una lista de sprites asociados. No resuelve el problema de los objetos que se oscurecen entre sí, pero es un comienzo.
Ryan Jenkins
@zergylord Sería útil si pudiera decir con qué firmeza desea mantener sus criterios de a) Jugar Diablo 2 yb) usar píxeles dibujados en la pantalla como su única fuente de entrada. Si quieres hacerte las cosas más fáciles, creo que tendrás que relajarte un poco (o ambos), ¿estás dispuesto a hacerlo?
Stompchicken
1
Votar para cerrar como demasiado amplio.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Respuestas:

54

Puedo ver que te preocupa cómo entrenar al ANN, pero este proyecto esconde una complejidad de la que quizás no seas consciente. El reconocimiento de objetos / personajes en los juegos de computadora a través del procesamiento de imágenes es una tarea muy desafiante (no es una locura para los juegos FPS y RPG). No dudo de sus habilidades y tampoco digo que no se pueda hacer, pero puede pasar 10 veces más tiempo trabajando en el reconocimiento de cosas que implementando el ANN (suponiendo que ya tenga experiencia con técnicas de procesamiento de imágenes digitales ). )

Creo que tu idea es muy interesante y también muy ambiciosa. . En este punto, es posible que desee reconsiderarlo. Siento que este proyecto es algo que estás planeando para la universidad, por lo que si el enfoque del trabajo es realmente ANN, probablemente deberías elegir otro juego, algo más simple.

Recuerdo que alguien más vino a buscar consejos sobre un proyecto diferente pero de alguna manera similar no hace mucho tiempo. Vale la pena echarle un vistazo.

Por otro lado, puede haber enfoques mejores / más fáciles para identificar objetos en el juego si acepta sugerencias. Pero primero, llamemos a este proyecto por lo que quieres que sea: un robot inteligente .

Un método para implementar bots accede a la memoria del cliente del juego para encontrar información relevante, como la ubicación del personaje en la pantalla y su estado de salud. Leer la memoria de la computadora es trivial, pero descubrir exactamente dónde buscar en la memoria no lo es. Los escáneres de memoria como Cheat Engine pueden ser muy útiles para esto.

Otro método , que funciona bajo el juego, consiste en manipular la información de representación. Todos los objetos del juego deben mostrarse en la pantalla. Esto significa que las ubicaciones de todos los objetos 3D eventualmente se enviarán a la tarjeta de video para su procesamiento. Prepárate para una depuración seria.

En esta respuesta, describí brevemente 2 métodos para lograr lo que desea mediante el procesamiento de imágenes. Si está interesado en ellos, puede encontrar más información sobre ellos en Explotar juegos en línea (capítulo 6), un excelente libro sobre el tema.

karlphillip
fuente
43

ACTUALIZACIÓN 2018-07-26: ¡ Eso es! ¡Ahora nos estamos acercando al punto en que este tipo de juego será solucionable! Usando OpenAI y basado en el juego DotA 2, un equipo podría hacer una IA que pueda vencer a los jugadores semiprofesionales en un juego 5v5 . Si conoces DotA 2, sabes que este juego es bastante similar a los juegos de Diablo en términos de mecánica, pero se podría argumentar que es aún más complicado debido al juego en equipo.

Como se esperaba, esto se logró gracias a los últimos avances en el aprendizaje por refuerzo con aprendizaje profundo, y al uso de marcos de juego abiertos como OpenAI que facilita el desarrollo de una IA ya que obtienes una API ordenada y también porque puedes acelerar el juego (la IA jugó ¡el equivalente a 180 años de juego contra sí mismo todos los días!).

El 5 de agosto de 2018 (¡en 10 días!) , Se planea enfrentar a esta IA contra los mejores jugadores de DotA 2. Si esto funciona, espera una gran revolución, tal vez no tan mediatizada como la resolución del juego Go, ¡pero sin embargo será un gran hito para los juegos de IA!

ACTUALIZACIÓN 2017-01: El campo se está moviendo muy rápido desde el éxito de AlphaGo, y hay nuevos marcos para facilitar el desarrollo de algoritmos de aprendizaje automático en los juegos casi todos los meses. Aquí hay una lista de los últimos que he encontrado:

  • OpenAI's Universe : una plataforma para jugar prácticamente cualquier juego utilizando el aprendizaje automático . La API está en Python, y ejecuta los juegos detrás de un entorno de escritorio remoto VNC, por lo que puede capturar las imágenes de cualquier juego. ¡Probablemente puedas usar Universe para jugar a Diablo II a través de un algoritmo de aprendizaje automático!
  • OpenAI's Gym : similar al Universo pero apuntando a algoritmos de aprendizaje de refuerzo específicamente (por lo que es una especie de generalización del marco utilizado por AlphaGo pero para muchos más juegos). Hay un curso sobre Udemy que cubre la aplicación del aprendizaje automático a juegos como breakout o Doom usando OpenAI Gym.
  • TorchCraft : un puente entre Torch (marco de aprendizaje automático) y StarCraft: Brood War.
  • pyGTA5 : un proyecto para construir autos sin conductor en GTA5 usando solo capturas de pantalla (con muchos videos en línea ).

Tiempos muy emocionantes!

ACTUALIZACIÓN IMPORTANTE (2016-06): Como señaló OP, este problema de entrenar redes artificiales para jugar usando solo entradas visuales ahora está siendo abordado por varias instituciones serias, con resultados bastante prometedores, como DeepMind Deep-Qlearning-Network (DQN ) .

Y ahora, si desea asumir el desafío del siguiente nivel, puede usar una de las diversas plataformas de desarrollo de juegos de visión de IA como ViZDoom , una plataforma altamente optimizada (7000 fps) para entrenar redes para jugar Doom usando solo entradas visuales :

ViZDoom permite desarrollar bots de IA que juegan Doom usando solo la información visual (el búfer de pantalla). Está destinado principalmente a la investigación en aprendizaje visual de máquinas, y aprendizaje de refuerzo profundo, en particular. ViZDoom se basa en ZDoom para proporcionar la mecánica del juego.

Y los resultados son bastante sorprendentes, ¡ mira los videos en su página web y el bonito tutorial (en Python) aquí!

También hay un proyecto similar para Quake 3 Arena, llamado Quagents , que también proporciona un fácil acceso API a los datos subyacentes del juego, pero puede eliminarlo y solo usar capturas de pantalla y la API solo para controlar a su agente.

¿Por qué es útil esta plataforma si solo usamos capturas de pantalla? Incluso si no accede a los datos subyacentes del juego, dicha plataforma proporciona:

  • Implementación de juegos de alto rendimiento (¡puede generar más generaciones de datos / juegos / aprendizaje con menos tiempo para que sus algoritmos de aprendizaje puedan converger más rápido!).
  • una API simple y receptiva para controlar a sus agentes (es decir, si intenta usar entradas humanas para controlar un juego, algunos de sus comandos pueden perderse, por lo que también lidiaría con la falta de confiabilidad de sus salidas ...).
  • Fácil configuración de escenarios personalizados .
  • renderizado personalizable (puede ser útil para "simplificar" las imágenes que obtienes para facilitar el procesamiento)
  • reproducción sincronizada ("paso a paso") (por lo que no necesita que su algoritmo funcione en tiempo real al principio, es una gran reducción de la complejidad).
  • características de conveniencia adicionales, como compatibilidad de plataforma cruzada, retrocompatibilidad (no corres el riesgo de que tu bot ya no funcione con el juego cuando hay una nueva actualización del juego), etc.

En resumen, lo mejor de estas plataformas es que alivian gran parte de los problemas técnicos anteriores con los que tuvo que lidiar (cómo manipular las entradas del juego, cómo configurar escenarios, etc.) para que solo tenga que lidiar con el algoritmo de aprendizaje sí mismo.

Así que ahora, ponte a trabajar y conviértenos en el mejor robot visual de IA de la historia;)


Publicación anterior que describe los problemas técnicos del desarrollo de una IA que se basa solo en entradas visuales:

Al contrario de algunos de mis colegas anteriores, no creo que este problema sea insoluble. ¡Pero sin duda es muy difícil!

El primer problema como se señaló anteriormente es el de la representación del estado del juego. : no puedes representar el estado completo con una sola imagen, necesitas mantener algún tipo de memorización(salud pero también objetos equipados y elementos disponibles para usar, misiones y objetivos, etc.). Para obtener dicha información, tiene dos formas: acceder directamente a los datos del juego, que es el más confiable y fácil; o bien puede crear una representación abstracta de estas informaciones mediante la implementación de algunos procedimientos simples (abrir inventario, tomar una captura de pantalla, extraer los datos). Por supuesto, extraer datos de una captura de pantalla tendrá que poner algún procedimiento supervisado (que defina completamente) o sin supervisión (a través de un algoritmo de aprendizaje automático, pero luego aumentará mucho la complejidad ...). Para el aprendizaje automático no supervisado, deberá utilizar un tipo bastante reciente de algoritmos llamados algoritmos de aprendizaje estructural (que aprenden la estructura de los datos en lugar de cómo clasificarlos o predecir un valor).http://techtalks.tv/talks/54422/

Entonces, otro problema es que, incluso cuando ha obtenido todos los datos que necesita, el juego solo es parcialmente observable . Por lo tanto, debe inyectar un modelo abstracto del mundo y alimentarlo con información procesada del juego, por ejemplo, la ubicación de su avatar, pero también la ubicación de elementos de búsqueda, objetivos y enemigos fuera de la pantalla. Quizás pueda buscar en los filtros de partículas de mezcla de Vermaak 2003 para esto.

Además, debe tener un agente autónomo , con objetivos generados dinámicamente. Una arquitectura conocida que puede probar es el agente BDI, pero probablemente tendrá que modificarla para que esta arquitectura funcione en su caso práctico. Como alternativa, también existe la Red de Petri Recursiva, que probablemente puede combinar con todo tipo de variaciones de las redes de Petri para lograr lo que desea, ya que es un marco muy bien estudiado y flexible, con excelentes procedimientos de formalización y pruebas.

Y, por último, incluso si haces todo lo anterior, deberás encontrar una manera de emular el juego a velocidad acelerada (usar un video puede ser bueno, pero el problema es que tu algoritmo solo funcionará sin control y podrá intentarlo por sí mismo es muy importante para aprender). De hecho, es bien sabido que el algoritmo actual de última generación requiere mucho más tiempo para aprender lo mismo que un humano puede aprender (aún más con el aprendizaje de refuerzo), por lo tanto, si no puede acelerar el proceso ( es decir, si no puedes acelerar el tiempo del juego), tu algoritmo ni siquiera convergerá en una sola vida ...

Para concluir, lo que quiere lograr aquí está en el límite (y tal vez un poco más allá) de los algoritmos de vanguardia actuales . Creo que puede ser posible, pero incluso si lo es, vas a pasar mucho tiempo , porque este no es un problema teórico sino un problema práctico que estás abordando aquí, y por lo tanto necesitas implementar y combinar mucho de diferentes enfoques de IA para resolverlo.

Es posible que varias décadas de investigación con todo un equipo trabajando en él no sean suficientes, por lo que si está solo y trabajando en él a tiempo parcial (ya que probablemente tenga un trabajo para ganarse la vida) puede pasar toda una vida sin llegar a ningún lado Una solución de trabajo.

Entonces, mi consejo más importante aquí es que baje sus expectativas y trate de reducir la complejidad tu problema sea utilizar toda la información que puedas y evitar la mayor cantidad posible de capturas de pantalla (es decir, intenta conectarte directamente al juego, busca la inyección de DLL) y simplifica un poco problemas al implementar procedimientos supervisados, no permita que su algoritmo aprenda todo (es decir, descarte el procesamiento de imágenes por el momento tanto como sea posible y confíe en la información interna del juego, más adelante si su algoritmo funciona bien, puede reemplazar algunas partes de su programa de IA con procesamiento de imágenes, logrando así su objetivo completo, por ejemplo, si puede lograr que algo funcione bastante bien, puede intentar complicar su problema y reemplazar los procedimientos supervisados ​​y los datos del juego de memoria por algoritmos de aprendizaje automático no supervisados ​​en las capturas de pantalla).

¡Buena suerte, y si funciona, asegúrate de publicar un artículo, seguramente podrás ser reconocido por resolver un problema tan difícil y práctico!

gaborous
fuente
27

El problema que persigue es insoluble en la forma en que lo ha definido. Suele ser un error pensar que una red neuronal aprendería "mágicamente" una rica representación de un problema. Un buen hecho a tener en cuenta al decidir si ANN es la herramienta adecuada para una tarea es que es un método de interpolación. Piense si puede enmarcar su problema para encontrar una aproximación de una función, donde tiene muchos puntos de esta función y mucho tiempo para diseñar la red y capacitarla.

El problema que propone no pasa esta prueba. El control del juego no es una función de la imagen en la pantalla. Hay mucha información que el jugador tiene que guardar en la memoria. Por un simple ejemplo, a menudo es cierto que cada vez que ingresas a una tienda en un juego, la pantalla se ve igual. Sin embargo, lo que compra depende de las circunstancias. No importa cuán complicada sea la red, si los píxeles de la pantalla son su entrada, siempre realizará la misma acción al ingresar a la tienda.

Además, está el problema de la escala. La tarea que propone es simplemente demasiado complicada para aprender en un período de tiempo razonable. Deberías ver aigamedev.com para ver cómo funciona la IA del juego. Las redes neuronales artificiales se han utilizado con éxito en algunos juegos, pero de manera muy limitada. El juego AI es difícil y a menudo costoso de desarrollar. Si hubiera un enfoque general de la construcción de redes neuronales funcionales, la industria probablemente lo habría aprovechado. Le recomiendo que comience con ejemplos mucho, mucho más simples, como tic-tac-toe.

Don reba
fuente
Lo suficientemente justo. Se podría llamar a casi cualquier cosa que se parezca a una red como ANN, pero difícilmente podría conducir a una discusión sustantiva. :)
Don Reba
Je, sí ... Debería haber explicado mi motivación con más profundidad. Sé que hay mejores formas de hacer IA de juegos, pero estoy haciendo esto para superar los límites del simulador ANN que he estado actualizando. Ver: stanford.edu/group/pdplab/pdphandbook
zergylord
1
En cualquier caso, Don Reba tiene razón, yo tampoco creo que sea factible aprender una estrategia para algo como Diablo sin incorporar muchos conocimientos previos y extraer características útiles en las que se pueda basar un enfoque de aprendizaje de refuerzo. Simplemente aprender de la entrada de video será extremadamente difícil, si no imposible, usando las computadoras de hoy.
ahans 01 de
18

Parece que el corazón de este proyecto es explorar lo que es posible con un ANN, por lo que sugeriría elegir un juego en el que no tenga que lidiar con el procesamiento de imágenes (que según las respuestas de otros aquí, parece un tarea realmente difícil en un juego en tiempo real). Puedes usar la API de Starcraft para construir tu bot, te dan acceso a todos los estados relevantes del juego.

http://code.google.com/p/bwapi/

tstramer
fuente
2

Como primer paso, puede observar la diferencia de fotogramas consecutivos. Tienes que distinguir entre el fondo y los sprites de monstruos reales. Supongo que el mundo también puede contener animaciones. Para encontrarlos, haría que el personaje se moviera y recogiera todo lo que se mueve con el mundo en una gran imagen de fondo / animación.

Podrías detectar e identificar enemigos con correlación (usando FFT). Sin embargo, si las animaciones repiten exactamente el píxel, será más rápido solo mirar unos pocos valores de píxel. Su tarea principal será escribir un sistema robusto que identifique cuándo aparece un nuevo objeto en la pantalla y gradualmente todos los cuadros del cuadro sprite a una base de datos. Probablemente también tengas que construir modelos para efectos de armas. Esas latas se deben restar para que no desordenen la base de datos de tu oponente.

whoplisp
fuente
2
Al estar familiarizado con el juego Diablo II, puedo decir que usa 256 colores (a menos que algún modo use color alto o verdadero). También hace un uso intensivo de sprites para mostrar diferentes objetos. Si puede extraer algunos sprites (incluso de la captura de pantalla), puede entrenar su herramienta para reconocer objetos basados ​​en el sprite (por ejemplo, una 'Poción de curación menor' caída siempre se verá igual). Sin embargo, si profundizo en las cosas específicas de Diablo II, surgirán más preguntas también. Buena suerte
Ivaylo Slavov
1

Bueno, suponiendo que en cualquier momento podría generar un conjunto de 'resultados' (podría implicar probabilidades) a partir de un conjunto de todos los 'movimientos' posibles, y que existe alguna noción de consistencia en el juego (por ejemplo, puede jugar el nivel X una y otra vez nuevamente), puede comenzar con N redes neuronales con pesos aleatorios y hacer que cada una de ellas juegue de la siguiente manera:

1) Para cada 'movimiento' posible, genere una lista de 'resultados' posibles (con probabilidades asociadas) 2) Para cada resultado, use su red neuronal para determinar un 'valor' (puntaje) asociado del 'resultado' (por ejemplo, un número entre -1 y 1, siendo 1 el mejor resultado posible, -1 siendo el peor) 3) Elija el 'movimiento' que conduzca a la puntuación más alta de prob * 4) Si el movimiento condujo a una 'victoria' o 'pérdida', detente, de lo contrario vuelve al paso 1.

Después de una cierta cantidad de tiempo (o un 'ganar' / 'perder'), evalúe qué tan cerca estaba la red neuronal del 'objetivo' (esto probablemente involucrará cierto conocimiento del dominio). Luego deseche el 50% (o algún otro porcentaje) de NN que estaban más lejos de la meta, haga un cruce / mutación del 50% superior y vuelva a ejecutar el nuevo conjunto de NN. Continúe corriendo hasta que salga un NN satisfactorio.

tstramer
fuente
Ah, agregar un GA a la mezcla, interesante. Desafortunadamente, dado que la red realmente envía pulsaciones de teclas / movimientos del mouse como acciones, necesitaría una computadora física por red>. <Otro problema es que el espacio de estado del entorno no es discreto (bueno, técnicamente lo es, pero en un grano muy fino) Por ejemplo, imagine el posible resultado asociado con un clic del mouse: un personaje bajo el control de la red podría moverse o atacar, pero los enemigos también podrían moverse, y habría diferencias de píxeles en el entorno de cosas como sombras y efectos climáticos. .
zergylord 01 de
Bueno, desde mi perspectiva, hay mucho que puedes hacer con una red neuronal. Parece que, en el mejor de los casos, podría usarse como una función heurística aprendible de alguna noción de un espacio de estado discreto. Para incorporar la variabilidad del enemigo, probablemente tendría que usar alguna otra heurística, luego podría usarla para crear un conjunto de posibles estados de resultado por movimiento con probabilidades asociadas. Además, siempre que haya una noción estática de configuración inicial y final, puede ejecutar cada red neuronal de una en una.
tstramer 01 de
1

Creo que su mejor opción sería una arquitectura compleja que involucre algunas redes / mayo: es decir, una que reconozca y responda a elementos, una para la tienda, otra para el combate (tal vez aquí necesitaría una para el reconocimiento del enemigo, una para los ataques), etc. .

Luego intenta pensar en el juego de Diablo II más simple posible, probablemente un bárbaro. Luego, manténgalo simple al principio, como el Acto I, solo en la primera área.

Entonces supongo que los 'objetivos' valiosos serían la desaparición de los objetos enemigos y la disminución de la barra de salud (puntuación inversa).

Una vez que tenga estas tareas separadas y "más simples" atendidas, puede usar un ANN "maestro" para decidir qué sub-ANN activar.

En cuanto a la capacitación, solo veo tres opciones: podría usar el método evolutivo descrito anteriormente, pero luego debe seleccionar manualmente los 'ganadores', a menos que codifique un programa completamente separado para eso. Podrías hacer que las redes 'vean' a alguien jugar. Aquí aprenderán a emular el estilo de un jugador o grupo de jugadores. La red intenta predecir la próxima acción del jugador, se refuerza para una suposición correcta, etc. Si realmente obtienes el ANN que deseas, esto podría hacerse con videojuegos, sin necesidad de un juego en vivo real. Finalmente, puedes dejar que la red juegue, teniendo muertes enemigas, subiendo de nivel, recuperando salud, etc. como refuerzo positivo y muertes de jugadores, salud perdida, etc. como refuerzo negativo. Pero viendo cómo incluso una red simple requiere miles de pasos de capacitación concretos para aprender incluso tareas simples,

En general, su proyecto es muy ambicioso. Pero por mi parte, creo que podría "en teoría hacerse", con tiempo suficiente.

Espero que ayude y buena suerte!

Vincent Courtemanche
fuente