{"id":6483,"date":"2023-05-05T14:08:11","date_gmt":"2023-05-05T12:08:11","guid":{"rendered":"https:\/\/blogs.etsii.urjc.es\/dseytr\/?p=6483"},"modified":"2023-05-05T17:51:47","modified_gmt":"2023-05-05T15:51:47","slug":"snake-io","status":"publish","type":"post","link":"https:\/\/blogs.etsii.urjc.es\/dseytr\/snake-io\/","title":{"rendered":"Snake.io"},"content":{"rendered":"\n<p><strong>Autores<\/strong>: Juan Carlos Moreno Garc\u00eda, Jhostin Davis Ortiz Moreno y Alessandro Nuzzi Herrero<\/p>\n\n\n\n<p>Grupo 7 \/ 2022-2023<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2023\/05\/IMG_5683-1-1-1024x768.jpg\" alt=\"\" class=\"wp-image-6490\" width=\"961\" height=\"721\" srcset=\"https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2023\/05\/IMG_5683-1-1-1024x768.jpg 1024w, https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2023\/05\/IMG_5683-1-1-300x225.jpg 300w, https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2023\/05\/IMG_5683-1-1-768x576.jpg 768w, https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2023\/05\/IMG_5683-1-1-1536x1152.jpg 1536w, https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2023\/05\/IMG_5683-1-1-2048x1536.jpg 2048w\" sizes=\"auto, (max-width: 961px) 100vw, 961px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Introducci\u00f3n<\/strong><\/h2>\n\n\n\n<p>El juego de la serpiente, o mejor conocido como <em>Snake Game<\/em>, es considerado un cl\u00e1sico desde su lanzamiento a mediados de la \u00e9poca de los 70s.<\/p>\n\n\n\n<p>Si bien es cierto que a d\u00eda de hoy es un juego muy simple y para algunos un poco m\u00e1s de lo que gustar\u00eda, muchos juegos interesantes han surgido a ra\u00edz de \u00e9l, entre ellos el conocido <em>slither.io<\/em>.<\/p>\n\n\n\n<p>Originalmente, pensamos en recrear el juego original y llevarlo a un sistema empotrado, pero en vista de que se convert\u00eda en un proyecto un tanto simple, decidimos a\u00f1adir nuevas funcionalidades. Nuestro proyecto se basa fuertemente en estas ideas y trata de llevar a una m\u00e1quina f\u00edsica lo que vemos como mero software en dispositivos m\u00f3viles y de sobremesa.<\/p>\n\n\n\n<p>Es por eso \u00faltimo que nuestra m\u00e1quina ofrece una experiencia \u00fanica, fruto de una idea que lleva con nosotros mucho tiempo pero con un toque m\u00e1s moderno y competitivo, el juego <em>snake.io<\/em> para dos jugadores.<\/p>\n\n\n\n<p>Para poder crear este juego, hemos necesitado componentes variados: matriz de LED RGB, joysticks anal\u00f3gicos, lector de tarjetas SD y altavoces, entre los componentes m\u00e1s destacados.<\/p>\n\n\n\n<p>A continuaci\u00f3n, se explicar\u00e1n m\u00e1s detenidamente las diferentes partes que juntas componen la totalidad del proyecto, pasando por los componentes hardware utilizados, el software que controla toda la l\u00f3gica del juego y todos los problemas que hemos afrontado, con nuestra forma de solucionarlos. A\u00f1adiremos tambi\u00e9n un apartado explicando las ideas a mejorar que nos han ido surgiendo por el camino y que finalmente no se han implementado, pero que en un futuro podr\u00edan ser factibles.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Desarrollo e Implementaci\u00f3n<\/strong><\/h2>\n\n\n\n<p>Para desarrollar la totalidad del proyecto, decidimos abordarlo de manera incremental, realizando peque\u00f1os avances, a\u00f1adiendo funcionalidades, probando y estudiando el comportamiento de cada uno de los diferentes componentes por separado\u2026hasta conseguir una versi\u00f3n final completamente funcional.&nbsp;<\/p>\n\n\n\n<p>Los pasos seguidos para implementar el juego han sido los siguientes::<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Selecci\u00f3n del hardware<\/strong>: Lo primero de todo fue decidir qu\u00e9 componentes \u00edbamos a utilizar para implementar el juego. En un principio pensamos en utilizar 4 pantallas led 8&#215;8, pero la gesti\u00f3n de estas era muy complicada, adem\u00e1s de que ocupar\u00edan la mayor\u00eda de salidas de la placa de Arduino y solo ten\u00edan un color, por lo que no se distinguir\u00edan f\u00e1cilmente las serpientes. Por ello, finalmente optamos por utilizar una matriz led rgb de 16&#215;16, que facilitaba mucho su uso y pod\u00edamos emplear varios colores.<\/li>\n\n\n\n<li><strong>Detectar el movimiento del joystick<\/strong>: Una vez elegidos los componentes, el primer paso fue conectar un joystick a la placa y estudiar su funcionamiento y los valores que le\u00eda en funci\u00f3n del movimiento, para poder as\u00ed crear una funci\u00f3n que determinara la direcci\u00f3n (arriba, abajo, izquierda o derecha).<\/li>\n\n\n\n<li><strong>Encender un led concreto<\/strong>: A continuaci\u00f3n, procedimos a estudiar el funcionamiento de la matriz led con el uso de la librer\u00eda recomendada. Fue en este punto donde nos dimos cuenta que la matriz era en realidad una tira de leds colocada de manera serpenteante, por lo que tuvimos que crear una funci\u00f3n que transformara la posici\u00f3n del led que quer\u00edamos encender dada en fila y columna, a la posici\u00f3n real del led.<\/li>\n\n\n\n<li><strong>Mover el led encendido por la pantalla<\/strong>: Una vez sab\u00edamos c\u00f3mo encender un led concreto en la pantalla, lo siguiente fue simular que ese led se moviera por la pantalla, encendiendo el siguiente led y apagando el anterior.<\/li>\n\n\n\n<li><strong>Mover el led en funci\u00f3n de la direcci\u00f3n del joystick<\/strong>: Acto seguido, conseguimos que el movimiento del led fuera en funci\u00f3n de la direcci\u00f3n marcada por el joystick.<\/li>\n\n\n\n<li><strong>Mover 2 leds de manera independiente con los joystick<\/strong>: Posteriormente, a\u00f1adimos un segundo joystick y encendimos otro led, consiguiendo que estos se movieran de manera independiente por la pantalla<\/li>\n\n\n\n<li><strong>A\u00f1adir el cuerpo de las serpientes<\/strong>: Con esto conseguido, el siguiente paso fue crear el <em>struct<\/em> que contiene la informaci\u00f3n de las serpientes y poder almacenar as\u00ed todas las posiciones que corresponden al cuerpo de cada serpiente. Para simular su movimiento, simplemente eliminamos la \u00faltima posici\u00f3n del cuerpo de la serpiente y a\u00f1adimos la nueva en funci\u00f3n de su direcci\u00f3n. Al inicio del juego, las serpientes tendr\u00e1n un tama\u00f1o de 5 posiciones.<\/li>\n\n\n\n<li><strong>Implementar la l\u00f3gica de ganador<\/strong>: En este punto el juego estaba casi terminado, por lo que procedimos a implementar la l\u00f3gica que indica cu\u00e1ndo un jugador ha ganado. Esto suceder\u00e1 \u00fanicamente cuando la cabeza de una de las serpientes se choque contra el cuerpo de la otra, siendo esta \u00faltima la ganadora. Mencionar que, en caso de que ambas serpientes choquen de frente, se establecer\u00e1 de manera aleatoria qui\u00e9n ha sido el ganador.<\/li>\n\n\n\n<li><strong>A\u00f1adir la l\u00f3gica de las manzanas<\/strong>: Para finalizar la l\u00f3gica del juego, simplemente faltaba a\u00f1adir las manzanas de manera aleatoria por la pantalla y, en caso de que una serpiente pase por esa posici\u00f3n, la serpiente aumentar\u00e1 de tama\u00f1o en una unidad. Para ello, simplemente no borramos la \u00faltima posici\u00f3n de la serpiente en esa iteraci\u00f3n.<\/li>\n\n\n\n<li><strong>A\u00f1adir m\u00fasica y sonidos<\/strong>: Una vez implementada toda la l\u00f3gica del juego, pasamos a a\u00f1adir la m\u00fasica de fondo y los sonidos de inicio, comer una manzana y fin del juego.<\/li>\n\n\n\n<li><strong>Empaquetar todo en una caja<\/strong>: Por \u00faltimo, dise\u00f1amos una caja con dos orificios para empaquetar todo, simulando una consola port\u00e1til con dos mandos.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Parte Hardware<\/strong><\/h2>\n\n\n\n<p>Para el desarrollo de este proyecto, hemos necesitado dos microcontroladores Arduino UNO, una matriz LED RGB de 16&#215;16, dos altavoces compatibles con Arduino, dos joysticks, un lector de tarjetas SD y cables para realizar las conexiones.<\/p>\n\n\n\n<p>Uno de los Arduino se ha utilizado para conectar los joysticks, la matriz LED y un altavoz. La funci\u00f3n de este microcontrolador era principalmente gestionar todo aquello relacionado con el juego, as\u00ed como los sonidos asociados a este.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2023\/05\/Captura-de-Pantalla-2023-05-05-a-las-13.54.14.png\" alt=\"\" class=\"wp-image-6503\" width=\"963\" height=\"956\" srcset=\"https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2023\/05\/Captura-de-Pantalla-2023-05-05-a-las-13.54.14.png 653w, https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2023\/05\/Captura-de-Pantalla-2023-05-05-a-las-13.54.14-300x298.png 300w, https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2023\/05\/Captura-de-Pantalla-2023-05-05-a-las-13.54.14-150x150.png 150w, https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2023\/05\/Captura-de-Pantalla-2023-05-05-a-las-13.54.14-80x80.png 80w\" sizes=\"auto, (max-width: 963px) 100vw, 963px\" \/><figcaption class=\"wp-element-caption\"><em>Dise\u00f1o hardware microcontrolador principal simulado en TinkerCad<\/em><\/figcaption><\/figure>\n\n\n\n<p>Por otro lado, el otro microcontrolador Arduino se ha utilizado para gestionar la m\u00fasica de fondo del juego. Se ha conectado el lector de tarjetas SD y uno de los dos altavoces. De esta manera, reproduce el archivo de m\u00fasica que tenga almacenado la tarjeta SD en el altavoz.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"896\" height=\"590\" src=\"https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2023\/05\/Captura-de-Pantalla-2023-05-05-a-las-13.56.58.png\" alt=\"\" class=\"wp-image-6504\" srcset=\"https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2023\/05\/Captura-de-Pantalla-2023-05-05-a-las-13.56.58.png 896w, https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2023\/05\/Captura-de-Pantalla-2023-05-05-a-las-13.56.58-300x198.png 300w, https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2023\/05\/Captura-de-Pantalla-2023-05-05-a-las-13.56.58-768x506.png 768w\" sizes=\"auto, (max-width: 896px) 100vw, 896px\" \/><figcaption class=\"wp-element-caption\"><em>Dise\u00f1o hardware microcontrolador de m\u00fasica simulado en TinkerCad<\/em><\/figcaption><\/figure>\n\n\n\n<p>Idealmente, se podr\u00eda haber hecho el mismo proyecto con un \u00fanico microcontrolador que incluyese cierto grado de concurrencia y permitiese la reproducci\u00f3n de m\u00fasica en paralelo al control del juego.<\/p>\n\n\n\n<p>Por \u00faltimo, mencionar que ambos microcontroladores son alimentados con pilas de 9V.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"768\" height=\"1024\" src=\"https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2023\/05\/IMG_5682-1-1-768x1024.jpg\" alt=\"\" class=\"wp-image-6505\" srcset=\"https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2023\/05\/IMG_5682-1-1-768x1024.jpg 768w, https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2023\/05\/IMG_5682-1-1-225x300.jpg 225w, https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2023\/05\/IMG_5682-1-1-1152x1536.jpg 1152w, https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2023\/05\/IMG_5682-1-1-1536x2048.jpg 1536w, https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2023\/05\/IMG_5682-1-1-scaled.jpg 1920w\" sizes=\"auto, (max-width: 768px) 100vw, 768px\" \/><figcaption class=\"wp-element-caption\"><em>Implementaci\u00f3n final<\/em><\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Materiales, costes y precios<\/strong><\/h2>\n\n\n\n<p>A continuaci\u00f3n se muestra una tabla con los materiales y componentes utilizados para la realizaci\u00f3n del proyecto, as\u00ed como su precio y el coste real que ha tenido sobre nosotros:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><strong>Nombre<\/strong><\/td><td><strong>Coste<\/strong><\/td><td><strong>Precio<\/strong><\/td><\/tr><tr><td>M\u00f3dulo Lector SD<\/td><td>5,49 \u20ac<\/td><td>5,49 \u20ac<\/td><\/tr><tr><td>2 Altavoces 3W<\/td><td>9,99 \u20ac<\/td><td>9,99 \u20ac<\/td><\/tr><tr><td>2 Pilas 9V<\/td><td>3,18 \u20ac<\/td><td>3,18 \u20ac<\/td><\/tr><tr><td>Matriz LED RGB 16&#215;16<\/td><td>20,00 \u20ac<\/td><td>28,99 \u20ac<\/td><\/tr><tr><td>2 Arduino Uno<\/td><td>&#8211;<\/td><td>20-30 \u20ac<\/td><\/tr><tr><td>1 Protoboard<\/td><td>&#8211;<\/td><td>4,79 \u20ac<\/td><\/tr><tr><td>1 Mini-Protoboard<\/td><td>&#8211;<\/td><td>2,33 \u20ac<\/td><\/tr><tr><td>2 Joystick<\/td><td>&#8211;<\/td><td>10 \u20ac<\/td><\/tr><tr><td>Cables<\/td><td>&#8211;<\/td><td>5 \u20ac<\/td><\/tr><tr><td>Pegamento<\/td><td>&#8211;<\/td><td>6,29 \u20ac<\/td><\/tr><tr><td>Pintura madera<\/td><td>&#8211;<\/td><td>4 \u20ac<\/td><\/tr><tr><td>Madera<\/td><td>&#8211;<\/td><td>10 \u20ac<\/td><\/tr><tr><td>Imanes<\/td><td>&#8211;<\/td><td>7,32&nbsp;\u20ac<\/td><\/tr><tr><td><strong>Total<\/strong><\/td><td>38,66 \u20ac<\/td><td>147,38 \u20ac<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Parte Software<\/strong><\/h2>\n\n\n\n<p>En cuanto al software del proyecto, mencionar que el c\u00f3digo est\u00e1 modularizado en peque\u00f1as funciones, evitando el c\u00f3digo repetido y favoreciendo la reutilizaci\u00f3n de c\u00f3digo, y est\u00e1 dise\u00f1ado para poder ser escalable. Esto es posible gracias a la creaci\u00f3n de un <em>struct<\/em> llamado <em>snake_t <\/em>que contiene toda la informaci\u00f3n necesaria de cada serpiente, como son su identificador, la posici\u00f3n de la cabeza, las posiciones del cuerpo, su color, el joystick asociado, la direcci\u00f3n, etc. Adem\u00e1s, contamos un con array de snakes, una por cada jugador (en este caso 2) y las funciones se encargan de recorrer este array, por lo que, en caso de aumentar el n\u00famero de jugadores, no ser\u00eda necesario modificar el c\u00f3digo.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>C\u00f3digo principal<\/strong><\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;Adafruit_NeoPixel.h&gt;\n#include &lt;LinkedList.h&gt;\n\n#ifdef __AVR__\n  #include &lt;avr\/power.h&gt;\n#endif\n\n\/\/ Struct that contains snake data\nstruct snake_t {\n  int id;\n  int read&#91;2] = {512, 512}; \/\/ Joystick read value\n  int joystick&#91;2]; \/\/ Joystick pins for X and Y axis\n  int head&#91;2]; \/\/ Snake head position (X, Y)\n  LinkedList&lt;int&gt; tail = LinkedList&lt;int&gt;(); \/\/ Snake tail positions, including head\n  uint32_t color;\n  uint32_t headColor;\n  char direction; \/\/ Snake direction\n};\n\nconst int SIDE = 16; \/\/ Matrix side\nconst int PLAYERS = 2; \/\/ Number of players\n\n\/\/ Dictionary used to calculate the real direction of the snake, taking into account that the movement of one snake is opposite to the other\nconst char DICT&#91;2]&#91;4] = {{'d', 'u', 'r', 'l'}, {'u', 'd', 'l', 'r'}};\n\nconst int LED_PIN = 3; \/\/ Output pin to LED matrix\nconst int SPEAKER_PIN = 9; \/\/ Output pin to speaker\n\nAdafruit_NeoPixel strip = Adafruit_NeoPixel(256, LED_PIN, NEO_GRB + NEO_KHZ800); \/\/ LED matrix object\n\n\/\/ Initial values for snakes\nconst int JOYSTICK_PINS_0&#91;2] = {A0, A1};\nconst int JOYSTICK_PINS_1&#91;2] = {A2, A3};\nconst int INITIAL_HEAD_POS_0&#91;2] = {0, 0};\nconst int INITIAL_HEAD_POS_1&#91;2] = {15, 15};\nconst int INITIAL_TAIL_0&#91;5] = {0, 1, 2, 3, 4};\nconst int INITIAL_TAIL_1&#91;5] = {240, 241, 242, 243, 244};\nconst uint32_t SNAKE_COLOR_0 = strip.Color(255, 0, 0);\nconst uint32_t SNAKE_COLOR_1 = strip.Color(0, 0, 255);\n\n\/\/ Numbers\nconst int RED_THREE&#91;13] = {89, 88, 87, 86, 73, 54, 56, 55, 41, 22, 25, 24, 23};\nconst int BLUE_THREE&#91;13] = {230, 231, 232, 233, 217, 198, 199, 200, 185, 166, 167, 168, 169};\nconst int RED_TWO&#91;14] = {89, 88, 87, 86, 73, 57, 56, 55, 54, 38, 25, 24, 23, 22};\nconst int BLUE_TWO&#91;14] = {230, 231, 232, 233, 214, 201, 198, 199, 200, 185, 166, 167, 168, 169};\nconst int RED_ONE&#91;10] = {23, 40, 55, 72, 87, 24, 39, 56, 71, 88};\nconst int BLUE_ONE&#91;10] = {168, 183, 200, 215, 232, 167, 184, 199, 216, 231};\n\n\/\/ WIN letters\nconst int RED_WIN&#91;23] = {\n  125, 130, 157, 99, 123, 101, 121, 134, 153,      \/\/ W\n  104, 119, 136, 151,                              \/\/ I\n  106, 117, 138, 149, 139, 115, 109, 114, 141, 146 \/\/ N\n};\nconst int BLUE_WIN&#91;23] = {\n  109, 114, 141, 147, 139, 149, 137, 118, 105,    \/\/ W\n  103, 120, 135, 152,                             \/\/ I\n  98, 125, 130, 157, 131, 123, 101, 122, 133, 154 \/\/ N\n};\n\n\/\/ Musical notes in 5 scales\nconst int C&#91;5] = {131, 262, 523, 1046, 2093};  \/\/ Do\nconst int CS&#91;5] = {139, 277, 554, 1108, 2217}; \/\/ Do#\nconst int D&#91;5] = {147, 294, 587, 1175, 2349};  \/\/ Re\nconst int DS&#91;5] = {156, 311, 622, 1244, 2489}; \/\/ Re#\nconst int E&#91;5] = {165, 330, 659, 1319, 2637};  \/\/ Mi\nconst int F&#91;5] = {175, 349, 698, 1397, 2794};  \/\/ Fa\nconst int FS&#91;5] = {185, 370, 740, 1480, 2960}; \/\/ Fa#\nconst int G&#91;5] = {196, 392, 784, 1568, 3136};  \/\/ Sol\nconst int GS&#91;5] = {208, 415, 831, 1661, 3322}; \/\/ Sol#\nconst int A&#91;5] = {220, 440, 880, 1760, 3520};  \/\/ La\nconst int AS&#91;5] = {233, 466, 932, 1866, 3729}; \/\/ La#\nconst int B&#91;5] = {247, 494, 988, 1976, 3951};  \/\/ Si\n\nsnake_t snakes&#91;PLAYERS];\nint winner;\nint apple;\nint delayValue;\n\nvoid setup() {\n  #if defined (__AVR_ATtiny85__)\n    if (F_CPU == 16000000) clock_prescale_set(clock_div_1);\n  #endif\n\n  randomSeed(analogRead(1));\n  strip.begin();\n  strip.setBrightness(100);\n  strip.show(); \n\n  setupInitialValues();\n}\n\nvoid setupInitialValues() {\n  setupSnake(&amp;snakes&#91;0], 0, JOYSTICK_PINS_0, INITIAL_HEAD_POS_0, INITIAL_TAIL_0, strip.Color(255, 0, 0), strip.Color(255, 0, 255), 'l');\n  setupSnake(&amp;snakes&#91;1], 1, JOYSTICK_PINS_1, INITIAL_HEAD_POS_1, INITIAL_TAIL_1, strip.Color(0, 0, 255), strip.Color(255, 0, 255), 'r');\n  delayValue = 200;\n  initialAnimation();\n  setApplePosition();\n  printApple();\n}\n\nvoid setupSnake(snake_t *snake, int id, int joystick&#91;2], int head&#91;2], int tail&#91;4], uint32_t color, uint32_t headColor, char direction) {\n  snake-&gt;id = id;\n  snake-&gt;joystick&#91;0] = joystick&#91;0];\n  snake-&gt;joystick&#91;1] = joystick&#91;1];\n  snake-&gt;head&#91;0] = head&#91;0];\n  snake-&gt;head&#91;1] = head&#91;1];\n\n  for (int i = 0; i &lt; 5; i++) {\n    snake-&gt;tail.add(tail&#91;i]);\n  }\n\n  snake-&gt;color = color;\n  snake-&gt;headColor = headColor;\n  snake-&gt;direction = direction;\n}\n\nvoid initialAnimation() {\n  \/\/ Red 3\n  for (int i = 0; i &lt; 13; i++) {\n    strip.setPixelColor(RED_THREE&#91;i], SNAKE_COLOR_0);\n  }\n  \/\/ Blue 3\n  for (int i = 0; i &lt; 13; i++) {\n    strip.setPixelColor(BLUE_THREE&#91;i], SNAKE_COLOR_1);\n  }\n  strip.show();\n  emitSound(E&#91;3], 100);\n  noTone(SPEAKER_PIN);\n  delay(900);\n  turnOffLeds();  \n\n  \/\/ Red 2\n  for (int i = 0; i &lt; 14; i++) {\n    strip.setPixelColor(RED_TWO&#91;i], SNAKE_COLOR_0);\n  }\n  \/\/ Blue 2\n  for (int i = 0; i &lt; 14; i++) {\n    strip.setPixelColor(BLUE_TWO&#91;i], SNAKE_COLOR_1);\n  }\n  strip.show();\n  emitSound(E&#91;3], 100);\n  noTone(SPEAKER_PIN);\n  delay(900);\n  turnOffLeds(); \n\n  \/\/ Red 1\n  for (int i = 0; i &lt; 10; i++) {\n    strip.setPixelColor(RED_ONE&#91;i], SNAKE_COLOR_0);\n  }\n  \/\/ Blue 1\n  for (int i = 0; i &lt; 10; i++) {\n    strip.setPixelColor(BLUE_ONE&#91;i], SNAKE_COLOR_1);\n  }\n  strip.show();\n  emitSound(E&#91;3], 100);\n  noTone(SPEAKER_PIN);\n  delay(900);\n  turnOffLeds(); \n\n  emitSound(C&#91;4], 500);\n  noTone(SPEAKER_PIN);\n}\n\nvoid loop() {\n  winner = isEndGame();\n\n  if (winner == -1)\n    mainGame();\n  else {\n    endGameScreen();\n  }\n}\n\nvoid mainGame() {\n  for (int i = 0; i &lt; PLAYERS; i++) {\n    getMovement(&amp;snakes&#91;i]);\n    moveSnake(&amp;snakes&#91;i]);\n  }\n  \n  \/\/ As time passes, snakes move faster\n  if (delayValue &gt; 0)\n    delay(delayValue--);\n}\n\nvoid getMovement(snake_t *snake) {\n  snake-&gt;read&#91;0] = analogRead(snake-&gt;joystick&#91;0]);\n  delay(100);                 \n  snake-&gt;read&#91;1] = analogRead(snake-&gt;joystick&#91;1]);\n\n  if (snake-&gt;read&#91;0] &gt;= 900) {\n    snake-&gt;direction = DICT&#91;snake-&gt;id]&#91;0];\n  } else if (snake-&gt;read&#91;0] &lt; 200) {\n    snake-&gt;direction = DICT&#91;snake-&gt;id]&#91;1];\n  } else if (snake-&gt;read&#91;1] &lt; 200) {\n    snake-&gt;direction = DICT&#91;snake-&gt;id]&#91;2];\n  } else if (snake-&gt;read&#91;1] &gt;= 900) {\n    snake-&gt;direction = DICT&#91;snake-&gt;id]&#91;3];\n  } \n}\n\nvoid moveSnake(snake_t *snake) {\n  if (!eatenApple(snake)) {\n    int pos = snake-&gt;tail.pop();\n    strip.setPixelColor(pos, strip.Color(0, 0, 0));\n    strip.show();\n  } else {\n    emitSound(E&#91;3], delayValue \/ 10);\n    noTone(SPEAKER_PIN);\n    setApplePosition();\n    printApple();\n  }\n\n  nextRow(snake);\n  nextColumn(snake);\n  snake-&gt;tail.add(0, transform(snake-&gt;head&#91;0], snake-&gt;head&#91;1]));\n\n  for (int i = 1; i &lt; snake-&gt;tail.size(); i++) {\n    strip.setPixelColor(snake-&gt;tail.get(i), snake-&gt;color);\n  }\n\n  strip.setPixelColor(snake-&gt;tail.get(0), snake-&gt;headColor);\n  strip.show();\n}\n\nvoid nextRow(snake_t *snake) {\n  switch (snake-&gt;direction) {\n    case 'u':\n      snake-&gt;head&#91;0] += 1;\n      break;\n    case 'd':\n      snake-&gt;head&#91;0] -= 1;\n      break;\n  }\n\n  if (snake-&gt;head&#91;0] &lt; 0)  \n    snake-&gt;head&#91;0] = SIDE - 1;\n  \n  snake-&gt;head&#91;0] = snake-&gt;head&#91;0] % SIDE;\n}\n\nvoid nextColumn(snake_t *snake) {\n  switch (snake-&gt;direction) {\n    case 'r': \n      snake-&gt;head&#91;1] += 1;\n      break;\n    case 'l':\n      snake-&gt;head&#91;1] -= 1;\n      break;\n  }\n\n  if (snake-&gt;head&#91;1] &lt; 0)  \n    snake-&gt;head&#91;1] = SIDE - 1;\n  \n  snake-&gt;head&#91;1] = snake-&gt;head&#91;1] % SIDE;\n}\n\n\/\/ Transform matrix position given in row and column to the actual matrix position\nint transform(int row, int column) {\n  if (row % 2 == 1)\n    return row * SIDE + SIDE - (column + 1);\n  \n  return row*SIDE + column;\n}\n\nvoid setApplePosition() {\n  apple = transform(random(SIDE), random(SIDE));\n\n  for (int i = 0; i &lt; PLAYERS; i++) {\n    for (int j = 0; j &lt; snakes&#91;i].tail.size(); j++) {\n      if (apple == snakes&#91;i].tail.get(j))\n        setApplePosition();\n    }\n  }\n}\n\nvoid printApple() {\n  strip.setPixelColor(apple, strip.Color(255, 255, 0));\n}\n\nbool eatenApple(snake_t *snake) {\n  return snake-&gt;tail.get(0) == apple;\n}\n\nint isEndGame() {\n  int randValue = random(2);\n\n  if (randValue == 0) {\n    if (checkWinner(&amp;snakes&#91;0], &amp;snakes&#91;1]))\n      return 0;\n    if (checkWinner(&amp;snakes&#91;1], &amp;snakes&#91;0]))\n      return 1;\n  } else {\n    if (checkWinner(&amp;snakes&#91;1], &amp;snakes&#91;0]))\n      return 1;\n    if (checkWinner(&amp;snakes&#91;0], &amp;snakes&#91;1]))\n      return 0;\n  }\n\n  return -1;\n}\n\n\/\/ Check if snake_l head (looser) is in snake_w tail (winner)  \nbool checkWinner(snake_t *snake_w, snake_t *snake_l) {\n  for (int i = 0; i &lt; snake_w-&gt;tail.size(); i++) {\n    if (snake_l-&gt;tail.get(0) == snake_w-&gt;tail.get(i)){\n      return true;\n    }\n  }\n\n  return false;\n}\n\nvoid endGameScreen() {\n  playEndSong();\n  winnerScreen(snakes&#91;winner].color);\n  resetGame();\n}\n\nvoid playEndSong() {\n  emitSound(G&#91;2], 500); noTone(SPEAKER_PIN); delay(100);\n  emitSound(G&#91;2], 500); noTone(SPEAKER_PIN); delay(100);\n  emitSound(G&#91;2], 500); noTone(SPEAKER_PIN); delay(100);\n  emitSound(DS&#91;2], 500); noTone(SPEAKER_PIN); delay(1);\n  emitSound(AS&#91;2], 125); noTone(SPEAKER_PIN); delay(25);\n  emitSound(G&#91;2], 500); noTone(SPEAKER_PIN); delay(100);\n  emitSound(DS&#91;2], 500); noTone(SPEAKER_PIN); delay(1);\n  emitSound(AS&#91;2], 125); noTone(SPEAKER_PIN); delay(25);\n  emitSound(G&#91;2], 500); noTone(SPEAKER_PIN);\n}\n\nvoid emitSound(int frec, int t) {\n  tone(SPEAKER_PIN, frec);      \n  delay(t);                \n}\n\nvoid winnerScreen(uint32_t color) {\n  winnerAnimation(color);\n  turnOffLeds();\n\n  for (int i = 0; i &lt; 5; i++) {\n    writeWin(color);\n    delay(500);\n    turnOffLeds();\n    delay(500);\n  }\n}\n\n\/\/ Color the full LED matrix the winner snake color\nvoid winnerAnimation(uint32_t color) {\n  for (int i = 0; i &lt; 512; i++) {\n    strip.setPixelColor(random(256), color);\n    strip.show();\n  }\n}\n\nvoid writeWin(uint32_t color) {\n  for (int i = 0; i &lt; 23; i++) {\n    if ((winner % 2) == 0)\n      strip.setPixelColor(RED_WIN&#91;i], color);\n    else\n      strip.setPixelColor(BLUE_WIN&#91;i], color);\n  }\n\n  strip.show();\n}\n\nvoid turnOffLeds() {\n  for (int i = 0; i &lt; strip.numPixels(); i++) {\n    strip.setPixelColor(i, strip.Color(0, 0, 0));   \n  }\n\n  strip.show();\n}\n\nvoid resetGame() {\n  for (int i = 0; i &lt; PLAYERS; i++) {\n    snakes&#91;i].tail.clear();\n  }\n\n  setupInitialValues();\n}<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>C\u00f3digo de control de la m\u00fasica<\/strong><\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;SimpleSDAudio.h&gt;\n\nconst int SD_PIN = 10 \/\/ SD card cs pin\n\nvoid setup() {\n  SdPlay.setSDCSPin(SD_PIN); \n\n  if (!SdPlay.init(SSDA_MODE_FULLRATE | SSDA_MODE_MONO | SSDA_MODE_AUTOWORKER)) {\n    while (1); \n  }\n  \n  if (!SdPlay.setFile(\"ms.wav\")) { \n    while (1);\n  }\n}\n\nvoid loop(void){\n  SdPlay.play(); \/\/ Play music\n\n  while (!SdPlay.isStopped())  {\n    delay(100);\n  }\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Casos de uso<\/strong><\/h2>\n\n\n\n<p>Hablaremos ahora sobre los diferentes casos de uso que tiene el juego:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Jugar partida<\/strong>: El jugador podr\u00e1 conectar las dos placas a una fuente de alimentaci\u00f3n, como pueden ser pilas de 9V, para empezar una partida y usar cualquiera de los dos joysticks disponibles para controlar a la serpiente roja o a la azul mediante movimientos horizontales y verticales. Al principio aparecer\u00e1 una cuenta atr\u00e1s de 3 segundos y, acto seguido, las serpientes empezar\u00e1n a moverse. La trayectoria original de ambas serpientes est\u00e1 establecida de tal manera que no sea posible chocar una con la otra hasta que alguno de los jugadores realice un movimiento, para evitar as\u00ed una muerte indeseada. Tambi\u00e9n cabe mencionar que existen l\u00edmites de pantalla, es decir, en caso de sobrepasar un borde de la pantalla, la serpiente aparecer\u00e1 por el lado contrario. Adem\u00e1s, a diferencia del juego original, las serpientes s\u00ed pueden pasar sobre su propio cuerpo sin morir.<\/li>\n\n\n\n<li><strong>Comer manzana<\/strong>: El jugador podr\u00e1 moverse hasta el LED iluminado de color amarillo para comerse la manzana y que el cuerpo de su serpiente aumente en una unidad.<\/li>\n\n\n\n<li><strong>Incremento de la velocidad<\/strong>: Las serpientes empiezan movi\u00e9ndose a una velocidad normal. Sin embargo, conforme va pasando el tiempo, estas van a empezar a moverse cada vez m\u00e1s r\u00e1pido, hasta alcanzar la m\u00e1xima velocidad.<\/li>\n\n\n\n<li><strong>Chocar con oponente<\/strong>: Si el jugador es lo suficientemente habilidoso, podr\u00e1 conseguir que el oponente choque con su cuerpo y as\u00ed ganar la partida, mostrando la animaci\u00f3n de victoria con el color de la serpiente del ganador y&nbsp; empezar despu\u00e9s una nueva partida.<\/li>\n\n\n\n<li><strong>Reiniciar partida<\/strong>: Los jugadores podr\u00e1n reiniciar en cualquier momento la partida pulsando el bot\u00f3n de reinicio de la propia placa de Arduino.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Problemas y soluciones encontradas<\/strong><\/h2>\n\n\n\n<p>De cara a los problemas que nos hemos encontrado a lo largo del desarrollo del proyecto, citamos a continuaci\u00f3n los m\u00e1s significativos y la forma de lidiar que hemos tenido con ellos:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Encontrar una matriz 16&#215;16 LED<\/strong>: Al principio del proyecto nos fue sumamente complicado dar con una matriz que cumpliera todos los requisitos necesarios. Empezamos a buscar por grandes distribuidoras como pueden ser Amazon o AliExpress, llegando a desistir de este camino por superar el presupuesto o por el hecho de que el componente no llegar\u00eda a tiempo. Finalmente, conseguimos un buen componente a un precio asequible en el mercado de segunda mano online a trav\u00e9s de un vendedor de Wallapop.<\/li>\n\n\n\n<li><strong>Cable de la matriz LED<\/strong>: A la hora de integrar de manera aislada la matriz LED a la placa Arduino, la matriz no dio ning\u00fan tipo de problema. Sin embargo, al integrar la pantalla con el resto de componentes y pegarla a la l\u00e1mina de contrachapado, esta empez\u00f3 a dar problemas debido a que los contactos de voltaje y tierra se ensuciaban e imped\u00edan el correcto uso de la placa. Esto nos provoc\u00f3 retrasos en el desarrollo e incluso nos llev\u00f3 a pensar en la rotura de una de las placas Arduino Uno.<\/li>\n\n\n\n<li><strong>Ejecuci\u00f3n en paralelo de la m\u00fasica<\/strong>: Una vez hecha la l\u00f3gica del juego y probada de manera que se mostraba robusta, tratamos de integrar la m\u00fasica le\u00edda desde una tarjeta SD conectada a la placa Arduino mediante un m\u00f3dulo lector de SD. El problema llegaba en que la m\u00fasica ten\u00eda que reproducirse continuamente y sin interferir en la experiencia de juego. Al no existir la ejecuci\u00f3n en paralelo en Arduino Uno, acabamos desarrollando finalmente dos c\u00f3digos, uno encargado de la l\u00f3gica de juego general y otro dedicado al propio m\u00f3dulo lector de tarjetas SD, cada uno de estos cargado a una placa Arduino, siendo este el principal motivo por el cual necesitamos de una placa Arduino adicional.<\/li>\n\n\n\n<li><strong>Uso de librer\u00edas<\/strong>: Al principio nos fue dif\u00edcil recurrir a una implementaci\u00f3n de la l\u00f3gica de juego y del control de componentes sin el uso de librer\u00edas, siendo esta la raz\u00f3n por la que hemos importado una serie de librer\u00edas que nos ayudan a gestionar de forma m\u00e1s sencilla, r\u00e1pida y eficiente el uso de los componentes en el propio c\u00f3digo.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Mejoras a futuro del proyecto<\/strong><\/h2>\n\n\n\n<p>Mencionaremos ahora las mejoras a incluir en un futuro que hemos pensado que mejorar\u00edan la experiencia general de nuestro proyecto y que finalmente por diversos motivos, entre los que se encuentra la falta de tiempo, no han sido implementadas:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>A\u00f1adir m\u00e1s jugadores<\/strong>: Nuestro c\u00f3digo est\u00e1 pensado para ser f\u00e1cilmente escalable de tal forma que ser\u00eda posible que m\u00e1s jugadores se unieran a la misma partida sin problemas. Bastar\u00eda simplemente con a\u00f1adir el hardware necesario (un joystick por cada nuevo jugador), teniendo en cuenta el l\u00edmite de entradas anal\u00f3gicas de Arduino, que en el caso de alcanzarse, ser\u00eda necesario incluir un multiplexor para permitir a\u00f1adir m\u00e1s entradas. Con respecto al software, solo har\u00eda falta incluir una nueva serpiente al inicializar el juego y modificar la funci\u00f3n de condici\u00f3n de final de juego.<\/li>\n\n\n\n<li><strong>Interruptor<\/strong>: Podr\u00eda ser interesante utilizar un interruptor que controle las pilas de ambas placas Arduino, dado que actualmente el juego se inicia nada m\u00e1s recibir voltaje.<\/li>\n\n\n\n<li><strong>Mejorar la estructura del artefacto<\/strong>: Si bien es verdad que la m\u00e1quina es compacta, ser\u00eda conveniente reforzar la estructura de contrachapado de la que est\u00e1 fabricada y los cables que la componen internamente para evitar cualquier comportamiento no deseado.<\/li>\n\n\n\n<li><strong>Mejorar conexiones<\/strong>: A pesar de que la gesti\u00f3n del cableado es correcta, convendr\u00eda un refuerzo de estos para evitar que no se desconecte ninguno y el proyecto no funcione como debiera.<\/li>\n\n\n\n<li><strong>Mandos m\u00e1s c\u00f3modos<\/strong>: A pesar de que los mandos que ofrecemos en el modelo actual se prestan a ser c\u00f3modos y no desconcentrar de la propia partida, podr\u00edan haberse fabricado con un dise\u00f1o m\u00e1s amigable al usuario.<\/li>\n\n\n\n<li><strong>Mejor sonido<\/strong>: Aunque la calidad de sonido actualmente es decente, convendr\u00eda mejorarla de cara al futuro, debido a que, por limitaciones de la librer\u00eda usada, el control de volumen transmitido por los altavoces es fijo y no se puede subir ni bajar. Adem\u00e1s, la calidad de sonido queda condicionada por los 8 bits de la propia placa Arduino y el formato .WAV soportado por ambas librer\u00edas y la placa.<\/li>\n\n\n\n<li><strong>Microcontrolador m\u00e1s apropiado para ejecuci\u00f3n de tareas en paralelo<\/strong>: Ser\u00eda posible tratar de conseguir un microcontrolador m\u00e1s potente que reemplazase las dos placas Arduino actualmente utilizadas por el dispositivo, al poder este soportar operaciones ejecutadas en paralelo a trav\u00e9s del propio hardware, dado que es tediosa e ineficiente la propia implementaci\u00f3n de esto en Arduino (simulado por software).&nbsp;<\/li>\n\n\n\n<li><strong>A\u00f1adir sonidos y mejorar la reproducci\u00f3n de los actuales<\/strong>: En relaci\u00f3n con el punto anterior, al conseguir la ejecuci\u00f3n de tareas en paralelo, se podr\u00eda conseguir un mejor comportamiento del sonido y la m\u00fasica del juego, pudiendo controlar cu\u00e1ndo reproducir y parar la melod\u00eda principal del juego, adem\u00e1s de a\u00f1adir m\u00e1s sonidos.<\/li>\n\n\n\n<li><strong>Mando inal\u00e1mbrico con tel\u00e9fono m\u00f3vil<\/strong>: De cara a futuras iteraciones del proyecto, ser\u00eda posible utilizar un m\u00f3dulo de conexi\u00f3n inal\u00e1mbrica a la placa Arduino que permitiera el uso de un tel\u00e9fono m\u00f3vil como mando para jugar a <em>snake.io<\/em>.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>V\u00eddeo explicativo del proyecto<\/strong><\/h2>\n\n\n\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<div class=\"video-container\"><iframe loading=\"lazy\" title=\"Grupo7 proyecto final SEyTR 2022-23 URJC\" width=\"500\" height=\"281\" src=\"https:\/\/www.youtube.com\/embed\/3d0R18MxH-o?feature=oembed&#038;wmode=opaque\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe><\/div>\n<\/div><figcaption class=\"wp-element-caption\"><em>Video desarrollo proyecto<\/em><\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>V\u00eddeo funcionando<\/strong><\/h2>\n\n\n\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<div class=\"video-container\"><iframe loading=\"lazy\" title=\"V\u00eddeo Demostraci\u00f3n - Proyecto Final SEyTR 2022-23 (Grupo 7)\" width=\"500\" height=\"281\" src=\"https:\/\/www.youtube.com\/embed\/1hJhGptrauc?feature=oembed&#038;wmode=opaque\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe><\/div>\n<\/div><figcaption class=\"wp-element-caption\"><em>Video ejemplo funcionamiento<\/em><\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Documentaci\u00f3n adicional<\/strong><\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/docs.google.com\/presentation\/d\/1AUVTzwKO7g8X09FTxtIfIO2Krxl8bJOCFtV9przKZZ4\/edit?usp=sharing\">Presentaci\u00f3n<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Autores: Juan Carlos Moreno Garc\u00eda, Jhostin Davis Ortiz Moreno y Alessandro Nuzzi Herrero Grupo 7 \/ 2022-2023 Introducci\u00f3n El juego de la serpiente, o mejor conocido como Snake Game, es considerado un cl\u00e1sico desde&#46;&#46;&#46;<\/p>\n","protected":false},"author":8,"featured_media":6490,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-6483","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-proyectos"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Snake.io - Proyectos con Arduino.<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/blogs.etsii.urjc.es\/dseytr\/snake-io\/\" \/>\n<meta property=\"og:locale\" content=\"es_ES\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Snake.io - Proyectos con Arduino.\" \/>\n<meta property=\"og:description\" content=\"Autores: Juan Carlos Moreno Garc\u00eda, Jhostin Davis Ortiz Moreno y Alessandro Nuzzi Herrero Grupo 7 \/ 2022-2023 Introducci\u00f3n El juego de la serpiente, o mejor conocido como Snake Game, es considerado un cl\u00e1sico desde&#046;&#046;&#046;\" \/>\n<meta property=\"og:url\" content=\"https:\/\/blogs.etsii.urjc.es\/dseytr\/snake-io\/\" \/>\n<meta property=\"og:site_name\" content=\"Proyectos con Arduino.\" \/>\n<meta property=\"article:published_time\" content=\"2023-05-05T12:08:11+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-05-05T15:51:47+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2023\/05\/IMG_5683-1-1-scaled.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"2560\" \/>\n\t<meta property=\"og:image:height\" content=\"1920\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"gdhwsw2\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Escrito por\" \/>\n\t<meta name=\"twitter:data1\" content=\"gdhwsw2\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tiempo de lectura\" \/>\n\t<meta name=\"twitter:data2\" content=\"19 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/snake-io\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/snake-io\\\/\"},\"author\":{\"name\":\"gdhwsw2\",\"@id\":\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/#\\\/schema\\\/person\\\/7491e54afbe5e7fd53467fccb9c7ce44\"},\"headline\":\"Snake.io\",\"datePublished\":\"2023-05-05T12:08:11+00:00\",\"dateModified\":\"2023-05-05T15:51:47+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/snake-io\\\/\"},\"wordCount\":2664,\"commentCount\":1,\"publisher\":{\"@id\":\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/snake-io\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/wp-content\\\/uploads\\\/sites\\\/8\\\/2023\\\/05\\\/IMG_5683-1-1-scaled.jpg\",\"articleSection\":[\"Proyectos\"],\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/snake-io\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/snake-io\\\/\",\"url\":\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/snake-io\\\/\",\"name\":\"Snake.io - Proyectos con Arduino.\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/snake-io\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/snake-io\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/wp-content\\\/uploads\\\/sites\\\/8\\\/2023\\\/05\\\/IMG_5683-1-1-scaled.jpg\",\"datePublished\":\"2023-05-05T12:08:11+00:00\",\"dateModified\":\"2023-05-05T15:51:47+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/snake-io\\\/#breadcrumb\"},\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/snake-io\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/snake-io\\\/#primaryimage\",\"url\":\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/wp-content\\\/uploads\\\/sites\\\/8\\\/2023\\\/05\\\/IMG_5683-1-1-scaled.jpg\",\"contentUrl\":\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/wp-content\\\/uploads\\\/sites\\\/8\\\/2023\\\/05\\\/IMG_5683-1-1-scaled.jpg\",\"width\":2560,\"height\":1920},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/snake-io\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Portada\",\"item\":\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Snake.io\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/#website\",\"url\":\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/\",\"name\":\"Proyectos con Arduino.\",\"description\":\"Blog de proyectos de Arduino de alumnos de la URJC\",\"publisher\":{\"@id\":\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"es\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/#organization\",\"name\":\"Universidad Rey Juan Carlos\",\"url\":\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/wp-content\\\/uploads\\\/sites\\\/8\\\/2022\\\/05\\\/logourjc-1.jpg\",\"contentUrl\":\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/wp-content\\\/uploads\\\/sites\\\/8\\\/2022\\\/05\\\/logourjc-1.jpg\",\"width\":745,\"height\":288,\"caption\":\"Universidad Rey Juan Carlos\"},\"image\":{\"@id\":\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/#\\\/schema\\\/person\\\/7491e54afbe5e7fd53467fccb9c7ce44\",\"name\":\"gdhwsw2\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/ed762cea3155134adfbecf1780d8a40c0fe5e4b642859a56b3a2b3611a1ca73a?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/ed762cea3155134adfbecf1780d8a40c0fe5e4b642859a56b3a2b3611a1ca73a?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/ed762cea3155134adfbecf1780d8a40c0fe5e4b642859a56b3a2b3611a1ca73a?s=96&d=mm&r=g\",\"caption\":\"gdhwsw2\"},\"url\":\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/author\\\/gdhwsw2\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Snake.io - Proyectos con Arduino.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/blogs.etsii.urjc.es\/dseytr\/snake-io\/","og_locale":"es_ES","og_type":"article","og_title":"Snake.io - Proyectos con Arduino.","og_description":"Autores: Juan Carlos Moreno Garc\u00eda, Jhostin Davis Ortiz Moreno y Alessandro Nuzzi Herrero Grupo 7 \/ 2022-2023 Introducci\u00f3n El juego de la serpiente, o mejor conocido como Snake Game, es considerado un cl\u00e1sico desde&#46;&#46;&#46;","og_url":"https:\/\/blogs.etsii.urjc.es\/dseytr\/snake-io\/","og_site_name":"Proyectos con Arduino.","article_published_time":"2023-05-05T12:08:11+00:00","article_modified_time":"2023-05-05T15:51:47+00:00","og_image":[{"width":2560,"height":1920,"url":"https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2023\/05\/IMG_5683-1-1-scaled.jpg","type":"image\/jpeg"}],"author":"gdhwsw2","twitter_card":"summary_large_image","twitter_misc":{"Escrito por":"gdhwsw2","Tiempo de lectura":"19 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/blogs.etsii.urjc.es\/dseytr\/snake-io\/#article","isPartOf":{"@id":"https:\/\/blogs.etsii.urjc.es\/dseytr\/snake-io\/"},"author":{"name":"gdhwsw2","@id":"https:\/\/blogs.etsii.urjc.es\/dseytr\/#\/schema\/person\/7491e54afbe5e7fd53467fccb9c7ce44"},"headline":"Snake.io","datePublished":"2023-05-05T12:08:11+00:00","dateModified":"2023-05-05T15:51:47+00:00","mainEntityOfPage":{"@id":"https:\/\/blogs.etsii.urjc.es\/dseytr\/snake-io\/"},"wordCount":2664,"commentCount":1,"publisher":{"@id":"https:\/\/blogs.etsii.urjc.es\/dseytr\/#organization"},"image":{"@id":"https:\/\/blogs.etsii.urjc.es\/dseytr\/snake-io\/#primaryimage"},"thumbnailUrl":"https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2023\/05\/IMG_5683-1-1-scaled.jpg","articleSection":["Proyectos"],"inLanguage":"es","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/blogs.etsii.urjc.es\/dseytr\/snake-io\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/blogs.etsii.urjc.es\/dseytr\/snake-io\/","url":"https:\/\/blogs.etsii.urjc.es\/dseytr\/snake-io\/","name":"Snake.io - Proyectos con Arduino.","isPartOf":{"@id":"https:\/\/blogs.etsii.urjc.es\/dseytr\/#website"},"primaryImageOfPage":{"@id":"https:\/\/blogs.etsii.urjc.es\/dseytr\/snake-io\/#primaryimage"},"image":{"@id":"https:\/\/blogs.etsii.urjc.es\/dseytr\/snake-io\/#primaryimage"},"thumbnailUrl":"https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2023\/05\/IMG_5683-1-1-scaled.jpg","datePublished":"2023-05-05T12:08:11+00:00","dateModified":"2023-05-05T15:51:47+00:00","breadcrumb":{"@id":"https:\/\/blogs.etsii.urjc.es\/dseytr\/snake-io\/#breadcrumb"},"inLanguage":"es","potentialAction":[{"@type":"ReadAction","target":["https:\/\/blogs.etsii.urjc.es\/dseytr\/snake-io\/"]}]},{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/blogs.etsii.urjc.es\/dseytr\/snake-io\/#primaryimage","url":"https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2023\/05\/IMG_5683-1-1-scaled.jpg","contentUrl":"https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2023\/05\/IMG_5683-1-1-scaled.jpg","width":2560,"height":1920},{"@type":"BreadcrumbList","@id":"https:\/\/blogs.etsii.urjc.es\/dseytr\/snake-io\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Portada","item":"https:\/\/blogs.etsii.urjc.es\/dseytr\/"},{"@type":"ListItem","position":2,"name":"Snake.io"}]},{"@type":"WebSite","@id":"https:\/\/blogs.etsii.urjc.es\/dseytr\/#website","url":"https:\/\/blogs.etsii.urjc.es\/dseytr\/","name":"Proyectos con Arduino.","description":"Blog de proyectos de Arduino de alumnos de la URJC","publisher":{"@id":"https:\/\/blogs.etsii.urjc.es\/dseytr\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/blogs.etsii.urjc.es\/dseytr\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"es"},{"@type":"Organization","@id":"https:\/\/blogs.etsii.urjc.es\/dseytr\/#organization","name":"Universidad Rey Juan Carlos","url":"https:\/\/blogs.etsii.urjc.es\/dseytr\/","logo":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/blogs.etsii.urjc.es\/dseytr\/#\/schema\/logo\/image\/","url":"https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2022\/05\/logourjc-1.jpg","contentUrl":"https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2022\/05\/logourjc-1.jpg","width":745,"height":288,"caption":"Universidad Rey Juan Carlos"},"image":{"@id":"https:\/\/blogs.etsii.urjc.es\/dseytr\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/blogs.etsii.urjc.es\/dseytr\/#\/schema\/person\/7491e54afbe5e7fd53467fccb9c7ce44","name":"gdhwsw2","image":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/secure.gravatar.com\/avatar\/ed762cea3155134adfbecf1780d8a40c0fe5e4b642859a56b3a2b3611a1ca73a?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/ed762cea3155134adfbecf1780d8a40c0fe5e4b642859a56b3a2b3611a1ca73a?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/ed762cea3155134adfbecf1780d8a40c0fe5e4b642859a56b3a2b3611a1ca73a?s=96&d=mm&r=g","caption":"gdhwsw2"},"url":"https:\/\/blogs.etsii.urjc.es\/dseytr\/author\/gdhwsw2\/"}]}},"_links":{"self":[{"href":"https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-json\/wp\/v2\/posts\/6483","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-json\/wp\/v2\/users\/8"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-json\/wp\/v2\/comments?post=6483"}],"version-history":[{"count":13,"href":"https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-json\/wp\/v2\/posts\/6483\/revisions"}],"predecessor-version":[{"id":6525,"href":"https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-json\/wp\/v2\/posts\/6483\/revisions\/6525"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-json\/wp\/v2\/media\/6490"}],"wp:attachment":[{"href":"https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-json\/wp\/v2\/media?parent=6483"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-json\/wp\/v2\/categories?post=6483"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-json\/wp\/v2\/tags?post=6483"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}