tag:blogger.com,1999:blog-64160702273035139152024-03-05T21:33:33.318+01:00Apaga y vuelve a encenderBlog principalmente sobre desarrollo Java, web, Android... o sobre lo que me esté dando por ahí en ese momento. Como ya tenemos una edad, contaré también mis historias del abuelo Cebolleta. Y gruñiré. MUCHO. ¡¡¡Grrrrrrrrr!!!Andréshttp://www.blogger.com/profile/06010147149377176406noreply@blogger.comBlogger29125tag:blogger.com,1999:blog-6416070227303513915.post-73064415791940309802014-07-11T13:58:00.000+02:002014-07-11T13:58:18.720+02:00A Tuenti le molan los developers yonkisEsto viene a ser en cierto modo un epílogo a mi serie de entradas sobre <a href="http://apagayvuelveaencender.blogspot.com/2014/05/tuentichallenge4-diario-de-un-developer.html"><b>mi participación en el concurso Tuenti Challenge</b></a>. Si las leíste, probablemente pensaste: este tío es <b>un patán</b>. Vueltas y revueltas raras a los ejercicios del concurso, interpolaciones que no vienen a cuento, falta de sueño, notitas tontorronas en los comentarios a los revisores... pfffff, seguro que has pensado que <b>tú lo harías mejor</b>.<br />
<br />
Pues bien, amigo lector... quiero compartir contigo que a pesar de todo esto (o quizá incluso <b>por</b> eso), dentro de nada <b>voy a empezar a trabajar en Tuenti</b>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEih2Rmbp6N3hG2u42IYalqc5A0PDSm-omdRu3ENNhqFxvwhC_J9n99J95DZHNpBWQWbdPQuXBZT-fhfnvhjFUopCbT152mAfp3pgQsvuqz50_JlLSJFt0vaOK4tNIuSOc-MmlSuLMap5vvw/s1600/uno.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEih2Rmbp6N3hG2u42IYalqc5A0PDSm-omdRu3ENNhqFxvwhC_J9n99J95DZHNpBWQWbdPQuXBZT-fhfnvhjFUopCbT152mAfp3pgQsvuqz50_JlLSJFt0vaOK4tNIuSOc-MmlSuLMap5vvw/s1600/uno.jpg" height="200" width="200" /></a></div>
Echaré de menos a los que han sido durante muchos años mis compañeros en <a href="http://www.digibis.com/"><b>DIGIBIS</b></a>, y con los que realmente <b>da gusto trabajar</b>. Doy ahora un giro y cuando ya casi casi entendía a los bibliotecarios, me aparto de ese mundillo. Y eso que en algún momento hasta había llegado a plantearme sacarme la carrera de Biblioteconomía, ya que con el tiempo mis conocimientos de <a href="http://www.loc.gov/marc">MARC21</a> y otros estándares infernales del mundo bibliotecario han llegado a ser bastante decentes. Y que poco a poco me he descubierto a mi mismo, cada vez más a menudo, pidiendo silencio a la gente.<br />
<br />
No sé todavía en qué departamento de Tuenti entraré, ni siquiera con qué tecnologías, lo mismo puede ser Java o Android que iOS, Erlang o... sí, PHP. Pero en cualquier caso espero que la experiencia me sirva para crecer profesionalmente y sea todo un reto.<br />
<br />
La lectura para ti, sin embargo, debería ser... ¡ey!, si yo, con esa cochambrosa interpolación en el segundo ejercicio, he conseguido entrar en Tuenti... <b>¡entonces tú también puedes!</b>. Ya sabes, espera unos mesecitos y dentro de nada se abrirá la convocatoria para la <b>Tuenti Challenge 2015</b>.<br />
<br />
Y si te encuentras un ejercicio con personajes divertidos pero desarrollo infernal... <b>sospecha</b>. Probablemente lo haya puesto yo.<br />
<br />Andréshttp://www.blogger.com/profile/06010147149377176406noreply@blogger.com6tag:blogger.com,1999:blog-6416070227303513915.post-58389474432873842292014-05-13T02:53:00.001+02:002014-05-13T02:55:14.843+02:00TuentiChallenge4: Diario de un developer yonki (3): Ejercicios más chungos y conclusiones<div style="background-color: #d9edf7; border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; border-top-left-radius: 4px; border-top-right-radius: 4px; border: 1px solid rgb(188, 232, 241); color: #31708f; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; padding: 15px;">
<div>
<b>¡OJO!</b>: Esta entrada es la última parte de una saga que empieza en:</div>
<div>
<b><a href="http://apagayvuelveaencender.blogspot.com/2014/05/tuentichallenge4-diario-de-un-developer.html">TuentiChallenge4: Diario de un developer yonki (1)</a></b><br />
<div>
<br />
Los fuentes Java de mis soluciones están disponibles <a href="https://github.com/andresviedma/tuentichallenge4">en Github</a>.</div>
</div>
</div>
<br />
<h2>
Día 7</h2>
Querido diario:<br />
<div style="-webkit-text-stroke-width: 0px; color: black; font-family: 'Times New Roman'; font-size: medium; font-style: normal; font-variant: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px;">
<div style="font-weight: normal; margin: 0px;">
<br /></div>
<div style="margin: 0px;">
Hoy el día ha sido muy largo. O quizá debería decir la noche. Después del bajón del día de ayer, decidí que <b>lo mejor que podía hacer era descansar muchas horas</b> y dedicar la noche a hacer <b>un ejercicio más</b>, ¡pero hacerlo bien!. Así que dediqué la mayor parte del día a descansar y a la tranquila vida familiar.</div>
<div style="font-weight: normal; margin: 0px;">
<br /></div>
<div style="font-weight: normal; margin: 0px;">
A última hora de la tarde, encendí el ordenador y le reté a un duelo de miradas. Esta vez iba a darlo todo.</div>
<div style="font-weight: normal; margin: 0px;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="font-weight: normal; margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYs83Agniclao1txs0vlrgvOG3-x4b6nNKKQ4Vf0EhtlfUgLD1NPoTzG6FCFcM2mm-tc2ORF81oT_h4PzivEbmpJRymsSMQ0x-THNIcskr0VDn5pgakik90t48dvXAJNQObQ2_mRXVpUZW/s1600/uno.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYs83Agniclao1txs0vlrgvOG3-x4b6nNKKQ4Vf0EhtlfUgLD1NPoTzG6FCFcM2mm-tc2ORF81oT_h4PzivEbmpJRymsSMQ0x-THNIcskr0VDn5pgakik90t48dvXAJNQObQ2_mRXVpUZW/s1600/uno.jpg" height="249" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">de <a href="http://vergag.com/">vergag.com</a></td></tr>
</tbody></table>
<div style="font-weight: normal; margin: 0px;">
<br /></div>
<div style="margin: 0px;">
Entonces me puse con el <b>ejercicio 14, <a href="https://contest.tuenti.net/Challenges?id=14">Train Empire</a></b>, que propone un juego de trenes con combustible limitado, en el que se incluyen rutas, estaciones y vagones con puntuaciones si consiguen alcanzar una estación de destino. Se trata de obtener la <b>máxima puntuación</b> posible a partir de un estado inicial dado. El ejercicio ha confirmado que estamos ya en fase chunga, y hay que darle bastantes vueltas para resolverlo.<br />
<br /></div>
<div style="margin: 0px;">
He planteado la resolución en <b>dos fases</b>. En la primera, por cada vagón obtengo <b>todas las posibles combinaciones que llevarían a que ese vagón llegara a su destino</b>, sin tener en cuenta la estación en la que comience el tren. En la segunda, <b>pruebo todas las permutaciones de las posibilidades de cada estación</b>, probando también a cambiar el orden en el que se obtendrá cada vagón. Al hacerlo, <b>recorro antes las posibilidades que exploran primero los vagones con más puntuación</b>, porque así es más fácil obtener rápidamente una solución buena. En cuanto una permutación no sea ya capaz de mejorar la mejor puntuación obtenida hasta el momento, se descarta.<br />
<div style="font-weight: normal;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRwf8OTWbqj9j7MroYbUYLuC9bGCBkHIm8NPxJQ05rfHPgTd6TPxtMo_myRv3StgG5Utiw87njCJSsNwxf77BrqeRB9E0xbDObAzQJESXqSWEK1iqhxQBYzfQH0j4w8lpNi2bDT2ccPZvc/s1600/uno.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRwf8OTWbqj9j7MroYbUYLuC9bGCBkHIm8NPxJQ05rfHPgTd6TPxtMo_myRv3StgG5Utiw87njCJSsNwxf77BrqeRB9E0xbDObAzQJESXqSWEK1iqhxQBYzfQH0j4w8lpNi2bDT2ccPZvc/s1600/uno.png" height="204" width="320" /></a></div>
<div style="font-weight: normal;">
<br /></div>
<div style="font-weight: normal;">
<br /></div>
<span style="font-weight: normal;">Esta prueba de cada permutación tiene </span><b>una sutileza</b> con la que hay que tener cuidado: al mover un tren anterior, puede que en parte de su camino no necesite llevar ningún vagón con puntos, por lo que <b>cabe la posibilidad de que el tren esté libre para mover un vagón en su recorrido y dejarlo en alguna estación intermedia</b>. Así que en dicho caso hay que ver cuál de esas estaciones va a ser más adelante la más cercana a su destino, y considerarlo para la situación inicial del siguiente tren. Tengo la impresión de que esta sutileza era la gran dificultad del ejercicio, y que puede hacer que mucha gente no resuelva bien el ejercicio.<br />
<div style="font-weight: normal;">
<br /></div>
<div style="font-weight: normal;">
En el enunciado se dice que no va a haber más de 2 trenes, por lo que seguramente exista alguna solución más sencilla que la mía que tenga en cuenta esto. La mía es genérica, valdría lo mismo para 2 trenes que para más, aunque por supuesto el rendimiento se resentiría mucho en caso de haber muchos trenes.</div>
<div style="font-weight: normal;">
<br /></div>
<span style="font-weight: normal;">Al ejecutarlo crucé los dedos para ver si era lo suficientemente rápido, pensando que el hecho de que solo hubiera 2 trenes debería ser suficiente, y efectivamente ha ejecutado la entrega en </span><b>10 segundos</b>. Muy satisfecho con mi solución, a pesar de no ser demasiado elegante, llegó el momento que ya había vivido varias veces estos últimos días: las tantas de la noche, agotado, <b>lo normal sería irse a dormir</b>, aunque eso supusiera ya el final del concurso. Pero ains, volví a caer... me he leído el enunciado del siguiente ejercicio y como buen developer yonki... ¡tenía que hacerlo!.<br />
<br />
<br />
Y tenía que hacerlo porque el <b>ejercicio 15, <a href="https://contest.tuenti.net/Challenges?id=15">Take a corner</a></b>, es... ¡¡¡un Othello!!!, o sea... ¡¡¡un Reversi!!!. <b>¡¡¡Me encanta el Reversi!!!.</b> ¡Con mi primer ZX Spectrum, hace ya potorrón de siglos, venía de regalo un juego de Reversi!. Pero es que hay más... ¡YO tengo programado un juego de Reversi!. Lo hice hace un montón de años para JavaME, y lo pasé a Android el año pasado.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj75rrN7j2s-ZNaKBJolcFxIqALQ0gEcK8R78QNauVeJhkgVakp4u9UROT0s-MvWdNTh3lsF7uV18uov_WLQUn2RzqZ0-roljyQ7iDLdfvYpmbeX_kuuBMB1etvycS-FQ__KyvwacLgaZ7-/s1600/uno.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj75rrN7j2s-ZNaKBJolcFxIqALQ0gEcK8R78QNauVeJhkgVakp4u9UROT0s-MvWdNTh3lsF7uV18uov_WLQUn2RzqZ0-roljyQ7iDLdfvYpmbeX_kuuBMB1etvycS-FQ__KyvwacLgaZ7-/s1600/uno.png" height="320" width="192" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Mi Reversi, ¡snif!</td></tr>
</tbody></table>
<br />
En el ejercicio se plantea una solución inicial y se pide qué movimiento hay que hacer para que en <b>N jugadas más, haga lo que haga el contrario, se gane una esquina</b>. Mi juego es malo con ansia, así que no cubría esa posibilidad, pero sí he aprovechado para copiar el código de gestión del tablero de Reversi y que obtiene los posibles movimientos a partir de una situación. Una vez teniendo eso, he hecho una sencilla exploración de todas las posibilidades, considerando que cuando le toca mover al jugador inicial basta conque un movimiento sea exitoso, y cuando le toca mover al contrario tienen que serlos todos.<br />
<div style="font-weight: normal;">
<br /></div>
<div>
Estaba tan emocionado ante la posibilidad de reutilizar el mismo código por tercera vez (soy un gran fan de la reutilización) que me recreé especialmente en la solución. ¡Y qué demonios!, <b>¡¡¡se lo iba a contar a mi amigo el revisor de Tuenti!!!</b></div>
<div style="font-weight: normal;">
<br /></div>
<pre class="brush:java">/**
* Dear Tuenti Engineer:
* I've programmed a solution a bit more elegant this time, thinking that this one
* was going to be the last. I'm not 100% sure, although it's almost 6:00 in the
* morning and I think this week has been exhausting enough.
* Thanks for your work and please keep doing things like this.
* I need a bed. Now!
* Good night!
*/</pre>
<span style="font-weight: normal;"><br /></span>
<br />
<div>
Ahora ya sí, con mi consciencia perdiéndose en ovejillas saltando vallas, ¿qué debería haber hecho?: dormir. ¿Qué he hecho?: pffff, está claro... ¡leerme el siguiente ejercicio!</div>
<span style="font-weight: normal;"><br /></span>
<span style="font-weight: normal;"><br /></span>
<span style="font-weight: normal;">Y así he llegado al </span><b>ejercicio 16, <a href="https://contest.tuenti.net/Challenges?id=16">ÑAPA</a></b>. Y, ¡ay!... <b>me volví a picar</b>. El ejercicio se trataba de calcular <b>cuántos círculos intersectan</b> entre un mogollón que te dan (potencialmente millones). <b>La solución obvia era... ¡tan obvia!</b>. Recorrerlos todos entre sí y hacer un sencillo cálculo de colisiones, aplicando para ello el teorema de Pitágoras... sí, ese mismo que habría hecho bien en aplicar en el ya lejano ejercicio 3 en lugar de las malditas interpolac... ¡¡¡AGH, NO QUIERO PENSAR EN ESO!!!.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6rav2KjKr1ScXaEK9F_J-eIL6756lHLoFZ5nNrIM1Ch-1Z0qmbZTM8bjo7riJjfO6ANs_QOOIDL0zXDfQYALa2uMOeuzux8c7qtJNxcKbPq9E91oVkhtDgkGgN_2Mwr8wLGg9HgGW1-iL/s1600/uno.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6rav2KjKr1ScXaEK9F_J-eIL6756lHLoFZ5nNrIM1Ch-1Z0qmbZTM8bjo7riJjfO6ANs_QOOIDL0zXDfQYALa2uMOeuzux8c7qtJNxcKbPq9E91oVkhtDgkGgN_2Mwr8wLGg9HgGW1-iL/s1600/uno.jpg" height="125" width="200" /></a></div>
<br />
El caso es que... qué demonios, <b>igual no había trampa</b>. Igual en Tuenti querían premiar a la gente que había llegado hasta aquí y ponerles algo facilón. Las ovejas me decían que no había otra solución posible. Y, bueno, me daba tiempo a probar. Los tests iniciales me funcionaban suficientemente rápido. ¿Qué pasaría con la entrega?. Por supuesto, <b>tenía que compartir esto con mi amigo el revisor de Tuenti</b>:<br />
<br />
<pre class="brush:java">/**
* Dear Tuenti engineering:
*
* Ouch! I shouldn't have read this challenge... just when I was dreaming on my
* feet and ready to go to bed, I had the terrible idea of reading it. And...
* bad idea, really really bad idea, because it's quite easy! Actually, I think it's
* the easiest challenge!... unless you pretend to process the 8 million points in
* a reasonable time and there's a hidden trick, but I don't think so (maybe
* that's because I'm almost asleep). I'll see it right now. I'm scared. If
* there's a trick, you are very clever, my friend... hmmm maybe "painting" the
* points in a grid with the limited 100x100 space, maybe?, and so iterating
* points in order N -and not N!-, and after that iterating the 100x100 points?...
* yeeks, I'll better not think on it, it's late!.
*
* I'll try as well to NOT reading the next challenge. Seriously. Promised. Or so.
* I don't think I have enough time to solve it, anyway...
*
* P.S.: Ooooooooook, I got it! I have and idea, will I correct it in time???
*
* Sincerely,
* @author andres
*/</pre>
<br />
Probé y... nada. Se tiraba mogollón de tiempo (ni sé cuánto, pero apuesto a que horas). Como se puede ver al final del comentario, dejé de escuchar a las ovejas y <b>se me ocurrió una solución</b>. Tampoco era demasiado complicado de hacer, aunque el tiempo se me estaba acabando, incluso aunque no durmiera nada.<br />
<br />
<b>Se trataría de dividir el espacio</b>, que tiene unos límites definidos (y que no era ni mucho menos 100x100 como pongo en el comentario, prueba inequívoca de que estaba ya en babia), en varias <b>zonas cuadradas</b>. Cada cuadrado se recorre enterito combinando todos los círculos que tenga dentro. Al pasar al siguiente cuadrado, se guardan en un hash las colisiones que se han detectado, porque <b>los mismos dos círculos que colisionan en una zona pueden colisionar también en la siguiente</b>, y no queremos contarla dos veces. Para que el hash no tenga demasiados elementos, calculamos el rectángulo que contiene la intersección de la colisión, y <b>cuando estemos en la zona que contiene la esquina inferior derecha, lo quitamos del conjunto hash</b>. Esto es así porque las zonas las recorría de arriba a abajo y de izquierda a derecha.<br />
<br />
Conseguí que la ejecución se hiciera en solo unos segundos, pero al hacerlo el resultado dejó de ser correcto. Creo que <b>la solución que he planteado está muy bien y seguramente sea "la buena", pero he debido hacer algo mal en la implementación</b>. Posiblemente al dividir el espacio en zonas, no sé.<br />
<br />
Ya no podía seguir, se me había acabado el tiempo, a pesar de que al final no he dormido nada. Me ha fastidiado no poder entregar correctamente el ejercicio, porque creo que ya casi lo tenía, pero así es la vida...<br />
<br />
<br />
<h2>
Conclusiones</h2>
<div>
El concurso es... mortal. <b>Requiere muchas energías</b>, son demasiados ejercicios, y no son sencillos. Incluso aunque le dediques solo ratos sueltos, si tienes un trabajo exigente y poco tiempo libre, te va a dejar agotado. Mi gran problema, además, es que cuando leía un ejercicio me picaba, independientemente de la hora que fuera. Y si algo he aprendido en este concurso es que <b>cuando llegas a cierto nivel de cansancio y falta de sueño es mejor parar</b>, porque las soluciones que encuentres no van a ser buenas, y te va a costar mucho pensar.</div>
<div>
<br /></div>
Personalmente preferiría que el concurso <b>tuviera pocos ejercicios y que fueran los más difíciles</b>. Que cada ejercicio que resuelvas tenga su mérito. Solo eso ya es suficiente para hacer un concurso chulo.<br />
<br />
Aparte de eso, tengo que decir que <b>el concurso es también muy interesante</b>. Los ejercicios, aparte de algún enunciado ambiguo o no suficientemente definido, están bastante bien, y algunos son realmente divertidos de resolver.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZD2impFQ2fQuhldQvTvw1J3ksP8I1DosB3PsWDyiHBcdS_foS6ZmA_ewM-zPLhT5J9k0rqt0IDMkeAWOBI35TaM7qhPBm6ug5I7hkEL_W-HoMuO_2HglhWEai5hOfogSRUYx8wGwzuYsn/s1600/uno.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZD2impFQ2fQuhldQvTvw1J3ksP8I1DosB3PsWDyiHBcdS_foS6ZmA_ewM-zPLhT5J9k0rqt0IDMkeAWOBI35TaM7qhPBm6ug5I7hkEL_W-HoMuO_2HglhWEai5hOfogSRUYx8wGwzuYsn/s1600/uno.png" /></a></div>
<br />
Por otra parte, mi crítica va también a la forma en la que estoy viendo que Tuenti trata el concurso una vez acabado. Mientras estábamos concursando teníamos <b>un ranking con el número de ejercicios que había entregado cada uno</b>, aun sin saber cuántos estaban bien o mal. En cuanto el concurso acabó, el ranking desapareció. Vale que se supone que la puntuación final tiene un componente subjetivo que le dan los revisores de Tuenti a la limpieza de cada solución, pero creo que <b>un simple ranking automático en base al número de ejercicios resueltos por cada uno nos hubiera encantado a todos los participantes</b>. Aunque luego no fuera definitivo y los ganadores no tuvieran por qué ser los primeros puestos de dicho ranking. Creo que basta con dejarlo claro. <b>Es que así es tan... ¡cortarrollos!</b><br />
<br />
Por mi parte, en el ranking provisional de ejercicios entregados sin corregir creo recordar que <b>quedé en el puesto 25</b>. Luego por email <b>me han confirmado que estoy entre los 50 primeros</b>, aunque no haya aún un ranking definitivo (que no tengo muy claro que al final vaya a existir).<br />
<br />
No me siento especialmente orgulloso de mi participación, creo que he hecho demasiados ejercicios con demasiado sueño, y quizá debería haberme centrado en hacer menos ejercicios pero con más calma y energías. Pero sí <b>estoy contento con cómo planteé los últimos ejercicios que hice</b>, los que comento en esta tercera parte del mega-artículo. Y oye, quedar entre los 50 primeros está bastante bien.<br />
<br />
Pero qué demonios, aun con todo, tengo que decir que lo más importante es que <b>me lo he pasado genial</b>.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOrvkqHbD9U_CmtzRxwARkEmYaqUi_qHkAjm322CNUZUPEeDccDWOhopFpGjLYE8Rj4G0hmqlc_rsVaqVrNd_ZqmJXXOX2ytMS9p1hgvuKWoiapIGBgqHjc1yUeM5VuHD1jdcv4MaorXy_/s1600/uno.gif" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOrvkqHbD9U_CmtzRxwARkEmYaqUi_qHkAjm322CNUZUPEeDccDWOhopFpGjLYE8Rj4G0hmqlc_rsVaqVrNd_ZqmJXXOX2ytMS9p1hgvuKWoiapIGBgqHjc1yUeM5VuHD1jdcv4MaorXy_/s1600/uno.gif" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">de <a href="http://protocoloipv6.blogspot.com/">protocoloipv6.blogspot.com</a></td></tr>
</tbody></table>
<br /></div>
</div>
Andréshttp://www.blogger.com/profile/06010147149377176406noreply@blogger.com7tag:blogger.com,1999:blog-6416070227303513915.post-9339334252775902182014-05-09T02:31:00.000+02:002014-05-13T02:54:21.420+02:00TuentiChallenge4: Diario de un developer yonki (2): la cosa se pone chunga<div style="background-color: #d9edf7; border-radius: 4px; border: 1px solid #bce8f1; color: #31708f; font-family: Helvetica Neue,Helvetica,Arial,sans-serif; padding: 15px;">
<div style="text-align: left;">
<b>¡OJO!</b>: Esta entrada es continuación directa de</div>
<div style="text-align: left;">
<b><a href="http://apagayvuelveaencender.blogspot.com/2014/05/tuentichallenge4-diario-de-un-developer.html">TuentiChallenge4: Diario de un developer yonki (1)</a></b><br />
<div>
<br />
Los fuentes Java de mis soluciones están disponibles <a href="https://github.com/andresviedma/tuentichallenge4">en Github</a>.</div>
</div>
</div>
<br />
<h2>
Día 4</h2>
<div>
Hoy me he puesto otro rato con el concursillo de marras, para no variar.</div>
<div>
<br /></div>
<div>
Primero he empezado con el <b>ejercicio 5, <a href="https://contest.tuenti.net/Challenges?id=5">Tribblemaker</a></b>, que se trata de implementar el <a href="http://en.wikipedia.org/wiki/Conway's_Game_of_Life">Juego de la Vida</a> (aunque no lo decían explícitamente, pero se daban pistas más que obvias), y detectar ciclos en la evolución. El ejercicio resultaba bastante entretenido de programar y daba para hacer código ordenadito, así que me he recreado en eso.</div>
<div>
<br /></div>
<div>
El siguiente, el <b>ejercicio 6, <a href="https://contest.tuenti.net/Challenges?id=6">Man in the Middle</a></b>, me ha encantado. Se trataba de crear un servicio que se metiera en medio de la comunicación encriptada entre un cliente y un servidor, basada en claves que se van intercambiando entre ellos.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgabsXxmE8WGgH595z-gAg5OglX8p2Oc9Deqlw0kFgobC0vLQ5KqovwiuR4aF3m-KhoKENDq5sxY78FKoa_b-0jHQMCx1LHIdUBwWAcHv_hH16mkGri56ce7EyxmX6siJVER1Ox5nim43Rl/s1600/uno.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgabsXxmE8WGgH595z-gAg5OglX8p2Oc9Deqlw0kFgobC0vLQ5KqovwiuR4aF3m-KhoKENDq5sxY78FKoa_b-0jHQMCx1LHIdUBwWAcHv_hH16mkGri56ce7EyxmX6siJVER1Ox5nim43Rl/s1600/uno.jpg" height="215" width="320" /></a></div>
<br />
Para poder resolverlo, se proporciona el código fuente tanto de la parte cliente como de la parte servidor... en Javascript, o sea, NodeJs. Para alguien con conocimientos de seguridad y que sepa NodeJs imagino que el ejercicio estaba chupado. Para los que no, <b>el ejercicio resultaba realmente divertido</b>. Y mira que yo de criptografía ni flowers, nada de nada.<br />
<br />
El ejercicio se podía hacer sin problemas en otros lenguajes, pero teniendo ya los fuentes en Javascript, lo normal es que sea mucho más sencillo resolverlo así. De esta forma, se trata de <b>instalar NodeJs</b>, ver cómo funciona, probarlo, revisar ambos códigos fuentes, <b>hacerte tus esquemas</b> de cómo funciona su intercambio de claves, y finalmente programar la solución, que básicamente se hace <b>mezclando el código</b> del cliente y el del servidor. Podría hacerse incluso sin saber Javascript ni nada de criptografía, que es lo que me parece más genial de este ejercicio. La clave en mi caso para que todo resultara más fácil fue <b>crear un objeto diferenciado para el cliente y otro para el servidor,</b> de forma que todo se hace bastante lógico y comprensible. Crecidito por lo bien que se me estaba dando el día, no he parado ahí.<br />
<br />
El siguiente ha sido el <b>ejercicio 7, <a href="https://contest.tuenti.net/Challenges?id=7">Yes we scan</a></b>, en el que se trata de encontrar una relación entre dos elementos a partir de un montón de conexiones. Temía que ya tuviera que ir pensando más en temas de rendimiento y algorítmica. Sin embargo, la verdad es que sólo con usar un par de hashes y tener un poco de cuidado con la forma en la que se obtienen nuevas conexiones indirectas por cada conexión nueva, conseguí que la prueba de entrega se resolviera en solo 10 segundos.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1Iv-P-MxHfzIw_dnx_DWzMdtonf3k4i1SikdDCwI4lHOmcTedMxwwIfR4bK-cULj24ONhXhy5lgDAZuMh7v3Y0JTScZSWd1R2kLadG05JQdUe2i4PLMNEoNi9huKaucQXoLG0GotyQsrm/s1600/uno.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1Iv-P-MxHfzIw_dnx_DWzMdtonf3k4i1SikdDCwI4lHOmcTedMxwwIfR4bK-cULj24ONhXhy5lgDAZuMh7v3Y0JTScZSWd1R2kLadG05JQdUe2i4PLMNEoNi9huKaucQXoLG0GotyQsrm/s1600/uno.jpg" height="232" width="320" /></a></div>
<br />
Y entonces <b>me he crecido</b>: ¡leche, en cuanto he dormido un poco qué bien me ha ido todo!. Eran ya las 3 y pico de la mañana, así que llegó ese momento que también conocen los jugadores de poker que están en racha: <b>el momento de retirarse y continuar otro día</b>. Por supuesto... <b>¡yo no lo hice!</b>.<br />
<br />
Así que toma porrazo con el <b>ejercicio 8, <a href="https://contest.tuenti.net/Challenges?id=8">Tuenti Reestructuration</a></b>. Se trata de reorganizar posiciones de personas en mesas, basadas en permutaciones, hasta llegar a una situación final. O sea, segundo momento importante de la noche: ese en el que me doy cuenta de que <b>posiblemente me encuentre ante un ejercicio típico de recorrido de caminos posibles</b>, de esos que en algorítmica tienen tan trillados, pero que <b>yo nunca me entero de cómo lo resuelvo</b>. ¡Ains, ya estoy como siempre!<br />
<br />
Lo peor es que <b>el enunciado me ha parecido muy confuso</b>, no deja muy claro cuáles son los movimientos posibles, así que estoy perdiendo muchísimo tiempo sólo para enterarme... y ya se está haciendo de día. ¡Mierda, con lo bueno que era el día! A dormir.<br />
<br />
<br />
<h2>
Día 5</h2>
<div>
<b>Esto de dejarse un ejercicio a medias no mola nada</b>, he estado todo el tiempo dándole vueltas al dichoso ejercicio hasta que me he podido poner con él. Por fin estoy seguro de qué movimientos son los válidos, y le he puesto las heurísticas que se me han ido ocurriendo para que no fuera demasiado lento: probar primero el camino que se acerque más a la solución, control para dejar de recorrer un camino cuando ya tengamos uno mejor, detectar estados ya recorridos... total, que entre unas cosas y otras me he tirado un montón de tiempo con el tema. Al final la entrega se ha tirado varios minutos de ejecución, así que imagino que habrá soluciones mejores, pero para no saber nada de algorítmica <b>creo que ha quedado bastante decente</b>. Eso sí, esto está empezando a <b>complicarse</b> de verdad.</div>
<div>
<br /></div>
<div>
Esto lo confirmó el <b>ejercicio 9, <a href="https://contest.tuenti.net/Challenges?id=9">Bendito Caos</a></b>, que tenía tela. Se trataba de averiguar cuántos coches pueden llegar en una hora desde un punto a otro, calculándolo a partir de las velocidades de los caminos entre cada par de vértices. En este caso estoy aún más seguro de que existen algoritmos que implementan esto sin problema. Pero a mi me iba a tocar hacerlo a lo bruto.</div>
<div>
<br /></div>
<div>
Me ha llevado un rato sacar <b>las reglas de mezcla de las velocidades</b>, para saber cómo se puede calcular la velocidad global entre el vértice de inicio y el de fin, combinando las de todos los caminos posibles. También había que tener cuidado con los bucles. Pero sobre todo no tenía ni idea de cuál sería el rendimiento de mi sencilla solución. En el ejemplo iba rápido, pero el enunciado de este ejercicio no era, la verdad, demasiado bueno. No sólo la explicación era un poco confusa (no tanto como el anterior pero casi), sino que sobre todo, <b>no dejaba claro en ningún momento cuáles eran los límites en número de nodos y de caminos</b>. <b>¡Tercer WTF del concurso!</b></div>
<div>
<br /></div>
<div>
Yo, siempre optimista, <b>lo interpreté como que eso sería que no le iban a meter mucha caña</b>. Gran error. Lo puse a ejecutar y eso seguía y seguía y no acababa. ¿Qué pasaría si lo cortaba a medias e intentaba arreglarlo?. Hice la prueba y vi que aparentemente se podía. Hice un cambio en la línea de comando para obtener más información y lo volví a ejecutar. <b>Grandísima cagada. Me equivoqué al poner la línea de comando</b>, así que lo ejecuté de forma incorrecta, pero la entrega se consideró válida.</div>
<div>
<br /></div>
<div>
Por culpa del ejercicio casi llego tarde al cine, donde pude desengrasar un poco mis pobres neuronas viendo a Spider-man pegando tortazos a troche y moche. Mano de santo, oiga, que el dolor de cabeza que se me había quedado hoy era tremendo.</div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJyacAJFYn3iwvgsMzIY0l2fTYMYQwXViEDOkMIxFZpUjw514Fv2zM3Gf-JvXbm6LkGw-q1IAFS-KSlm5yBclHRNKBPDbnXiJSPYvGTisc3SYXG2vDfPtLpg8aq_Glv0txrm2uExu-Sk-Y/s1600/uno.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJyacAJFYn3iwvgsMzIY0l2fTYMYQwXViEDOkMIxFZpUjw514Fv2zM3Gf-JvXbm6LkGw-q1IAFS-KSlm5yBclHRNKBPDbnXiJSPYvGTisc3SYXG2vDfPtLpg8aq_Glv0txrm2uExu-Sk-Y/s1600/uno.jpg" height="180" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Spidey sí que sabe cómo hay que enfrentarse a los Challenges del Tuenti<br />
<b>¡¡¡A tortazos!!!</b></td></tr>
</tbody></table>
<div>
<br /></div>
<div>
Al volver a casa le he echado un vistazo al siguiente ejercicio, con la firme intención de no ponerme con él. Y ha resultado ser un WTF con todas las de la ley. A ver si mañana entiendo algo, porque hoy lo veo realmente negro.</div>
<div>
<br /></div>
</div>
<div>
<br /></div>
<h2>
Día 6</h2>
<div>
El <b>ejercicio 10, <a href="https://contest.tuenti.net/Challenges?id=10">Random Password</a></b>, es <b>tan tan tan WTF</b>, que el enunciado apenas dice: </div>
<div>
<br /></div>
<div>
<blockquote class="tr_bq">
It seems to be a random password... how could it be?<br />
Get the key for your input. Start at: <a href="http://random.contest.tuenti.net/?input=INPUT" style="color: #3f98c5; text-decoration: none;">http://random.contest.tuenti.net/?input=INPUT</a></blockquote>
</div>
<div>
<br /></div>
<div>
¡¡¡¡¿¿¿Eeeeeeeeeeeeeeeeeeeeeeeeeeeeh???!!!! Espera que lo lea otra vez... sí. Ya veo. Entendido. <b>Entendido que no entiendo nada, quiero decir</b>. Probé a mirar el código fuente del servidor y poco más se me ocurrió. Como ya he dicho, no tengo ni idea sobre seguridad, que es de lo que obviamente trataba esto, así que tras estar un buen rato dándole vueltas, lo descarté.</div>
<div>
<br /></div>
<div>
El <b>ejercicio 11, <a href="https://contest.tuenti.net/Challenges?id=11">Pheasant</a></b>, insiste en la seguridad. ¡Otra vez!. Aunque en este caso parece que algo se puede hacer sin saber nada de encriptación. Se trata de <b>averiguar una clave AES en la que faltan 3 posiciones</b>, a partir de datos conocidos. Lo único que se me ha ocurrido es probar todas las combinaciones en esas 3 posiciones hasta dar con la buena. En lugar de hacerlo con el fichero entero, creo que lo importante es <b>hacerlo solo con los 32 primeros bytes</b>, que he visto que era suficiente en cualquier caso según los límites dados, y que agilizaba muchísimo el proceso. Al hacer la entrega he visto que se ha tirado bastantes minutos, pero sin conocer cómo funciona el AES creo que era imposible hacer nada mejor. También sospecho que la <b>implementación de AES</b> que he usado, que es la que viene por defecto en Java (JCE), debe ser <b>bastante lenta</b>.</div>
<div>
<br /></div>
<div>
El <b>ejercicio 12, <a href="https://contest.tuenti.net/Challenges?id=12">Taxi Driver</a></b>, volvía a ser algorítmico. Es más, en el fondo el problema era muy muy similar al número 8, el de la reestructuración de mesas que tanto tiempo me llevó y que no me quedó demasiado rápido, y que seguro que conociendo los algoritmos típicos se hace en un momentín... <b>¡¡¡Otra vez el mismo problema de siempre, el que he hecho millones de veces y nunca bien!!!</b>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWP8ymF6Flend5nohu1etJMR4aVNqYwEGZXFgDnPd6Gp27TnAJdngoNYmyOj_yAcoYpjA0zFcl1UTiL50DnbFmkwOJGfOjMEeO0M9ivkEoGBa_7gr4ncL6YQeG4Fub089g8FQvV15o8naL/s1600/uno.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWP8ymF6Flend5nohu1etJMR4aVNqYwEGZXFgDnPd6Gp27TnAJdngoNYmyOj_yAcoYpjA0zFcl1UTiL50DnbFmkwOJGfOjMEeO0M9ivkEoGBa_7gr4ncL6YQeG4Fub089g8FQvV15o8naL/s1600/uno.png" height="371" width="640" /></a></div>
<br /></div>
<div>
<b>He entrado en tal estado de enajenación que he decidido comunicarle mi frustración a un posible corrector</b>. Así que he puesto <b>este comentario en el código</b>, con un par:</div>
<div>
<br /></div>
<div>
<div>
<pre class="brush:java">/**
* NOTE
* ===============
*
* Dear Tuenti Engineer:
*
* Oh, no, the same problem... again! This is almost the same as challenge 8!
* I'm pretty tired of doing the same problem, and not finding a really GREAT
* solution to avoid loops in a proper way and find good heuristics (I could
* swear I've found it also other times in my past... in Google Code Jam, maybe?).
*
* This time, I've decided to program a reusable solution, in the form of this
* PathFinder class. It's a pity I can't use it for challenge 8 yet, but I'm
* in the hope that I can find this same problem again. Call it a longshot if
* you may.
*
* I'm losing some precious minutes in this, but I'm sure you will appreciate
* it. Enjoy it, my friend.
*
* @author andres
*
*/</pre>
</div>
</div>
<div>
<br /></div>
<div>
<b>He hecho una preciosa clase PathFinder</b> capaz de resolver todos estos problemas similares. Como ya he dicho, la falta de sueño y el dolor de cabeza que me habían causado los problemillas me han hecho entrar en un grave estado de enajenación. Y tanto, no sabía hasta qué punto...</div>
<div>
<br /></div>
<div>
El caso es que al ejecutar la entrega, <b>sintiéndome en pleno deja vú</b>, veo que eso sigue ejecutando... y sigue ejecutando... y sigue ejecutando... y no para. Mato el proceso, cambio la línea de comando, vuelvo a ejecutar y... adivina.</div>
<div>
<br /></div>
<div>
<b>¡¡¡Sí!!!. ¡¡¡Vuelvo a equivocarme al modificar la línea de comando!!!.</b></div>
<div>
<br /></div>
<div>
Otra entrega a freír espárragos. Para una vez que me pongo a hacer una clase más genérica, primero la hago demasiado lenta y luego la dejo a medias por pura torpeza... qué grande.</div>
<div>
<br /></div>
<div>
<b>Ejercicio 13, <a href="https://contest.tuenti.net/Challenges?id=13">Tuenti Timing Auth</a></b>.Con los ojos ardiendo en fuego, miro el siguiente ejercicio, con la esperanza de que sirviera para redimirme. ¿Y qué encuentro?.</div>
<div>
<br /></div>
<div>
<b>¡¡¡Otro ejercicio de seguridad, similar al otro que me salté!!!</b></div>
<div>
(en este caso sobre "side channels", tema sobre el que sé lo mismo que el anterior, o sea, nada).</div>
<div>
<br /></div>
<div>
No me lo podía creer.</div>
<div>
<br /></div>
<div>
Tras darle vueltas al tema la correspondiente ración de tiempo inútil, desistí.<br />
<b>¡¡¡¡¡WTF doble, diablos!!!!!</b></div>
<div>
<br /></div>
<div>
Al rato me levanté, tembloroso, casi sin fuerzas. En la espuma a mis pies yacían dos mundos muertos. Con mi propósito casi olvidado tras el torbellino de violencia, miré estúpidamente a la pantalla. Al poco, recuperé mi raciocinio. Buscaba venganza. ¿Podía aprovechar de alguna forma las circunstancias?...</div>
<div>
<br />
<br />
<div style="background-color: #d9edf7; border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; border-top-left-radius: 4px; border-top-right-radius: 4px; border: 1px solid rgb(188, 232, 241); color: #31708f; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; padding: 15px;">
<div>
<b><br class="Apple-interchange-newline" />¡OJO!</b>: Esta entrada continúa en:</div>
<div>
<b><a href="http://apagayvuelveaencender.blogspot.com.es/2014/05/tuentichallenge4-diario-de-un-developer_13.html">TuentiChallenge4: Diario de un developer yonki (3)</a></b></div>
<div>
<br /></div>
</div>
</div>
<div>
<div style="text-align: center;">
<div>
<i><br /></i>
<i><br /></i>
<i><br /></i>
<i><br /></i></div>
</div>
<div style="text-align: center;">
</div>
</div>
Andréshttp://www.blogger.com/profile/06010147149377176406noreply@blogger.com3tag:blogger.com,1999:blog-6416070227303513915.post-34584660276791701472014-05-07T02:06:00.001+02:002014-05-13T02:53:00.809+02:00TuentiChallenge4: Diario de un developer yonki (1)<div style="background-color: #d9edf7; border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; border-top-left-radius: 4px; border-top-right-radius: 4px; border: 1px solid rgb(188, 232, 241); padding: 15px;">
<div style="text-align: left;">
<div style="color: #31708f; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;">
Los fuentes Java de mis soluciones están disponibles en Github:</div>
<span style="color: #31708f; font-family: Helvetica Neue, Helvetica, Arial, sans-serif;"><b><a href="https://github.com/andresviedma/tuentichallenge4">https://github.com/andresviedma/tuentichallenge4</a></b></span></div>
<div style="color: #31708f; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; text-align: left;">
</div>
</div>
<br />
<h2>
Día 0</h2>
Querido diario:<br />
<br />
Hoy he decidido que voy a presentarme al <a href="https://contest.tuenti.net/"><b>concursillo de programación que organiza Tuenti</b></a>. Ya que no pude presentarme al <a href="http://code.google.com/codejam/">Code Jam</a> de Google como otros años porque estaba de viaje, voy a intentarlo con uno más patrio. No sé ni cómo va, y la verdad es que entre el curro y el finde que me he pegado de viajes y de dormir poco estoy <b>bastante cansado</b>. Pero pone que dura una semana y <b>está el puente</b>, así que seguro que hay tiempo de sobra para resolver los problemas que te pongan. <b>¡¡¡Esto lo gano fijo!!!</b>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMhNjBH0dqfLMywhiSTiLziv2O8OTyuqbmyEXAPb1geVTgwlIHY8HPFX3ec9WJ_7d_d07XkBZw75W5jGsmrRnjXIEdQISHlmq0fEyhnCOOIVFemiDMok6leE2Eh4Kw-TXUdYUTYMY_gr-V/s1600/uno.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMhNjBH0dqfLMywhiSTiLziv2O8OTyuqbmyEXAPb1geVTgwlIHY8HPFX3ec9WJ_7d_d07XkBZw75W5jGsmrRnjXIEdQISHlmq0fEyhnCOOIVFemiDMok6leE2Eh4Kw-TXUdYUTYMY_gr-V/s1600/uno.png" /></a></div>
<br />
<br />
<b>Como voy a andar bien de tiempo</b> creo que voy a hacerlo en algún otro lenguaje que no sea Java. ¿Qué tal <a href="http://apagayvuelveaencender.blogspot.com/2013/11/aparta-javascript-llega-dart.html">en Dart</a>, ya que <a href="http://apagayvuelveaencender.blogspot.com/2013/12/proyecto-picross-haciendo-un-videojuego.html">le estoy dando caña</a> últimamente?. O si no podría hacerlos en Groovy... bueno, bah, ya lo pienso cuando me ponga con ello.<br />
<br />
¿Serán algorítmicos como los de Google?. Igual debería mirarme cosas de algorítmica, lo del <b>backtracking, los A estrella, recorridos de grafos</b> y todas esas mandangas, que lo di en la Facultad hace un mollón de años pero no me acuerdo de nada. Y siempre estoy igual, que oye, molaría poner cara de molón y decir: <b>"¡Voy a resolverlo en un momentín con el algoritmo Magicflush!"</b>. O igual debería mirarme los problemas que han puesto otros años para hacerme una idea de cómo van... aunque bueno, seguro que estos serán facilones. Va, aunque sean las 8 de la tarde <b>me voy a dormir una siesta</b> y luego lo pienso.<br />
<br />
<br />
<h2>
Día 1</h2>
<div>
Querido diario:</div>
<div>
<br /></div>
<div>
Ayer al final también dormí muy poco, me quedé dormido cuando sonó el despertador de la siesta porque estaba baldado, y luego me desperté a la 1 o así y ya no me pude volver a dormir hasta casi por la mañana. <b>Necesito un fin de semana para recuperarme del fin de semana</b>. Menos mal que viene el puente y podré descansar.</div>
<div>
<br /></div>
<div>
Ya empezó el concursito de marras. Cuando he vuelto del teatro, aunque era ya tarde y yo estaba cansado, he mirado el primer ejercicio para ver qué pinta tienen los ejercicios. <b>¡Había 1582 personas registradas!</b> En fin, igual no va a ser esto tan fácil.</div>
<div>
<br /></div>
<div>
<div>
Por lo que he visto, hay que ejecutar unas herramientas que te pasan para ejecutar una prueba corta y ver si vas bien, y luego otra más fuerte para enviarlo, que sólo se puede hacer una vez. Cuando fui a <b>programar en Dart</b>, me di cuenta de que iba a tener que <a href="http://apagayvuelveaencender.blogspot.com/2014/03/historia-de-una-promise-1-el-modelo-de.html">usar Futures</a> para toda la entrada / salida, y <b>me dio tal pereza</b> solo de pensarlo que al final pasé. Descarté también <b>Groovy</b>, por la pereza que me daba ya solo meterme cuando realmente no tengo fluidez ninguna con el lenguaje (estoy empezando a pensar que esto de programar con sueño no es bueno). ¡Qué demonios, voy a tirar con <b>Java</b> y así empiezo de una vez!.</div>
</div>
<div>
<br /></div>
<div>
<b>El ejercicio 1, <a href="https://contest.tuenti.net/Challenges">Anonymous Poll</a></b>, es bastante sencillote, no tiene mucha ciencia. En estos concursos muchas veces la gente programa las cosas con gran economía de líneas, usando arrays a tope y con un número mínimo de funciones. Como a mi eso no me va mucho y además dicen que para el concurso se valorará la calidad del código, he optado por <b>organizar los ejercicios con sus clases, sus métodos</b>, etc., quedará todo más claro aunque también más largo.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQyh_8oR9HD_qGRAl9C3F9Np_kM_0ZUn_jKNMgzwWvKHHx9oFVqOLL50OjMG3Ejn-9Tci7FDVwzw2wmBAZIbzvs4yRI56vqFPrak67zb4y8eYCJGjMuB4qFpRE_sDEYB-5vpWPlaDtIuKY/s1600/uno.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQyh_8oR9HD_qGRAl9C3F9Np_kM_0ZUn_jKNMgzwWvKHHx9oFVqOLL50OjMG3Ejn-9Tci7FDVwzw2wmBAZIbzvs4yRI56vqFPrak67zb4y8eYCJGjMuB4qFpRE_sDEYB-5vpWPlaDtIuKY/s1600/uno.png" height="56" width="320" /></a></div>
<div>
<br /></div>
<div>
<b>El ejercicio 2, <a href="https://contest.tuenti.net/Challenges?id=2">F1 Bird's Eye Circuit</a></b>, se trataba de recibir en una sola línea el diseño de un circuito, con sus rectas y curvas, y ensamblarlo y pintarlo ya en dos dimensiones. A pesar de que era bien tarde pensé que era facilón y lo podía hacer en un momentín. Una vez terminado de programar me he dado cuenta de una cosa: <b>tenía trampa</b>. Al leerlo la primera vez me pareció que el primer caracter de la cadena se suponía que estaba mirando hacia la derecha. Pero al releerlo me he dado cuenta de que no, que el que se supone que está mirando a la derecha es un caracter '#' que hay por ahí, y que se supone que es la salida. ¡En el fondo fue una suerte que la haya releído, porque <b>en el programa de la prueba daba la casualidad que todos los casos de prueba salían correctos</b>!.</div>
<br />
<b>¡Primer What The Fuck!.</b><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1yXIz7X5n6s41aTCKuc0BzpwvmEmW8Tt2FUERhSx6JZPZ_YmDA3k8A_FlgyxWWtfwBOHxgMoInfYH4L6nXeSob15OYpbfj5tJoUYAvy0ZD8686R-210PZtccY7sT8DCh4jqfKXzUtWxGz/s1600/uno.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1yXIz7X5n6s41aTCKuc0BzpwvmEmW8Tt2FUERhSx6JZPZ_YmDA3k8A_FlgyxWWtfwBOHxgMoInfYH4L6nXeSob15OYpbfj5tJoUYAvy0ZD8686R-210PZtccY7sT8DCh4jqfKXzUtWxGz/s1600/uno.png" height="172" width="320" /></a></div>
<br />
<br />
Si hubiera estado más despierto probablemente hubiera optado por <b>comenzar a leer la cadena por la posición del caracter '#'</b> y santas pascuas. Pero no, claro, he hecho algo mucho más bizarro: cuando llega el caracter # miro en qué dirección se supone que estoy mirando y la guardo en una variable, y luego <b>¡giro la pista al pintarla!</b>, cambiando unos caracteres por otros según si miramos en horizontal o en vertical, o según cómo queden las curvas al girarlas. Un poco infernal, la verdad, con la tontería me han dado las 4 de la mañana. Estoy roto. A dormir.<br />
<br />
<br />
<h2>
Día 2</h2>
<div>
Querido diariozzz:</div>
<div>
<br /></div>
<div>
<b>Lo volví a hacer</b>. Después de la charla de <a href="https://twitter.com/adelatorrefoss">@adelatorrefoss</a> en <a href="https://twitter.com/madriagil">MadriAgil</a> y de ver el fútbol, por fin, a las tantas, me he vuelto a poner con el concursillo. No sé cuántos ejercicios hay, pero esto no parece tener fin.</div>
<div>
<br /></div>
<div>
<b>El ejercicio 3, <a href="https://contest.tuenti.net/Challenges?id=3">The Gambler's Club</a></b>, es, es, es... ¡ey, es Guybrush Threepwood!, ¡¡¡<b>Monkey Island</b>!!!.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5jRPPYONSv5A8j273AaCZu3KVwxC1Z4Q7Bwg04M8mrx4n8H2Y-BHJECwrFlKET5OrAvwCXNTWnWNahWoDX8F332DXA-yGdMCEaxcKFIW_bvZN5NGXq8XB4-mRqHGOTVDx7J45NM9PsEDB/s1600/uno.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5jRPPYONSv5A8j273AaCZu3KVwxC1Z4Q7Bwg04M8mrx4n8H2Y-BHJECwrFlKET5OrAvwCXNTWnWNahWoDX8F332DXA-yGdMCEaxcKFIW_bvZN5NGXq8XB4-mRqHGOTVDx7J45NM9PsEDB/s1600/uno.png" height="203" width="320" /></a></div>
<div>
<br /></div>
<div>
Está bien, ¡TENÍA que hacerlo!. ¡La de tiempo que habré pasado yo con los monkeys!. <b>¡Y seguro que un ingeniero amante del Monkey Island sería un genio que habría ideado un reto divertidísimo!</b>...</div>
<div>
<br /></div>
<div>
<b>Pues no.</b></div>
<div>
<br /></div>
<div>
Resulta que una vez leído te dabas cuenta de que se trataba de, a partir de un conjunto de datos, obtener la ecuación con la que se obtienen. Si conoces algún programa matemático, esto se resuelve en un pis-pas. <b>YO NO</b>. ¡Llevo sin usar un programa matemático desde la Universidad, hace cuatro o cinco millones de años! (redondeando).</div>
<div>
<br /></div>
<div>
Hice un programa que obtuviera los datos de la web y me puse a buscar en Google. Los ojos se me cerraban, pero ey! ¡en cuanto lo encontrara podría irme a dormir!. Rosario en mano y cantándole a los angelitos, <b>probé con Excel</b>. ¡Meeeeeeec!. Nones. Ni conseguí sacar ecuaciones con dos variables, ni conseguí sacar una ecuación convincente con una variable dejando la otra fija. Probé entonces con <a href="https://www.wolframalpha.com/">Wolphram Alpha</a>, que sabía que se podían hacer cosas de este estilo. Al ir a meter los datos, veo que la cajica está deshabilitada y tiene un bonito botoncico donde pone <b>"Subscribe to Pro"</b>. La madre que los parió. O dicho de otra forma, <b>¡segundo WTF!</b>.</div>
<div>
<br /></div>
<div>
Buscando, buscando, buscando, vi que la cosa estaba chunga. Y a estas horas daba una pereza tremenda ponerse a instalar nada para probar programitas matemáticos, y encima en Linux. Viendo la curva en Excel, daba la impresión de que la ecuación tenía que ser polinomial, y me extrañaba que Excel no la sacara. <b>¡A ver si es que había que hacer una interpolación!</b>. Dicho y hecho, me copié una clase que encontré por ahí que hacía una interpolación trilineal y ahí que la metí. Con un par. Porque yo lo valgo. Y encima funcionaba. <b>Qué grande soy</b>. Pues a tomar viento, la envío y fuera.</div>
<div>
<br /></div>
<div>
Claro, que en cuanto la he enviado me he dado cuenta de que <b>eso no iba a funcionar ni de coña</b>. Te avisaban de que el programa de prueba usaba números menores o iguales a 30, que eran justo los de la muestra de datos. Y claro, en cualquier interpolación, por chunga que sea, <b>si le pides uno de los puntos de la muestra te lo va a devolver con una precisión perfecta</b>. Por otra parte, también te avisaban de que en los datos de prueba que se ejecutaban al enviar, se usaban todos números mayores, los de muestra llegaban solo hasta 30, y los de la prueba final llegaban hasta mil y pico. <b>O sea, que la interpolación a hacer gárgaras</b>. ¿Para qué demonios sirve una interpolación si todos los datos están tan alejados de la muestra?.</div>
<div>
<br /></div>
<div>
Deprimido al darme cuenta de lo ocurrido y después de echar un trago del peor orujo que tenía como penitencia, he decidido que no podía acostarme así.</div>
<div>
<br /></div>
Así que he pasado al <b>ejercicio 4, <a href="https://contest.tuenti.net/Challenges?id=4">Shape shifters</a></b>, y <b>¡oooooooooh, es Mística!</b>. ¡Un ingeniero amante de Mística sería un genio que habría ideado un reto divertidísimo!... <b>obviamente</b>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnHb3KOtDQt7ZUEg8j1m_er_IWv5zyjYfobaZBC8XfMBVffNSwIELR-nSs6zmlMiJxJ8N5LtMKo66DhyphenhyphenlvpHlV_cTqzCMIPClW8jZORkkvXLSuErcS5E-xJEPFBUT7Bq8hP9vaDn5CoU9Y/s1600/uno.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnHb3KOtDQt7ZUEg8j1m_er_IWv5zyjYfobaZBC8XfMBVffNSwIELR-nSs6zmlMiJxJ8N5LtMKo66DhyphenhyphenlvpHlV_cTqzCMIPClW8jZORkkvXLSuErcS5E-xJEPFBUT7Bq8hP9vaDn5CoU9Y/s1600/uno.jpg" height="276" width="320" /></a></div>
<br />
<br />
Se trataba de tener una cadena de caracteres de inicio y otra de fin, y un conjunto de estados intermedios posibles, y de crear transiciones de estados cambiando un caracter hasta llegar al objetivo. Con un recorrido de todas las posibilidades de transiciones y un control para no pasar por estados repetidos se resolvía con cierta facilidad, aunque ya me imagino que no será lo óptimo. Son casi las 5 de la mañana pero ¡entregado!. Y veo que han puesto un "top" y aparezco ya en él <b>en el hipotético puesto 100</b>, absolutamente falso porque no cuenta si los ejercicios están bien o mal, solo los que se han entregado. ¡Y hay un tío que ya tiene hechos 15! Para mi que la gente no trabaja...<br />
<br />
En cualquier caso... ¡ay!, no me quito de la cabeza al puñetero Guybrush, la madre que lo engendró... ¡<b>y el resto de su familia, obtenida a partir de estúpidas interpolaciones trilineales!</b>.<br />
<br />
<br />
<h2>
Día 3</h2>
Queridozzz diariozzz:<br />
<br />
Son las 12 de la noche y acabo de volver del entrenamiento de basket. Esta mañana he tenido que madrugar un poco más porque venían a revisarme la caldera, así que creo que estoy empezando a sentirme mucho más cercano a los zombis (más majos ellos!).<br />
<br />
Viendo las máquinas que hay en el puñetero concurso, creo que voy a ver si presento un par de ejercicios más, que... ¡diablos!, <b>¡¡¡he mirado y resulta que hay 20 ejercicios!!!</b>. Y a 2 por día no me va a dar tiempo aunque, Guybrush aparte, por suerte <b>no son excesivamente complicados</b>.<br />
<br />
Pero primero voy a tirarme un rato en el sofá a relajarzzzzzzzzzzzZZZZZZZZZZzzzzzzzzzzZZZZzzz<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSghJgpF45M1W3XO1zhj-8orFwaNvFm9_NiwnPwn5QSNs1SQg2Wo7wFXEyyKaupf_MEawHVPZT8Q_1gvXNXfJkC_y6au3PHECrhG6w3Yk2dT4AQYFLSCOLTAOu3ksdiqJEPrMNklrGX-cA/s1600/uno.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSghJgpF45M1W3XO1zhj-8orFwaNvFm9_NiwnPwn5QSNs1SQg2Wo7wFXEyyKaupf_MEawHVPZT8Q_1gvXNXfJkC_y6au3PHECrhG6w3Yk2dT4AQYFLSCOLTAOu3ksdiqJEPrMNklrGX-cA/s1600/uno.gif" height="229" width="320" /></a></div>
<br />
<div style="background-color: #d9edf7; border-radius: 4px; border: 1px solid #bce8f1; color: #31708f; font-family: Helvetica Neue,Helvetica,Arial,sans-serif; padding: 15px;">
<div style="text-align: left;">
<b>¡OJO!</b>: Esta entrada continúa en:</div>
<div style="text-align: left;">
<b><a href="http://apagayvuelveaencender.blogspot.com.es/2014/05/tuentichallenge4-diario-de-un-developer_9.html">TuentiChallenge4: Diario de un developer yonki (2)</a></b></div>
</div>
<br />
<br />
<br />
<br />
<br />Andréshttp://www.blogger.com/profile/06010147149377176406noreply@blogger.com5tag:blogger.com,1999:blog-6416070227303513915.post-33212076833044476232014-03-07T02:01:00.000+01:002014-03-07T02:15:44.412+01:00Historia de una promise (1): el modelo de concurrencia con ejecución asíncronaComo ya habréis podido comprobar, últimamente estoy jugando mucho con el lenguaje <b>Dart</b>. Una de las cosas a las que más me ha costado acostumbrarme es al modelo de concurrencia basado en la <b>ejecución asíncrona</b> (o "basado en eventos"), heredado de Node.js. En Dart los elementos que se usan para esto se llaman <b>futures o promises</b>, patrones que no son realmente nuevos, aunque no ha sido hasta los últimos años que se han puesto de moda. Para alguien como yo acostumbrado al mundo Java y la <b>concurrencia multithread</b>, esto supone todo un cambio de enfoque en la programación, especialmente cuando programo la parte del servidor.<br />
<br />
Yendo a las raíces de la asincronía, hoy nos preguntamos... ¿<b>cómo se ha llegado</b> a esto?. ¿Realmente <b>es eficiente</b> este modelo en el lado del <b>servidor</b>?. ¿Qué modelo de concurrencia <b>es mejor</b>?. Y en cualquier caso, ¿qué <b>ventajas</b> tiene cada uno?.<br />
<br />
Si tú también te preguntas todo esto, sigue leyendo...<br />
<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh71LrRie21nt9QvAVOYqCaercbagDYIzTL-ZUKCRQCUG-PPPVyaRLj1n1JnsREZLyxEKKipeACzugwV5ChRty9uE6jnGRU5GaWCFEbh9CKwxxqhuqd2pYP566FTgVVu8jg6tgHXPO7eNrB/s1600/uno.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh71LrRie21nt9QvAVOYqCaercbagDYIzTL-ZUKCRQCUG-PPPVyaRLj1n1JnsREZLyxEKKipeACzugwV5ChRty9uE6jnGRU5GaWCFEbh9CKwxxqhuqd2pYP566FTgVVu8jg6tgHXPO7eNrB/s1600/uno.jpg" height="640" width="456" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">De <a href="http://geekandpoke.typepad.com/geekandpoke/2012/09/simply-explained-concurrency.html">Geek and Poke</a></td></tr>
</tbody></table>
<br />
<br />
<br />
<h2>
Concurrencia multithread</h2>
Antes de la irrupción de Java, cuando se quería desarrollar un servidor que respondiera a algún protocolo de comunicación como por ejemplo RPC, lo más usual era programarlo en C ó C++. Habitualmente, se gestionaba la concurrencia con distintos threads de ejecución (o incluso procesos), y cada programador tenía que hacerse su propio pool de threads y su propia gestión de los mismos. Para controlar el <b>acceso a la memoria compartida</b> entre ellos y que no se pisaran unos a otros, lo más habitual era usar <b>semáforos</b>, aunque existían otras soluciones.<br />
<br />
Entonces apareció Java, y encontró un filón en la programación para el servidor. No olvidemos que en C/C++ si se accedía a un puntero null o sin asignar, el servidor entero se caía. Y que cada vez que se reservaba memoria luego había que liberarla explícitamente, con la consiguiente alta probabilidad de memory leaks. Nada de excepciones en el log y nada de garbage collector, comodidades a las que ya nos hemos acostumbrado con cualquier lenguaje y ¡ay, como nos las quiten!.<br />
<br />
En cuanto a la concurrencia, Java también añadía facilidades para el control del acceso a memoria compartida, gracias a <b>la palabra clave synchronized</b>, que permite que bloques de código no puedan ejecutarse por varios threads simultáneamente de una forma más intuitiva que con los semáforos.<br />
<br />
A pesar de todo esto, <b>programar un acceso concurrente mediante varios hilos a un objeto compartido por todo el servidor</b>, algo muy necesario cuando se quiere cachear información de acceso frecuente, sigue siendo <b>realmente peligroso</b>.<br />
<br />
Muchos novatos (o no tan novatos) programarían una información cacheada en un Map que forme parte de un objeto compartido así:<br />
<br />
<pre class="brush:java">private Map<String, Elephant> elephantCache = null;
public Elephant getElephantByCode(String code) {
this.loadElephants();
return this.elephantCache.get(code);
}
private void loadElephants() {
if (this.elephantCache == null) {
this.elephantCache = new HashMap<String, Elephant>();
datos = sqlElephantQuery();
fillElephantCache(datos);
log.debug("Elephant cache filled");
}
log.debug("Done");
}
</pre>
<br />
<br />
¿El problema?. <b>No hay control ninguno del acceso concurrente</b>. Un hilo puede estar intentando meter elementos en el Map de la caché mientras otro intenta acceder a ellos. Lo peor de todo es que lo haces, <b>lo pruebas y... funciona</b>. Y de repente un día tu web empieza a <b>hacer cosas raras</b>. Como poco un error en uno de los hilos, o los dos, y con suerte el objeto se queda incluso en un estado estable.<br />
<br />
<b>Pero puede ser mucho peor</b>. En algunas versiones de Java, incluso, puedo prometer que algo tan tonto como esto puede causar <b>un bucle infinito</b>, lo cual puede llegar a originar, con cierta facilidad, que los hilos empiecen a bloquearse y finalmente <b>tu servidor se muera</b>, llevándose junto a tu aplicación cualquier otra que pueda estar instalada en el servidor de aplicaciones. Y a ver entonces quién es el guapo que encuentra el error, que según las circunstancias de la instalación <b>se puede haber convertido incluso en inencontrable</b>...<br />
<br />
<br />
<h2>
Concurrencia asíncrona</h2>
<div>
Saltamos ahora al JavaScript, para explicar cómo se ha popularizado otro modelo completamente distinto.</div>
<div>
<br /></div>
<div>
Por motivos de seguridad y control, o por simplificar cosas que no necesitaban ser más complejas, JavaScript no permite ejecución multithread con memoria compartida. <b>Sólo un hilo de código propio estará en ejecución</b>.<br />
<div>
<br /></div>
Al principio ni falta que hacía más, el código prácticamente no podía hacer mucho más que manipular el DOM y los formularios. Si había varios eventos, se van encolando todos y procesando uno detrás del otro, nunca varios a la vez.</div>
<div>
<br /></div>
<div>
Luego llegó Ajax, y con él la posibilidad de hacer llamadas HTTP al servidor desde el propio código JavaScript, para luego manipular el resultado. <b>Como sólo hay un hilo de ejecución, no nos conviene que se quede bloqueado esperando el resultado de la llamada HTTP</b>, que obviamente puede ser lenta, como sí se haría en el modelo de ejecución de Java. Lo que nos conviene es que una vez lanzada la petición HTTP, <b>sigamos procesando los siguientes eventos</b> que pueda haber pendientes, y procesemos la respuesta ya cuando se reciba el evento y le toque dentro de la cola.<br />
<br />
El tema se fue complicando cada vez más. La programación en el se ha ido haciendo cada vez más ambiciosa, moviendo al cliente buena parte de la lógica de negocio. Pero sobre todo, un día alguien pensó: ¿por qué no hacer un modelo de servidor basado en JavaScript, que mantenga el mismo lenguaje pero consiga ser concurrente y eficiente sin la problemática de la ejecución multithread?. Y entonces apareció <b>Node.js</b>, y JavaScript pasó al servidor.<br />
<br />
Hay que considerar que en el servidor se usa este mismo sistema de parar la ejecución de un evento y pasar al siguiente cuando se accede a un <b>fichero</b>, o se llama a una <b>base de datos</b>, o se <b>comunica con otro proceso</b>... o sea, para un montón de cosas. Y que mientras que en el cliente se entiende que sólo va a haber una persona interactuando, en el servidor nos pueden llegar muchísimas peticiones en cuestión de segundos. Cada petición HTTP que recibamos se considera un evento, así que no pasaremos a la siguiente hasta que la actual no haya acabado o haga un acceso de entrada / salida. <b>La concurrencia, por tanto, no se produce nunca en nuestro código, sino entre nuestro código y las peticiones de E/S</b>. Es una concurrencia "falsa", en cierto modo. En el fondo se vuelve al modelo de multitarea de Windows 3.1 (y ya sabemos cómo acabó aquello... aunque, bueno, ¡aquello era un sistema operativo!)<b>.</b><br />
<br />
Así que la pregunta es: <b>¿realmente este modelo funciona para una ejecución en servidor?</b>.<br />
<br />
<br />
<h2>
Funcionamiento de los dos modelos y comparativa</h2>
Vamos a aprovechar que tengo aquí a los hermanos Marx y les voy a pedir que me ayuden. Groucho (hablando en azul) y Chico (en rojo) quieren hablar a la vez pero no pueden pronunciar ningún sonido al mismo tiempo (olvidad a Harpo, porque... bueno, es mudo, y además vive en su mundo). Supongamos que <b>cada palabra es una ejecución de código de procesamiento puro</b>: operaciones matemáticas, procesamiento de imágenes, gestión de colecciones en memoria, lo que sea; y que <b>las pausas entre cada palabra</b> son, por ejemplo, <b>accesos a una base de datos</b>. El modelo multithread sería así:</div>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3YOPlqYEBa_iMJBgeg4ar4W3rfbbZ6VlWAQ_R6sjbmXPzuN9cwN1fxjeY-p3AjAwKhYzR2lqD6EPhBrVdDs-Jkgqv_mPLDd7jVqV5WtFJ58Knud6FbSrQFq0hNVB4A5zqqOE1XB5JRMsz/s1600/final0_threads.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3YOPlqYEBa_iMJBgeg4ar4W3rfbbZ6VlWAQ_R6sjbmXPzuN9cwN1fxjeY-p3AjAwKhYzR2lqD6EPhBrVdDs-Jkgqv_mPLDd7jVqV5WtFJ58Knud6FbSrQFq0hNVB4A5zqqOE1XB5JRMsz/s1600/final0_threads.png" height="434" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Concurrencia multi-thread</td></tr>
</tbody></table>
<br />
Aparentemente los dos están hablando al mismo tiempo, aunque en realidad la ejecución está pasando de uno a otro continuamente. El modelo asíncrono, por otra parte, sería así:<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvybPXWy4E9TVk7pOeiBhLYrNJtFItP1mE33Lbh-TsZ3gU7l_08DVDDJoPX-JFiTjGgPpLb-ybOSFqJ4KwFwkaMBXxplhfMaY6HDrSQHfAurBZz5qeP_vptMkjZ6nwM_IFrtwUuuOxycdg/s1600/final0_async.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvybPXWy4E9TVk7pOeiBhLYrNJtFItP1mE33Lbh-TsZ3gU7l_08DVDDJoPX-JFiTjGgPpLb-ybOSFqJ4KwFwkaMBXxplhfMaY6HDrSQHfAurBZz5qeP_vptMkjZ6nwM_IFrtwUuuOxycdg/s1600/final0_async.png" height="434" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Concurrencia con ejecución asíncrona</td></tr>
</tbody></table>
<br />
Como se puede observar, en este caso se ejecuta todo el procesamiento de Groucho un tirón hasta que se llega a un acceso a base de datos (una pausa entre palabras), y mientras se espera a que la base de datos responda, se libera a Chico, hasta que él también llegue a otro acceso a base de datos.<br />
<br />
<b>¿Este modelo funciona, es eficiente?</b>. Pues... <b>depende</b>.<br />
<br />
Supongamos ahora que Groucho suelta su irrefrenable lengua y se pone a hablar y hablar sin hacer pausas entre palabras:<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPEqbBrDPJJPQn3Is-sf8qONZ5WHiI7-A_32L6_SFc4tbuk47caSo4yJg-iZJFK4cT6PntNmEb98A2lnEKzx5sV_1eMbsqrYigViBvRWDOd7fC2GnajoZT03I7PfWpGb8IY4dmrqdbyP7h/s1600/final0_async_problem.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPEqbBrDPJJPQn3Is-sf8qONZ5WHiI7-A_32L6_SFc4tbuk47caSo4yJg-iZJFK4cT6PntNmEb98A2lnEKzx5sV_1eMbsqrYigViBvRWDOd7fC2GnajoZT03I7PfWpGb8IY4dmrqdbyP7h/s1600/final0_async_problem.png" height="434" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Atasco en la concurrencia asíncrona</td></tr>
</tbody></table>
<br />
O dicho de otra forma, supongamos que tenemos <b>una ejecución que requiere mucho procesamiento</b> pero no tiene apenas entrada/salida, es decir acceso a procesos o dispositivos externos como pueda ser los ficheros o una base de datos. Hasta que Groucho no termine su procesamiento, Chico se queda en espera sin poder hacer su parte, con lo que se causa un atasco absolutamente innecesario y que nos llevaría a una situación potencialmente muy ineficiente.<br />
<br />
En el lado positivo, sin embargo, para ejecuciones cortas es de esperar que<b> se ahorre algo de tiempo por no tener que cambiar de contexto entre los threads</b>, y por no tener que controlar la concurrencia en la memoria compartida.<br />
<br />
Buscando un poco se pueden encontrar un montón de <b>comparativas de rendimiento</b> entre los dos modelos. Pero... como podréis suponer, el resultado depende enormemente del tipo de procesos que se estén ejecutando. <b>Es tan fácil hacer trampa con los datos</b> para concluir que el de Node.js es el modelo más eficiente... tan tentador cuando Node.js es tan "cool" y aumenta tanto tu molómetro... hay tanta diferencia entre hacer la prueba con un tipo de procesamiento y con otro... Al final lo que parece que está ocurriendo (como impresión puramente personal) es que muchos piensan que el modelo de Node.js es más rápido y más escalable sólo porque "lo han oído por ahí".<br />
<br />
Mi conclusión principal en cuanto al rendimiento, sin haber hecho yo ninguna prueba real y basándome sólo en la lógica, es que <b>cada modelo será más o menos adecuado según el tipo de aplicación</b>. Si <b>no se hacen procesamientos pesados</b> (pudiendo considerar "pesadas" ejecuciones incluso de sólo unas pocas centésimas de segundo), creo que <b>el modelo asíncrono sí debería funcionar bastante bien</b>. Al fin y al cabo, la mayor parte de las webs actuales dedican la mayor parte del tiempo en servidor a acceder a la base de datos, más que a hacer cálculos o manipulaciones costosas de memoria. Y cuando lo hacen, normalmente es en funcionalidades muy muy localizadas.<br />
<br />
Aparte de con los procesamientos "pesados", es importante tener muchísimo cuidado con no programar ninguna situación que pueda llevar a un bucle infinito, porque eso podría llevar a que se bloqueara por completo el servidor. Y a Chico le podría dar un patatús con tanta espera.<br />
<br />
<br />
<h2>
Necesita un modelo complementario</h2>
En cualquier caso, en mi opinión no basta con eso. Además de usar el modelo asíncrono de forma general, sí queremos hacer aplicaciones de cierto tamaño pienso que <b>el lenguaje nos debe proporcionar otro modelo de concurrencia con el que podamos crear procedimientos que sí se puedan ejecutar sin bloquear a los demás</b>, aunque sea algo puntual y sólo para determinados tipos de procesos. Primero para que podamos aislar de esta forma procesos que podamos tener con uso intensivo del procesador, sin que bloqueen a los demás. Y si no tenemos aún procesos intensivos, porque las aplicaciones crecen, y en cualquier momento, cuando menos lo esperemos, <b>es muy probable que nos vaya a hacer falta alguno</b>.<br />
<br />
Aparte de eso, hay otro motivo: <b>los procesadores actuales tienen varios núcleos</b>, cada vez más, y por tanto realmente <b>SÍ</b> que son capaces de <b>ejecutar varias cosas a la vez</b>. Vale que siempre podemos ejecutar varios procesos de nuestro servidor dentro de la misma máquina y balancearlos, pero aun con eso todo lo que podamos hacer para facilitar el aprovechamiento de los diferentes núcleos dentro de la misma instancia va a ser bueno.<br />
<br />
Otro tema es cómo sea ese mecanismo alternativo que nos pueda proporcionar el lenguaje, y que <b>no tiene por qué tener memoria compartida</b> como en el caso de los threads, con los problemas y los quebraderos de cabeza que hemos visto antes, ya que al fin y al cabo es lo que estamos intentando evitar con todo esto.<br />
<br />
El caso es que todos los lenguajes con ejecución asincronía dan una solución a esto, y todas son muy similares. Básicamente lo que permiten crear son <b>elementos de ejecución en paralelo que tienen su propio espacio de memoria</b>, y que se comunican entre sí mediante paso de mensajes. En JavaScript en el cliente (HTML5) existen los <b>webworkers</b>. En Node.js son <b>subprocesos</b>.<br />
<br />
En <b>Dart</b> estos elementos reciben el nombre de <b>isolates</b>, y por definición no se indica cómo se implementan en el servidor, si con subprocesos o con threads. La diferencia entre hacerlo con uno u otro, al ser memoria independiente, no afecta a la forma de programarlos, pero <b>sí al rendimiento</b>. Crear un subproceso es bastante más costoso que un thread, y la comunicación entre procesos también es más lenta.<br />
<br />
Lo curioso del caso es que los isolates se iban a implementar originalmente en Node.js, pero finalmente <a href="https://groups.google.com/forum/#!msg/nodejs/zLzuo292hX0/F7gqfUiKi2sJ">lo descartaron</a>. Al parecer probaron a hacerlo pero esto causó inestabilidad en el servidor, así que decidieron pasar y quedarse sólo con los subprocesos. Más allá de que se me quedan un poco los ojos como platos con el tema, el acercamiento de Dart de crear la semántica de los isolates sin indicar cómo se implementan internamente parece prudente porque se cura en salud "por si acaso".<br />
<br />
<br />
<h2>
Conclusiones</h2>
Diablos, no me cae bien Node.js. Es hipster, sorprendentemente se ha puesto de moda y parece que se ha exacerbado de forma absurda. ¿Programar en JavaScript también en el servidor?. ¿Como si no tuviéramos bastante con el cliente?. ¡Uf!<br />
<br />
Sin embargo, tengo que reconocer que <b>sí me gusta su modelo de ejecución asíncrona</b>. Yo ya estoy curtido con los threads y no tengo ningún problema en utilizarlos, pero reconozco que cada vez que veo a un novato creando código con objetos compartidos en memoria tiemblo tanto que al final le tengo que poner una velita a la Santa Virgen de los Javitos Desamparados.<br />
<br />
Imagino que en el fondo lo que me pasa es que por mucho que no me caiga bien Node.js, <b>odio mucho más la programación concurrente</b>. Tantos ConcurrentModificationException, tantos servidores fritos, tantos días dedicados a perseguir errores imposibles, tantos WTF! al revisar código concurrente hecho por otros... (como ya sabemos, seamos quien seamos los WTF siempre son con el código de los demás, nunca con el nuestro propio!).<br />
<br />
Salvo necesidad perentoria o extorsión, no pienso ponerme a programar en Node.js. Pero al final <b>este mismo modelo de ejecución es el que ha heredado el lenguaje Dart</b>. Y como ya comenté hace tiempo, <a href="http://apagayvuelveaencender.blogspot.com.es/2013/11/aparta-javascript-llega-dart.html">Dart me parece un grandísimo avance sobre JavaScript</a>.<br />
<br />
En definitiva, el modelo me parece una buena alternativa. Principalmente, porque <b>soluciona problemas antes de que ocurran</b>. Y mientras se tenga un poco de cuidado en no poner ejecuciones con mucho procesamiento matemático o en memoria, no sé si el rendimiento será un poco mejor o un poco peor que en el caso de los threads, pero estoy seguro de que en cualquier caso será más que suficiente.<br />
<br />
Como tantas y tantas cosas en la vida, <b>esto también tiene un precio</b>. Y es que aunque elimine los errores de concurrencia, programar el código con este modelo puede llegar a ser un pequeño dolor de cabeza, y requiere acostumbrarse a ello. Pero de eso <b>ya hablaré en la segunda parte del artículo</b>... pronto en su kiosko o ultramarinos más cercano.<br />
<br />
<br />Andréshttp://www.blogger.com/profile/06010147149377176406noreply@blogger.com3tag:blogger.com,1999:blog-6416070227303513915.post-72967459328498544822014-01-29T01:43:00.001+01:002014-01-29T01:43:36.685+01:00Jugar mientras conduces ES POSIBLETanto cacharrito, tanto Internet de las cosas, tanto móvil, tablet, reloj, gafas, pulsera, ¡tanta leche!... y oye... ¡¡¡que <b>KITT, el coche fantástico</b>, sigue sin existir!!!.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwuJ35rnNmhj2C37UpsNSdpYXEwlL-hyIucgLJyaS7qxt_Qb1JCMEKSWckuqL7Iz23P213h-hXTu6K84NA5QDfVRAvSgysGWWq_u2ycDNQqwQAuKByFvsIm4EqDf6mukeu8X09OkqfKvHU/s1600/uno.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwuJ35rnNmhj2C37UpsNSdpYXEwlL-hyIucgLJyaS7qxt_Qb1JCMEKSWckuqL7Iz23P213h-hXTu6K84NA5QDfVRAvSgysGWWq_u2ycDNQqwQAuKByFvsIm4EqDf6mukeu8X09OkqfKvHU/s1600/uno.jpg" height="480" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">El glamour y chulería de David Hasselhoff van aparte, practica todos los días frente al espejo y lo conseguirás. ¡Tú puedes!</td></tr>
</tbody></table>
<br />
<h2>
"Smart cars"</h2>
Lo cierto es que se está trabajando en ello, pero claro, no se tarda lo mismo en hacer un coche que una pulsera. El camino se está marcando: <a href="http://appleinsider.com/articles/13/06/07/bmw-says-siri-eyes-free-support-will-come-to-all-of-its-2014-models">BMW y Chevrolet apuestan por los iPhone y su Siri Eyes Free</a>, y parece que ya ha salido algún modelo y se esperan más durante este mismo año. Otros como <a href="http://www.caranddriverthef1.com/coches/planeta-motor/86091-la-tecnologia-conectividad-ford-y-microsoft-llega-espana">Ford apuestan por un sistema Sync de Microsoft</a>, sobre el cual tengo unas ganas enormes por ver cómo reproducirán de forma sonora los pantallazos azules (apuesto a que sonará como los pitidos de carga de juegos del ZX Spectrum).<br />
<b><br /></b>
<b>Audi parece hoy por hoy la más atrevida</b>, y <a href="http://www.motorpasion.com/audi/audi-muestra-el-interior-del-tt-2014-en-el-ces-de-las-vegas">apuesta por su propia pantalla Virtual Cockpit</a> integrada en lugar del clásico cuadro de mandos, y apuesta por <b>la estandarización de Android</b> y se alía con Google y otros fabricantes como General Motors, Honda y Hyundai para crear la <a href="http://www.openautoalliance.net/#about">Open Automotive Alliance</a>.<br />
<br />
En fin, aparentemente la baraja está lista y sólo queda echar las cartas. La referencia por ahora es <a href="http://news.drive.com.au/drive/motor-news/ces-2014-car-gadgets-coming-soon-20140109-30j28.html">el CES2014, que es donde se han presentado todas estas novedades de los coches</a>, y según eso aparentemente este mismo año se empezarán a ver cosillas en la calle. De hecho, si comparamos las fotos que se están mostrando ahora de los cuadros de mandos de Audi con el de KITT la verdad es que por ahí ya vamos ganando.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEharXa6HjRuvd7fkVIhXL5xB4nekH3Mm7yTOz-gFAPeo9M-KF6Pl6NLwNBMC3S9IGS-xuhJjHCqS0_pLnd4lJlsYdzYR5a6jnxxJQYpg-BT0RX6Nab79rJopCWixccTyJUavsZz1dppWCCU/s1600/uno.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEharXa6HjRuvd7fkVIhXL5xB4nekH3Mm7yTOz-gFAPeo9M-KF6Pl6NLwNBMC3S9IGS-xuhJjHCqS0_pLnd4lJlsYdzYR5a6jnxxJQYpg-BT0RX6Nab79rJopCWixccTyJUavsZz1dppWCCU/s1600/uno.jpg" height="179" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Audi Virtual Cockpit</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; margin-left: 1em; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj7p6KyFVSZsFQ0uZXGyBGd6hJ0AhrkBgvwv3cdKCuBg2BmKL_JQXOia8zkPUnzPwMfjMPr_UnRYVz8LYFU3bmLw9MFHSKMj1IhqStno1tlvFoq6RA_Ki-z4dYaajVJ1cRATTYD6TySNG_u/s1600/uno.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj7p6KyFVSZsFQ0uZXGyBGd6hJ0AhrkBgvwv3cdKCuBg2BmKL_JQXOia8zkPUnzPwMfjMPr_UnRYVz8LYFU3bmLw9MFHSKMj1IhqStno1tlvFoq6RA_Ki-z4dYaajVJ1cRATTYD6TySNG_u/s1600/uno.jpg" height="112" width="200" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Más Audi, ¡leche!</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEdqLA4f_0jJWKjjO4BvWuUEU6CtNKUmwAyu_S8xkfVwTd_j614JMX5Yq9C1uBPYPYFDECW0A3ZxDObxe0Ek-kH1JYEYWn6HOT2YAQBmUJWb9KRgNGGmKDRGizg9xM8tkNPPkuXjU3Sua7/s1600/uno.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEdqLA4f_0jJWKjjO4BvWuUEU6CtNKUmwAyu_S8xkfVwTd_j614JMX5Yq9C1uBPYPYFDECW0A3ZxDObxe0Ek-kH1JYEYWn6HOT2YAQBmUJWb9KRgNGGmKDRGizg9xM8tkNPPkuXjU3Sua7/s1600/uno.jpg" height="209" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">KITT, vintage a tope pero... ¡más mono!</td></tr>
</tbody></table>
<br />
¿Y qué harán estos smart cars, o como vayan a llamarlos?. Navegador GPS, claro. ¿Y aparte?... ayudas para aparcar, que el coche te lea los wasap y correos, ayudas a la conducción... ¡BOBADAS!. Vale, seguro que el coche conduce mejor que mucha gente pero ¿de verdad te vas a fiar hoy por hoy de lo que conduzca?.<br />
<br />
<b>A mi todo eso me da igual</b>. Yo lo único que quiero es que ya que tiene tanto cacharro y tanta gaita, cuando tenga un viaje en el que vaya yo solo conduciendo no tenga que estar aburrido oyendo música o cualquier chorrada que pongan en la radio. Lo que yo quiero es que... <b>¡PUEDA JUGAR!</b>.<br />
<br />
Sin matarme al hacerlo, claro.<br />
<br />
<br />
<h2>
¿Cómo puedo jugar sin usar las manos ni apartar la vista?</h2>
Esta es la pregunta clave: ¿es posible?. Previsiblemente, al menos cuando la cosa esté lo bastante avanzada, <b>el interfaz con el smart car tiene que ser fundamentalmente a través de la voz</b>. Cada vez que quieras que el coche haga algo, le hablas. Para que reconozca que quieres hablar con él, supongo que al principio seguramente tengas que pulsar un botón o una palanca del volante, pero lo normal es que llegue un momento en que <b>el coche esté continuamente activo esperando a que le digas algo, y que reaccione ante una palabra clave: su nombre</b>. Incluso, se podría poner en "modo conductor solitario" y que reaccionase ante cualquier cosa que le dijeras sin tener que decir su nombre.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4GYNiYD5XJi9pXxBmA9eaCL-QOtM6wLoZo7QDIErpbUhorMJ33s36-YOEHQsrnyQXUM0yAB1I_X2K98ORXgOiCGFZT4CsOs8KyiDNA2PAXS8R4HmuWBkdOMSH86RviaiQUyxiSPIfT3cv/s1600/uno.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4GYNiYD5XJi9pXxBmA9eaCL-QOtM6wLoZo7QDIErpbUhorMJ33s36-YOEHQsrnyQXUM0yAB1I_X2K98ORXgOiCGFZT4CsOs8KyiDNA2PAXS8R4HmuWBkdOMSH86RviaiQUyxiSPIfT3cv/s1600/uno.jpg" height="244" width="320" /></a></div>
Se ha trabajado mucho en <b>reconocimiento de voz</b> últimamente. Antes en inglés todavía, pero en español no reconocía ni papa. Ahora con los avances del <b>Siri de Apple y el Google Now</b>, más otros "outsiders" como <a href="http://sher.pa/"><b>Sherpa</b></a> (que además es español), el reconocimiento de voz está mejorando cada vez más. Ya se puede hablar con el móvil y mientras lo hagas con cierta calma, funciona bastante bien. Cualquiera podéis hacer la prueba con vuestro smartphone, si no lo habéis probado aún. Creo que todavía le falta un puntito para que sea más cómodo, para <b>poder hablar con menos cuidado y que te siga entendiendo</b>, pero no me cabe duda de que se conseguirá.<br />
<br />
El coche, por supuesto, también responderá con la voz. La <b>síntesis de voz</b> también funciona muy bien actualmente. Cualquiera que hayáis usado un GPS en vuestro móvil lo habréis visto. Existen otros motores de síntesis de voz más avanzados, que a menudo son de pago. El reto en este caso es conseguir que <b>la voz tenga alma</b>. Que sea capaz de entonar un poco, no sólo leer. ¡Diablos, al menos como lo hacía KITT, que tampoco era el alma de la fiesta!<br />
<br />
Entonces, de lo que se trataría es de <b>encontrar un tipo de juego que se pueda jugar sólo con la voz, hablando con el coche</b>. Y que no sea el "veo veo", vaya.<br />
<br />
El caso es que existe un tipo de juegos que encaja perfectamente con esta forma de comunicación: <b>las aventuras conversacionales</b>.<br />
<br />
<br />
<h2>
Aventuras conversacionales</h2>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmNyrn6buVom8ohe5Cogj9mbx3PgZ4FfsUzQwyVLWYPKdth5d4RzcyPKuUXRp3Jz40rKfj0B9inQa2-kHtDTvmpypwEfeNksNCf9rWVdfZ_FvkPyb4pZ4V_n6hN25wYGHCNVY0p7FVLLTt/s1600/uno.jpg" height="275" style="margin-left: auto; margin-right: auto;" width="400" /></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Sin gráficos: <a href="http://www.caad.es/fichas/fotopia.html">Fotopía</a></td></tr>
</tbody></table>
<br />
Las <a href="http://es.wikipedia.org/wiki/Aventura_conversacional">aventuras conversacionales</a>, o interactive fiction (IF) como se las conoce en inglés, son un tipo de juego antiiiiiiiiiiiiguo. La primera se considera que es Adventure, data del año 1975 y se programó en Fortran en un PDP-10. O sea, tela. Sin embargo, vamos a ver cómo su simplicidad y su falta (o no necesidad) de gráficos juegan muy en su favor en este caso.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJdRrqJ4PTRdbQvY3K6_XTRyz3yemJR-Qehn7BPO_aPMH1tSvMnrDqDj8i090Rk1oxWM4zVSu9Rrcgmoue2joRjp0_O0VT4A1h0ZxWl3vCEDHK0Ky5aGLzawHfbE5QBzDdAx6BJkNaNw7O/s1600/uno.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJdRrqJ4PTRdbQvY3K6_XTRyz3yemJR-Qehn7BPO_aPMH1tSvMnrDqDj8i090Rk1oxWM4zVSu9Rrcgmoue2joRjp0_O0VT4A1h0ZxWl3vCEDHK0Ky5aGLzawHfbE5QBzDdAx6BJkNaNw7O/s1600/uno.png" height="352" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Distribución típica, con gráficos arriba: <a href="http://www.caad.es/fichas/a%C2%B7l%C2%B7i%C2%B7e%C2%B7n-la-aventura.html">Alien</a></td></tr>
</tbody></table>
<br />
En una aventura conversacional, <b>se te cuenta una historia y se te pone en situación </b>y describe tu localización actual <b>mediante texto</b>. Entonces tú, el jugador, <b>escribes también por texto y en lenguaje "natural" lo que quieres hacer</b>. El juego devuelve el resultado de tu acción otra vez como texto, y así sucesivamente, de forma que se crea una conversación entre el juego y tú. La historia va evolucionando con lo que vas haciendo, y se te van presentando <b>retos y puzzles a resolver</b>.<br />
<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgGA5q67OmFImw2nkoM9RpJ0Qo20OwB-1Dem_pEq1D4-IDBTQzduBc0gjFYOsPgJyN1bQbrWgAF3dMiblD_RCTGlWLAF-dbylWDuDw6Uhf0CNnAW5iQYDfOqjr0WlvMEl7fl_A7slwp_hV_/s1600/uno.jpg" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgGA5q67OmFImw2nkoM9RpJ0Qo20OwB-1Dem_pEq1D4-IDBTQzduBc0gjFYOsPgJyN1bQbrWgAF3dMiblD_RCTGlWLAF-dbylWDuDw6Uhf0CNnAW5iQYDfOqjr0WlvMEl7fl_A7slwp_hV_/s1600/uno.jpg" height="200" width="165" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">de computeremuzone.com</td></tr>
</tbody></table>
Puede que te suenen porque en España tuvieron su época dorada en los años 80-90, cuando <a href="http://es.wikipedia.org/wiki/Aventuras_AD">Aventuras AD</a> lanzó para los ordenadores de 8 bits juegos como <a href="http://wiki.caad.es/La_Aventura_Original">La aventura original</a>, <a href="http://wiki.caad.es/Don_Quijote,_La_Aventura">Don Quijote</a>, <a href="http://wiki.caad.es/El_Jabato">El Jabato</a> o <a href="http://wiki.caad.es/Cozumel">La Diosa de Cozumel</a>. Incluso, por entonces llegaron a España varios juegos en inglés, especialmente <a href="http://en.wikipedia.org/wiki/The_Hobbit_(1982_video_game)">El Hobbit</a>, y que obligaron a muchos jóvenes de la época a tirar de diccionario. Aunque ya por entonces la mayor parte de los juegos tenían gráficos descriptivos de las localidades, lo cierto es que dichos gráficos eran normalmente superfluos y no afectaban al desarrollo del juego, y su objetivo fundamentalmente es hacer los juegos más atractivos a la vista (cosa que nos importa poco mientras conducimos).<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<b>Este tipo de juegos, evidentemente, encaja perfectamente con un interfaz de voz</b>. Tú dices lo que quieres hacer, el coche responde. Curva cerrada a la derecha, te callas y te concentras. Vuelves al juego, dices lo siguiente... te puedes tirar un montón de tiempo así. Y creo que a la vez, aparentemente <b>no es tan inmersivo como para que pierdas la concentración en la conducción</b>.<br />
<br />
Y además... <b>¡son un tipo de juegos muy divertidos!</b> (incluso si no los comparamos sólo con el veo-veo).<br />
<br />
Esta sería una hipotética transcripción de una conversación entre KITT (obviamente llamaríamos así a nuestro coche) y tú, que dé paso a una sesión de jugar una aventura:<br />
<br />
<br />
<div style="background-color: #f0f0f0; margin-left: 1em; margin-right: 1em; padding: 1em;">
KITT: Buenos días, Andrés<br />
<br />
Andrés (reemplázalo con tu nombre para disfrutarlo más): Hola, KITT<br />
<br />
K: ¿Dónde vamos?<br />
<br />
A: Vamos a casa<br />
<br />
K: ¿A casa, a la calle Ríos Rosas?<br />
<br />
A: Sí, eso es<br />
<br />
(KITT programa el GPS y tú mientras arrancas y te pones en camino)<br />
<br />
A: KITT, vamos a jugar a Olvido mortal<br />
<br />
K: Cargando Olvido mortal. Continuamos la partida que dejaste ayer. ¿Correcto?<br />
<br />
A: Sí<br />
<br />
KITT: Oficinas<br />
Estás en una especie de oficinas.<br />
No ves ningún cartel que te indique qué lugar es este. La cola se extiende por la alargada localidad, enorme. Por detrás, una pared te impide ver dónde acaba. La fila de gente continúa por una puerta abierta en la pared.<br />
En el otro sentido, las cabezas te impiden ver qué hay al principio de la cola.<br />
<br />
La mujer de delante en la cola parece ser la única persona que te presta algo de atención.<br />
<br />
<br />
(un chalao se te cruza en ese momento y te centras en lo tuyo)
<br />
<br />
A: Perdona, KITT, ¿puedes repetir?
<br />
<br />
K: Oficinas.......... (y repite toda la descripción, ¡más majo!)
<br />
<br />
A: Resumen
<br />
<br />
K: Despertaste en la cola sin recordar quién eras ni dónde estabas.
<br />
<br />
A: Inventario
<br />
<br />
K: Llevas: una cartera (que está cerrada)
<br />
<br />
A: Abre la cartera
<br />
<br />
K: Abres la cartera, descubriendo un carnet de identidad y una foto.
<br />
<br />
A: Mira el carnet<br />
<br />
K: Es un carnet de identidad normal y corriente. La foto del carnet está un poco difuminada, pero se ve lo suficiente.<br />
<br />
"¿Es posible que ese sea yo?. Desde luego, la cara me resulta familiar, pero no soy siquiera capaz de asegurar tajantemente que sea la mía."<br />
<br />
<br />
(...)<br />
(y así pasa el tiempo y cuando te quieres dar tiempo estás ya en casa... ¡y no quieres dejar de jugar!)</div>
<br />
<br />
<br />
¿Qué tal, te convence?. ¡¡¡A mi sí!!!<br />
<br />
Otra buena noticia es que muchos de estos juegos son multi-plataforma y se ejecutan sobre una máquina virtual. O dicho de otra forma: <b>es muy muy fácil adaptar un intérprete de estos juegos para que se ejecute en un coche y se juegue con la voz</b>. Y automáticamente, en cuanto tengas hecho el intérprete, <b>tienes disponibles cientos, miles de juegos, listos para jugar</b>.<br />
<br />
En español, el mejor sitio donde encontrar juegos es <a href="http://www.caad.es/"><b>la web del CAAD</b></a>, el sitio donde se reúnen todos los "chalaos" de este tipo de juegos y aúnan esfuerzos alrededor de la aventura. Una de las grandes ventajas que tienen estos juegos, además, es que casi cualquiera puede programar uno. No hace falta ser programador, ni tampoco saber dibujar ni componer música. Esto ha hecho que se cree una comunidad alrededor de ellos y que se sigan programando juegos. En inglés, por otra parte, la comunidad es aún más activa y para descargar juegos tenemos el <a href="http://ifarchive.org/">Interactive Fiction Archive</a>.<br />
<br />
Si queréis probar con alguno de estos juegos, ¡qué demonios!. ¡Prueba alguno de <b>los que he hecho yo</b>! Sí, así a lo tonto y mientras hablaba de "esos chalaos" en tercera persona, os metía de tapadillo <b>mis juegos</b> (hechos hace ya un buen montón de años, en el 2001, ahí es ná): <a href="http://www.caad.es/fichas/olvido-mortal.html"><b>Olvido mortal</b></a>, que ya habéis probado un poco con KITT pero podéis <b><a href="http://iplayif.com/?story=http://www.caad.es/jugar/aventuras/olvido.z5">jugar online aquí</a></b>, y <a href="http://www.caad.es/fichas/akbarr-pc.html"><b>Akbarr</b></a>.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbLJcSuIZoTEhWQW7QGXNT_2ILSTorvDjxmoXM9Zte4A6JuYUF1tnc8NVTx-KBnAu5KeHOy1yeYGlp1iHayPp0LD_pulGouXmyd4IthpCfG96CugqZo1McDRuE9B7f1wWQDvjQDZXjhjgq/s1600/uno.gif" imageanchor="1" style="display: inline !important; margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbLJcSuIZoTEhWQW7QGXNT_2ILSTorvDjxmoXM9Zte4A6JuYUF1tnc8NVTx-KBnAu5KeHOy1yeYGlp1iHayPp0LD_pulGouXmyd4IthpCfG96CugqZo1McDRuE9B7f1wWQDvjQDZXjhjgq/s1600/uno.gif" height="300" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Forma original en forma de libro: <a href="http://www.caad.es/fichas/akbarr-pc.html">Akbarr</a></td></tr>
</tbody></table>
<br />
<br />
<h2>
Conclusión</h2>
<div>
Esto no es más que elucubrar pero, ¿por qué no?. <b>Está todo ahí</b>: los <b>coches</b> ya produciéndose integrados con <b>tecnologías móviles</b> como Android e iPhone, <b>los motores de reconocimiento y síntesis de voz</b> a un puntito de ser cómodos y molones, justo ese puntito de más que daría el interés por el mercado de los coches... y <b>las aventuras conversacionales</b> ahí, listas para que las juguemos charlando con nuestro coche mientras hacemos un viaje.</div>
<div>
<br /></div>
<div>
¿Y vosotros, qué pensáis de todo esto?...</div>
<div>
<b><br /></b></div>
<div>
<b>¿Y tú, KITT?. ¿Te apetece que juguemos?.</b></div>
<div>
<br /></div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
Andréshttp://www.blogger.com/profile/06010147149377176406noreply@blogger.com9tag:blogger.com,1999:blog-6416070227303513915.post-23243470572860882362013-12-29T13:13:00.000+01:002014-01-28T23:11:38.508+01:00Proyecto Picross: haciendo un videojuego HTML5 en DartYa lo dije en <a href="http://apagayvuelveaencender.blogspot.com/2013/11/aparta-javascript-llega-dart.html"><b>mi anterior entrada sobre el lenguaje Dart</b></a>: Dart está muy bien, puede suponer una revolución en la web y su futuro potencialmente es muy prometedor. Pero claro, una cosa es el posible futuro y otra es el presente. ¿Cuál es realmente <b>el estado actual</b> de la plataforma Dart?.<br />
<br />
Por otra parte, otra tecnología que me llama la atención es la de los <b>videojuegos HTML5</b>. Sobre todo para videojuegos 2d, sencillos, que aparentemente ya deberían poder hacerse en la web. Con la gran ventaja de ser <b>multiplataforma</b>, que se puedan jugar en Android, en iOS, o hasta desde el Facebook, y en este último caso sin tener que instalar nada. ¿Están estas tecnologías suficientemente maduras?.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvxClqbBb2q6gzkPYxzPbbikWnPyLoLa5Eh9jptAl6VcqUPrk9NOikX4smA8rYbejANldj7AMkWgNYKb5iktTYxgegO9kfMB6FXm27b_PgkUh4r_OJnytFiREo3oKKiYltVijQCo8MOjrI/s1600/uno.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvxClqbBb2q6gzkPYxzPbbikWnPyLoLa5Eh9jptAl6VcqUPrk9NOikX4smA8rYbejANldj7AMkWgNYKb5iktTYxgegO9kfMB6FXm27b_PgkUh4r_OJnytFiREo3oKKiYltVijQCo8MOjrI/s640/uno.png" height="360" width="640" /></a></div>
<br />
<br />
Con ánimo de comprobarlo y a la vez divertirme, me lié la manta a la cabeza, uní las dos inquietudes y me puse a hacer ¡<b>un videojuego en Dart</b>!. Y aquí cuento todo el proceso, que duró sólo una semana, pero que me dio para asistir a la Gameme5 e incluso participar en la PiWeek.<br />
<br />
<br />
<h2>
La GameMe5</h2>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhRC97JvasczDONiCFSfS06S86roZN9f89oRg49zhKPumOkI-yad40n4q96nPoFqYcSLl_IY8HHYCfmNfg8DUwKOR9gLttVtTP6MA0HZppBNHqe-pP2uGI39vzhKVqsJoWnbqZ3C7WjSOqB/s1600/uno.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhRC97JvasczDONiCFSfS06S86roZN9f89oRg49zhKPumOkI-yad40n4q96nPoFqYcSLl_IY8HHYCfmNfg8DUwKOR9gLttVtTP6MA0HZppBNHqe-pP2uGI39vzhKVqsJoWnbqZ3C7WjSOqB/s200/uno.png" height="200" width="178" /></a></div>
Yo de videojuegos en HTML5, la verdad, <b>ni idea</b>. Afortunadamente, estaba apuntado a la <a href="http://html5-spain.com/html5-spain/GameMe5/"><b>GameMe5</b></a>, un evento organizado por <a href="http://html5-spain.com/html5-spain/">HTML5 Spain</a> y <a href="http://www.wimi5.com/">Wimi5</a> en el que ofrecían un taller de programación de videojuegos en Javascript el Viernes y varias charlas el Sábado.<br />
<br />
El taller lo daban Carlos Benítez (<a href="https://twitter.com/EtnasSoft">@EtnasSoft</a>) y Sergio Ruiz (<a href="https://twitter.com/serginator">@serginator</a>), y en él fueron explorando <a href="https://github.com/serginator/workshopGameMe5">un juego que se habían currado aposta</a> y que era muy muy completito, desarrollado enteramente en Javascript a pelo y sin librerías.<br />
<br />
Fueron avanzando poco a poco en el desarrollo y cubrieron muy bien muchos aspectos del desarrollo de videojuegos en general y de Javascript en particular, desde los temas más básicos como el <b>loop principal y el doble buffer</b> hasta otros más complejos como las rotaciones, los fondos por trocicos (en mosaicos), los métodos de detección de colisiones, algoritmos de búsqueda (pathfinders), manejo de física y sistemas de partículas. Lo mejor del taller es que aparte de estos aspectos más o menos generales de los videojuegos, iban comentando también temas de <b>rendimiento y problemas de Javascript</b>. Dijeron que un buen juego JS puede llegar a estar a la altura de un juego de PS2, si es 2d, o entre PS1 y PS2, si es 3d. Pero además comentaron problemas que tenían los navegadores si querían hacer efecto espejo automáticamente en las imágenes, usar base64 o como no tuvieran cuidado con los arrays y el recolector de basura (al eliminar un elemento de un array no lo elimina de verdad, sino que lo deja pendiente de GC, lo cual puede llegar a causar un parón sensible en un videojuego).<br />
<br />
En las charlas del día siguiente hubo de todo, pero me gustaría destacar sobre todo 3 que fueron especialmente interesantes. En la primera, José Javier García-Aranda de Alcatel-Lucent hablaba sobre un algoritmo en el que están trabajando para compresión de imágenes y vídeo, <a href="http://www.dit.upm.es/doct/SI/2013-2014/2013-10-22-LHE_v003.pdf" style="font-weight: bold;">LHE</a> (Logarithmical Hopping Encoding), y que puede ser muy potente para el <b>Cloud Gaming</b> y las videoconferencias, ya que se consiguen tiempos de codificación rondando los 2ms y una calidad decente a 0,1 bits por pixel. Fue una de esas charlas que destacan porque lo que se cuenta es muy interesante, se entiende muy bien y además el ponente es muy ameno.<br />
<br />
En la segunda Jorge del Casar (<a href="https://twitter.com/JorgeCasar">@jorgecasar</a>) hablaba sobre <b>WebSockets</b>, y nos hacía una demo con un Tetris multi-jugador.<br />
<br />
Y por último Imanol Fernández (<a href="https://twitter.com/MortimerGoro">@MortimerGoro</a>) de Ludei nos daba una apabullante lección sobre <b>rendimiento de Javascript</b>, haciendo una demostración de un pequeño programa que tardaba 600 veces más en su versión Javascript que en la versión C++, y luego le aplicaba muchos trucos hasta conseguir que fuera "sólo" 6 veces más lenta. Sobre todo se usaron técnicas para conseguir que el compilador JIT de Javascript hiciera "inline caching" de las funciones más importantes, ya que es muchísimo más rápido, con cosas tan aparentemente absurdas como borrar un comentario o borrar un try-catch. Por ahí rondaron conceptos como las "hidden classes" (que se crean cuando añades atributos nuevos en tiempo de ejecución, y que ralentizan bastante) y arrays de más de 64K (leeentos). Pero vamos, si os interesa el tema, lo mejor es que veais la <a href="http://mortimergoro.github.io/SuperSaiyanJS/#/15"><b>presentación completa</b></a>.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjEwlPuQTYPbMWhccnTjhdNUfmsvEc43K9695VgGJSbWdV6cPh73GxZIRXGEZ9XfM63hGqj7PDCiEQIxp6SgQSZDvy70R6rC-HlE-kS3izV98BikKoYcOoN9WjVe9vwoXpyJXQOIuYRSoLM/s1600/uno.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjEwlPuQTYPbMWhccnTjhdNUfmsvEc43K9695VgGJSbWdV6cPh73GxZIRXGEZ9XfM63hGqj7PDCiEQIxp6SgQSZDvy70R6rC-HlE-kS3izV98BikKoYcOoN9WjVe9vwoXpyJXQOIuYRSoLM/s200/uno.png" height="200" width="186" /></a>Aparte de eso, también nos habló de <a href="https://www.ludei.com/cocoonjs/"><b>CocoonJS</b></a>, una herramienta que ha hecho que permite <b>publicar tus videojuegos HTML5 en móviles</b>, pero que al contrario que Phonegap, en lugar de utilizar los browsers que vienen de serie en las respectivas plataformas, utiliza uno propio, con su propia implementación de canvas, audio, webGL, etc., y con un <b>rendimiento optimizado</b> respecto a los otros (are we crazy? yes, but we're from Bilbao). La verdad es que tenía una pinta tremenda.<br />
<br />
<br />
<br />
<h2>
El videojuego: Picross</h2>
La verdad es que la GameMe5, en la práctica, sirvió a mi proyecto sobre todo para una cosa: <b>acojonarme</b>. Tanta optimización, tanto comportamiento extraño de los motores JS, tanto lío con los navegadores, tanta facilidad para quedarse sin memoria... y voy yo y le meto una capa más de riesgo por encima, Dart.<br />
<br />
Así que decidí que ya tenía bastante cubierto mi cupo de riesgo y decidí hacer un juego sencillito, que no requiere gran rendimiento pero que a la vez escala muy bien, y da para ir añadiéndole cositas poco a poco. <b>Y por supuesto, ¡muy divertido!</b>.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmMUMAqCNTGbkgcH6aNbdCqosH9ZBzHcA9J-WesZ11IeUa237xyHCD5LM4NIuNUyf8hQHJ4SYZ_PrYr7-1X1iDUx1Vpq3giZC5VtJSCQ3Srq1dRvOPFI0QPWTv1-Rkp_cdeXjQW4eBrRTR/s1600/uno.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmMUMAqCNTGbkgcH6aNbdCqosH9ZBzHcA9J-WesZ11IeUa237xyHCD5LM4NIuNUyf8hQHJ4SYZ_PrYr7-1X1iDUx1Vpq3giZC5VtJSCQ3Srq1dRvOPFI0QPWTv1-Rkp_cdeXjQW4eBrRTR/s200/uno.jpg" height="179" width="200" /></a><b>Picross</b> es un juego de tipo puzzle que se conoce por muchos otros nombres de los cuales el parecer el más oficial es <a href="http://en.wikipedia.org/wiki/Nonogram">"nonogramas"</a>. Habrán salido millones de versiones del juego, tanto para ordenador como en papel, pero la que se hizo más famosa en su día fue <a href="http://es.wikipedia.org/wiki/Picross_DS">la versión de Nintendo DS</a>, o al menos esta es la que yo conocía y de la que me vicié hace años. Como buen juego de puzzles, se puede dejar el rendimiento un poco de lado y que siga siendo jugable, y eso es lo que a mi me importaba llegado a este punto. Sobre todo, porque tenía que tener una versión presentable en una semana, ya que me había presentado a la PiWeek.<br />
<br />
El funcionamiento del juego es sencillo: hay una matriz de celdas, y cada una de ellas es un píxel, que puede ser blanco o negro. Todas juntas forman <b>un dibujo binario que es el que hay que averiguar</b>. Para hacerlo, cada fila y cada columna tienen una serie de números que indican los <b>grupos de píxels negros</b> que son consecutivos. Por ejemplo, si en una fila pone "3 2" significa que hay 3 píxels negros seguidos y luego separados otro grupo de 2 píxels negros. Entre medias, antes y después, hay un número indeterminado de píxels blancos. Combinando las pistas de las filas y las columnas, se va averiguando el dibujo.<br />
<br />
<br />
<h2>
La PiWeek</h2>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmz4dg2w0M1a7DY7m77xU38yS41EuVqOZEO5XMFfx1IxYtHhoYk5dQiWuSaKAKeMYKM2GDo2TnKxbVSm4pepnUG9q98TeHzJAEBgbmjU-f12WJkJTYOLyu9Vq3BG8uBV-vN69HZJT7eRm0/s1600/uno.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmz4dg2w0M1a7DY7m77xU38yS41EuVqOZEO5XMFfx1IxYtHhoYk5dQiWuSaKAKeMYKM2GDo2TnKxbVSm4pepnUG9q98TeHzJAEBgbmjU-f12WJkJTYOLyu9Vq3BG8uBV-vN69HZJT7eRm0/s1600/uno.png" /></a></div>
<a href="http://kaleidos.net/"><b>Kaleidos</b></a> es una empresa de desarrollo que probablemente pueda presumir de tener el mayor ratio de densidad de <b>geeks por metro cuadrado</b> en toda España. Se definen como una empresa orientada a proyectos de innovación, así que tienen varias iniciativas muy interesantes orientadas a la innovación y la mejora. Una de ellas es <b>la PiWeek</b> ("Pi" de "Personal innovation"), <b>una semana entera en la que paran por completo todos los proyectos que estén haciendo en ese momento para hacer... lo que le dé la gana a cada uno</b>. Así, tal cual, lo que sea que le interese. Las únicas reglas son usar software libre para el desarrollo, y tener algo enseñable para una demo el Viernes.<br />
<br />
La PiWeek tiene <b>vocación abierta</b>, y por tanto admite gente que no sean empleados de Kaleidos, ya sean individuos o empresas. El caso es que a mi me quedaba todavía una semana de vacaciones, sin ningún plan concreto, y de hecho tenía pensado dedicarla a este proyectillo, así que, ¿<b>por qué no presentarme a la PiWeek</b>, y así por un lado obligarme a hacer algo y por otro poder compartir proyectos con más gente?. Dicho y hecho, el Viernes anterior a la PiWeek se presentan propuestas de proyectos para formar equipos... y allí estuvo Picross.<br />
<br />
Yo ya conocía a unos cuantos de Kaleidos, sobre todo a través del grupo de usuarios de Groovy <a href="http://www.meetup.com/madrid-gug/">Madrid GUG</a>, pero la semana me dio la ocasión de charlar con todos, y la verdad es que es una gozada, en general son gente muy preparada y sobre todo derrochan pasión por la tecnología y el desarrollo. Entre <b>los proyectos que se presentaron a la PiWeek</b> había algunos como <a href="https://github.com/lmivan/yasn">un clon de Twitter</a> usando Redis y Spring integration, un <a href="https://github.com/pabloalba/komics">visor de comics Android</a> con detección de viñetas, un plugin de Chrome capaz de <a href="https://github.com/superalex/super-gif-capture">capturar pantallazos como GIF animados</a>, un traductor de Python a Javascript (bautizado como <a href="https://github.com/niwibe/cobrascript">CobraScript</a>) o un <a href="http://piweek.tumblr.com/image/70577995630">aplausómetro hecho en Arduino</a>, junto a otros más... rarunos, como <a href="https://github.com/hirunatan/mine-eiffel">un MUD</a> hecho en Eiffel o <a href="https://github.com/alejandrogomez/parsero">una librería que permite crear parsers</a> en Clojure. Salieron un montón de proyectos, pero todos tenían algo que contar. <b>El ambiente que se crea durante la PiWeek es impresionante.</b><br />
<br />
<br />
<h2>
Haciendo el juego</h2>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihnKCBwPl-kRByyJ4cCmVr79FBJoll8Ma9rf-o42aeMGKayo4-DEwufBQOB7FreTHCXYsI0GkLcbP7qxvjjSozupI0Vo-HuYARd5PHpJpK8LuGX65770t40aFEwsdjkOq_ZzehbjgzRad-/s1600/uno.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihnKCBwPl-kRByyJ4cCmVr79FBJoll8Ma9rf-o42aeMGKayo4-DEwufBQOB7FreTHCXYsI0GkLcbP7qxvjjSozupI0Vo-HuYARd5PHpJpK8LuGX65770t40aFEwsdjkOq_ZzehbjgzRad-/s1600/uno.png" /></a></div>
Y llegó el momento de ponerse con el juego. <b>Las primeras sensaciones con Dart son muy buenas</b>, no es un lenguaje ni unas herramientas a las que estés acostumbrado, no son ni mucho menos tu "zona de confort", pero <b>tanto las herramientas como el lenguaje y las librerías resultan cómodos e intuitivos</b>. Esperaba encontrarme con alguna característica del lenguaje que echara de menos (el típico "no me puedo creer que esto no exista aquí"), pero no encontré ninguna.<br />
<br />
<b>Integración de Dart con Javascript</b><br />
Mi primera intención era <b>hacer un interfaz Dart para una librería Javascript</b> de videojuegos. Después de estar echando un vistazo a unas cuantas me decidí por <a href="http://melonjs.org/">MelonJS</a>, ya que había oído hablar bien de ella y era más pequeña y ligera que otras como <a href="http://www.cocos2d-x.org/wiki/Cocos2d-html5">Cocos2D</a>. Después de varias pruebas básicas que aparentemente funcionaron, fui creando clases "proxy" que intermediaran con la librería, usando sólo lo que iba necesitando... hasta que de repente una prueba, justo después de haber hecho un montón de código, dejó de funcionar.<br />
<br />
Tras un rato pegándome con ello, descubro que no podía llevar a cabo lo que pretendía. El caso es que Dart permite hacer llamadas a funciones y objetos Javascript sin ningún problema, y de una forma bastante cómoda, convirtiendo colecciones de una manera sencilla. También se le pueden mandar funciones Dart que sirvan de "callback" y se las llame desde JS. Sin embargo, la integración tiene una limitación importante, y es que <b>no se puede llamar a objetos Dart desde código Javascript</b>. Esto invalida por completo la posibilidad de usar un framework como es MelonJS, ya que en él todas las entidades del juego se definen como objetos a los que invoca el núcleo Javascript de la librería.<br />
<br />
Un día entero perdido con la tontería. Y en realidad es culpa mía, porque lo ponía muy claro <a href="https://api.dartlang.org/docs/channels/stable/latest/dart_js.html">en la documentación</a>. <b>Odio los Lunes.</b><br />
<br />
<b>Problemas APIs HTML5</b><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCULruH_hOcIFif7YabsFshhWClIjP5qWJkTKqgHecOSDV_vJebxJUiNMDApHgdBauMzCenq4UZK_v-YVkGv3QdaPiAhu6fwli3a94IQSzwjdhKBsTngdf-LiBg0s8-ICTMXcTAYYEHOam/s1600/howlerjs_logo.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCULruH_hOcIFif7YabsFshhWClIjP5qWJkTKqgHecOSDV_vJebxJUiNMDApHgdBauMzCenq4UZK_v-YVkGv3QdaPiAhu6fwli3a94IQSzwjdhKBsTngdf-LiBg0s8-ICTMXcTAYYEHOam/s200/howlerjs_logo.png" height="68" width="200" /></a></div>
Como había oído que el sonido daba problemas, decidí usar la librería <a href="http://goldfirestudios.com/blog/104/howler.js-Modern-Web-Audio-Javascript-Library"><b>Howler</b></a> para que ella se encargue de elegir el fichero de audio adecuado según el navegador, poniendo versiones de los sonidos en mp3, ogg y wav. En este caso al no tratarse de un framework no tuve ningún problema para encapsularla en clases Dart. Pensaba que con esto ya conseguiría que los sonidos y músicas sonaran en todos los navegadores modernos pero... craso error. Ni así. <b>El tema del audio en los navegadores es un berenjenal de cuidado</b>. He ido probando en varias versiones y nunca sabes si te va a funcionar o no, a veces incluso versiones del mismo navegador con muy poca diferencia entre ellas. Con Chrome por ejemplo, en Dartium no funciona la música pero sí los sonidos, y lo mismo en otras versiones de Chrome que he probado. Sin embargo, en mi Chrome y la mayor parte de versiones que he probado sí funciona también la música. En Firefox más de lo mismo, aunque aquí a veces me ha ocurrido lo contrario, que funcionaba la música pero no los sonidos.<br />
<br />
<b>Rendimiento</b><br />
La verdad es que hasta ahora no he cuidado nada el rendimiento del juego, ni siquiera dentro de las limitaciones que pudiera tener usando Dart, pero aun así los resultados son curiosos. En Chrome en general el juego parece funcionar bastante bien, al menos en los ordenadores en los que he probado (imagino que en ordenadores antiguos le costará más). Curiosamente, parece que <b>funciona igual de rápido</b> en Chrome, es decir, <b>ejecutando el código compilado a Javascript</b>, que en Dartium, <b>ejecutando el código de forma nativa</b>. En Firefox, al menos en Linux, sufre mucho más, notándose mucha mucha diferencia según el tamaño del dibujo que se intenta averiguar. En Windows me pareció que funcionaba un poco mejor, aunque pudo ser por la máquina.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgybuynDZif8_DEM0dRpIVURq8maDCanKOnrWA4t73xJdufDUN4_z5Ci3L4WKWwUa_3gecb7z-O-Ag3lhGuRPeDI-hO8tnV_MgsDlq0x_IMHsWYoxbuvuB6f42eN9EmuGzRV6hrR2U2O8JW/s1600/uno.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgybuynDZif8_DEM0dRpIVURq8maDCanKOnrWA4t73xJdufDUN4_z5Ci3L4WKWwUa_3gecb7z-O-Ag3lhGuRPeDI-hO8tnV_MgsDlq0x_IMHsWYoxbuvuB6f42eN9EmuGzRV6hrR2U2O8JW/s1600/uno.png" /></a></div>
<b>En el Chrome de mi tablet Android el juego funciona</b>, justita de rendimiento, pero funciona. Parece sufrir bastante en cuanto tiene que usar cualquier sonido, lo cual me hace sospechar que los sonidos pueden ser causantes en buena parte de los problemas de rendimiento. Al final se acabó quedando colgado. En cualquier caso no me parece muy preocupante por el momento, porque como ya he dicho no he mirado todavía nada del rendimiento, y para la versión móvil <b>probaré con el ya mencionado CocoonJS</b>, que espero que no tenga problemas con el sonido (y si los tiene ya les vale).<br />
<br />
Imagino que Dart debe estar ralentizando en general todo el código, y de hecho puede que la lentitud en Firefox sea por eso, aunque tampoco me extrañaría nada que fuera sencillamente un tema de rendimiento de las librerías HTML5, que no las veo demasiado optimizadas. Aunque la conclusión principal que saqué de charlas del GameMe5 es que el rendimiento de Javascript es muy muy muy sensible, y un pequeñísimo cambio puede causar de repente un gran aumento en la velocidad. En cualquier caso, en principio para este juego me vale.<br />
<br />
<b>Programando en Dart</b><br />
Esperaba que Dart me diera algún problema: que las herramientas no funcionaran bien, que me encontrara con algún bug molesto en alguna librería, que no encontrara documentación sobre las librerías... Sin embargo, no ha sido así, todo ha funcionado como la seda.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh2UO3-k0OPuCsViKd-F6T5BVsP0dTZ3VrmW4cz_0X99EGpq7_GFg7IJPE_AMhs-vDq8kcIVw5U4sX-Jibfo1iJHcS79_bIYsQTYvUFD-McycM7AzZwJ0CK6j5WBvi7F4ToAzYfk2lfrYvm/s1600/uno.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh2UO3-k0OPuCsViKd-F6T5BVsP0dTZ3VrmW4cz_0X99EGpq7_GFg7IJPE_AMhs-vDq8kcIVw5U4sX-Jibfo1iJHcS79_bIYsQTYvUFD-McycM7AzZwJ0CK6j5WBvi7F4ToAzYfk2lfrYvm/s320/uno.png" height="213" width="320" /></a></div>
<a href="https://www.dartlang.org/tools/editor/">El IDE</a> funciona muy bien. A pesar de tener tipado opcional, hace una buena inferencia de tipos y <b>permite autocompletar, buscar referencias, refactorizar o navegar por las clases incluso en variables sin tipo explícito declarado</b>. Encontré algunos errores en esto, en cuanto a variables de las que de repente es incapaz de inferir el tipo aunque un rato antes sí lo hacía, pero lo considero errores menores e imagino que se arreglarán. También detecta errores de llamada a métodos o propiedades inexistentes, aunque al ser un lenguaje dinámico los marca como warnings en lugar de errores. Hubiera preferido lo segundo, pero me vale, e imagino que en el futuro permitirán esta opción.<br />
<br />
<b><a href="https://www.dartlang.org/tools/dartium/">Dartium</a></b>, el navegador que incluye la máquina virtual Dart para ejecutar de forma nativa, funciona también muy bien, y el debugger tampoco me dio ningún problema. Incluso, me encontré alguna sorpresa agradable como que <b>cuando el debugger te muestra los atributos de un objeto, te incluye también los valores de sus getters</b>, es decir, de las propiedades que tenga que se calculan a partir de una función en lugar de devolver directamente el valor de una variable. Esto es comodísimo.<br />
<br />
<b>Me encontré muy cómodo también con el lenguaje</b>. Me fastidia el que las reglas de estilo recomienden tabulaciones de dos espacios, que creo que hacen el código menos legible, y al venir yo de lenguajes de tipado estático me costó un rato hacerme a la idea de que no tenía por qué declarar tipos en variables locales (en propiedades de clases y parámetros de métodos yo que tú sí lo haría siempre). <b>Todo lo demás me encantó desde el principio</b>. No eché nada de menos al plasmar un diseño orientado a objetos, tiene sus clases, objetos, clases abstractas, e incluso modificadores de atributos interesantes para el control del código como const y final. Pero sobre todo el lenguaje tiene un montón de "azúcar sintáctico", con <b>comodidades muy importantes</b> como los <b>getters/setters</b> implícitos, las funciones <b>lambda</b>, los <b>parámetros opcionales y/o nombrados</b> en los métodos, los <b>constructores</b> con inicialización directa de propiedades con argumentos, el <b>operador en cascada</b> y el manejo de <b>colecciones</b>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhViO_sk0HEQxGQi8xKaqzBm6DkjboP37EXM_XKIzRJh2WCAoY6HughYZTv1woE3zPhIQZu85nVH238RufQMC53j2fLN5dZTyWcqP0Cp-FQBOwkuW7QrNfRMYnxu-TfGjGBMDwRHtbS1u4I/s1600/uno.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhViO_sk0HEQxGQi8xKaqzBm6DkjboP37EXM_XKIzRJh2WCAoY6HughYZTv1woE3zPhIQZu85nVH238RufQMC53j2fLN5dZTyWcqP0Cp-FQBOwkuW7QrNfRMYnxu-TfGjGBMDwRHtbS1u4I/s320/uno.png" height="222" width="320" /></a></div>
<b>Las librerías estándar también son muy completas y están muy bien documentadas</b>, existen clases para cualquier cosa básica que se te puede ocurrir a hacer y, también muy importante, se encuentra cualquier cosa muy rápido buscando en <a href="http://api.dartlang.org/">http://api.dartlang.org/</a>. Si se quiere hacer algo más especializado (aunque a mi no me ocurrió), también existe un <b>repositorio de librerías</b> en el que es fácil buscar: <a href="http://pub.dartlang.org/">http://pub.dartlang.org/</a> y gracias al <b>gestor de paquetes incluido en Dart, <a href="http://pub.dartlang.org/doc/">pub</a></b>, usar cualquiera de esas librerías es muy sencillo.<br />
<br />
Lo más importante que puedo decir es que olvidé por completo la sensación de que estaba programando para el navegador. <b>Creo que la separación entre programación "front" y "back", aunque tenga cierto sentido, es un poco artificial</b>. Se ha hecho muy necesaria de unos años a esta parte en programación web porque <b>programar para la parte cliente era un infierno, en el que contaba más conocer los truquillos y las compatibilidades en los navegadores que la programación real</b>. Pero eso está cambiando mucho: con jQuery y demás librerías JS nos podemos olvidar de las incompatibilidades en el acceso al DOM, con Bootstrap (como ya comenté en <a href="http://apagayvuelveaencender.blogspot.com/2013/07/bootstrap-3-y-el-marcado-semantico.html">otro artículo</a>) y otras librerías de LESS y SASS nos podemos olvidar en buena parte de los dolores de cabeza con el CSS. <b>Con Dart podemos dar un paso más y olvidarnos de la problemática de Javascript y sus librerías</b>, comenzando a programar exactamente igual a como se hace en la parte back, al menos en mi caso, con un diseño orientado a objetos, con encapsulación, con librerías potentes, con tipado, con las facilidades de un buen IDE...<br />
<br />
<br />
<h2>
El resultado</h2>
<b>Se puede acceder al juego online en esta dirección</b>: <a href="https://googledrive.com/host/0B-qqsnsC2gHuS210TnQ4cENGSkk/index.html">https://googledrive.com/host/0B-qqsnsC2gHuS210TnQ4cENGSkk/index.html</a><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRrKfWxMVUno5rc2S5HfOiTRlG0qWvieMhuPuEFjyKMLTR2ktjxRZ-MJvqHrBUdsgFK1R8HvWQYCMDSL65QqY70UnbimfqJVRCnEw3AijB6iJIIH1xz7mEGjVN7GA7_rAR0pgmh4HcxQq7/s1600/uno.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRrKfWxMVUno5rc2S5HfOiTRlG0qWvieMhuPuEFjyKMLTR2ktjxRZ-MJvqHrBUdsgFK1R8HvWQYCMDSL65QqY70UnbimfqJVRCnEw3AijB6iJIIH1xz7mEGjVN7GA7_rAR0pgmh4HcxQq7/s320/uno.png" height="250" width="320" /></a></div>
<b>Es completamente jugable</b>, aunque sólo tiene 4 niveles y a veces le pasan cosas raras. Esta es la versión que presenté en la demo del Viernes de la PiWeek. Tampoco hay instrucciones, así que lo cuento aquí: botón izquierdo del ratón = negro, botón derecho = blanco (se ve como una X con sombras).<br />
<br />
Mi intención es mejorarlo y convertirlo en un "juego de verdad". Se pueden hacer un montón de cosas, como:<br />
<br />
<ul>
<li><b>Añadirle muchas más fases</b>: una de las grandes ventajas (y también alicientes) de este juego es que añadir más fases es tan fácil como añadir un pequeño dibujo pixelado... y <b>si empiezas a tirar del hilo de los juegos retro ¡hay un montón!</b>. Tres de los cuatro dibujos de la demo están hechos así, uno de ellos incluso con un gráfico propio de un mono que era el sello de mi "marca" de juegos de Spectrum, ¡sniffffff!. ¿Reconoces los otros dos?.</li>
<li>Mejorar el código, sobre todo el loop principal del juego y la carga de recursos, ya que me basé en el código del taller de Gameme5 y no me gusta mucho cómo les quedó esta parte. Tengo localizada ya una <a href="http://pub.dartlang.org/packages/game_loop">librería para el loop</a> y otra para <a href="http://pub.dartlang.org/packages/asset_pack">la carga de recursos</a>, ambas con buena pinta.</li>
<li><b>Versión para móviles</b> (probando CocoonJS)</li>
<li><b>Modo "duelo" multijugador</b>, que me permitiría también probar a hacer un mini servidor en Dart (y reutilizar clases de la parte cliente), y probar los WebSockets.</li>
<li>Conectarlo con Facebook y/o Google Play Games.</li>
</ul>
<br />
En definitiva: Dart me ha funcionado muy bien, HTML5 un poco más regular, y sobre todo me ha encantado la experiencia y me lo he pasado muy bien. Y lo mismo... hasta acaba saliendo como resultado un juego de verdad. <b>Permanece atento a la pantalla</b>.<br />
<br />Andréshttp://www.blogger.com/profile/06010147149377176406noreply@blogger.com0tag:blogger.com,1999:blog-6416070227303513915.post-84674301469653265102013-11-13T09:42:00.003+01:002014-01-28T23:15:57.299+01:00Aparta, Javascript. Llega... ¡DART!<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqmRBw36OaqiZFH6SDK6bl5ggIfsrYAoBxDOzGpbiYpzoi5KbRDIE4H93FdRrYqay0Vs7Ivkyyjsw6e0lv6PyUz0jMahxq8OnvdutG2dfXXhxUaQ9uhyumRYXYFGDQ6FtDJM9cNB4qijiA/s1600/dart-logo.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqmRBw36OaqiZFH6SDK6bl5ggIfsrYAoBxDOzGpbiYpzoi5KbRDIE4H93FdRrYqay0Vs7Ivkyyjsw6e0lv6PyUz0jMahxq8OnvdutG2dfXXhxUaQ9uhyumRYXYFGDQ6FtDJM9cNB4qijiA/s1600/dart-logo.png" /></a></div>
Dos añitos se ha tirado la <b><a href="https://www.dartlang.org/">plataforma Dart</a></b> de Google para conseguir alcanzar la suficiente estabilidad tanto en el lenguaje como en las librerías y herramientas, como para llegar a su <b>primera versión estable</b>, la versión 1.0, cuya salida según el equipo de desarrollo es inminente.<br />
<br />
¿Y qué demonios es Dart?. Pues la forma más rápida de definirlo es que es <b>un reemplazo de JavaScript</b>. Un reemplazo que pretende aprovechar las virtudes de JavaScript, y a la vez superar sus defectos. Esto lo hace especialmente interesante cuando lo que se pretende desarrollar es <b>una aplicación web</b> (o de forma más general, un "rich client"), es decir, una aplicación con interfaz web y con mucho código en la parte cliente. No obstante, si pensamos más allá nos podemos dar cuenta de que sus posibilidades son aún mayores.<br />
<div>
<br />
Te estoy viendo. Tienes serias dudas. ¿Cuántas veces te han vendido la moto del enésimo lenguaje de moda que todos deben usar porque es el más bonito e indudablemente el mejor, para finalmente darte cuenta de que no tenía nada especial y era lo mismo de siempre o, incluso, mucho peor?.<br />
<br />
Lo cierto es que <b>Dart cubre un hueco</b>, tiene un propósito. Hoy por hoy no hay otro igual o del mismo estilo.<br />
<br />
¿No me crees?. Sigue leyendo, a ver qué piensas al final del artículo...<br />
<br />
<h2>
Pero... ¡yo amo Javascript!</h2>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; margin-left: 1em; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYHbwBW8mHSVyRfYSyPMjO0HuP44xwaVeyJS1rgmHC1hy-aU-gQFKvou8AlJAt7QmDLFoxlU4aP1i7psg9_IscN4g8ctYlDd2ch8nElWsa9o9E_tb7GgpBdY4HsFjGHYU-4wLtRn-xXsJq/s1600/uno.png" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYHbwBW8mHSVyRfYSyPMjO0HuP44xwaVeyJS1rgmHC1hy-aU-gQFKvou8AlJAt7QmDLFoxlU4aP1i7psg9_IscN4g8ctYlDd2ch8nElWsa9o9E_tb7GgpBdY4HsFjGHYU-4wLtRn-xXsJq/s200/uno.png" height="200" width="155" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">El bueno</td></tr>
</tbody></table>
<div>
JavaScript tiene indudablemente algunas virtudes. Es un lenguaje con <b>un buen manejo de prototipos</b> y con la posibilidad de usar <b>funciones como valores dentro de variables</b>. Pero también es un <b>lenguaje muy guarro</b>, especialmente si pretendes hacer una aplicación más o menos grande, algo que cada vez es más habitual con la evolución que han sufrido las tecnologías web. <b>Se nota que el lenguaje está pensado "en pequeño"</b>.</div>
<div>
<br /></div>
<div>
Las variables son globales, y si quieres crear un espacio propio de nombres o <b>modularizaciones</b> adecuadas en general, te metes en problemas. <b>No existe encapsulación</b>, no se pueden tener elementos privados a nivel de clase (si aceptásemos que existen clases, quiero decir, cosa que no es cierta). El uso de this es para darle de comer aparte (cada vez que te ves obligado a hacer un var self = this, muere un gatito), <a href="http://zero.milosz.ca/">los operadores son exageradamente casquivanos</a>... cosas muy básicas del diseño de aplicaciones, y especialmente del diseño orientado a objetos.</div>
<div>
<br /></div>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWClEgJoiu46Lw9I15r_TeEc2Os6BaxVoRSLmunJXdPB7EL9as3EEk2StUjqX0uL2uZ_ALTUR_s0cWQ_5kbKcXftC-1USBA2K335cuWi_H0QVH2na1Hca9QFgpkfXDPSwHq1nBITvoTLo1/s1600/uno.jpg" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWClEgJoiu46Lw9I15r_TeEc2Os6BaxVoRSLmunJXdPB7EL9as3EEk2StUjqX0uL2uZ_ALTUR_s0cWQ_5kbKcXftC-1USBA2K335cuWi_H0QVH2na1Hca9QFgpkfXDPSwHq1nBITvoTLo1/s200/uno.jpg" height="200" width="151" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">El feo</td></tr>
</tbody></table>
<div>
Por supuesto, puedes diseñar y programar aplicaciones JavaScript correctamente, incluso orientadas a objetos, siguiendo varias recomendaciones sobre cómo organizar correctamente tu código, y qué características del lenguaje evitar. Hay un montón de libros y artículos sobre el tema, y es verdad que uno de los grandes problemas de Javascript es que durante mucho tiempo se ha considerado un lenguaje "para hacer chapucillas en la web". Y la gente que programaba en Javascript a menudo no eran programadores, lo que ha hecho que se haya extendido mucho código basura.</div>
<div>
<br /></div>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; margin-left: 1em; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZMeQBTTxLtbyllCD8s1masB1CyJv0ELmEkWEfL27DdLBCmiI3SwYvIVhFDLLTIax7xtRIh1bmW2ErkNdcVslvRLFD34-skNW2GNz6kppPPHgnpB-tKqh2pK3oqCgcwMGuNdIhr0dXBOQ0/s1600/uno.png" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZMeQBTTxLtbyllCD8s1masB1CyJv0ELmEkWEfL27DdLBCmiI3SwYvIVhFDLLTIax7xtRIh1bmW2ErkNdcVslvRLFD34-skNW2GNz6kppPPHgnpB-tKqh2pK3oqCgcwMGuNdIhr0dXBOQ0/s200/uno.png" height="200" width="151" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">El malo</td></tr>
</tbody></table>
<div>
Pero también es verdad que <b>el lenguaje no ayuda a estructurar mejor el código, sino todo lo contrario, ni tampoco ayuda a la legibilidad</b>. ¿Por qué tengo que leerme un libro para enterarme de qué cosas del lenguaje debo evitar a toda costa y qué patrones debo seguir no para que mi código sea mejor, sino para que sencillamente no sea pura caca de vaca?. ¿Por qué tengo que leérmelo incluso para entender muchas cosas arcanas que lleva el lenguaje dentro, y que muchos programadores gustan de utilizar para demostrar todo lo que saben?.</div>
<div>
<br /></div>
<div>
En cualquier caso, si ya has superado ese umbral, tienes conocimiento sobre cómo diseñar de una forma legible y mantenible una aplicación JavaScript y, qué demonios, te encuentras cómodo con ello, entonces Dart no será para ti.</div>
<div>
<br /></div>
<h2>
Lenguaje limpio, con clases y orientado a objetos </h2>
Hoy por hoy, si quieres hacer una aplicación cliente en la web, en web "pura", se tiene que ejecutar en Javascript, ya que es lo único que los navegadores saben ejecutar. Dadas sus limitaciones, han ido apareciendo otros lenguajes de reemplazo, que compilan a Javascript, como por ejemplo <a href="http://coffeescript.org/">CoffeeScript</a> y <a href="http://www.typescriptlang.org/">TypeScript</a>.<br />
<br />
Dart va un paso más allá que estos dos, porque al contrario que ellos, <b>el lenguaje no está basado directamente en Javascript</b>. Se parece en algunas cosas, sí, porque la mayor parte de su "target" es la gente que está trabajando con Javascript, por lo que es conveniente que haya cosas que les resulten familiares.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWne4nkLCmrK5nQzaU36mSi75V6UF8dd8xIQMxFDiMpt3PA-k3NTjZHHSBcrqKjfz1fZPDpgTuK5gyxIrRAGLkBBT5LGvn0pj3OWP6ah24MkmQfFv5Pgf53hQUJPtAaCK0D9L6LKXQBnbm/s1600/uno.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWne4nkLCmrK5nQzaU36mSi75V6UF8dd8xIQMxFDiMpt3PA-k3NTjZHHSBcrqKjfz1fZPDpgTuK5gyxIrRAGLkBBT5LGvn0pj3OWP6ah24MkmQfFv5Pgf53hQUJPtAaCK0D9L6LKXQBnbm/s200/uno.png" height="200" width="199" /></a></div>
En contraposición a Javascript, <b>la palabra que mejor define a Dart es que es limpio</b>. Tiene funciones, que también se pueden asignar a variables, pero también tiene clases, lo que facilita que se haga un <b>diseño orientado a objetos</b>. Permite crear librerías, versionarlas e importarlas en otro proyecto con un espacio de nombres propio, para evitar colisiones. Tiene la posibilidad de crear propiedades y métodos privados dentro de una clase.<br />
<br />
Además, de esto, <b>el lenguaje tiene mucho "syntantic sugar"</b>, es decir, muchas formas sencillas de declarar las cosas en pocos términos. Para que un elemento sea privado, basta con hacer que su nombre empiece por "_". Los getter y setter son opcionales, y se les llama automáticamente al usar la propiedad, de forma que desde el punto de vista del que los llama no sabe si existen o no (sí, sí, encapsulación poco trabajosa). Se pueden declarar métodos sencillos que devuelvan un valor o una operación de forma rápida usando "=>". Se pueden concatenar llamadas consecutivas a un objeto con el operador "..". Se pueden declarar fácilmente funciones anónimas para pasarlas como parámetro. Se pueden declarar datos de colecciones de forma sencilla usando literales [] y {}...<br />
<br />
El lenguaje Dart <b>tiene tipado dinámico</b>, aunque a ellos les gusta más llamarlo <b>"tipado opcional"</b>. Puedes declarar el tipo de cualquier variable, o no hacerlo. Dart tiene un modo de ejecución llamado "checked mode", que es el que se recomienda para desarrollo, y que es más lento pero da error ante manipulaciones erróneas de variables sin tipo declarado según su valor actual. Por ejemplo este código no daría error en "modo producción", pero sí haría saltar una excepción en el modo checked, al tratar una cadena como si fuera un booleano (lo de los undefined, null, etc. como false dentro de las condiciones no se ha heredado de JS; en las condiciones sólo pueden ir booleanos):<br />
<br />
<pre class="programlisting prettyprint lang-dart" style="background-color: whitesmoke; border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; border-top-left-radius: 4px; border-top-right-radius: 4px; border: 1px solid rgba(0, 0, 0, 0.14902); color: #333333; font-family: Monaco, Menlo, Consolas, 'Courier New', monospace; font-size: 13px; line-height: 21.988636016845703px; margin-bottom: 22px; padding: 10.5px; white-space: pre-wrap; word-break: break-all; word-wrap: break-word;"><span class="kwd" style="color: black; font-weight: bold;">var</span><span class="pln" style="color: black;"> name </span><span class="pun" style="color: black;">=</span><span class="pln" style="color: black;"> </span><span class="str" style="color: #dd1144;">'Bob'</span><span class="pun" style="color: black;">;</span><span class="pln" style="color: black;">
</span><span class="kwd" style="color: black; font-weight: bold;">if</span><span class="pln" style="color: black;"> </span><span class="pun" style="color: black;">(</span><span class="pln" style="color: black;">name</span><span class="pun" style="color: black;">)</span><span class="pln" style="color: black;"> </span><span class="pun" style="color: black;">{</span><span class="pln" style="color: black;">
print</span><span class="pun" style="color: black;">(</span><span class="str" style="color: #dd1144;">'You have a name!'</span><span class="pun" style="color: black;">);</span><span class="pln" style="color: black;"> </span><span class="com" style="color: #999988;">// Prints in JavaScript, not in Dart.</span><span class="pln" style="color: black;">
</span><span class="pun" style="color: black;">}</span></pre>
No sé muy bien por qué, pero <b>el editor de Dart no es tan listo como eso, aunque sí que es listillo</b>. En el código anterior no daría ninguna advertencia, pero si pulsamos <b>autocompletar</b> en "name." sí que nos dará una lista con todos los atributos y métodos públicos de la clase String (lo que me hace pensar que lo anterior también es alcanzable). También es capaz de hacer <b>cambios de nombre</b> en clases, propiedades o métodos propagando el cambio a todos los que lo usen, así como hacer otros tipos de <b>refactorizaciones</b>. Por tanto, los que se encuentren más cómodos con lenguajes estáticos (entre los que me incluyo) podrán mitigar un poco esa incomodidad gracias a esta posibilidad de hacer refactorizaciones y renombrados. Por supuesto, en los sitios en los que las variables o los parámetros sí que los declaremos con su tipo, se detectará cualquier manipulación errónea.<br />
<br />
En definitiva, sí, el lenguaje <b>se parece a... muchos otros lenguajes que ya existen</b>. Tiene bastantes puntos en común con Groovy, por ejemplo. Pero tiene una diferencia importante respecto a ellos: <b>se puede ejecutar en el navegador</b>.<br />
<br />
<h2>
"Mundo real": Rendimiento, compatibilidad, conectividad</h2>
<div>
Todo esto es muy bonito, pero la vida real no vive sólo de lenguajes. Consideremos otros aspectos fundamentales a la hora de tomar una decisión:</div>
<div>
<br /></div>
<div>
<ul>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOqzCAqG21V5nSnqVo9pXjk98Nkw3d7LwfBo4KCa_CwWsBDN7tMuzazHu3GeUDxtmZYMQqY1QE2UeJgW791wvy6_HCkFEm8djcf9AJBpmycr7pCRDLPy8ZkvtITnjJiTcRG1_of-spFfrO/s1600/uno.jpg" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOqzCAqG21V5nSnqVo9pXjk98Nkw3d7LwfBo4KCa_CwWsBDN7tMuzazHu3GeUDxtmZYMQqY1QE2UeJgW791wvy6_HCkFEm8djcf9AJBpmycr7pCRDLPy8ZkvtITnjJiTcRG1_of-spFfrO/s200/uno.jpg" height="200" width="200" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">de 11870.com</td></tr>
</tbody></table>
<li><b>Rendimiento</b>. Este ha sido el objetivo número uno del equipo de Dart una vez definido el lenguaje. Es obvio que el rendimiento es importantísimo, el compilador de Javascript debe generar código que sea suficientemente rápido y pequeño, o si no no merecerá la pena. En cuanto a la velocidad, <b>Google afirma que su lenguaje actualmente puede llegar a ser incluso más rápido que si haces la aplicación directamente en Javascript</b>. Los datos se pueden encontrar en <a href="https://www.dartlang.org/performance/">este benchmark</a>. Sea verdad o no (ya se sabe que los benchmarks son como las encuestas de los políticos), la verdad es que los ejemplos que he visto sí me han parecido suficientemente rápidos. En cuanto al tamaño, Dart <b>optimiza la carga de librerías, de forma que sólo se compila a JS el código que realmente se utiliza dentro de la aplicación</b>. Ahora mismo hay alguna librería que al utilizarse sí que aumenta mucho el tamaño, pero teniendo en cuenta que se trata aún de una versión 1.0 de la plataforma y que el rendimiento es el objetivo principal actualmente, es de esperar que se hagan optimizaciones. Habrá que ver hasta dónde se consigue llegar.</li>
</ul>
<div>
<br /></div>
<ul>
<li><b>Compatibilidad</b>. El código generado es compatible con todos los navegadores actuales... excepto con <b>Internet Explorer 8</b> o inferiores. En Octubre del 2013 el uso de IE8 según StatsCounter es del 9,56%, todavía alto. Por otra parte, las herramientas de Dart no funcionan en Windows XP, sistema operativo que todavía según la misma web tiene un uso del 20,06%. Mi interpretación es que este es uno de los aspectos en los que se nota que <b>Dart sabe que su momento no iba a llegar este año... pero puede que sí el que viene</b>, ya que es de esperar que ambas estadísticas y especialmente la de IE8 desciendan durante los próximos meses.</li>
</ul>
<br />
<ul>
<li><b>Conectividad</b>. Desde Dart <b>se puede llamar a librerías Javascript</b> sin ningún tipo de problema. El enfoque sugerido es hacer una librería Dart que encapsule las llamadas, y en general es así como se está haciendo. Por otra parte, a pesar de lo pronto que todavía es para Dart, existen ya <b>librerías para acceso a bases de datos</b> como MySQL, PostgreSQL o MongoDB. Por supuesto, el margen de mejora en cuanto a librerías es todavía grande.</li>
</ul>
</div>
<div>
<br /></div>
<h2>
Librerías de acceso al navegador</h2>
Para acceder al navegador tenemos la <b>librería html</b>, una librería bastante grande que encapsula el acceso al DOM del navegador, HttpRequest, WebSockets, y las múltiples nuevas APIs que están surgiendo en HTML5 (almacenamiento local, sonido, WebRTC, etc.). También tenemos la librería <b>js</b> que permite acceder a JavaScript.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjA8ybm8OGOZBVNtS_JfORYsKDQu9c91Mo3Vx8k-eBRayo0iM3F-bSaZZmIcdbqS_2Z1_QqYHp2KynuFWC0ehQPHviC11cf2TjrfWJW_hfawDaYEq7ptsl5eyUE68AwaSQ_EHb2hx_2syU0/s1600/uno.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjA8ybm8OGOZBVNtS_JfORYsKDQu9c91Mo3Vx8k-eBRayo0iM3F-bSaZZmIcdbqS_2Z1_QqYHp2KynuFWC0ehQPHviC11cf2TjrfWJW_hfawDaYEq7ptsl5eyUE68AwaSQ_EHb2hx_2syU0/s200/uno.png" height="137" width="200" /></a></div>
Luego sobre ellas se construyen algunas librerías que facilitan la creación de la web según estándares modernos y modularizables, pensando especialmente en la creación basada en componentes. La librería que se considera "base" para esto es <b><a href="https://www.dartlang.org/polymer-dart/">polymer</a></b>, basada en <a href="http://www.polymer-project.org/">el proyecto Javascript</a> del mismo nombre, y que permite definir elementos y atributos propios dentro del DOM o extender otros ya existentes, enlazar automáticamente con datos de los objetos Dart, incluso con <b>enlazado doble, si cambia el elemento HTML cambia el objeto Dart y viceversa</b>, y crear estructuras condicionales y bucles.<br />
<br />
La cosa no se queda ahí ya que también se está creando un port del cada vez más popular <a href="http://angularjs.org/">AngularJS</a>, llamado <a href="http://news.dartlang.org/2013/11/angular-announces-angulardart.html"><b>AngularDart</b></a>. Este proyecto va más allá que polymer, ya que es un framework MVC más completo.<br />
<br />
Hay que tener en cuenta que toda la parte del cliente, incluyendo estas librerías, al final se acaba convirtiendo en JavaScript. Es decir, nada de SEO (o sea, fundamentalmente nada de aparecer en buscadores) ni de accesibilidad (me refiero a la accesibilidad tradicional <a href="http://www.w3.org/TR/WCAG10/#gl-new-technologies">WAI WCAG-AA</a>, que se sigue exigiendo en muchos proyectos de la administración pública, no a la más moderna <a href="http://www.w3.org/WAI/intro/aria">WAI-ARIA</a>). Por eso dije al principio que Dart es ideal fundamentalmente para aplicaciones web, no para sitios web públicos que queramos que aparezcan al buscar en Google.<br />
<br />
<h2>
Se puede ejecutar en el servidor</h2>
La aparición de node.js supuso una pequeña revolución, ya que permitía ejecutar Javascript no sólo en el navegador, sino que también la parte de servidor se hiciera en el mismo lenguaje. Dart ha tomado también este modelo, y desde el principio <b>se ha preparado para poder ejecutarse en un servidor web</b>. La diferencia fundamental entre la parte de cliente y la de servidor es que esta última no se compila a Javascript, sino que se ejecuta directamente en la máquina virtual de Dart. Además no podrá utilizar, obviamente, las librerías de acceso al navegador, y a cambio tendrá las suyas específicas que no podrán usarse en el cliente (muchas otras serán comunes para los dos lados).<br />
<br />
<b>La librería principal del servidor es io</b>, que permite acceso al sistema de ficheros, sockets, cliente y servidor web, etc.<br />
<br />
Para esta primera <b>versión 1.0</b> el equipo de desarrollo se ha planteado como <b>prioridad el compilador de Javascript y su rendimiento</b>, y la ejecución en la parte del cliente en general, <b>dejando para más adelante las optimizaciones en el servidor</b>. Esto quiere decir que el soporte de Dart en el servidor, aun siendo completo, sólo lo veo recomendable por el momento para aplicaciones que no tengan muchas complicaciones en el lado del servidor. Un API que acceda casi directamente a una base de datos, por ejemplo. Si no, para valientes.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRwkLBILX_H-M_Huk0jzcYA-EOdRAvd3SGWqf05i966G2r7pexmAxP7aHDKilZhbcdVBvTxoQvGuJi4wKQ6C2T5mLe2dyG_7piaKjO_yQzMYHkK65qXTWuiCSFlT2eX_Iy5e2RHdnl6YkN/s1600/uno.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRwkLBILX_H-M_Huk0jzcYA-EOdRAvd3SGWqf05i966G2r7pexmAxP7aHDKilZhbcdVBvTxoQvGuJi4wKQ6C2T5mLe2dyG_7piaKjO_yQzMYHkK65qXTWuiCSFlT2eX_Iy5e2RHdnl6YkN/s200/uno.jpg" height="177" width="200" /></a></div>
Algunos ejemplos de incidencias o mejoras que se han pospuesto tienen que ver con la velocidad de la propia máquina virtual y de la concurrencia. Concurrencia que en Dart se ofrece en forma de <a href="https://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html#ch03-dartisolate---concurrency-with-isolates"><b>isolates</b></a>, elementos de ejecución que no comparten memoria y se comunican entre sí por medio de mensajes, para evitar la existencia de errores chungos al gestionar la sincronización. Aparte del modelo de concurrencia, Dart permite ejecución asíncrona mediante <a href="https://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html#ch03-asynchronous-programming" style="font-weight: bold;">Futures</a>, que no se ejecutan simultáneamente sino uno detrás de otro, pero que permiten establecer el orden de las ejecuciones de una forma un poco particular. Son similares a las <a href="http://www.javascriptturnsmeon.com/promises-in-javascript/">promises</a> de Javascript. Siendo interesantes a priori ambas propuestas (aunque no tengo una opinión demasiado firme sobre ninguna de los dos por el momento y ambas me chocan un poco), lo cierto es que les queda trabajillo para facilitar la programación en el servidor, tanto <a href="https://groups.google.com/a/dartlang.org/forum/#!searchin/misc/isolates/misc/EVUMkZXFXtY/0Z5kFP1-KFIJ">en los isolates</a> como <a href="https://groups.google.com/a/dartlang.org/forum/#!topic/misc/tlqawJR_hSU">en los futures</a> (los futures se usan también en el cliente habitualmente pero entiendo que ahí no tienen por qué complicarse demasiado y me da que basta con lo que hay). Incluso la mismísima serialización de objetos con JSON, que debería ser importantísima en Dart para la comunicación cliente-servidor, entre isolates o usando sockets, está aún poco trabajada (aunque hay soluciones para crear y leer JSON automáticamente, pero ya las contaré otro día).<br />
<br />
Sin embargo, el que tanto el cliente como el servidor se puedan crear en el mismo lenguaje Dart tiene <b>ventajas muy interesantes</b>. Es obvio que podríamos compartir código entre ellos, incluyendo los propios objetos que se serialicen en la comunicación cliente-servidor, pero puede ser aún más interesante <b>si creamos interfaces comunes para determinadas partes que son similares en el cliente y el servidor</b> en cuanto a concepto aunque su implementación sea completamente distinta. Especialmente el cliente HTTP, aunque también posiblemente los sockets / websockets. Esto nos permitiría poder trasladar código de cliente a servidor y viceversa con mucha facilidad, haciendo que por ejemplo <b>podamos trasladar cosas fácilmente de acuerdo al rendimiento, la seguridad o simplemente cambios de requisitos</b>.<br />
<br />
Incluso, se me ocurre que potencialmente podríamos hacer un framework en el servidor que reemplazara la librería de acceso al DOM y creara los elementos en memoria usando el mismo Polymer o cualquier otro sistema de plantillas que usemos en el cliente, y devolviera el HTML resultante al cliente para partes de la web que queramos que aparezcan en buscadores. Sí, quizá después de todo el SEO sí que sea posible.<br />
<br />
Es de esperar que Google vaya con fuerza a por el servidor después de la versión 1.0, e incluso que le dé soporte en <a href="https://appengine.google.com/start">AppEngine</a>, de forma que podamos tener con cierta facilidad un hosting básico gratuito.<br />
<br />
<h2>
Yendo un paso más allá</h2>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1WhgqLcXjdKAAqAtRzroZ6B401429iCJQYrLG4eTiVzZdW-PipxBAWV8I2JHaBh4kf2dJUgjGC7ok2P6WMOSwriVtviwDU7DpkjsEeGizLNo6NZhuNgc06uFocs0CrS0tF-ANfQKWmU4d/s1600/uno.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1WhgqLcXjdKAAqAtRzroZ6B401429iCJQYrLG4eTiVzZdW-PipxBAWV8I2JHaBh4kf2dJUgjGC7ok2P6WMOSwriVtviwDU7DpkjsEeGizLNo6NZhuNgc06uFocs0CrS0tF-ANfQKWmU4d/s320/uno.png" height="128" width="320" /></a></div>
<div>
Al ser Dart un proyecto de Google, se pueden adivinar intenciones que tiene la empresa para el lenguaje. Se puede adivinar que pronto la versión oficial de <b>Google Chrome</b> va a ejecutar Dart de forma nativa (bueno, además es que lo han dicho ellos mismos). Al fin y al cabo, ya existe una máquina virtual que ejecuta Dart directamente, la DartVM, y ya existe una versión de Chromium que también ejecuta Dart de forma nativa, Dartium. No olvidemos que Chrome tiene un uso actualmente del 40,44% (nuevamente StatsCounter, Octubre 2013).</div>
<div>
<br /></div>
<div>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNdYXyBZw0FYN6zY0GvVV-IkIn4IsZIUXZjaXNnVPMNvBsYjpz1jjxFMj4ZlBn7EDHp059Go5SH10PNxHaLXJ5wDBJNF_u9mXS0gF6EZivUhC1d1Y3BIuvzqemGaXPVuT2oAcARmat60Ao/s1600/uno.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNdYXyBZw0FYN6zY0GvVV-IkIn4IsZIUXZjaXNnVPMNvBsYjpz1jjxFMj4ZlBn7EDHp059Go5SH10PNxHaLXJ5wDBJNF_u9mXS0gF6EZivUhC1d1Y3BIuvzqemGaXPVuT2oAcARmat60Ao/s200/uno.png" height="200" width="200" /></a>Al hacer esto Google va a conseguir una jugada a varias bandas: por un lado, esta vez seguro que sí, las aplicaciones Dart serán más rápidas que las aplicaciones Javascript. Por otro lado, las aplicaciones Dart serán más rápidas en Chrome que en el resto de navegadores. Y por otro lado, las aplicaciones Dart podrán tener un rendimiento comparable a las de escritorio, por lo que se aumentará la tendencia de aplicaciones hacia las tecnologías web. Triple win para Google.</div>
<br />
Además de esto, no olvidemos que HTML5 + JS se está utilizando actualmente en otros ámbitos, no sólo aplicaciones web. Por ejemplo, para hacer <b>aplicaciones móviles multiplataforma, o para videojuegos</b>. Y vaya hombre, Google también está detrás de <b>Android</b>, por lo que es de esperar que finalmente también consigan que las aplicaciones hechas en Dart funcionen mucho mejor en Android que en IOS (y ya van cuatro wins). En este sentido, existen ya librerías específicas para hacer aplicaciones móviles en Dart, especialmente <a href="http://rikulo.org/">Rikulo</a>.<br />
<br />
<h2>
Conclusiones</h2>
</div>
<div>
¿Y ahora?. ¿Estás ya convencido de que esto no es lo mismo de siempre?. ¿Ves no sólo lo que ya aporta, que es mucho (aunque algunas cosas estén aún un poco verdes), sino en lo que puede llegar a convertirse, en lo que se está convirtiendo?. Te invito a que dejes un comentario con tus impresiones. ¿Piensas como yo que supone <b>un nuevo paso en la propia evolución de la web</b>?.</div>
<div>
<br /></div>
<div>
Pues corre, vete a <a href="https://www.dartlang.org/">la página de Dart</a>, ¡y dale duro!.</div>
<div>
<br /></div>
<div style="text-align: center;">
<b><span style="font-family: Trebuchet MS, sans-serif; font-size: large;">¡La web te necesita!</span></b></div>
<div style="text-align: center;">
<br /></div>
<div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTQ04dHRmI3twhzZh28OrPZt44wac6EomzVSYtadZtcU5esLLGeoe4qWjRccGrztpvfJtsvxhLcRkLp1VZqlztNEw5QJjTn82G2BIgLAqCdGT1q1_BB2aEv66tWD8H868GqbKv8QQ7RjdN/s1600/fp2529-star-wars-empire-needs-you-poster.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTQ04dHRmI3twhzZh28OrPZt44wac6EomzVSYtadZtcU5esLLGeoe4qWjRccGrztpvfJtsvxhLcRkLp1VZqlztNEw5QJjTn82G2BIgLAqCdGT1q1_BB2aEv66tWD8H868GqbKv8QQ7RjdN/s400/fp2529-star-wars-empire-needs-you-poster.jpg" height="400" width="266" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">de panicposters.com</td></tr>
</tbody></table>
<br /></div>
Andréshttp://www.blogger.com/profile/06010147149377176406noreply@blogger.com5tag:blogger.com,1999:blog-6416070227303513915.post-48506430462990350622013-10-11T02:13:00.000+02:002014-01-28T23:25:34.361+01:00Oda al informático vago<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; margin-left: 1em; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1RolOKbz9AkkMYs0xjis-DmgE2l_E0KHhqlSZ7vWYX0T1GyRj_yfBc_ZgzurJMK7VSGMbpdFveGegS9kRcYTGwIKTkOg7_pewwsfZjoLSWn4419X6ChSxpXHNRSxFapGq4iX-oTd-cwvi/s1600/1370_la_vida_del_vago.jpg" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1RolOKbz9AkkMYs0xjis-DmgE2l_E0KHhqlSZ7vWYX0T1GyRj_yfBc_ZgzurJMK7VSGMbpdFveGegS9kRcYTGwIKTkOg7_pewwsfZjoLSWn4419X6ChSxpXHNRSxFapGq4iX-oTd-cwvi/s320/1370_la_vida_del_vago.jpg" height="281" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">de <a href="http://desmotivar.com/">desmotivar.com</a></td></tr>
</tbody></table>
Amigo <b>cazatalentos</b>, no le des más vueltas. Deja de estudiar la personalidad de tus candidatos desarrolladores de software: su positividad, su entusiasmo, su inteligencia, su liderazgo, su empatía, sus valores y todas esas zarandajas. Que sí, que pensabas que eso era importante, lo sé. Pero es mucho más sencillo que eso. Si estás buscando a los mejores informáticos, hay un aspecto que te mostrará de forma inequívoca quiénes son. Distinguirás al mejor porque será <b>un vagazo</b>. Un perraco. Un zángano de monte. Un gandul del abedul. Un oso perezoso. Un haragán sin cura posible. Un remolón irredento. Un indolente natural. <b>Lo más holgazán que ha parido madre</b>.<br />
<br />
Ese y sólo ese será el factor que te hará reconocer a tu candidato uno entre un millón. El tío capaz de cambiar las cosas. El factor diferencial. <b>El informático alfa</b>.<br />
<br />
No me crees, ¿verdad?.<br />
<br />
Al fin y al cabo llevas toda la vida <b>escuchando la importancia de la disciplina y el trabajo duro</b>. Piensa en tu propia historia. Cuando eras un niño pequeño, te tirabas el día jugando, imaginando, <b>creando</b>. Llegaste al colegio y todo cambió. De repente no sólo tenías que estar todo el día escuchando el rollo macabeo que te contaba el profesor, y que te importaba un pimiento, sino que cuando por fin llegabas a casa tenías que... ¡hacer los <b>deberes</b>!. Deberes que estaban diseñados aposta de forma que fueran, bueno, un rollazo. Que no aportaran nada. Su único objetivo era moldearte de acuerdo a esos principios de la disciplina, trabajo, etc., o sea, que su único objetivo era que agacharas la cabeza y te acostumbraras a perder unas horas de tu precioso tiempo haciendo algo que ni te aportaba nada a ti, ni le aportaba nada a nadie, <b>ni disfrutabas haciéndolo</b> (bueno, quizá tú sí lo disfrutaras un poco... ¡y por eso no eres un informático alfa!).<br />
<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0W0gUAab2IxOZwsscbc06hQAaQJd7bsidliITZ_dTAsExSL05JI7t9XntnO6l52ByubZer_WFAp-nyJfTvCElF3hyphenhyphen_HtKM-Xy5QMva02o_W2-rU_NGWpaX1lL-f1dbzC6CydviFQJzLLe/s1600/2621_me_dicen_vago.jpg" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0W0gUAab2IxOZwsscbc06hQAaQJd7bsidliITZ_dTAsExSL05JI7t9XntnO6l52ByubZer_WFAp-nyJfTvCElF3hyphenhyphen_HtKM-Xy5QMva02o_W2-rU_NGWpaX1lL-f1dbzC6CydviFQJzLLe/s320/2621_me_dicen_vago.jpg" height="278" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">de <a href="http://desmotivar.com/">desmotivar.com</a></td></tr>
</tbody></table>
Ahora bien, retrocedamos unos años, y estudiemos la historia de <b>Willi, el primer informático alfa</b>. Willi estaba pasando a limpio uno de esos insufribles trabajos del cole con su máquina de escribir. Taka-taka-taka-ta-ka-takataka-kata¡CRACK!... ¡cagonlaleche!, ¡ya me he vuelto a equivocar!. Como buen vagazo, Willi <b>no había comprado aún el típex</b>, que le hubiera permitido corregir los errores (más mal que bien) y que se le había acabado hace dos años. Por supuesto, <b>Willi no estaba dispuesto a volver a escribir la página entera</b>, bastante se había aburrido ya preparando ese trabajo sobre las opciones reproductivas del berberecho silvestre en celo. Como no era la primera vez que no presentaba un trabajo (dos años sin típex dan para muchos trabajos sin presentar), Willi se encontró conque para aprobar el curso le habían puesto la condición de... preparar otro trabajo para Septiembre. A máquina, por supuesto (la letra de Willi era deslabazada y poco definida, como corresponde a todo buen informático alfa).<br />
<br />
Como <b>la necesidad aguza el ingenio</b>, Willi pensó una solución a sus males. Cogió cuatro condensadores, unas resistencias, una caja de zapatos, una malla de las patatas, un gnomo del bosque (esto es sólo una leyenda urbana no verificada, al contrario que el resto del artículo), un cristal de la ventana y unos botones de camisa, se puso manos a la obra y creó... <b>el primer ordenador</b>. Gracias a él, cada vez que se equivocaba al pulsar el botón equivocado mientras escribía, podía apretar la goma de borrar (en un alarde de ingenio y originalidad Willi usó una goma de borrar Milán en lugar de un botón para eliminar la última letra escrita), y no tenía que volver a empezar cada vez que la cagaba. Willi celebró su hallazgo durmiendo <b>una profunda siesta de 3 horas</b>.<br />
<br />
El día antes de la fecha límite de entrega del trabajo, Willi se dio cuenta de una cosa... tenía todos los bytes del trabajo guardados en el tambor de Colón floppy que le servía de almacenamiento, pero <b>no podía llevar el trabajo así</b>, porque el profesor no estaba preparado aún para tamaño avance (y aparte de eso, no tenía su dirección de email). Se puso manos a la obra y con unas agujas de coser, unas plastilinas y el líquido de siete latas de calamares en su tinta, <b>creó la primera impresora</b>, con la que pudo plasmar el trabajo en papel y entregarlo. Es verdad que tuvo suerte para que su madre tuviera la despensa llena de latas de calamares, y que estos no fueran en salsa americana (el mundo no estaba aún preparado para las impresiones en color), pero lo cierto es que esta es otra de las características que persiguen a los informáticos alfa: <b>cuanto más acorralados parece que están, más suerte tienen</b>.<br />
<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; margin-left: 1em; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiVXya-xp8rsGz0iYB7Y0RKsLBh4exZpZqjO8v7nbEruRoTCU5eDcmOXBUgvtFAHki_xAWi1j5QppgSY1w09pMRfcJ-FV2BHmps447xeuwLFSj6w1WQU1bJMTW_MEPpDwjgkvsriKWiDAS/s1600/vago_1.jpg" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiVXya-xp8rsGz0iYB7Y0RKsLBh4exZpZqjO8v7nbEruRoTCU5eDcmOXBUgvtFAHki_xAWi1j5QppgSY1w09pMRfcJ-FV2BHmps447xeuwLFSj6w1WQU1bJMTW_MEPpDwjgkvsriKWiDAS/s320/vago_1.jpg" height="262" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">de <a href="http://desmotivaciones.es/">desmotivaciones.es</a></td></tr>
</tbody></table>
¿Por qué sucede esto?. Obviamente, <b>es una cuestión evolutiva</b>. La Naturaleza ayuda al ser humano a garantizar su supervicencia, y en los momentos importantes es capaz de dar un empujoncito para apoyar estos sucesos que nos hacen evolucionar. <b>Dios no juega a los dados</b>. Si Willi no hubiera sido más vago que la chaqueta de un guarda, hubiera escrito otra vez su trabajo, que tampoco era para tanto el sufrimiento, y por tanto no hubiera creado nunca un ordenador. <b>Y la Informática no hubiera existido jamás</b>.<br />
<br />
El arma principal del informático alfa, que ya hemos visto en acción en la emotiva historia de Willi, es <b>el detector de coñazos</b>. El informático alfa tiene un detector natural que le hace percibir de forma inequívoca cuándo una tarea es automatizable y optimizable, y se debería buscar una forma diferente de hacerla, o de evitarla para que no sea necesaria. Y lo siente en forma de coñazo. Y lo siente tan fuerte, que <b>recibe unas energías que hacen aumentar su ingenio</b> y le ayudan a encontrar una solución que optimice el trabajo, y que por tanto le distinguen frente al resto de informáticos obedientes.<br />
<br />
Ejemplos los tenemos a patadas. <b>Toda la evolución de los procesos y herramientas de desarrollo de aplicaciones</b> ha surgido a partir de informáticos alfa. Todas las herramientas de desarrollo las ha creado uno de ellos, como no podía ser de otra forma. Y <b>las metodologías ágiles</b>, por ejemplo, son resultado indudable de la agitada mente de un informático alfa, que supo usar su detector de coñazos para percibir que <b>las metodologías</b> estaban llenitas de ellos, que escribir <b>documentación</b> para los programas era un aburrimiento y no podía ser bueno, que las <b>reuniones eternas con clientes</b> en las que no se avanza nada no hay cristo que las aguante, y que las <b>estimaciones y los planes</b> definidos a largo plazo acaban llevando a hacer tareas poco lógicas, sin sentido y, claro, aburridas.<br />
<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; margin-left: 1em; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLWq5mDqFSFuHWvYT6nTZkPGbvoHLMkgfXdQDupXsoQb5RvXEO9WGJjLz4Tp5ixnNAhtwL0GgOhDIy9kX9GXfb6H0eIyhBll-YJEh4uuRx5MuFmGYnA-URFAhqddcxYB5Nd9XrSE0duCQo/s1600/d%C3%ADa+vago2%5B4%5D.jpg" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLWq5mDqFSFuHWvYT6nTZkPGbvoHLMkgfXdQDupXsoQb5RvXEO9WGJjLz4Tp5ixnNAhtwL0GgOhDIy9kX9GXfb6H0eIyhBll-YJEh4uuRx5MuFmGYnA-URFAhqddcxYB5Nd9XrSE0duCQo/s1600/d%C3%ADa+vago2%5B4%5D.jpg" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">de <a href="http://himajina.blogspot.com/">himajina.blogspot.com</a></td></tr>
</tbody></table>
Quizá pienses que si el candidato es tan vago <b>no hará nada</b> y punto. Pero te equivocas. <b>El informático vago disfruta trabajando para no trabajar</b>. Y en el fondo es conocedor del importante papel que tiene en el desarrollo de la Humanidad, aunque no necesariamente de forma consciente. Su detector de coñazos le convierte en el mejor definidor y propulsor de buenas prácticas de desarrollo. Y ya hemos visto la importancia de todo esto para cualquier mínima evolución en el mundo de la Informática.<br />
<br />
¿Me crees ya?.<br />
<br />
<b>Pues ahora escucha, amigo cazador de talentos</b>. Si me haces caso, puedes resumir tus entrevistas de trabajo en una sola pregunta:<br />
<br />
1.a. ¿Te definirías a ti mismo como un vagazo?<br />
<br />
Ni siquiera hace falta hacerla en persona, puedes mandar un formulario a los candidatos, o una encuesta online. Y tendrás una efectividad del 100%.<br />
<br />
Por tanto, con esto tienes en tu mano la oportunidad de convertirte en un pionero... de convertirte en <b>EL PRIMER CAZATALENTOS ALFA VAGAZO</b>.<br />
<br />
Y pegarte la vida padre, ya puestos.<br />
<br />Andréshttp://www.blogger.com/profile/06010147149377176406noreply@blogger.com3tag:blogger.com,1999:blog-6416070227303513915.post-65039421892067122862013-08-22T09:12:00.000+02:002014-01-28T23:27:00.294+01:00Nekromanteia, rituales de los muertos: novela negra no, ¡negrísima!<h2>
Introducción</h2>
Hoy hablamos sobre "Nekromanteia, rituales de los muertos", una escalofriante novela sobre espíritus y...<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHGXg70gyelrjCN-NMfzqs6QhGgc4z75WRMaZHpntJCbKo71LHNNfBGBmjj-cnu4Qg4BsQZ7h5c_rf5aP-fDI7WQHxS7FaLAo06ugV1pvWipUmopYRFNGEswRm3pM1v6o-AsaVq7nhyphenhyphenZeI/s1600/hulka1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHGXg70gyelrjCN-NMfzqs6QhGgc4z75WRMaZHpntJCbKo71LHNNfBGBmjj-cnu4Qg4BsQZ7h5c_rf5aP-fDI7WQHxS7FaLAo06ugV1pvWipUmopYRFNGEswRm3pM1v6o-AsaVq7nhyphenhyphenZeI/s640/hulka1.jpg" height="204" width="640" /></a></div>
<br />
Ejem. Después de que Jen... la sensacional Hulka de John Byrne, que tan excelsamente publicó Marvel, y que cada día está más guapa... me haya interrumpido, nos ponemos serios y como decía... con todos ustedes, ¡"Nekromanteia, rituales de los muertos"!. Una novela que no es para tomarse a broma, como vamos a ver.<br />
<br />
<h2>
El Protagonista</h2>
No es fácil ser <b>Etham Loss</b>... tu obsesión por el estudio de los misterios que hay <b>más allá de la muerte</b> te ha llevado a <b>no valorar a los vivos</b>, y tu absoluta <b>falta de empatía</b> hace que ni tú mismo seas consciente de tus propios sentimientos y que los evites continuamente, convirtiéndote así en un grandísimo hijo de perra. <b>No tienes amigos</b>, y ni siquiera piensas que te importe. Conoces varias personas dentro del mundo de la nigromancia, sí, pero ninguno se puede considerar realmente un amigo. Ni siquiera tu maestra en dicho arte, <b>Noa</b>, siempre queriendo demostrar su superioridad a ti. Ni tampoco otros, como <b>Erictho</b>, esa falsa vidente, o como <b>Margoth</b>, esa hedonista chiflada con demasiado contacto con la magia infernal. Y no hablemos de <b>Darren</b>, ese asqueroso necrófilo idiota, que te es útil para conseguir algunos cadáveres, pero de quien piensas que realmente el mundo estaría mejor sin él. ¿Parejas?. ¿<b>Judith</b>? Muerta. ¿<b>Mara</b>?... Mara... se acaba de suicidar. Y eso te obsesiona, <b>te obsesiona capturar su espíritu</b>, preguntarle por qué ha hecho tal cosa, apresarla todo el tiempo que puedas.<br />
<br />
Aparte de eso tienes tus libros, tus conocimientos, tus conjuros... y <b>un puñado de espíritus</b> que a menudo te vienen muy bien para ocupar el cuerpo de alguien y enloquecerlo o matarlo. Al fin y al cabo, <b>uno tiene que tener sus diversiones</b>.<br />
<br />
<h2>
La novela</h2>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjANGcGtoA4fhKcoxm94TO4JY7rMIYWJo4y5e_omll573gFPCXKOgLh7nb2bbeEVPuGPHx9HOtotlP9kkoBRcyMXAFJV5M6sdEv7fmEXD2y3612L1wBQaV0vsQap_An9ZiETL2o-K-ShHWb/s1600/uno.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><br class="Apple-interchange-newline" /><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjANGcGtoA4fhKcoxm94TO4JY7rMIYWJo4y5e_omll573gFPCXKOgLh7nb2bbeEVPuGPHx9HOtotlP9kkoBRcyMXAFJV5M6sdEv7fmEXD2y3612L1wBQaV0vsQap_An9ZiETL2o-K-ShHWb/s640/uno.jpg" height="640" width="449" /></a></div>
<br />
<br />
Uno de los mayores logros que tiene el libro es precisamente <b>conseguir que no chirríe con un personaje tan amoral y falto de empatía</b> como este. Especialmente, cuando es un libro muy en primera persona, es decir, muy centrado en el protagonista, siguiendo continuamente todas sus acciones y pensamientos. Uno de los motivos por los que consigue que sintamos cierta empatía o identificación por él es que está rodeado en general de <b>personajes aún más detestables</b>.<br />
<br />
La estructura del libro <b>me recuerda mucho a la novela negra</b>, la de detectives solitarios investigando un crimen y metiéndose en un enorme lío casi sin darse cuenta, normalmente instigados por mujeres malas y de voluptuosas curvas. Sólo que la ambientación cambia por completo. No es un detective solitario borracho y autodestructivo pero duro, sino un <b>nigromante</b> igual de solitario y autodestructivo, pero obsesionado con la muerte... y también duro, claro. No es una mujer mala de voluptuosas curvas la que engaña al detective de primeras, sino que <b>lo que le mueve y le mete en el lío es su propia obsesión</b> por invocar el espíritu de su amante suicida. Y por supuesto, casi sin querer se meterá en un lío, en un enorme lío. Y la mayor parte del tiempo no tendrá ni idea de qué está ocurriendo a su alrededor ni por qué le ocurren las cosas, e incluso muchas veces actuará sin tener muy claro por qué, e intentando coscarse de algo investigando como puede (ya sea hablando con vivos o con muertos, o haciendo visitas a lugares alegres como cementerios o iglesias abandonadas...).<br />
<br />
<b>Lo que cambia es el entorno</b>, especialmente la ambientación esotérica. Con eso de tanto invocar espíritus, lo cierto es que lo de estar muerto no es para tanto. La muerte de primeras no es tan definitiva como en otros, y <b>que un personaje muera no significa ni mucho menos que no vaya a volver a aparecer</b> para tener unos momentillos de charla con nuestro nigromante favorito. Y claro, os podéis imaginar que <b>muere un montón de gente</b>. El protagonista no está asediado por un señor feo que le sigue, sino que lo que le acosan son espíritus o "larvas" que quieren adueñarse de su cuerpo. Por otra parte, el lío en el que se mete en el protagonista no es algo como un simple asesinato, sino que lo que tenemos son <b>multitud de cuerpos muertos pululando por la ciudad</b> cual zombies, y cargándose aún más gente. Y cómo no, con <b>el diablo y la magia demoníaca de por medio</b>. Hay momentos en el libro realmente brutos y asquerosillos (no es para todos los estómagos, vaya).<br />
<br />
Es decir, que me recuerda a la novela negra, pero deja a aquella en pañales como un simple "gris clarito" y a esta la podemos catalogar como "<b>novela negrísima</b>".<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3ceCz6i-aRPOeI4ljEcUBUxD0oeS-a_Cr29PaL6AYmRIDr2ERAPx4uhAsDbpyDQOSzrn34-7GDbJt13xIvVrv6EyEWtd_e1rrTUf5HfQWUseTgkxNT2TMq3Wed3pod7Kb0eRjfr2HMXQx/s1600/uno.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3ceCz6i-aRPOeI4ljEcUBUxD0oeS-a_Cr29PaL6AYmRIDr2ERAPx4uhAsDbpyDQOSzrn34-7GDbJt13xIvVrv6EyEWtd_e1rrTUf5HfQWUseTgkxNT2TMq3Wed3pod7Kb0eRjfr2HMXQx/s1600/uno.jpg" /></a></div>
El libro está bien escrito, tiene muchas <b>descripciones realmente desasosegantes</b>. Si se puede leer de noche y bajo la luz de una vela mejor... bueno, si luego somos capaces de dormir, quiero decir. Está <b>muy bien documentado todo el tema esotérico de la nigromancia</b>, los rituales, símbolos, demonios (¡viva Tetragramatón!), incluso con citas de los, esto, "grandes del género", al principio de cada capítulo. Por otro lado, <b>la portada es impresionante</b>. Es de esas que llama la atención, que te deja muy a las claras cómo es el libro (chicos, os presento a Mara, ¿a que es mona?), que invitan a comprarlo y a leerlo.<br />
<br />
Aunque el escritor es un "casi novato" (es su segundo libro, más alguna historia corta), <b>el guión está muy bien estructurado</b>. La información va cayendo a cuentagotas, <b>bien dosificada</b>, y nos invita continuamente a averiguar más. El ritmo está bien medido, y la resolución no decepciona. Eso no quita que existan en mi opinión algunos aspectos mejorables. Hay momentos en que se echa de menos algo mas de tensión dramática, quizá todos los personajes sean demasiado parecidos en algunas cosas (básicamente, en ser todos unos hijos de perra sin corazón) y llegue un momento en que falte algo de sentimiento. Por otra parte <b>no me acabó de convencer el principio del libro</b>. Hay varios capítulos al principio que dan sensación al leerlos de ser prácticamente introductorios, que no acaban de meterse en la historia. Está hecho así con un propósito, es parte de la dosificación de la información, pero el problema es que llegas al tercer capítulo y todavía no acabas de tener muy claro qué te están contando, parece todo algo inconexo. No es grave, y lo mismo es sólo una impresión personal. En cualquier caso, luego el libro ya despega y no para.<br />
<br />
En definitiva, <b>si te gustan las novelas del género negro y además te atrae el ocultismo</b> y los espíritus que hacen cosas como hablar y controlar un cuerpo para asesinarse a sí mismos, <b>no dejes pasar este libro</b>.<br />
<br />Andréshttp://www.blogger.com/profile/06010147149377176406noreply@blogger.com6tag:blogger.com,1999:blog-6416070227303513915.post-27717206912033732912013-07-27T18:37:00.001+02:002014-01-28T23:29:17.486+01:00Bootstrap 3 y el marcado semántico<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTsPWkcQF4v6IkZo2hpp3IzOaHOv2jM-F3RN-1e6zJePEENR6ZRQxQGd1UVSyGA9bRwtWdzbxSAtF-cp7S24ferY5Ogc0N6gt5ErNiWtbqXGjXf3LzBeqGMxAz8SsM_DHTCTvDCFH1s51d/s1600/uno.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTsPWkcQF4v6IkZo2hpp3IzOaHOv2jM-F3RN-1e6zJePEENR6ZRQxQGd1UVSyGA9bRwtWdzbxSAtF-cp7S24ferY5Ogc0N6gt5ErNiWtbqXGjXf3LzBeqGMxAz8SsM_DHTCTvDCFH1s51d/s1600/uno.png" /></a></div>
Probablemente estés ya hasta las narices de <b><a href="http://getbootstrap.com/">Bootstrap</a></b>. Artículos y artículos, herramientas que lo usan o generan código compatible, y lo peor de todo... muchas webs con lo que yo llamo <b>"pestuzo Bootstrap"</b>, que no se molestan casi ni en cambiar el estilo que trae por defecto, así que son todas igualicas. Por otra parte, también es posible que no lo hayas usado jamás e incluso que ni sepas lo que es.<br />
<br />
Acaba de salir la primera <b>release candidate de la versión 3 de Bootstrap</b>, una versión que imagino que puede ser polémica (igual es por eso que la han sacado un Sábado veraniego casi de Agosto), así que aprovecho la ocasión para escribir este artículo. Empezaré contando qué es Bootstrap y qué tiene de bueno, sobre todo para los que no lo conozcáis aún (¿en qué cueva os habéis metido?). Incidiré en cosas que no me gustaron de su planteamiento general, especialmente contaré cómo se puede ir más allá y <b>mejorar la separación entre contenido y presentación</b>, haciendo nuestro código más semántico. Finalmente, aprovecharé que llevo varias semanas usando Bootstrap 3 para contar <b>qué puedes esperar de esta versión</b> y por qué tiene algunos <b>cambios realmente interesantes</b> para el futuro, junto a <b>otros frustrantes</b> para los que ya estaban usando la versión 2.<br />
<br />
<h2>
¿Por qué Bootstrap?</h2>
No hay nada que haga a uno sentirse más como un <b>perro apaleado</b> que programar el <b><i>front</i></b> de una web. Desde los primeros años de la web, se ha maltratado sistemáticamente todo lo que tenía que ver con su programación, casi siempre por motivos comerciales. Primero la guerra entre Microsoft y Netscape hizo que cada uno usara el JavaScript que le daba la gana. Luego la guerra entre Microsoft y... el resto del mundo, hizo... que en general <b>Micro$oft interpretara cualquier posible estándar de la web como le diera la gana</b>. Programar JavaScript y CSS significaba, básicamente, perder días y días pegándose en dura batalla con los navegadores, fundamentalmente con todas y cada una de las versiones de IE, ya que era con diferencia el navegador más utilizado y encima ninguna versión era igual a la anterior (ni tampoco se acogía a los estándares).<br />
<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; margin-left: 1em; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8eEIUu0hK6co_kGkryNLkT_VLEPueZpPt85HP8fWkDE6_56y_Z7cJkFCetVOniDoCVYzLU7ZXUbe21qLnewX-br21grdkBtJekBo6uLAPqEhKcQuT3edrIesX-0PdPjCO2MbfpprD6IUi/s1600/uno.jpg" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8eEIUu0hK6co_kGkryNLkT_VLEPueZpPt85HP8fWkDE6_56y_Z7cJkFCetVOniDoCVYzLU7ZXUbe21qLnewX-br21grdkBtJekBo6uLAPqEhKcQuT3edrIesX-0PdPjCO2MbfpprD6IUi/s320/uno.jpg" height="320" width="259" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">de html5code.com</td></tr>
</tbody></table>
Perdón, ¿estoy hablando en pasado?. Me temo que eso <b>aún no ha acabado</b>. Internet Explorer 8, aún uno de los navegadores más usados, sigue haciendo lo que le da la gana con muchas cosas. No he probado aún lo suficiente IE9 para saber si también es así, aunque algo he oído de que avanza bastante respecto a las versiones anteriores en cuanto a su estandarización pero todavía no acaba de cuajar. ¿Quizá IE10?.<br />
<br />
Los estándares intentan moverse, modernizarse. No es normal que después de tanta guerra estemos casi en el mismo punto que hace 20 años. Se crea <b>HTML5</b>, sí... y después de varios años, todavía es una "<i>candidate recommendation</i>" y cada navegador implementa las partes que quiere. <b>CSS3</b>... más o menos lo mismo, con la coña de que tiene partes aprobadas y otras que aún no.<br />
<br />
El precio de todo esto es enorme. Hacer una aplicación web es <b>muchísimo más costoso</b> de lo que debería, y la web avanza mucho más lentamente de lo que sería normal.<br />
<br />
Como ocurre a menudo, las soluciones las ha ido proporcionando <b>la propia comunidad</b>. No necesitamos estándares <i>de iure</i>, tengamos estándares <i>de facto</i>. Así, especialmente en el campo del JavaScript fueron surgiendo librerías que encapsulaban las diferencias entre los navegadores, fundamentalmente en el acceso a DOM: MooTools, Prototype... y sobre todo la que finalmente parece que se alzó como la ganadora, jQuery.<br />
<br />
Sin embargo, la revolución real está ocurriendo <b>ahora mismo</b>. En cuestión de estos últimos meses. En estos momentos, Internet Explorer ya no es el rey, y está en un declive cada vez mayor. Y ahora están saliendo productos que <b>crean una capa</b> por encima de HTML-CSS-JavaScript. Productos con una pinta estupenda, y que facilitan la programación del front. Entre ellos, seguramente el más popular ahora mismo sea Bootstrap.<br />
<br />
<h2>
Primera impresión</h2>
La primera impresión es muy buena. Bootstrap utiliza un curioso sistema para facilitar muchísimo el diseño de la web. Lo que predica es lo siguiente: utiliza <b>HTML5 estándar</b> para hacer la web, y <b>coloca estratégicamente determinados "class"</b> en cada elemento para conseguir:<br />
<ul>
<li>Un sencillo pero potente sistema de <b>layout</b>, basado en filas y columnas.</li>
<li>Varios <b>componentes prediseñados</b>. Algunos de ellos, con código JavaScript listo para hacer que esos componentes sean dinámicos, sin que tengas que hacer nada de primeras. Así tendremos botones, pestañas, menús con varios niveles, componentes de paginación... un gran número de elementos que HTML no incorpora, pero que se utilizan habitualmente como interfaz de usuario en muchas webs.</li>
</ul>
<div>
Este es un ejemplo de código HTML (de Bootstrap 2). Obsérvense los distintos class que tiene:</div>
<div>
<br />
<pre class="brush:html"><div class="container">
<!-- Main hero unit for a primary marketing message or call to action -->
<div class="hero-unit">
<h1>Hello, world!</h1>
<p>This is a template for a simple marketing or informational website. It includes a large callout called the hero unit and three supporting pieces of content. Use it as a starting point to create something more unique.</p>
<p><a href="#" class="btn btn-primary btn-large">Learn more »</a></p>
</div>
<!-- Example row of columns -->
<div class="row">
<div class="span4">
<h2>Heading</h2>
<p>Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui. </p>
<p><a class="btn" href="#">View details »</a></p>
</div>
<div class="span4">
<h2>Heading</h2>
<p>Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui. </p>
<p><a class="btn" href="#">View details »</a></p>
</div>
<div class="span4">
<h2>Heading</h2>
<p>Donec sed odio dui. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Vestibulum id ligula porta felis euismod semper. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.</p>
<p><a class="btn" href="#">View details »</a></p>
</div>
</div>
</div> <!-- /container -->
</pre>
<br /></div>
<div>
Hacer una web con este sistema es realmente fácil, y aunque no toques apenas nada la web ya te quedará con una pinta bastante decente.<br />
<br />
La distribución "normal" de Bootstrap trae un fichero .js y un fichero .css. Para personalizar los estilos, se supone que hay que añadir más reglas CSS, o al menos eso es a lo que parece que te invita.<br />
<br />
Sin embargo, aunque esta es la forma de programar que propone Bootstrap, lo cierto es que <b>no nos deberíamos conformar con eso</b>. Eso sí, me gustaría recalcar que es una forma muy interesante y rápida por ejemplo para crear prototipos de una web. Pero si estamos haciendo algo serio podemos exigir más.<br />
<br />
<h2>
Personalizando con LESS</h2>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgK2-sGJW6aGy4rP3sJJMbR-P-NXrYFd_4IS2WhIpbRNRuQqvAmxcWvVHfxkFT4P0-iOh1Fyp9BbtOlSa-YXsYkvxuzst4WAsmSe7ybyNQpnj4sfkNTyQcIsk7BX3jdBqyLvqH1XHZ5LdIx/s1600/uno.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgK2-sGJW6aGy4rP3sJJMbR-P-NXrYFd_4IS2WhIpbRNRuQqvAmxcWvVHfxkFT4P0-iOh1Fyp9BbtOlSa-YXsYkvxuzst4WAsmSe7ybyNQpnj4sfkNTyQcIsk7BX3jdBqyLvqH1XHZ5LdIx/s1600/uno.png" /></a>Modificar directamente el CSS tiene un problema, y es que estamos perdiendo una de las ventajas más importantes que realmente tiene Bootstrap, y es que <b>está hecho en <a href="http://lesscss.org/">LESS</a></b>. De hecho, Bootstrap se puede considerar una librería de LESS unida a otra de JavaScript.<br />
<br />
LESS es un lenguaje que se construye sobre CSS, añadiendo características muy cómodas, fundamentalmente:<br />
<br />
<ul>
<li><b>Anidamiento de reglas</b>, que mejora mucho la legibilidad y te facilita el que haya un orden dentro del fichero (los ficheros CSS tienden naturalmente al caos más absoluto)</li>
<li><b>Variables</b>: puedes meter valores comunes como colores, tamaños de padding, etc. en variables, y utilizarlas luego en otras reglas</li>
<li><b>Funciones y operaciones</b>: también puedes crear valores que resulten de aplicar una operación sobre otro valor, como por ejemplo poner un color que sea un 20% más oscuro que otro (el cual puede estar, por ejemplo, en una variable).</li>
<li><b>Mixins</b>: esto es lo más importante que aporta LESS. Los mixins son conjuntos de reglas que puedes usar en distintos sitios. Es decir, permite crear <b>componentes reutilizables</b> de CSS.</li>
</ul>
<br />
La librería LESS de Bootstrap está en general bien diseñada. Hay un fichero "<b>variables.less</b>" que tiene un montón de variables con las que se pueden controlar y personalizar muchísimos aspectos de la presentación por defecto: colores, fuentes, espaciados de márgenes y paddings... Otro fichero, "<b>mixins.less</b>" contiene un montón de mixins muy útiles de propósito general.<br />
<br />
El resto de ficheros .less están dedicados a componentes o partes específicas: botones, tablas, barras de navegación, etc. En ellos se encuentran los estilos por defecto para todos estos tipos de elementos, junto a opciones de presentación de cada uno según sus clases.<br />
<br />
Imagino que Bootstrap no incluye los ficheros LESS en la distribución normal porque intenta facilitar al máximo el que cualquiera pueda usarlo. Es decir, <b>trata a los usuarios como idiotas</b>. En mi opinión esta es un arma de doble filo, porque lo que está consiguiendo con ello es que mucha gente <b>personalice muy poco lo que viene por defecto</b>, consiguiendo así el efecto "pestuzo Bootstrap" que hay en tantas y tantas webs, y que comentaba al principio del artículo.<br />
<br />
Créeme, <b>trabaja directamente utilizando los ficheros .less</b>, y creando otros <b>less propios</b> que redefinan las variables y pongan tus estilos. Es mucho más cómodo y a la vez mucho más potente (salvo que seas un idiota, claro).<br />
<br />
<h2>
Marcado semántico en Bootstrap</h2>
</div>
<div>
Hace muchos, muchos años, en una galaxia muy, muy lejana, el layout de las páginas se definía directamente <b>dentro del propio HTML usando tablas</b>. Entonces surgió la creación de layouts con CSS, la que se ha venido usando desde entonces. Lo cierto es que esta forma de crear los layouts era un coñazo integral porque cada versión de Internet Explorer interpretaba (y sigue interpretando) las propiedades CSS, y especialmente las que permiten formar layouts, como le daba la gana. A pesar de esto acabó triunfando, y una de las grandes ventajas que defendía el layout por CSS es que gracias a él se podía separar el contenido, la información que queremos mostrar, de la presentación de ese contenido. Se trataba de hacer <b>marcado semántico</b>, dentro de lo posible.<br />
<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; margin-left: 1em; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSjOHGinr8ZrrBuG2ewhAmY631gcsd5wwGmPc6nYc4jgzBP19wCDOPA2cL6jkLBbdARSdTHKR5IAZLYPuFvGKo5DRxUDe-LphcA9m7Zk9wF6vIknf7PF2n95mk2i9cBpsoPoZ4_4OB2H0v/s1600/uno.jpg" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSjOHGinr8ZrrBuG2ewhAmY631gcsd5wwGmPc6nYc4jgzBP19wCDOPA2cL6jkLBbdARSdTHKR5IAZLYPuFvGKo5DRxUDe-LphcA9m7Zk9wF6vIknf7PF2n95mk2i9cBpsoPoZ4_4OB2H0v/s320/uno.jpg" height="268" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">de <a href="http://coding.smashingmagazine.com/2007/01/12/free-css-layouts-and-templates/">coding.smashingmagazine.com</a></td></tr>
</tbody></table>
¿Cuál es el problema de la forma de hacer layouts que propone Bootstrap?. Pues precisamente esto, que volvemos a mezclar dentro del HTML el layout de la página con el contenido, aunque sea en forma de .class. Pues para eso volvemos a las tablas, ¿no?...<br />
<br />
Es prácticamente imposible que el contenido de tu página sea semántico puro y no piense un poco en el layout. Ahí están los div, que sobre todo sirven para agrupar cosas que imaginas que pondrás luego juntas en el layout. Pero sí pienso que es bueno intentar separarlo lo máximo posible.<br />
<br />
En mi caso es fundamental esta separación. Trabajo en un <b>producto reutilizable</b>, que se instala en varios clientes y que en cada uno puede <b>cambiar la presentación</b>. Tengo que intentar evitar al máximo el que tenga que modificar el HTML cuando lo único que necesite sea cambiar aspectos de presentación. Aparte de eso, aunque tu producto no sea reutilizable, pienso que en general es una <b>buena práctica</b>.<br />
<br />
¿Entonces?. ¿Pasamos de Bootstrap?. No es necesario. Como ya he comentado antes, BS está basado en LESS. Y esa precisamente va a ser la solución.<br />
<br />
Al principio descargué la última versión oficial de BS, la 2.3.2. Algunos de los class de Bootstrap se pueden considerar realmente semánticos: este div va a ser una barra de menú, o un elemento de paginación... Pero otros son claramente de presentación, como por ejemplo si un botón va a ser grande o pequeño, o si una barra de botones se va a poner alineada a la izquierda o a la derecha.<br />
<br />
En seguida me di cuenta de que para la mayor parte de los casos, no era realmente necesario poner los class dentro del HTML, aprovechando las capacidades de LESS. Así, por ejemplo, si quiero que los botones de un formulario sean pequeños, no necesito poner el HTML así:<br />
<br />
<pre class="brush:html"><form class="form-login">
(...)
<button type="button" class="btn btn-small">Ver cambios</button>
</form>
</pre>
<br />
sino que puedo hacer esto otro:<br />
<br />
<pre class="brush:html"><form class="form-login">
(...)
<button type="button" class="btn">Ver cambios</button>
</form>
</pre>
<br />
y luego en el .less:<br />
<br />
<pre class="brush:css">.form-login {
.btn {
.btn-small;
}
}
</pre>
<br />
Alegría, saltos, fiesta... pero espera... esto no ocurre para todos los casos. O mejor dicho, había un caso fundamental en el que esto <b>no funcionaba</b>: precisamente, <b>el sistema de grid para el layout</b>.<br />
<br />
Escondidos entre los .less de Bootstrap encontré unos mixins que me podían ayudar: <b>makeRow y makeColumn</b>. Sin embargo, <b>no funcionaban bien</b>. No era lo mismo poner los class que usar estos mixins. Mi gozo en un pozo.<br />
<br />
Cuando estaba pensando alternativas, encontré que estaba en desarrollo una versión 3. Miro los cambios y ¡bingo!, <b>han cambiado enterito el sistema de grid</b>. Ahora el sistema de grid es mobile-first, y no diferencia entre "filas fluid y no fluid", todas son fluidas. También han cambiado el nombre de los class.<br />
<br />
Vuelvo a hacer la prueba y, esta vez sí, compruebo que funciona. Esto es un ejemplo de un grid en Bootstrap hecho con marcado semántico:<br />
<br />
<pre class="brush:html"><div class="wrapper">
<div class="content-main">...</div>
<div class="content-secondary">...</div>
</div>
</pre>
<br />
Y su LESS:
<br />
<pre class="brush:css">.wrapper {
.make-row();
}
.content-main {
.make-column(8);
}
.content-secondary {
.make-column(3);
.make-column-offset(1);
}
</pre>
<br />
De hecho, aunque hasta hace poco no estaba y yo tuve que llegar a ello a base de hacer arqueología en el código, estos mixins y la forma de usarlos ya aparecen dentro de <a href="http://getbootstrap.com/css/#grid-less">la propia documentación del sistema de grid</a> (bueno, a mi me ha servido para copiar el ejemplo...).<br />
<br />
No sólo esto, sino que <b>la librería LESS está realmente mejor diseñada</b>. No es sólo el sistema de grids, en general todos los componentes están mucho más basados en mixins, es mucho más fácil hacer marcado semántico ahora que en la versión 2.<br />
<br />
Así que sí, querido lector, te lo puedo decir: <b>se puede hacer marcado semántico con Bootstrap</b>.<br />
<br />
<h2>
Bootstrap 3: qué más me voy a encontrar</h2>
<div>
Si ya eras usuario de Bootstrap 2, tengo una noticia realmente mala para ti: no es sólo que <b>tu código anterior no sea compatible</b>. Es que ha cambiado un montón, muchas veces en cosas muy pequeñas.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhiiJ3WRX5GL__mWp_ueICEzqnI-rYw-ZDoH1bG7QT1AElou63SGvN36z1OD2KkSXaoFzOQ__G-3xaCkGryQSAdIyFxHMGyk5y_uSqXYoKpuG6LPxpmL5IO2W60_sRhKuDw9MVIcljZNczk/s1600/uno.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhiiJ3WRX5GL__mWp_ueICEzqnI-rYw-ZDoH1bG7QT1AElou63SGvN36z1OD2KkSXaoFzOQ__G-3xaCkGryQSAdIyFxHMGyk5y_uSqXYoKpuG6LPxpmL5IO2W60_sRhKuDw9MVIcljZNczk/s200/uno.png" height="150" width="200" /></a></div>
<div>
Lo primero que te vas a encontrar es que <b>ha cambiado el aspecto por defecto</b>. El diseño actual pretende ser más "aséptico", menos intrusivo. Los botones y otros elementos no tienen detalles como gradientes, <b>es un diseño más plano, más "metro"</b>. Esto es fácil de ver, basta conque vayas a la <a href="http://getbootstrap.com/">página principal de Bootstrap</a>, porque lo que se está mostrando ahí ya es la versión 3.</div>
<div>
<br /></div>
<div>
Lo segundo que te vas a encontrar es que <b>han cambiado el nombre de un montón de clases y variables</b>. La intención es hacer los nombres más homogéneos, y en verdad lo han conseguido. Pero olvídate de que tu código funcione con ellos, claro. Los más obvios son los del sistema de layout, cuando antes se ponían las columnas con elementos como "span3" y las filas muchas veces con "row-fluid", ahora hay que utilizar cosas como "col-3" o "col-lg-3", y las filas van siempre con "row". Pero hay que decir que no se han cortado nada, han cambiado muchísimos nombres.</div>
<div>
<br /></div>
<div>
En cuanto a los formularios, ahora los componentes ocupan por defecto el 100% del ancho disponible, y han cambiado por completo la forma de agrupar campos.</div>
<div>
<br /></div>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; margin-left: 1em; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2IqqSshMVyGuFGHOansXztP69xirx85mjI3MeQKO_vzOyCr62PqRk57vb68V6_WHAB2yxSpd0MooGgfFoxG2p3Q_MIOtwEcoG00t0bw_T_3k_XPuMgVQzpM6gpkbOAxaq5OqJsNsFD6Ob/s1600/dos.png" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2IqqSshMVyGuFGHOansXztP69xirx85mjI3MeQKO_vzOyCr62PqRk57vb68V6_WHAB2yxSpd0MooGgfFoxG2p3Q_MIOtwEcoG00t0bw_T_3k_XPuMgVQzpM6gpkbOAxaq5OqJsNsFD6Ob/s200/dos.png" height="106" width="200" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">de soyouwanna.com</td></tr>
</tbody></table>
<div>
Los iconos también se han rediseñado por completo, ahora se dibujan con una fuente (es decir, son glyphicons). Bueno, y han cambiado los nombres de los class, claro.</div>
<div>
<br /></div>
<div>
Han desaparecido muchas opciones de presentación de los distintos elementos, muchos "-inverse" por ejemplo, y muchas formas de agrupar tipos de elementos. También han desaparecido elementos enteritos, como los thumbnails. A cambio, aparecen otros nuevos como los panels y los list groups.</div>
<div>
<br /></div>
<div>
Si además pretendes que tu código sea compatible con IE7 o Firefox 3.6, ni intentes actualizarte: BS3 ha dejado de ser compatible con ellos.</div>
<div>
<br /></div>
<div>
Pero bueno, lo mejor es que chequees tú mismo la gran <a href="https://github.com/twbs/bootstrap/pull/6342">lista oficial de cambios realizados para la versión 3</a>.<br />
<br />
Habrá que ver a partir de ahora qué harán todas esas webs que generan código Bootstrap de forma gráfica, o que venden temas ya prediseñados, y que al fin y al cabo pueden considerarse una de las ventajas de usar Bootstrap: su popularidad. ¿Se actualizarán?, ¿no se actualizarán?, ¿se mantendrán compatibles con las dos versiones? (posiblemente la mejor opción). Algunas de ellas son estas:<br />
<br />
<ul>
<li><a href="http://stylebootstrap.info/">StyleBootstrap.info</a>: generador de temas</li>
<li><a href="http://bootswatch.com/">BootSwatch</a>: temas prediseñados gratuitos</li>
<li><a href="https://wrapbootstrap.com/">WrapBootstrap</a>: temas prediseñados de pago</li>
<li><a href="https://jetstrap.com/">Jetstrap</a>: un diseñador WYSIWYG</li>
<li><a href="https://www.easel.io/">Easel.io</a>: otro diseñador WYSIWYG</li>
<li>Y muchos otros... tantos y tantos...</li>
</ul>
</div>
<br />
En definitiva, si eras usuario de Bootstrap 2, <b>actualizar tu HTML a BS3 no será nada sencillo</b>. A pesar de eso, opino que <b>los cambios en general son para mejor</b>, la librería está <b>mejor organizada</b>, es mucho <b>más fácil hacer HTML más semántico</b>, los <b>nombres son más homogéneos</b>, y se han eliminado muchas opciones que eran quizá demasiado intrusivas.<br />
<br />
Aunque bah! la verdad es que todo eso me importa un pimiento. Como no llegué a usar nunca la versión 2, lo único que realmente quería es que <b>me dejara hacer marcado semántico, y ahora... ¡se puede!</b>.<br />
<br /></div>
Andréshttp://www.blogger.com/profile/06010147149377176406noreply@blogger.com12tag:blogger.com,1999:blog-6416070227303513915.post-82220835487880094882013-07-01T19:12:00.001+02:002014-01-28T23:32:43.665+01:00Móntate la mejor Smart TV + centro de descargas + servidor con la Raspberry Pi<div class="separator" style="clear: both; text-align: center;">
</div>
<div style="text-align: start;">
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
¿Cómo te gusta ver las pelis y las series en casa?. ¿Eres de verlas en <b>sitios online</b> o de <b>descargarlas</b>?. Si eres de los segundos, y tienes unos mínimos conocimientos de cacharreo con terminales Linux, <b><u>este es tu artículo</u></b>.<br />
<br />
<b>Controlarás tus descargas al máximo, desde cualquier sitio y en cualquier momento, con un coste energético mínimo y sin ruido</b>. Y sin tener que hacer nada, copiar nada ni tener que arrancar nada más, encenderás tu tele y <b>tendrás tu catálogo completo navegable con información completa y la portada de cada peli</b>, y podrás elegir la que quieras ver manejando todo <b>con el propio mando</b> de la tele.<br />
<br />
<b>¿Preparado?</b><br />
<br />
NOTA: Por supuesto, estoy hablando siempre de descargas legales. Si usas este sistema para descargar algo que no sea gratuito o sobre lo que no tengas derechos, este blog y su autor no se responsabilizan en absoluto.<br />
<br />
<h2>
Introducción</h2>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsSfuuXh_CkDqOQViTMn8NKfIqJpe3NlkwwYAvCnTreLviAaPxmJN_qneLO8UIq1FBdsgp7V2wFkzSDTp7b2iZioBSi9p-TBz02-05iufYw3ZXqdMIGPN_Gl0ylZ9C7_Gs2zhiwAM3TF3_/s1600/uno.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsSfuuXh_CkDqOQViTMn8NKfIqJpe3NlkwwYAvCnTreLviAaPxmJN_qneLO8UIq1FBdsgp7V2wFkzSDTp7b2iZioBSi9p-TBz02-05iufYw3ZXqdMIGPN_Gl0ylZ9C7_Gs2zhiwAM3TF3_/s320/uno.jpg" height="240" width="320" /></a>Si no teníamos suficiente inteligencia en el mundo con los <b>smartphones</b>, ahora vienen las teles a hacerles la competencia, y cada vez se oye más el nuevo término molón: las <b>Smart TV</b>.<br />
<br />
Lo que está claro es que la tele ya no es lo que era. Hace ya mucho tiempo que eso de que sean <b>las emisoras las que deciden lo que puedes ver es cada vez más cosa del pasado</b>... El caso es que la tele está en un importante momento de cambio. Contratos del pasado y miedos del presente hacen que <b>servicios online como Netflix no existan en España</b>, y que los que existen, como <a href="http://www.filmin.es/">Filmin</a> o <a href="https://es.wuaki.tv/">Waki.tv</a> no tengan, en mi opinión, un precio ni un catálogo comparable (y el precio y el catálogo, amigos, es lo principal de todo esto). Eso merma mucho las posibilidades online actuales en nuestro país, aunque poco a poco el panorama está mejorando mucho. También hay sitios online de pirateo, pero tienen sus limitaciones (de muchos tipos). Mientras los servicios online acaban de estabilizarse, tenemos la interesante opción de las descargas.<br />
<br />
En este artículo os voy a contar cómo os podéis montar <b>la mejor Smart TV al menor precio posible</b>. Existen otras opciones, cada vez más, sobre todo basadas en Android, y ahí están Google TV y Apple TV con el revólver desenfundado. Nosotros usaremos un ordenador barato, la <b>Raspberry pi</b>, perfecta para este uso. Como software principal del centro multimedia le pondremos uno de los más populares actualmente, y que es la leche: <b>XBMC</b>. No contentos con ello, aprovecharemos que tenemos un peazo de Linux con todas sus posibilidades, y lo convertiremos también en un <b>centro de descargas</b> y a la vez en un <b>servidor</b>.<br />
<br /></div>
<h2 style="text-align: start;">
La Raspberry Pi</h2>
<div style="text-align: start;">
</div>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4XoDmFWhhRf9j1ye18lHyBZFUzxq0F8V-dCgQD7vwafXi7Q7PQ9lrbpX2h9ulEQEei4WsBtcJ4QtkNSZKgGl8BfxMrwGEvRFQ3LxJ6WIt5vzRT7DSVgvJBHZ7j4ZdbOCkQua0WMQZmQQY/s1600/uno.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4XoDmFWhhRf9j1ye18lHyBZFUzxq0F8V-dCgQD7vwafXi7Q7PQ9lrbpX2h9ulEQEei4WsBtcJ4QtkNSZKgGl8BfxMrwGEvRFQ3LxJ6WIt5vzRT7DSVgvJBHZ7j4ZdbOCkQua0WMQZmQQY/s200/uno.jpg" height="133" width="200" /></a><br />
La <b>Raspberry Pi</b> es un mini-ordenadorcillo poco potente y barato, que viene con lo mínimo minimísimo para poder llamarlo ordenador. No trae ni un solo periférico, es decir, no lleva pantalla (tiene una conexión HDMI y otra de vídeo compuesto RCA), ni teclado, ratón, etc. (tiene dos conectores USB), ni discos duros (tiene una ranura para tarjetas SD, donde se puede instalar el sistema operativo), ni siquiera fuente de alimentación (se alimenta por micro-USB). Por no tener no tiene ni caja. O sea, lo que podéis ver en la foto.<br />
<br />
Se ha puesto un poco de moda en el mundillo <i>geek</i> por eso de que es un juguetito "teóricamente" barato, aunque eso ha llevado a que mucha gente no sepa qué hacer con ella pasadas las semanas. Lo cierto es que, precio aparte, le veo al cacharrillo algunas ventajas importantes para ciertos usos, que son los que voy a explorar en este artículo.<br />
<br />
Cuidadín, aviso que la instalación de la Raspberry y sus aplicaciones no es para todo el mundo. Conviene tener un mínimo de conocimientos de Linux para ponerla en marcha, sobre todo por la parte de instalación de aplicaciones como servidor. Casi todas las instrucciones van por consola y es fácil que en algunos momentos tengamos que salirnos de lo que te cuentan e instalar algún paquete adicional para que todo funcione, y aparte de eso tendremos que ir pegándonos con el router para abrir puertos, asignar direcciones IP estáticas, etc. Si no te ves capaz, siempre puedes simplemente instalar XBMC y ya está, que eso sí es fácil y sale prácticamente solo.<br />
<br />
<h2>
La lista de la compra</h2>
<div>
El truco de la Raspberry es que es barata... porque está pelada. La mayor parte de cosas que puedes necesitar es fácil que las tengas ya por casa, pero siempre hay algo que no. Según lo que tengas o dejes de tener, tu lista de la compra real se puede parecer a la siguiente (ojo, los precios que pongo, redondeados, son los que he conseguido yo; no son los más baratos ni de coña, he buscado siempre la comodidad y conseguir lo que fuera sin tener que esperar):</div>
<div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlOe3Z9K0TcBpEKAQzmJpLMkDyUv8B-L5gZ8TbB2ExNW_nf3_Yo1udT1yGB-iOTDrFFeYAHoPKF9up5aC26O5xQtJDReRMNYKNaC7x4TYyjaV4swIzv3a0TwA5PkZyhyPqAzoCRM4IlbWj/s1600/uno.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlOe3Z9K0TcBpEKAQzmJpLMkDyUv8B-L5gZ8TbB2ExNW_nf3_Yo1udT1yGB-iOTDrFFeYAHoPKF9up5aC26O5xQtJDReRMNYKNaC7x4TYyjaV4swIzv3a0TwA5PkZyhyPqAzoCRM4IlbWj/s320/uno.jpg" height="238" width="320" /></a></div>
<ul>
<li><b>La Raspberry Pi</b> modelo B con 512 MB de RAM. Tanto ella como varios de los complementos los compré directamente en una tienda física de Madrid, ya que me pillaba muy cerca y no tardaba nada en comprarla: <a href="http://www.electronicaembajadores.com/Productos/Detalle/-1/LCRBPI5/modulo-raspberry-pi-modelo-b---512-ram">Electrónica Embajadores</a>. Por Internet y comprando en el extranjero se pueden conseguir precios mejores, aunque sin pasarse. 44 euros.</li>
<li><b>Una caja</b> donde meterla, para que no se quede con la melena al aire, que da penica. Hay cientos de tipos y diseños de cajas distintos, algunos con bastante gracia, de hecho ni siquiera tienes por qué comprártela, te puedes <a href="http://geekdad.hotwired.com/photo/lego-raspberry-pi-case">hacer una con Lego</a>. Yo no me compliqué la vida y me compré una <a href="http://www.electronicaembajadores.com/Productos/Detalle/-1/LCRBBX1/caja-transparente-para-raspberry-pi">caja transparente</a>, que también tiene su aquel. 11 euros.</li>
<li><b>Un cargador de corriente USB</b> y un cable de USB a micro-USB. Esta será la alimentación de la Raspberry. Puede valer el cargador de un móvil, aunque... ¿entonces cómo cargamos el móvil?. Si tenéis alguno de sobra, os valdrá. Lo más importante es mirar los amperios del alimentador. Como poco deberían ser 700 mA. Puede valer con menos, pero hay que tener en cuenta que lo que conectemos a los USB del cacharro también chupa potencia. Para poder poner dispositivos a troche y moche sin miedo, recomiendo que tenga más potencia aún. Yo me compré uno de 2100 mA, pa que no nos falte de ná (en la misma tienda). 13 euros.</li>
<li><b>Una tarjeta SD de clase 10</b>. El tamaño no es tan importante, 8 GB por ejemplo está bien, pero la velocidad de la tarjeta sí tiene importancia. Tened en cuenta que en ella va a estar el sistema operativo, así que para algunas aplicaciones nos convendrá que vaya rapidito. Si tenemos una sobrante de clase 4 ó 6 podemos probar también con ellas, que puede que nos valga. Yo compré una <a href="http://www.fnac.es/Sandisk-MicroSd-8GB-Ultra-Tarjeta-de-Memoria-Tarjeta-de-memoria-Tarjeta-de-Memoria/a807761">microSD clase 10 de 8 GB</a> (recomendable que sea microSD porque nos valdrá para otros cacharrillos) por 12 euros.</li>
<li>Puede que te hagan falta otros cables si por lo que sea no los tienes, básicamente necesitarás un cable <b>Ethernet</b> y otro <b>HDMI</b> (también puede valer un cable de vídeo compuesto)... bueno, ¡y una tele, claro!</li>
<li><b>Un disco duro externo USB</b>. Para no cagarla al final, lo suyo es que no tenga ventilador ni soniquetes "raca-raca". Si tienes ya uno, fenomenal, en mi caso me compré <a href="http://www.fnac.es/Toshiba-STOR-E-PLUS-1-TB-Almacenamiento-Disco-duro-externo/a873062">uno de 1TB de esos pequeñines</a> sin alimentación ni ventilador. Ojo, si no tiene alimentación propia seguramente tengas que conectarlo a un hub USB enchufado a la corriente (yo lo he hecho). A mi me el disco me costó 70 euros.</li>
</ul>
</div>
<div>
Como veis, al final este "ordenador de 30 dólares" puede llegar a convertirse en unos 150 euros, aunque depende mucho de lo que tengamos disponible por ahí. También es verdad que todos estos componentes los podemos acabar reutilizando en otras cosas, especialmente el componente más caro, el disco duro externo.</div>
<div>
<br /></div>
<div>
Otras cosas que podríamos comprar... o no:</div>
<div>
<ul>
<li>Adaptador Wifi USB. Entre que nuestro cacharro vamos a ponerlo a descargar como loco y que queremos que consuma lo mínimo posible, lo suyo es conectarlo al router directamente mediante un cable de red. Pero puede que eso físicamente no sea posible, en cuyo caso nos haría falta uno de estos.</li>
<li>Teclado y ratón: en general, lo cierto es que no hacen demasiada falta. En cuanto puedas acceder a un terminal en remoto, podrás manejar todo desde un ordenador, digamos, "normal". Si no tienes ordenador normal, siempre puedes ponerle unos inalámbricos. Ojo, si conectas más de dos dispositivos necesitarás también un hub USB. Si es para hacer cosillas de forma ocasional, siempre podemos comprar un <a href="http://www.mundopda.com/comprar/196-teclados-mediacenter/37392-riitek-mini-rt-mwk10-teclado-tactil-wireless-24ghz-con-puntero-laser-espanol">mini-tecladito-touchpad</a> </li>
<li>Mando remoto para manejar las "pelis". Otro que no hace demasiada falta, como veremos más adelante. Hay otras opciones muy buenas. En cualquier caso, si hace falta, existen</li>
</ul>
<div>
<br />
<h2>
XBMC: espectacular centro multimedia</h2>
<div>
<b>Instalar XBMC en la Raspberry</b> es realmente fácil. Existen varias distribuciones que lo llevan ya de serie, pero yo recomiendo <a href="http://www.raspbmc.com/download/">seguir estas instrucciones para instalar <b>Raspbmc</b></a>. Para poder usarlo luego de servidor, es importante ponerle una <b>IP fija</b>. Esto se puede hacer desde el propio instalador, si se instala desde Windows.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6zZqD0GbhCNwuHbf_ZZaGOePSHkiIJvqhvLw1JvBnJFCaHSxVdJy_3sKgppmvUCqZuda1oxHvlr2naE7TsRbJJj_z3O4G4Ro1aXGeo3UQZeN9NTEJwbwNpUpT-_9Wcoe-Ck7xbY8W20r_/s1600/uno.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6zZqD0GbhCNwuHbf_ZZaGOePSHkiIJvqhvLw1JvBnJFCaHSxVdJy_3sKgppmvUCqZuda1oxHvlr2naE7TsRbJJj_z3O4G4Ro1aXGeo3UQZeN9NTEJwbwNpUpT-_9Wcoe-Ck7xbY8W20r_/s320/uno.jpg" height="166" width="320" /></a></div>
Ahora conecta la Raspberry, con la tele encendida. ¿Por qué con la tele encendida?. Porque si tienes una tele compatible con <a href="http://en.wikipedia.org/wiki/HDMI#CEC">CEC</a> (y la mayor parte de las teles actuales lo son), <b>vas a poder controlar XBMC con el mando de la tele</b>, sin tener que poner ningún receptor de infrarrojos en la Rasp (la señal se transmite de la tele al cacharro por el cable HDMI). Por lo menos en mi caso, para que esto funcione la tele tiene que estar encendida cuando conectas la Raspberry (simplemente encendida, da igual en qué canal esté).<br />
<br />
Si no te funciona, o si reiniciaste la Raspberry con la tele apagada, tienes otra opción sencilla: <b>usar el móvil como mando</b>. En Android tienes aplicaciones como <a href="https://play.google.com/store/apps/details?id=org.xbmc.android.remote">la oficial de XBMC</a> ó <a href="https://play.google.com/store/apps/details?id=org.leetzone.android.yatsewidgetfree">Yatse</a> que cumplen este papel a la perfección, además de permitirte otras cosas como por ejemplo explorar tu catálogo de películas, series y música. Pruébalas conectando por wifi. Y si no... siempre puedes conectarle un teclado o un ratón a la Raspberry. Otra ventaja de tener estas aplicaciones en el móvil es que te permiten consultar tu catálogo, así que si quieres por ejemplo puedes elegir qué película vas a ver mientras vas a casa en el metro.<br />
<br />
<b>XBMC es una gozada</b>. Le dices el directorio donde tienes las películas y las series, y él solito se pone a pensar un rato y te hace un catálogo completo con todas ellas: portadas, ficha técnica, argumento, información sobre el tipo de fichero... en fin, lo mejor es mirar las capturas de pantalla. ¡Todo eso sale solo!. Y por muy baratera que sea la Raspberry, reproduce <b>vídeos HD de 1080p sin ningún problema</b>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVi7-0F5Ggb0E4Kcm1O8bd0xJdva3jSyEWuVvKk2UwaMPKQweQOnkk5uSVrlvHi-KcqtODUn3BjZO7Ky1Tt2xjLgX3xh32cFMTlhID5GY_SUfhzmozl1BasfsoGg9Rjhpx_YGCVLin965u/s1600/uno.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVi7-0F5Ggb0E4Kcm1O8bd0xJdva3jSyEWuVvKk2UwaMPKQweQOnkk5uSVrlvHi-KcqtODUn3BjZO7Ky1Tt2xjLgX3xh32cFMTlhID5GY_SUfhzmozl1BasfsoGg9Rjhpx_YGCVLin965u/s640/uno.png" height="360" width="640" /></a></div>
<br />
XBMC tiene muchas más posibilidades. Por ejemplo, tiene un administrador de ficheros que nos puede venir muy bien para colocar ficheros recién descargados, tiene distintos skins... y sobre todo, también <a href="http://pluginsxbmc.blogspot.com.es/">existen add-ons</a> para acceder a múltiples <b>servicios online</b>.<br />
<br /></div>
</div>
</div>
<h2>
Mini servidor "full time"</h2>
Ya tenemos nuestro centro multimedia "estándar". Pero... ¿por qué conformarse con eso?. La Raspberry puede ser también un <b>gran servidor</b>, porque:<br />
<ul>
<li>Tiene un <b>consumo energético</b> ridículamente bajo.</li>
<li>Es silenciosa. No tiene ventilador, ni disco duro haciendo raca-raca... no que haga poco ruido... <b>absolutamente</b> <b>silenciosa</b></li>
</ul>
<div>
Y... ¡es completamente compatible tener el servidor con tener el XBMC!. No sólo compatible, sino que se complementan a la perfección.<br />
<br />
Como desventaja, tiene poca potencia, así que olvidaros de instalarle un servidor de base de datos, una web Java potente o simplemente cualquier servidor con un gran número de accesos concurrentes. Aunque, bueno, tampoco digo yo que no pueda servir para todo esto, sencillamente no parece la solución ideal para esos casos.</div>
<div>
<br /></div>
<div>
¿Entonces qué tipo de servidores le podemos instalar?. Básicamente, podemos usarlo como:</div>
<div>
<ul>
<li><b>Centro de descargas</b>: torrents, descargas directas, eMule...</li>
<li><b>Servidor web</b> HTTP + PHP</li>
<li><b>Servidor de almacenamiento en la nube</b>, al estilo de Dropbox, Drive, Box, etc.</li>
</ul>
<div>
<br /></div>
<div>
<h2>
Preparando el terreno</h2>
Por lo pronto, de serie ya trae instalado un <b>servidor SSH</b>. Gracias a él, podemos conectarnos con cualquier otro ordenador e instalar lo que queramos (Raspbmc es una distribución basada en <a href="http://www.debian.org/">Debian</a>). No sólo eso, también podemos acceder al sistema de ficheros cómodamente con cualquier cliente FTP (como por ejemplo <a href="https://filezilla-project.org/">Filezilla</a>) a través de <b>SFTP</b>.</div>
<div>
<br /></div>
<div>
Al acceder por primera vez por SSH, se configuran algunos elementos más: es conveniente poner el locale es-ES_UTF8 (salvo que seas iberoamericano, en cuyo caso sería el dialecto correspondiente, pero es importante que sea UTF8). También es conveniente cambiar la password, ya que para aprovechar todo esto a tope lo suyo es que el acceso SSH (así como el resto de servicios que estemos instalando) sean accesibles desde fuera de la red local. Por tanto, ya tenemos listo nuestro acceso por consola para instalar lo que queramos.<br />
<br />
Algo importante es el <b>montaje de nuestro disco externo</b>. Por defecto, Raspbmc automonta el disco con el usuario pi y con permisos de escritura sólo para él (ni siquiera para el grupo). Como los servidores que le instalemos tendrán en general sus propios usuarios, lo mejor es que montemos el disco con <b>permisos de lectura y escritura para el grupo</b>. Para mejorar el control, podemos crear un grupo propio "ntfs":<br />
<br />
sudo groupadd ntfs<br />
sudo usermod -a -G ntfs pi<br />
sudo usermod -a -G ntfs root<br />
<div>
<br /></div>
<div>
Como no se pueden cambiar los permisos por defecto para el automontaje, tenemos que cambiar a mano la configuración del montaje de nuestro disco en concreto en el fichero <b>/etc/fstab</b>. Primero obtenemos el <b>UUID</b> de nuestro disco:</div>
<div>
<br /></div>
<div>
<div>
sudo blkid /dev/sda1</div>
<div>
(probablemente sea /dev/sda1 pero para asegurarnos podemos ejecutar antes sudo fdisk -l | grep NTFS)</div>
</div>
<div>
<br /></div>
<div>
Raspbmc trae un editor "cómodo" para editar ficheros, <b>nano</b>, que podemos usar para modificar cualquier fichero de configuración (si eres un fanático del vi lo tienes también, claro).</div>
<div>
<br /></div>
<div>
<div>
sudo nano /etc/fstab</div>
</div>
<div>
<br /></div>
<div>
Añadimos una línea con el UUID del disco (aquí pondré XXXXX, reemplazar por el que tengáis) y el punto de montaje, que normalmente será un subdirectorio de media (aquí voy a poner <b>externaldisk</b>, pero puede ser lo que queráis):</div>
<div>
<br /></div>
<div>
UUID="<i>XXXXXXXXX</i>" /media/<i>externaldisk</i> ntfs-3g auto,gid=ntfs,umask=0002,uid=pi 0 0</div>
<div>
<br /></div>
<div>
Para asegurarnos, creamos el subdirectorio en media:</div>
<div>
<br /></div>
<div>
<div>
sudo mkdir externaldisk</div>
<div>
sudo chown pi:ntfs externaldisk</div>
<div>
sudo chmod 775 externaldisk</div>
</div>
<div>
<br /></div>
<div>
A partir de aquí, por cada servidor que instaléis que queráis que tenga acceso de escritura al disco, <b>deberéis añadir el usuario con el que se ejecute el proceso</b> (que se puede ver ejecutando sudo ps -ef | grep <parte de nombre de proceso>) al <b>grupo "ntfs"</b>:</div>
<div>
<br /></div>
<div>
sudo usermod -a -G ntfs <i><usuario></i></div>
<div>
<br /></div>
<div>
Normalmente después de hacer esto habrá que reiniciar (sudo reboot).</div>
<div>
<br />
[EDITADO] Las instrucciones anteriores suponen que el disco lo tenemos formateado en NTFS, que fue lo que hice yo para poder llevarlo con más facilidad a otras máquinas o centros multimedia ajenos. Sin embargo, si tenéis una conexión a Internet rápida es muy recomendable para el rendimiento formatearlo en ext4 (gracias a Antonio Muños por la información).<br />
<br /></div>
<div>
Una última recomendación: en general vamos a instalar servidores que te proporcionan un acceso web. El propio XBMC también tiene uno. Para no liar mucho el tema, recomiendo modificar el usuario por defecto y poner en todos los servidores el mismo usuario y password. Ojo, que sea uno propio, no uséis uno estándar, porque cualquiera podría acceder a ellos y liaros una buena. Aparte de eso, para que cualquiera de estos servidores sea accesible por Internet, habrá que abrir los puertos en el router.</div>
<div>
<br /></div>
<div>
<h2>
Instalando servidores</h2>
</div>
</div>
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhHlS7s_1rblTxPUwCLF6nyPpRg-Eybti1i4uQz4qCe0_bQSkgk2jKExFMR_ksfX_6GnyHSTUXXa-_wTctLOiEgN8ehlmkY3vYzblp7aaEHPTF8ouOflIt3X3QGHG4s3OKOJuBx4_AZxD-/s1600/uno.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhHlS7s_1rblTxPUwCLF6nyPpRg-Eybti1i4uQz4qCe0_bQSkgk2jKExFMR_ksfX_6GnyHSTUXXa-_wTctLOiEgN8ehlmkY3vYzblp7aaEHPTF8ouOflIt3X3QGHG4s3OKOJuBx4_AZxD-/s640/uno.png" height="544" width="640" /></a></div>
<br />
Para empezar a darle caña, podemos poner un <b>cliente bittorrent</b> con estas <a href="http://www.electroensaimada.com/torrent.html">instrucciones para instalar Transmission</a>, y poder descargar lo que queráis al disco duro externo. Como podéis ver, Transmission incluye un interfaz web, así que si abrimos el puerto (por defecto 9091) podremos gestionar nuestras descargas desde cualquier sitio. Ojo con la password en ese caso, claro.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiqjXEyi55UAxVnAN6KN7VxqAWjqR09PbgrO8baicsOvve1IK-PsAy_whWRg_TDzteY50GzOiA9Gff3QJE3M5ZdhKEyyK-ZA9fHAXiG3WgggXRgrgYMgFtTjFybhZv9Ljb1RkV3xZluhBWW/s1600/uno.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiqjXEyi55UAxVnAN6KN7VxqAWjqR09PbgrO8baicsOvve1IK-PsAy_whWRg_TDzteY50GzOiA9Gff3QJE3M5ZdhKEyyK-ZA9fHAXiG3WgggXRgrgYMgFtTjFybhZv9Ljb1RkV3xZluhBWW/s200/uno.jpg" height="200" width="125" /></a>Añadimos el usuario debian-transmission al grupo ntfs, cambiamos la configuración para que se descarguen las cosas al disco externo, y todo debería ir como la seda. Como los torrents tienen muchísimo peligro de colapsar la conexión, es importante limitar también la velocidad de subida. En <a href="http://infinite-source.de/az/az-calc.html">esta dirección podéis calcular qué límite de velocidad es adecuado para vuestra conexión</a>.<br />
<br />
Para que cualquier sitio sea <b>cualquier sitio</b>, también podéis controlar vuestras descargas con una aplicación móvil. Para Android por ejemplo tenéis <a href="https://play.google.com/store/apps/details?id=com.neogb.rtac&hl=es">Remote Transmission</a>. Y... también podéis acceder desde el propio XBMC, con lo cual si estáis pegados a la tele no necesitáis despegaros del mando. Basta conque instaléis desde el mismo XBMC <a href="http://wiki.xbmc.org/index.php?title=Add-on:Transmission">el correspondiente add-on</a>.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoX_zeTdqto1-c_nInkKyFtaj38LF4yvFGq62w5BFhrEVdR-ipSadqoTAyqr15XtSYFiKLfIOlEdXfc8spBDUoy4hn8garcUWtF4SuttCXRz1lkdiP8X9OG3Om4c674raR9tdB-3pMsjQH/s1600/uno.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoX_zeTdqto1-c_nInkKyFtaj38LF4yvFGq62w5BFhrEVdR-ipSadqoTAyqr15XtSYFiKLfIOlEdXfc8spBDUoy4hn8garcUWtF4SuttCXRz1lkdiP8X9OG3Om4c674raR9tdB-3pMsjQH/s320/uno.png" height="176" width="320" /></a>Pero no sólo de torrents vive el hombre... también tenemos las <b>descargas directas de la web o a través de servidores de descargas</b>. ¿JDownloader? No... mejor instalar <b>pyLoad</b>, un programa que es mucho más ligero, tiene interfaz web y funciona muy bien en nuestra Raspberry. Podéis seguir <a href="http://www.megaleecher.net/Free_download_manager_for_Raspberry_Pi">estas instrucciones</a>, aunque ojo, yo he tenido que instalar muchos más paquetes que faltaban, así que el punto 1 de la instalación a mi me quedó así:<br />
<br />
sudo wget -O pyload-cli.deb http://get.pyload.org/get/ubuntu-cli<br />
<div>
sudo apt-get install python python-pycurl python-crypto unrar-free tesseract-ocr tesseract-ocr-eng python-imaging spidermonkey-bin libgif4 libwebp2 libgmp10 liblcms1 python-support libnspr4 libtesseract3 tesseract-ocr-osd tesseract-ocr-equ</div>
<div>
sudo dpkg -i pyload-cli.deb</div>
<div>
<br />
Una vez hecho esto, todo debería funcionar correctamente. Sin embargo, veremos que al reiniciar dejará de funcionar. Añadimos el usuario al grupo ntfs y todo debería funcionar correctamente.<br />
<br /></div>
<div>
Por si te lo estabas preguntando, sí, <b>pyLoad</b> también tiene una <a href="https://play.google.com/store/apps/details?id=org.pyload.android.client&hl=es">aplicación Android</a> para gestionar tus descargas con el móvil.<br />
<br />
EDITADO: Antonio Muñoz añade también que es importante para el rendimiento de pyLoad configurar su servidor threaded en lugar de builtin.<br />
<br />
Aprovechando que tenemos un cacharrillo propio constantemente encendido, también podemos aprovechar para instalarle un <b>servidor HTTP</b>. Seguro que en algún momento le podemos dar uso. Por ejemplo, puedes <a href="http://muyraspi.blogspot.com.es/2013/03/lighttpd-con-php.html">instalar el servidor ligero lighttpd, con soporte de PHP</a>. Ponle también <a href="http://stinebaugh.info/how-to-setup-lighttpd-with-a-self-signed-ssl-cert-on-debian-with-multiple-hosts-using-name-based-virtual-hosting/">soporte para SSL</a>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggutkTIclZyMmLm5k4xRMU3pg0VBWXmj50NCev0GOJFjQtMy5JlCdfj3EAE1mSMvLBEMe49v4jUw3BU_ZZBQ27ZLHZOoiM4Z1ZCg6Y3laeYtNZlGzXM5vNiA8jrLo5TtszsRBjExZnBUsa/s1600/uno.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggutkTIclZyMmLm5k4xRMU3pg0VBWXmj50NCev0GOJFjQtMy5JlCdfj3EAE1mSMvLBEMe49v4jUw3BU_ZZBQ27ZLHZOoiM4Z1ZCg6Y3laeYtNZlGzXM5vNiA8jrLo5TtszsRBjExZnBUsa/s200/uno.png" height="116" width="200" /></a></div>
Aunque tenemos un servicio sFTP, nos va a venir bien tener también acceso al <b>sistema de ficheros con un interfaz web</b>. Así que podemos <a href="http://ajaxplorer.info/download/"><b>instalar Ajaxplorer</b></a> simplemente descomprimiéndolo en el directorio /var/www y dando permisos de escritura en el subdirectorio data.<br />
<br />
sudo apt-get install unzip<br />
wget -O ajaxplorer.zip http://sourceforge.net/projects/ajaxplorer/files/latest/download?source=files<br />
sudo unzip ajaxplorer.zip -d /var/www<br />
sudo mv /var/www/ajaxplorer* /var/www/ajaxplorer<br />
rm ajaxplorer.zip<br />
sudo apt-get install php5-cli php5-gd php5-mcrypt<br />
sudo chmod 776 /var/www/ajaxplorer/data<br />
<br />
(al arrancarlo aparecerán avisos varios, cada uno tiene más o menos instrucciones de cómo resolverlo; en cualquier caso, debería funcionar ya)<br />
<br />
<b>Ajaxplorer</b> tiene varias cosas que están bastante bien. Permite <b>streaming</b>, como poco de ficheros MP3 (no sé si también será capaz de hacer streaming de vídeo). También tiene herramientas para sincronizar automáticamente un directorio local con un directorio del servidor, al estilo de Dropbox, como <a href="http://sourceforge.net/projects/ajaxplorer/files/ajaxplorer-sync/dev/?">esta</a> y <a href="https://github.com/ajaxplorer/ajaxplorer-sync">esta</a>. Y también permite crear usuarios y roles, por lo que podemos crear carpetas públicas, o invitar a gente a subir ficheros a una carpeta. Y si no te acaba de convencer, siempre puedes probar <b><a href="http://www.electroensaimada.com/owncloud.html">Owncloud</a></b> (no tengo muy claro cuál de las dos es mejor o más ligera, la verdad).<br />
<br />
¿Más cosas?. Todas las que quieras. Puedes <a href="http://www.aseodiario.com/raspberry-pi-mldonkey-server-samba-webmin/">instalar un cliente para descargas de la red de eMule, poner un sistema de administración por web, un servidor Samba</a>, <a href="http://www.vicente-navarro.com/blog/2008/01/13/backups-con-rsync/">configurar rsync para hacer backups</a>, <a href="http://pi.gadgetoid.com/post/001-who-watches-the-watcher">poner un proceso que reinicie la máquina cuando estén caída</a>, o incluso probar a instalar un <a href="http://tjws.sourceforge.net/">servidor J2EE ligero como TJWS</a>... en fin, todo lo que vayas necesitando. ¡Por este artículo creo que es más que suficiente!<br />
<br />
<h2>
Configuración final XBMC</h2>
<div>
Ahora vamos a cambiar algunas cosillas de la configuración de XBMC para evitar problemas. Si tenemos la Raspberry conectada a la tele por HDMI, la configuración por defecto tiene un inconveniente para nuestro servidor: si al encender la Raspberry el televisor está apagado, no detectará el HDMI y <b>automáticamente mandará la señal de vídeo por el RCA</b>, con lo cual <b>no veremos nada</b>. Esto se puede deshabilitar <a href="http://choorucode.com/2012/10/13/forcing-raspbmc-to-turn-on-hdmi-at-boot/">siguiendo estas instrucciones</a>. Aun así, al menos en mi caso es conveniente conectar o resetear la Raspberry con la tele encendida, porque como comenté antes, parece que si no el mando no funciona. Aunque por lo menos nos aseguramos de que podemos ver lo que estamos haciendo y usar el móvil como mando.<br />
<br />
Además, <b>XBMC trae instalado un firewall</b>. Para que podamos usar nuestra maquinilla por Internet, lo podemos <b>deshabilitar</b>. Esto se puede hacer directamente desde la pantalla de configuración de Raspbmc, en Programas > Raspbmc settings > System configuration. Esto me ha estado funcionando durante un tiempo, pero en la última actualización creo que han introducido un bug que hace que no funcione. Si estás en el mismo caso, edita el fichero /etc/network/if-up.d/secure-rmc y al final pon:<br />
<br />
sudo /sbin/iptables --flush</div>
<div>
<br /></div>
<h2>
¡Listo!</h2>
¿Ya lo tienes todo funcionando?. Pues ahora... revisa la agenda, llama a todos tus amigos frikis, y... ¡¡¡<b>presume de Smart TV</b>!!!<br />
<br /></div>
Andréshttp://www.blogger.com/profile/06010147149377176406noreply@blogger.com60tag:blogger.com,1999:blog-6416070227303513915.post-38159091552811715562013-05-24T10:49:00.000+02:002013-05-24T15:00:22.963+02:00Haciendo un juego en Android: lecciones aprendidas (2)Después del <b><a href="http://apagayvuelveaencender.blogspot.com.es/2013/04/haciendo-un-juego-en-android-lecciones.html">primer capítulo</a></b> que publiqué hace unas semanas, ya tenemos lo básico para hacer un juego en Android "a pelo". ¡Pero no nos conformamos con eso! Hoy contaré otras cosillas más que fui añadiendo a mi librería personal para el juego según iba avanzando.<br />
<br />
<h2>
Componentes gráficos</h2>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvxX3TGLmT-AuQ3t3_yUkWzTyDlBLdvbA2gAScjIbAvr-bb8x1LA9fp5gZFYVQbcEdlB3o52gqEIyFKA0vZEwZ0_5mh9r_wxm3ZMNto0U0gDAtKllM1DkR-EgDDp8CubOZ98LoWIgnAytO/s1600/uno.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="179" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvxX3TGLmT-AuQ3t3_yUkWzTyDlBLdvbA2gAScjIbAvr-bb8x1LA9fp5gZFYVQbcEdlB3o52gqEIyFKA0vZEwZ0_5mh9r_wxm3ZMNto0U0gDAtKllM1DkR-EgDDp8CubOZ98LoWIgnAytO/s320/uno.jpg" width="320" /></a>Para los que hemos trabajado con interfaces de ventanas, el <b>diseño basado en componentes gráficos</b> resulta muy natural. ¿Por qué no aplicarlo también a un juego?.<br />
<br />
La idea es muy sencilla: hacer que el código de cada componente no tenga que preocuparse de coordenadas globales, ni de lo que ocurre en el resto del juego, sino que vive "en su propio mundo" y preocupado de sus cosas. Orientación a objetos pura, vaya. Así, la pantalla se va formando a base de componentes, unos dentro de otros, que acaban conformando todo lo que hay en el juego. Cada uno tiene su propia dinámica, y luego pueden reaccionar ante lo que hagan los otros.<br />
<br />
Todas estas librerías tradicionales de componentes de ventanas, como las MVC del Visual C++, o la del Borland C++, o incluso las del más moderno SWT suelen tener un problema gordo en su diseño: <b>abusan mucho de las subclases</b>. Se puso de moda diseñar esto así, y como documentación de la librería aparecía, tachán!, ¡la jerarquía de clases!. O sea, todo el diseño estaba hecho en forma de jerarquía de subclasificación.<br />
<br />
El caso es que a mi las subclases en general me dan un poco de urticaria. Los interfaces son mucho más limpios. Las subclases me gustan para reutilizar implementaciones por defecto o sencillas de los interfaces, pero poco más. Así que en lugar de hacer una jerarquía de clases como las de toda la vida (curiosamente Swing, con todo lo que se le ha criticado, está mucho mejor diseñada que todas las demás), me dediqué a darle unas vueltas más (y liar un poquito el tema, ya puestos).<br />
<br />
¿Qué necesita cada uno de estos componentes?. Según vimos en la entrada anterior, lo mínimo que necesita cualquier entidad independiente del juego es:<br />
<ul>
<li>Que sea capaz de reaccionar a eventos</li>
<li>Que sea capaz de actualizarse sola por cada unidad de tiempo</li>
<li>Que sea capaz de dibujarse</li>
</ul>
<div>
Además de esto, nuestros componentes gráficos necesitarán:</div>
<ul>
<li>Una posición relativa a su componente padre</li>
<li>Un tamaño</li>
</ul>
Y por supuesto, necesitaremos entidades contenedoras, a las que podamos meter otras entidades dentro de forma relativa.<br />
<br />
Así que hice un interfaz <i>GameEntity</i> para lo básico que tienen que tener todas las entidades de cualquier juego (los tres primeros puntos), y reservé dos interfaces para los otros dos: un <i>Positionable</i> y un <i>Measurable</i>. ¿Por qué usar interfaces para estos dos en lugar de beans?. Porque me puede dar más juego. Por supuesto, creo implementaciones beans que implementen esos interfaces, y un <i>DelegateComponent</i> que cree un componente a partir de una composición de objetos que implementen cada interfaz (y que no tienen por qué ser objetos distintos).<br />
<br />
Una vez que te acostumbras a esta forma de trabajar, resulta comodísima, y sobre todo, muy potente. Este es el diseño resultante:<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKQ0qLLK_I6wywRm2nX_BKxTOTzdGz6EM_EcGzOYKQM_fD34Q_0Tv3MyMLVuH0FmKLWXHPu2l5yTBiusDkpwqxBqk8Vf2ZLv_w1N9WrGw5ocke8ABomW5BraNfnOj4cXfYhhZqYNNfSyg3/s1600/graph.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="434" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKQ0qLLK_I6wywRm2nX_BKxTOTzdGz6EM_EcGzOYKQM_fD34Q_0Tv3MyMLVuH0FmKLWXHPu2l5yTBiusDkpwqxBqk8Vf2ZLv_w1N9WrGw5ocke8ABomW5BraNfnOj4cXfYhhZqYNNfSyg3/s640/graph.png" width="640" /></a></div>
<br />
<br />
<h2>
Animaciones, efectos y el estado</h2>
Cada objeto normalmente tendrá su <b>estado</b> e irá cambiando según las cosas que le ocurran. Eso ya dependerá de cada entidad. Sin embargo, hay algo que también es muy interesante facilitar, que son las <b>animaciones y efectos</b>. Aunque pueda confundirse, lo cierto es que estos se gestionan mucho mejor si <b>se separan</b> un poco del propio estado del objeto.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTtVGmZA8yBk4MZu5Uet_rVPAEe5YFEew_EqNgmUBoHQ4BvGWI4reoGzQOvPUzYQE2qUpVJ51TBOXrw_vfMhP3QHvMVpnkapmJEySnFMhtwgOF_o6jJZQVIFj-iJazRjM9fifksCXN0Tu9/s1600/uno.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="168" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTtVGmZA8yBk4MZu5Uet_rVPAEe5YFEew_EqNgmUBoHQ4BvGWI4reoGzQOvPUzYQE2qUpVJ51TBOXrw_vfMhP3QHvMVpnkapmJEySnFMhtwgOF_o6jJZQVIFj-iJazRjM9fifksCXN0Tu9/s200/uno.jpg" width="200" /></a></div>
Por ejemplo, un personaje puede estar caminando. Su estado es "caminando". Sin que el estado cambie demasiado, se estará moviendo hacia la derecha. Y habrá una animación de caminar que irá cambiando sola cada X frames. Podríamos gestionar todo esto de forma explícita dentro de cada objeto, pero si lo facilitamos para que se declare desde el principio como funciona, nos evitaremos el tener que gestionar cosas incómodas como cuál es el frame actual que se debe mostrar.<br />
<br />
Para eso, creé una clase <i>AnimatedComponent</i>, que decora cualquier otro componente. A este componente se le registrarán una serie de estados de transiciones o animaciones posibles, representadas con el interfaz <i>Transition</i>. Al registrar cada transición se indica cómo funciona: qué propiedades modificará, cada cuánto tiempo y qué ocurrirá cuando acabe (¿será cíclica?, ¿se quedará en el estado en el que estaba?, ¿desaparecerá el objeto?). Estas transiciones son las que se ocupan de hacer efectos y transiciones sin que el objeto tenga por qué preocuparse mucho por ello.<br />
<br />
Como ejemplos de transiciones están las animaciones de gráficos, movimiento, efectos de "fade", cortinillas... A pesar del tinglado anterior del diseño de componentes por interfaces separados, lo cierto es que en la práctica casi todos los objetos <b>utilizarán un bean </b>para la posición. También bastantes para el tamaño, aunque no tantos, ya que muchas veces puede depender del tamaño de su bitmap o de su texto, por ejemplo. Por supuesto, también las animaciones es lógico que vayan con una propiedad explícita... en definitiva, una de las transiciones más sencillas que podemos hacer es que automáticamente se vaya <b>incrementando o decrementando el valor de una propiedad del componente</b>. De aquí surgió la clase <i>BeanPropertyTransition</i>. Para controlar de forma independiente a qué ritmo se va modificando el valor de la propiedad, se hace que utilice un interfaz <i>IntPropertyChange</i>, con una implementación sencilla que aumente el valor de la propiedad de forma lineal, es decir, de forma constante en el tiempo.<br />
<br />
Así quedó el diseño:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzDU4FESI-mrGAyUmILjZsqBRlQLLwXS4eM7jKyhKjJxmSOJ70A_pnrPlVlAw2fVw3YyAGFaSrSm9_tl7yVxpKV1ZuXIrEVj8k9-wQho_Y1qV7t8pfYJDYqC8F4vl29kiCiwr-rfhCzVv3/s1600/animations.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="472" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzDU4FESI-mrGAyUmILjZsqBRlQLLwXS4eM7jKyhKjJxmSOJ70A_pnrPlVlAw2fVw3YyAGFaSrSm9_tl7yVxpKV1ZuXIrEVj8k9-wQho_Y1qV7t8pfYJDYqC8F4vl29kiCiwr-rfhCzVv3/s640/animations.png" width="640" /></a></div>
<br />
<h2>
Agrupando objetos "globales"</h2>
En las primeras versiones del juego, los constructores de los distintos objetos cada vez eran más grandes. Había una serie de objetos, digamos, <b>prácticamente globales</b>, que se podían utilizar <b>casi en cualquier sitio</b>.<br />
<br />
Dos de ellos son clases que creé para encapsular, facilitar y/o mejorar el rendimiento de la <b>reproducción de sonido</b>: <i>SoundManager</i> para efectos de sonido, y <i>Jukebox</i> para música. A ellos se les suma el necesario <i>Context</i> de Android, con el que se cargan todos los recursos, y que face falta básicamente en... <b>todos los sitios</b> donde haga falta un recurso. Y otros que iban apareciendo y desapareciendo según se iba refinando el diseño, como por ejemplo una clase que facilita la carga de Bitmaps.<br />
<br />
La solución en este caso es muy clara, encapsular todos estos objetos, que además son genéricos y valen para cualquier juego, en una sola clase <i><b>GameContext</b></i>, que permita acceder a ellos. Así, <b>sólo será este objeto el que habrá que pasar a todos los demás</b> (junto a otros objetos del propio juego que potencialmente también harán falta). Además, si en algún momento aparece otro objeto del sistema que nos venga bien de forma global, se puede añadir también sin tener que tocar todas las demás clases para que se lo pasen de unas a otras.<br />
<br />
Esto parece una tontería, pero lo cierto es que si no se tiene un poco de cuidado, en un juego es muy fácil acabar con miles de objetitos que se van pasando a troche y moche de unos a otros, y eso <b>se convierte en un caos</b>. También hay que tener mucho cuidado de no mezclar churras con merinas, y no encapsular dentro del mismo objeto todo lo global que pueda necesitar el juego. Una cosa son estos objetos que pueden hacer falta en cualquier juego y son, digamos, del sistema y sus recursos, y otra muy distinta meter también por ejemplo los objetos que controlen la dinámica del juego concreto.<br />
<br />
En nuestro caso, este es el diseño que quedó:<br />
<div>
<br /></div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgur2G7WBBu6DjSGM9Qc2jRFbjS6IlOTp-P_IQXw7m3IOQdKFrpyg9-H2bKlTMGzSfhJM1D9cI4VY-DgniRv-CSnlfrstWN3D3SAm68cJuzb6q123_g1Nuj_gsEaaU8_rfVhpFouT1UVJe3/s1600/context.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="496" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgur2G7WBBu6DjSGM9Qc2jRFbjS6IlOTp-P_IQXw7m3IOQdKFrpyg9-H2bKlTMGzSfhJM1D9cI4VY-DgniRv-CSnlfrstWN3D3SAm68cJuzb6q123_g1Nuj_gsEaaU8_rfVhpFouT1UVJe3/s640/context.png" width="640" /></a></div>
<div>
<br /></div>
<h2>
Acabando, que es gerundio</h2>
<div>
¡Buah, menudo coñazo de serie que me he marcao! Todavía el primer capítulo tenía su aquel, pero en este me he metido más bien en detalles de diseño e imagino que ha quedado bastante espeso. Y no he puesto chistes ni chorradinas ni ná. Así que nadie estará leyendo esto ya, ¡snif!.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj75rrN7j2s-ZNaKBJolcFxIqALQ0gEcK8R78QNauVeJhkgVakp4u9UROT0s-MvWdNTh3lsF7uV18uov_WLQUn2RzqZ0-roljyQ7iDLdfvYpmbeX_kuuBMB1etvycS-FQ__KyvwacLgaZ7-/s1600/uno.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj75rrN7j2s-ZNaKBJolcFxIqALQ0gEcK8R78QNauVeJhkgVakp4u9UROT0s-MvWdNTh3lsF7uV18uov_WLQUn2RzqZ0-roljyQ7iDLdfvYpmbeX_kuuBMB1etvycS-FQ__KyvwacLgaZ7-/s200/uno.png" width="120" /></a></div>
El mensaje fundamental de todo esto es el primero que di: <b>si estáis dudando</b> en poneros o no a hacer un juego con Android, no lo dudeis: <b>hacedlo</b>. Es muy agradecido, con poco que hagáis van saliendo cosas. <b>La librería de Android es genial</b>, da muchas facilidades. Es más, yo hay cosas en las que me he complicado la vida porque he querido, porque lo cierto es que creo que algunas de las cosas que he hecho yo están ya en la propia librería estándar de Android. Y eso por no hablar del resto de librerías que existen para hacer juegos. Simplemente, <b>me apeteció hacerlo así</b>. Y ojo, mientras refinaba un poco la librería me dio tiempo a hacer otro juego, un <b>Reversi</b> (este ya no lo voy a publicar, porque Reversis hay montones y seguro que juegan mejor que el mío, que es un pobre patán...).<br />
<br />
El secreto de todo esto de hacer juegos para móviles, lo que lo hace genial, es que <b>es pequeño</b>. No necesitas dedicar meses y meses de tu vida para hacer un juego. En una tarde ya ves avances. <b>Cada tarde que te pongas haces algo, consigues algo nuevo</b>. Es muy gratificante. Estoy convencido de que los juegos pequeños tienen su espacio, que no todo tienen que ser grandes producciones. Dan más pie a la imaginación, a la innovación, a atreverse a hacer cosas que pensabas que no iban a salir... en definitiva, ¿a qué estás esperando?, <b>¡¡¡ponte ya a hacer tu juego, leche!!!</b>.<br />
<br />
<br />
<br />
<h2>
Bola extra</h2>
<div>
<b>Has intentado entender el artículo</b>. Realmente lo has intentado. Te lo has leído de principio a fin, has imprimido los diagramas en grande para seguir las flechitas, has buscado por ahí a ver qué leche es esa mierda de los componentes gráficos... y eso sólo te ha desorientado más aún. Finalmente, has llegado a una conclusión ineludible: <b>¡no hay dios que entienda este artículo!</b></div>
<div>
<br /></div>
<div>
Pues bien, aprovechando que <a href="http://www.somosasi.org/"><b>hoy es el "día Somos"</b></a>, que propone darle la vuelta al mundo, he apoyado la causa y he hecho una nueva versión del mismo en la que <b>le he dado la vuelta por completo</b>. Jamás la Informática había sido tan sencilla, jamás algo complejo se había visto de una forma tan clara. Jamás había sido tan fácil conseguir que cualquier no iniciado puede comprenderlo con facilidad.</div>
<div>
<br /></div>
<div>
<b>No te pierdas la <a href="http://rotateme.org/?u=http%3A%2F%2Fapagayvuelveaencender.blogspot.com.es%2F2013%2F05%2Fhaciendo-un-juego-en-android-lecciones.html&r=m">versión revisada del artículo</a></b>. De repente verás la luz y lo comprenderás en toda su extensión.</div>
<div>
<br /></div>
<div>
</div>
Andréshttp://www.blogger.com/profile/06010147149377176406noreply@blogger.com1tag:blogger.com,1999:blog-6416070227303513915.post-24377811275751390262013-04-15T15:47:00.000+02:002013-04-15T15:47:34.902+02:00Haciendo un juego en Android: lecciones aprendidas (1)Uno de los principales motivos por los que hace unos meses me puse con el desarrollo del <b><a href="http://apagayvuelveaencender.blogspot.com.es/2013/03/proyecto-west-bank-android.html">West Bank</a></b> es porque tenía ganas de empezar a aprender algo de <b>Android</b>. Android te permite algo que ya se había perdido un poco, y es que puedas hacer una aplicación más o menos pequeña, pero que a la vez esa aplicación sea publicable e incluso sea útil. Y en algunos casos, hasta te haga ganar dinero. Para los que no tenemos casi tiempo libre eso es genial, claro. En este artículo cuento un poco algunas de las cosas que me fui encontrando y lecciones aprendidas..<br />
<br />
<h2>
Hacer juegos con Android es muy fácil. Incluso sin librerías</h2>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJ4myxEk2tCkW4e4LBjrCfQlAkwNZapzagL9Tak0G7Z1srnq9jHsGXqTL-xx37pHuDtJNiErROOh5zizqeWMUDGlvs7yghhc3Kg8yiK5S2y8Us4EykJTKH3cMf-XAIAWlJOO4BmY5-otU0/s1600/uno.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJ4myxEk2tCkW4e4LBjrCfQlAkwNZapzagL9Tak0G7Z1srnq9jHsGXqTL-xx37pHuDtJNiErROOh5zizqeWMUDGlvs7yghhc3Kg8yiK5S2y8Us4EykJTKH3cMf-XAIAWlJOO4BmY5-otU0/s1600/uno.png" /></a></div>
Esta es seguramente la conclusión más importante que he sacado, algo que por otra parte ya me imaginaba. En mi caso, comencé primero buscando un poco alguna librería / framework / engine de desarrollo de juegos que me facilitara la vida. La idea es que fuera una librería sencillita y enfocada al 2D, nada de polígonos ni historias. La primera que vi fue <a href="https://code.google.com/p/rokon/"><b>Rokon</b></a>, que tenía buena pinta y encajaba en lo que buscaba, pero el autor recomendaba no usarla (imagino que acabó cansado de responder emails de gente haciéndole preguntas). Como el objetivo era complicarse la vida lo menos posible y hacer el juego rápido, la descarté.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMbIz1gFeJwRygItbm69kb5lsc9WHHxXrzQ4UCnxfsP1FA1h1MC7DJpmqhzhMZLUPFeyjkQXdeW27zfXatGrmCClZidLYXJShrKLcgYIz_FOXIEnfM_3KP7ap143b2w8SGLAUxSWs4NINj/s1600/uno.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="150" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMbIz1gFeJwRygItbm69kb5lsc9WHHxXrzQ4UCnxfsP1FA1h1MC7DJpmqhzhMZLUPFeyjkQXdeW27zfXatGrmCClZidLYXJShrKLcgYIz_FOXIEnfM_3KP7ap143b2w8SGLAUxSWs4NINj/s200/uno.png" width="200" /></a></div>
Entonces miré <a href="https://code.google.com/p/libgdx/"><b>libgdx</b></a>, que es una librería multiplataforma. Eso es una ventaja evidente, pero a la vez para este caso también es una desventaja, porque el objetivo con el que empecé era aprender algo de Android. Cuando me di cuenta de esto, y llevándome eso a descartar sin apenas mirarlas otras librerías con muy buena pinta como <a href="http://www.andengine.org/"><b>AndEngine</b></a>, pensé: "¿Y si lo hago directamente usando las librerías nativas de Android?".<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEga3g_lFr6dxs8XpjnY0ETVW8ylWUtCJl8UypR_53kWTHkJaQWet3P1sXP3hZO1Be-GMNCP9CJPsGR_r_I5DpBQaO6K6FXbixsxn9OF5Myt01dpVLOL19-wwSQN0geXIUwtp_OKwdsW5PBQ/s1600/uno.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEga3g_lFr6dxs8XpjnY0ETVW8ylWUtCJl8UypR_53kWTHkJaQWet3P1sXP3hZO1Be-GMNCP9CJPsGR_r_I5DpBQaO6K6FXbixsxn9OF5Myt01dpVLOL19-wwSQN0geXIUwtp_OKwdsW5PBQ/s1600/uno.png" /></a></div>
Buscando por Internet encontré este buen <a href="http://www.javacodegeeks.com/2011/06/android-game-development-tutorials.html"><b>tutorial de introducción</b></a> de JavaCodeGeeks. Y sólo mirándolo por encima ya vi que Android de serie te da enormes facilidades para manejar gráficos, sonidos y eventos táctiles. Por otra parte, para el juego que nos ocupa no iba a necesitar ningún tipo de aceleración gráfica OpenGL ni otras mandangas de optimizaciones. Así que decidido: no usaría ninguna librería, <b>haría la mía propia basada en la librería estándar de Android</b>.<br />
<br />
<h2>
Gráficos en pantallas con distintas resoluciones</h2>
Esto ha sido seguramente lo que más quebraderos de cabeza me ha dado. Y lo cierto es que si lo entiendes bien y no te metes en líos, tampoco es algo que tenga por qué darte problemas. En Android a priori no sabes cuál es el tamaño de la pantalla, ni tampoco sus proporciones (screen ratio), y tienes que intentar que en todas ellas el juego se vea lo mejor posible.<br />
<br />
Esto implica <b>redimensionamiento</b> de tres elementos: los gráficos, las posiciones en los que pintas los gráficos y los puntos en los que se detectan los eventos táctiles. De primeras solucioné esto creando una clase (más bien cutre) <i>PointTranslator</i>, con un objeto que le pasaba a todos los demás objetos del juego y al que llamaba cada vez que quería traducir una posición o pintar un bitmap.<br />
<br />
Para solucionar el problema de <b>las proporciones de pantalla</b> puse unas franjas negras en la parte que sobrara de la pantalla. Otra solución hubiera sido alargar el bitmap, pero prefería no distorsionar las imágenes. Mi resolución estaba clara, como utilizaba directamente los gráficos del ZX Spectrum, la suya sería la resolución que iba a usar: 256x192 (con proporción 3:4).<br />
<br />
Cuando ya tenía algo que pintaba los gráficos y detectaba las pulsaciones en su sitio, me di cuenta de otro problema: según el móvil en el que cargabas los bitmaps, ¡el propio bitmap podía tener un tamaño diferente al real!. Por lo que vi, esto dependía de otro parámetro: la <b>densidad</b>. Esto afecta sobre todo a la carga de <i>sprites</i>. Una de las típicas técnicas en los juegos es meter todos <b>los gráficos de un personaje en un solo fichero</b>. Al dibujar uno de ellos, se dibuja sólo la parte del gráfico que corresponda. Al no tener el bitmap el tamaño que se suponía iba a tener, esto se desmadraba. Ale, otra chapuza a meter al "soluciones todo-en-uno" PointTranslator.<br />
<br />
Otro problema que tuve con esto fue el del <b>redondeo</b>. Normalmente los bitmaps se cargaban en su tamaño o en un tamaño múltiplo. Pero, ¡ay!, no siempre es así. Concretamente, <b>el Nexus 7 carga los bitmaps en una escala extraña</b>. Esto hace que en bitmaps con muchos gráficos, el redondeo fuera importante y no se cargaran bien. Concretamente, el problema era muy evidente en las fuentes bitmap que usaba para escribir los textos. Vuelvo a tocar (¡cómo no!) ese maravilloso PointTranslator para que use coma flotante para estas cosas y listo.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTyI3xV3cyJCc_mLbK8CiidotrYMGG53N5B6OmMh4zH2U7BdPwnZbn9uXXMBVSgZrN6e2b4Bp1YWAaI0Rq7Axf0uRfuhLLfgdo_YxhQI-TDzYqKKy7DbFDXw-K7VWlO6qH8dMEimqLNDFD/s1600/uno.gif" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTyI3xV3cyJCc_mLbK8CiidotrYMGG53N5B6OmMh4zH2U7BdPwnZbn9uXXMBVSgZrN6e2b4Bp1YWAaI0Rq7Axf0uRfuhLLfgdo_YxhQI-TDzYqKKy7DbFDXw-K7VWlO6qH8dMEimqLNDFD/s1600/uno.gif" /></a>Lo cierto es que estos dos últimos problemas: carga de bitmaps y redondeo <b>no tienen por qué existir</b>. Los cuento porque creo que puede ser interesante saberlo, pero la verdad es que desde el principio fue por una metedura de pata mía. Como todo el proyecto lo he ido haciendo sobre la marcha y sin documentarme debidamente, ya que lo más importante era ir avanzando y obtener cosas funcionando lo más rápido posible (doctor, ¿me habré hecho "ágil"?), cuando probé a meter el primer gráfico lo hice en la carpeta "res\drawable-mdpi". En mi ignorancia, pensaba que estas carpetas <b>ldpi, mdpi, hdpi</b> servirían para cargar gráficos más o menos grandes según la resolución de tu dispositivo, y que si sólo encontraba un gráfico en una carpeta cargaría ese y ya está. Craso error. Lo primero es que no es eso lo que significan esas carpetas, no funcionan según la resolución de pantalla (en cuanto a número de pixels), sino en cuanto a la densidad, es decir, los puntos por pulgada del dispositivo. Es decir, el objetivo de usar esto es, por ejemplo, que se vea más o menos igual de grande (en cuanto a tamaño físico) un gráfico cargado en un tablet que cargado en un móvil con resolución alta o en otro con resolución baja. En definitiva, <b>nada que a priori nos interese ni lo más mínimo cuando estamos haciendo un juego</b>. Para más información, tenéis el <a href="http://developer.android.com/guide/practices/screens_support.html">artículo oficial sobre el tema</a> (un poco ladrillete, pero es que esto es así...). ¿La solución a esto?. Muy fácil, una de estas:<br />
<br />
<ul>
<li>Meter los gráficos en una carpeta <b>drawable-nodpi</b>. </li>
<li>Si queremos cargar diferentes gráficos según la resolución de pantalla, usar carpetas de recursos drawable que dependan del tamaño en píxeles: <b>small, normal, large, xlarge</b></li>
<li>Meter los gráficos como <b>assets</b> en lugar de como resources. Esto, además, nos permite componer de forma dinámica el nombre del bitmap a cargar, o de su carpeta</li>
</ul>
<br />
Esto último es por lo que me he decantado yo, ya que quiero cargar distintos gráficos según la configuración del juego: versión ZX Spectrum, o nueva versión con gráficos HD... ¡pronto en sus kioskos!.<br />
<br />
De hecho, esto último me ocasiona un nuevo problema: <b>los gráficos del juego tendrán distintos tamaños, posiciones y hasta resoluciones diferentes según su configuración</b>. Esto me ha llevado a hacer una <b>refactorización</b>, eliminando alguna chapucilla y mejorando el diseño de las clases para facilitar esto. Y sí, tuve que tomar la difícil decisión de eliminar mi clase-bombero... es decir... el <i>PointTranslator</i> ha muerto (¡viva el <i>PointTranslator</i>!).<br />
<br />
Por lo pronto, en lugar de redimensionar todos los puntos sobre la marcha dentro del propio juego, ahora lo que hago es pintar todo en un <b>buffer intermedio</b>, que tiene el <b>tamaño exacto de la resolución del juego</b>. Al terminar de dibujar todo, se pinta redimensionado en el buffer de pantalla. Para encapsular todo esto he creado una clase <i><b>Camera</b></i>. Cada vez que el controlador del juego quiere pedir a los objetos que se dibujen, llama a la cámara para que devuelva el <i>Canvas</i> (la clase estándar Android donde se pintan cosas) bien configurado. Al terminar todos de dibujar, vuelve a llamarle para que lo plasme. De esta forma, toda la complejidad del proceso se queda en las clases genéricas de mi librería, y las clases específicas del juego se despreocupan totalmente de los problemas de resolución, ellas trabajan siempre con las dimensiones que marque el juego y ya está.<br />
<br />
Todavía me he encontrado con un problema, que ha sido a la hora de traducir las posiciones de los eventos táctiles. Para estas cosas, Android tiene una clase, <i>MotionEvent</i>, que la verdad es que me gusta bastante tal cual está y por tanto no tenía intención de crear otra nueva para lo mismo. Pues bien, resulta que la clase <b>MotionEvent no permite reescalar ni modificar sus posiciones</b>. Bueno, a partir de la versión 11 del API sí, pero quiero que el juego funcione en versiones de Android más antiguas. Lo solucioné creando mi propia clase <i>GameMotionEvent</i>, que utiliza <a href="http://es.wikipedia.org/wiki/Delegation_(patr%C3%B3n_de_dise%C3%B1o)"><b>el patrón de diseño delegate</b></a> para encapsular la clase anterior, proporcionando un interfaz igual y llamando en cada método al equivalente a la anterior, haciendo las pertinentes traducciones de puntos cuando hagan falta a través de la clase <i>Camera</i>.<br />
<br />
<h2>
El bucle principal: con cuatro cosillas lo haces, ¡pero cuidado!</h2>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhztOph4nLhNAxIXgGqd8bAEpSk3h1OwZXHRWtzxsRPT1uNF_oyLN-7GzdMkveYpYcTcu12ZeqTY5e0SNhzXWpJ-qOfTIrZpPbKptGVq7JE3zzS9JPzVAn0pA3uRkIagRVE5yf8KYloPW7u/s1600/uno.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhztOph4nLhNAxIXgGqd8bAEpSk3h1OwZXHRWtzxsRPT1uNF_oyLN-7GzdMkveYpYcTcu12ZeqTY5e0SNhzXWpJ-qOfTIrZpPbKptGVq7JE3zzS9JPzVAn0pA3uRkIagRVE5yf8KYloPW7u/s200/uno.png" width="182" /></a></div>
<span style="text-align: center;">Como bien sabrás si has hecho un juego alguna vez, el bucle principal (el </span><i style="text-align: center;"><b>game loop</b></i><span style="text-align: center;">) supone la estructura fundamental de cualquier juego. Es un bucle "infinito" de tres pasos: </span><b style="text-align: center;">procesar entrada, actualizar estado de los objetos, dibujarlos</b><span style="text-align: center;"> (aunque en realidad lo de procesar la entrada no tiene por qué ir estrictamente en ese orden y se puede hacer más bien en forma de eventos)</span><span style="text-align: center;">. Y hacerlo además de forma que cada ciclo se haga en el mismo tiempo, gestionando condiciones como que si tardamos más tiempo de lo que deberíamos en hacer un ciclo, nos podamos saltar pasos de dibujar para que todo vaya lo más suave posible, y si tardamos menos, esperemos un ratito hasta que quede cuadrado. En realidad todo esto está muy bien explicado en el </span><b style="text-align: center;">tutorial</b><span style="text-align: center;"> que enlacé antes, especialmente en un capítulo en el que </span><a href="http://www.javacodegeeks.com/2011/07/android-game-development-basic-game_05.html" style="text-align: center;">se da un bucle básico</a><span style="text-align: center;"> y en otro posterior donde </span><a href="http://www.javacodegeeks.com/2011/07/android-game-development-measuring-fps.html" style="text-align: center;">se mejora la implementación</a><span style="text-align: center;">. Como digo en el título, hacer un bucle principal es muy sencillo teniendo en cuenta cuatro cosas que son muy conocidas y que este tutorial cuenta muy bien. Pero ojo, ¡es muy importante tenerlas en cuenta!.</span><br />
<span style="text-align: center;"><br /></span>
Lo que no me gusta tanto del tutorial es el <b>diseño de clases</b> que se da en su implementación, ya que me parece bastante "sucio", haciendo que la clase principal herede directamente de <i>Thread</i> y obligando además al que la use a extender directamente esta misma clase para poder hacer una implementación para un juego concreto. Así que decidí cambiar este diseño y hacer uno más genérico, con <b>una clase limpia <i>GameController</i></b> que se pueda invocar fácilmente desde el <i>Activity</i> y que use el thread de forma interna. Incorporé las clases <i>Camera</i> y <i>GameMotionEvent</i> que he contado en el punto anterior, para el escalado de los gráficos. Y para permitir la implementación concreta de los objetos creé primero un interface básico <i>GameEntity</i>, con lo mínimo que se necesita para pintar un objeto y que reaccione a eventos. Luego creé otro extendido <i>Scenario</i>, que me pareció interesante para facilitar la creación de "partes" del juego completamente diferenciadas entre sí.<br />
<br />
Este es el diseño que quedó:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-tLTog86hj8LgksE9XFKfOhSO7ZAmQxGRz5GN_ebjf0tbtGvKBfkNx8GHnN72-XdkKwdBk9iXPwL7aJwnBX1_izPszaLAwusDn2t0yhgVt6gXRont4-t2EE6M8w6AwagZOpysl3Yt89AE/s1600/control.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="490" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-tLTog86hj8LgksE9XFKfOhSO7ZAmQxGRz5GN_ebjf0tbtGvKBfkNx8GHnN72-XdkKwdBk9iXPwL7aJwnBX1_izPszaLAwusDn2t0yhgVt6gXRont4-t2EE6M8w6AwagZOpysl3Yt89AE/s640/control.png" width="640" /></a></div>
<br />
<br />
<h2>
Continuará...</h2>
<div>
Y hasta aquí por hoy mis historias programando el juego en Android. Haré un capítulo más, en el que contaré otros refinamientos que he hecho en el diseño, sobre todo para poder tener un sistema sencillo de componentes gráficos y otras cosas como animaciones y efectos. En breve <b>aquí mismito</b>.</div>
<br />
<br />Andréshttp://www.blogger.com/profile/06010147149377176406noreply@blogger.com1tag:blogger.com,1999:blog-6416070227303513915.post-77149926326261958572013-03-22T09:34:00.000+01:002013-03-22T09:34:05.243+01:00En la nube y gratis, ¡barra libre! (¿Google is evil?)<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNRmciQfwx9jq0MTORSsfJ-ZEsif1mFz87DeMiQkcNQ0hfDGc0PzTwdEgHfaZwLEHUPiZxF7PPWRd0bOI8pTgrqX8WhZeh3NifnJloVqFphlBt9RtVYfjWXnSGM4hhEPSECcXjPYizdEcN/s1600/googleevil07.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="76" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNRmciQfwx9jq0MTORSsfJ-ZEsif1mFz87DeMiQkcNQ0hfDGc0PzTwdEgHfaZwLEHUPiZxF7PPWRd0bOI8pTgrqX8WhZeh3NifnJloVqFphlBt9RtVYfjWXnSGM4hhEPSECcXjPYizdEcN/s200/googleevil07.jpg" width="200" /></a></div>
La semana pasada saltó la noticia: Google había decidido cerrar uno de sus servicios gratuitos en la nube, <a href="http://reader.google.com/"><b>Google Reader</b></a>. Esto ha creado una importante polémica, ya que muchos de sus usuarios se han sentido engañados por Google, que no ha tenido en cuenta sus sentimientos y necesidades y en su lugar ha atendido al "vil dólar".<br />
<br />
Esta reacción me ha dejado, la verdad, bastante sorprendido. Y leche, voy a opinar, ¡que pa eso tengo un blog!<br />
<br />
Ha habido gente que siempre ha demostrado muchísimo criterio y educación, como Enrique Dans (gran <a href="http://www.enriquedans.com/">blog</a> el suyo aunque ahora no esté de acuerdo con él), que de repente, en mi opinión, pierden un poco los papeles con tweets como este:<br />
<br />
<blockquote class="twitter-tweet" lang="es">
Hey, @<a href="https://twitter.com/google">google</a>, remember last Spring cleaning, when you killed Reader? Now take Google Keep and stick it up your ***...<br />
— Enrique Dans (@edans) <a href="https://twitter.com/edans/status/314629865317990400">21 de marzo de 2013</a></blockquote>
<script async="" charset="utf-8" src="//platform.twitter.com/widgets.js"></script>
<br />
<br />
Traducción (no literal pero creo que sí bastante equivalente): "Ey, @google, ¿recuerdas tu última limpieza de Primavera, cuando te cargaste el Reader? Pues ahora coge el Google Keep y metételo por el ****..." (Keep es un nuevo servicio que ha sacado Google durante estos días)<br />
<br />
También debo decir que Dans ha reconocido su grosería en ese mensaje y que por lo demás ha dado explicaciones sobre su opinión <a href="http://www.enriquedans.com/2013/03/google-y-el-desprecio-a-sus-usuarios-el-cierre-de-google-reader.html">aquí</a> y <a href="http://www.enriquedans.com/2013/03/google-alienando-a-sus-usuarios.html">aquí</a>, pero... ¿qué ha ocasionado que tanto él como muchos otros pillen semejante cabreo?. ¿¿¿Qué ha hecho Google tan diabólico como para llegar a eso???.<br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
Creo que casi nadie duda, o debería dudar, de que Google, como empresa privada, está en su derecho de pensar en <b>sus beneficios</b> por encima de los de sus usuarios. David Bonilla, por ejemplo, razonaba bien esto en <a href="http://us2.campaign-archive2.com/?u=374c664073e1a1fa3deca53b4&id=27965d0fd8">un artículo</a> sobre el tema. Pero creo que ese no es el meollo principal del asunto. De lo que se acusa a Google es de <b>maltratar a sus usuarios</b> en el cierre, de no ser justo con ellos. De "jugar sucio".<br />
<br />
Yo creo que esto hace que el tema no sea tanto de lógica como de sentimientos, de <b>corazones rotos</b>. Como <a href="http://apagayvuelveaencender.blogspot.com.es/2012/11/maven-te-quiero-te-odio.html">Maven y yo</a>, vaya. Examinemos pues la historia de amor-odio desde sus principios.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQ5Nt-GqX5DGXBrjXKRMM7qCxcwFqze6hXEWoT89JwP2MN_apiBH5AORex_uzHpRWntR3hYR6tkK1cK-d1bLekp0tfUVsr42hTQUotubyOH_8ZZzIPU6B3-WTqOmK2b7RWjJxnFVhZaCQK/s1600/Altavista-1999.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="141" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQ5Nt-GqX5DGXBrjXKRMM7qCxcwFqze6hXEWoT89JwP2MN_apiBH5AORex_uzHpRWntR3hYR6tkK1cK-d1bLekp0tfUVsr42hTQUotubyOH_8ZZzIPU6B3-WTqOmK2b7RWjJxnFVhZaCQK/s200/Altavista-1999.png" width="200" /></a></div>
Año 1999. Para todo el mundo, Google es <b>ese buscador</b> que ha salido en los últimos años y que es la leche, y que encuentra más cosas que Altavista y Yahoo. Bueno, no es para tanto, aunque, ¿te has dado cuenta?. Me está mirando.<br />
<br />
Año 2000. Google empieza a sacar otros servicios en Internet, como AdWords, con el que empieza a mostrar las cartas de su <b>estrategia empresarial</b>. También empieza a llevar a cabo una de las prácticas que se convertirá en marca de la casa: <b>comprar productos</b> que han hecho otros y hacerlos suyos. Así nace Google Groups. Ey, pues parece que tiene su gracia y hace cosas que no están mal, aunque tía, no me enrollaría con él ni borracha.<br />
<br />
Año 2002. Google crea Google <b>Labs</b>, con el que envía otro mensaje: "<b>Nosotros molamos</b>. Estamos continuamente investigando y probando nuevos productos para que todo lo que hagamos sea la leche". Se empieza a conocer que los empleados de Google tienen permiso para dedicar el 20% de su tiempo a proyectos que decidan ellos, y que son los que alimentan el Labs. Pues oye, vale, no es guapo... pero tiene algo especial, no sé cómo explicarlo. Aunque no está tan bueno como Migolsón, claro.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjdwMMdGQx79gZvmUslRxAfivXuRgGmvVazD67K1FsCLb6OTvBV0WY4wAaj1c8BlongSEZYgTMr7LmhP_8Q7pRes4MAdioY5D0r5q9pJUtIV-X2epE8VqEhNE23_BG8Z_Jj1kpeECpbS3e6/s1600/old-livejournal.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="180" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjdwMMdGQx79gZvmUslRxAfivXuRgGmvVazD67K1FsCLb6OTvBV0WY4wAaj1c8BlongSEZYgTMr7LmhP_8Q7pRes4MAdioY5D0r5q9pJUtIV-X2epE8VqEhNE23_BG8Z_Jj1kpeECpbS3e6/s200/old-livejournal.png" width="200" /></a></div>
Año 2003. Compra <b>Blogger</b>, y con esto empieza a petarlo, por varios motivos. Por un lado, es un servicio que gana <b>muchísimos usuarios</b>, y que además consigue unir el nombre de Google a una nueva moda que se empieza a imponer en Internet, la creación de blogs. Por otro lado, supone un nuevo mensaje de Google al mundo: "No necesitas Windows, se pueden hacer grandes aplicaciones<b> directamente en la web</b>". No olvidemos que en ese momento Microsoft, su Windows y su Office dominaban el mercado, sin que aparentemente le importara usar malas prácticas para conseguir el monopolio (y estos de verdad, aunque también en esto hay cierta polémica). El caso es que empieza a mostrar otra de sus líneas estratégicas: cargarse a Microsoft, no enfrentándose en su mismo terreno, los sistemas operativos de escritorio, sino yendo más allá, cambiando el paradigma: <b>llevemos las aplicaciones a la web</b>, retornemos desde el ordenador monolítico hacia el cliente-servidor, aprovechando la existencia de Internet. Microsoft tiene su corralito muy bien montado, pero no está preparado para esa pelea. Hasta este momento, no se hacían "aplicaciones" completas en la web, que no se consideraba suficientemente cómoda para ello. Se hacían en Windows. Jo, tía, ¡me está empezando a traer loca! Es tan interesante en lo que dice, es tan sensible, tan especial... Migolsón está muy bueno, pero no mola tanto, te acabas dando cuenta de que es un soso, no tiene fondo.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLNUcXQZpuPpuNWcUE3awjEZSj1v9LQwNukXzwGrmbyTnZMOwxpik20BqNIRzZq16Pqi_jGDLmzZzKfYpYfQYd5bIGcV8Gp9sgXEQD1C_YfpeeQH-9J_Hf2pTRurP6il-4lwESjOW8LX-c/s1600/bush_hotmail.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="124" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLNUcXQZpuPpuNWcUE3awjEZSj1v9LQwNukXzwGrmbyTnZMOwxpik20BqNIRzZq16Pqi_jGDLmzZzKfYpYfQYd5bIGcV8Gp9sgXEQD1C_YfpeeQH-9J_Hf2pTRurP6il-4lwESjOW8LX-c/s200/bush_hotmail.jpg" width="200" /></a></div>
Año 2004. Lanza <b>GMail</b>, y ahora ya sí que la lía parda. Sigue una inteligente estrategia comercial: aprovecha que ya tiene ganado un gran prestigio, y saca el servicio en forma de <b>"beta privada" con invitaciones</b>. Si quieres ser uno de los "privilegiados" en probarlo y usarlo, necesitas que alguien te dé una invitación. Los que la prueban hablan maravillas del producto, y además presumen de que "yo la tengo y tú no". Además, es que es verdad que GMail está realmente bien. Acaba de un plumazo con algo que hasta ese momento se sufría mucho en el correo electrónico: tenías que estar vigilando siempre el espacio libre que quedaba, y borrar mensajes. Se da una gran capacidad de almacenamiento a cada cuenta y santas pascuas. Aparte de esto, crea un sistema de agrupación de mensajes por conversaciones realmente bien pensado. GMail está tan bien, que 9 años después nadie ha intentado ni siquiera enfrentarse a él. Tía, ¡creo que me mola!, ¿pero qué se ha creído?, le he dicho de salir y me ha dicho que iba a tener unas semanas muy ocupado, ¡que ya me llamaría!. Te lo digo yo, ¡este no se me escapa!<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpO_n0H8GN0ldfJP8mQa7__ZC6_rrdZ40ZbtWQNUBXlJH2mcyz6TIQt-McaMaQBtZumr2XLtWw8yDPf46j_nxClDUWYgDNilg4EyuA5Vwy1B_ezfdyYFmFSWfaZeSDqArBpVy08cFH7dmn/s1600/callejeropagsam.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="131" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpO_n0H8GN0ldfJP8mQa7__ZC6_rrdZ40ZbtWQNUBXlJH2mcyz6TIQt-McaMaQBtZumr2XLtWw8yDPf46j_nxClDUWYgDNilg4EyuA5Vwy1B_ezfdyYFmFSWfaZeSDqArBpVy08cFH7dmn/s200/callejeropagsam.jpg" width="200" /></a></div>
Año 2005. Google cada vez lanza más aplicaciones en la web. Una de ellas de gran importancia con el tiempo, <b>Google Maps</b>, con un completísimo callejero de todo el mundo. Y siguen saliendo más servicios: Google Docs, Picasa, Calendar... Google Reader. Todos gratis. Sin publicidad. Google mola mucho. Google no piensa en ganar dinero, ¡Google piensa en nosotros!. ¡¡¡Tía, qué feliz soy!!! ¡Es perfecto, maravilloso, no tiene ningún defecto! ¡No hay nadie como él! ¡Y sólo piensa en mi, no le importa nada más en el mundo!<br />
<br />
Siguieron pasando los años, claro, en los que Google fue dejando cada vez más claras sus estrategias comerciales. Apostó por los móviles con Android. Fue a "matar" a Internet Explorer con Chrome. Sigue intentando cargarse también a Windows, por un lado con los Chromebooks, por otro con Google Apps. Dejó claro que todo eso que nos estaba dando gratis tenía un precio: estaba obteniendo información sobre nosotros, para dar un servicio de publicidad ajustado automáticamente a nuestros gustos, que es revolucionario y con el que se puede ganar (claro) muchísima pasta.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBig1TyWsNFOvQ9oXjDRiEhs1TjukRfkGOb0ehHkEMJlyu-ei3IqzaKhtPrjfHPjXMjlKyc5pPgGEuKNwndcNJYLm5P6sU_ryVBOvhOrhAgTmgoJOTSm88IVd8dwwCImwBkQjn9Cmhrxec/s1600/dead-ie-jp.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBig1TyWsNFOvQ9oXjDRiEhs1TjukRfkGOb0ehHkEMJlyu-ei3IqzaKhtPrjfHPjXMjlKyc5pPgGEuKNwndcNJYLm5P6sU_ryVBOvhOrhAgTmgoJOTSm88IVd8dwwCImwBkQjn9Cmhrxec/s200/dead-ie-jp.jpg" width="150" /></a></div>
Y es aquí cuando llegamos al meollo. Google nunca ha dicho que piense más en el usuario que en ganar dinero. Google acuñó desde el principio una frase: "se puede ganar dinero sin ser malvado". Se refería a Microsoft, claro. Microsoft aprovechaba su estatus de dominio <b>para hacer el mundo un poco peor</b>. Se saltaba los estándares a la torera. No le interesaban. Lo que le interesaba es que sus productos fueran oscuros y cerrados, y que no fueran compatibles con nada, para cargarse su competencia. Nada de usar formatos estándar de documentos para Office. Nada de usar estándares para las páginas web, ¿para qué?. Si lo que queremos es que todo el mundo use Internet Explorer. Personalmente, culpo a Internet Explorer y por tanto a Microsoft, de que el desarrollo en la web haya crecido tan lentamente.<br />
<br />
De lo que se acusa ahora a Google es precisamente de esto: <b>de ser malvado</b>. De dejar tirados a sus usuarios. Sin embargo, lo cierto es que Google en ningún momento ha usado su posición de dominio para ocultar la información y cargarse a la competencia. Google ha hecho todo lo contrario, ha dejado siempre más o menos claro cómo acceder a sus servicios, ha creado APIs, ha fomentado los estándares. Si nadie se ha opuesto a Google en su terreno es porque <b>nadie ha pensado que podía hacerlo mejor</b>.<br />
<br />
Una de las cosas que se le achaca es que "<b>Google se equivoca</b>". Suponemos que lo usa "mucha" gente. Suponemos que si es así le tiene que interesar a Google, sin pensar en qué gana Google con todo esto, sin pensar en que el mantenimiento de los servidores y del almacenamiento son dinero que Google pierde. Suponemos que si le interesaba hace 8 años le tiene que seguir interesando. Suponemos que Google ha hecho mal las cuentas, que claro que le tiene que interesar. Suponemos que Google quiere perjudicarnos para colárnosla por otro lado... ¿Por qué?. ¿Por qué va a ser así?. ¿Porque lo usamos yo y mis amigos?<br />
<br />
Aparte de esto, digo yo, ¿qué se supone que tiene que hacer una empresa que está dando un servicio gratuito cuando está perdiendo dinero por ese servicio o sencillamente no le interesa continuar con él por el motivo X?. ¿Qué tiene que hacer para cuidar a sus usuarios y darles la posibilidad de migrar a otro sistema? ¿Para <b>tratarlos bien</b>?. En mi opinión, si quieres ir de buenas y buscas el bien de tus usuarios tienes que hacer esto:<br />
<br />
<br />
1. <b>Avisar</b> con tiempo suficiente de cualquier cambio que quiera hacer en este sentido (cesar el servicio o cambiar sus condiciones)<br />
<br />
2. Permitir a los usuarios <b>extraer</b> de alguna forma sus datos, para poder <b>migrarlos</b> a otro sistema<br />
<br />
(habría una tercera, que no es aplicable a Reader: el día que Google decida cerrar otros servicios como GMail y Blogger, espero que durante un tiempo permitan configurar una redirección desde tu página o dirección de correo a otra página / dirección)<br />
<br />
<br />
Esto lo ha hecho Google, y lo ha hecho <b>muy bien</b>. El mismo día que Google anunció que iba a cerrar Reader, <a href="http://www.feedly.com/">Feedly</a> ya aseguraba que <a href="http://blog.feedly.com/2013/03/14/google-reader/">iban a permitir una migración transparente</a> sin que el usuario tenga que hacer nada. Esto lo puede hacer Feedly porque <b>Google lo permite</b>, ni más ni menos.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpfGv7SihVdJQXQVm20eZ9Xq-axAlpP07eP0bfRgT1DQWoL161JoA_3MhnVP0zm1YmcE1LELJQX26OUUqsjWvJhJZ7h95-gCcaEi7cM4UVNDuyzn9nspATV5FGTueGLwmCykXZ-RIqg01c/s1600/images.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="94" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpfGv7SihVdJQXQVm20eZ9Xq-axAlpP07eP0bfRgT1DQWoL161JoA_3MhnVP0zm1YmcE1LELJQX26OUUqsjWvJhJZ7h95-gCcaEi7cM4UVNDuyzn9nspATV5FGTueGLwmCykXZ-RIqg01c/s200/images.jpg" width="200" /></a></div>
¿Y qué es lo que le piden los que se quejan?. Que Google <b>ofrezca un reemplazo</b>. Vamos a ver, pongámonos en la piel de Google, supongamos que somos nosotros los que damos ese servicio. Si el servicio no me compensa, porque he hecho cuentas y sé que no me compensa, no voy a hacer otro producto que haga lo mismo. ¿Y ofrecer a mis usuarios que se muevan a un producto de otra compañía?. Soy Google, estoy dando una <b>garantía de calidad</b> demostrada con los años. Si te ofrezco un producto de otra compañía, no te puedo garantizar esa calidad. No puedo responder de la otra compañía. Pueden ser unos chapuceros. Sinceramente, si Google hubiera hecho esto sí que <b>estaría</b> <b>perdiendo </b>algo de mi confianza. Y si resulta que no existe ningún producto similar con un nivel parecido, Google no tiene culpa de nada, hay que dejar que sea el mercado el que decida la realidad que hay detrás de todo esto. Una de dos, o aparece un buen producto aprovechando la buena base de usuarios (es lo que ha pasado con Feedly, que se estará frotando las manos), o es que nadie quiere hacerlo porque se pierde dinero con dicho servicio. El caso es que cualquiera puede hacerlo, Google no pone trabas.<br />
<br />
Entonces, ¿qué es lo que ha ocurrido?. Yo creo que esto pasa única y exclusivamente por ser Google. Creo que había gente obnuvilada. Que confundió no ser malvado con ser tonto. Que pensó que Google era una ONG. Que usaban cualquier producto de Google sólo porque era de Google, aunque existiera otro mejor. Porque, claro, <b>tenemos sentimientos</b>. Y es tan bonito enamorarse, pensar que el otro es perfecto. Hasta que cualquier día te das cuenta que ¡zas!, es humano igual que tú. Y tiene necesidades igual que tú. Y que, vale, te quiere, pero está mirando a esa otra. Y en ese momento nos sentimos decepcionados y engañados.<br />
<br />
Pero tranquilos, que eso se pasa. Se llama <b>realidad</b>, y si la sabes entender, es maravillosa. En cuanto te des cuenta de que pasa el tiempo y otras empresas van cerrando también sus servicios, y que ninguna hace eso que le exigías a Google (pero que tampoco tienes muy claro lo que era), y que al contrario, muchas lo hacen mucho peor... entonces igual vuelves a mirarlo y piensas "Oye, pues no estaba tan mal. Y ey, <b>me está mirando</b>".<br />
<br />Andréshttp://www.blogger.com/profile/06010147149377176406noreply@blogger.com4tag:blogger.com,1999:blog-6416070227303513915.post-81627500755427784072013-03-11T20:29:00.000+01:002013-03-11T21:04:20.102+01:00West Bank: Crónica RetroMadrid 2013<div class="separator" style="clear: both; text-align: left;">
Antes que nada, os presento al gran campeón del <a href="http://apagayvuelveaencender.blogspot.com.es/2013/03/concurso-west-bank-retromadrid.html"><b>concurso</b></a>, y ganador de la exclusiva camiseta de <a href="http://apagayvuelveaencender.blogspot.com.es/2013/03/proyecto-west-bank-android.html">West Bank</a>, con una impresionante puntuación de <u>196,900 puntos</u>... ¡<b>ARQUILLOS</b>!</div>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggX6P78upF9rWATtQNQiHMMNJqGhmdd1kaymDd48IEXLfSlkdXiU5YFx8JAZga1RpswJrlqRgwEE4rGWU0305JZ2RGIzI2vcxh-RlbfknJmqGnJSbt6KBY3J3FTljNcacs2dg3Tk7O0KFt/s1600/IMG-20130309-WA0000.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="300" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggX6P78upF9rWATtQNQiHMMNJqGhmdd1kaymDd48IEXLfSlkdXiU5YFx8JAZga1RpswJrlqRgwEE4rGWU0305JZ2RGIzI2vcxh-RlbfknJmqGnJSbt6KBY3J3FTljNcacs2dg3Tk7O0KFt/s400/IMG-20130309-WA0000.jpg" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Arquillos, campeón del concurso West Bank</td></tr>
</tbody></table>
<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; margin-left: 1em; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKBYz0HDDS8WHTpfPMG-nwuXZbOAlFb8e2CYdhMcLgP49GknfyzrL9dC-kSaqNDvcV9P6tZC6r8ZLeiYiAja37YjcG_NUjoJzID7IzT8ZHvQDT0CxBUvM5MoqgXlKKIRB0tVVlGvMhXLYr/s1600/IMG-20130309-WA0003.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="150" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKBYz0HDDS8WHTpfPMG-nwuXZbOAlFb8e2CYdhMcLgP49GknfyzrL9dC-kSaqNDvcV9P6tZC6r8ZLeiYiAja37YjcG_NUjoJzID7IzT8ZHvQDT0CxBUvM5MoqgXlKKIRB0tVVlGvMhXLYr/s200/IMG-20130309-WA0003.jpg" width="200" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">VTC con la camiseta de Ardent Monkey</td></tr>
</tbody></table>
También estuvo presente <b>VTC</b>, el segundo clasificado, con una puntuación de 144,910 puntos. VTC por su tenacidad y también gran puntuación, ganó un improvisado segundo premio, una camiseta de <b>Ardent Monkey Games</b>. Como anécdota, comentar que VTC hizo esta gran puntuación sin pasar de la fase 1, ya que no se había dado cuenta de que se podía mover de unas puertas a otras para pasar de fase (error nuestro, en realidad, ya que sólo se explica en la página del Play Store pero no dentro del juego). De hecho, el propio Arquillos nos comentó que para conseguir su máxima puntuación decidió no pasar de fase adrede y se quedó en la segunda, para conseguir ahí el mayor número posible de puntos.<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; margin-left: 1em; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPkV8zHVJ8KzPS4Gb9FhIMFtrpN_R-Gti6jRDNQHYL85krwK0hyur_LOKcskuzz-qEgv7zyVDo-LhUaq9YQxGXRkdpmOrhQ1ytUtx5XUxBja3S9NK6_1TqmXd3cHzm05ueaD9xLNeYoRrZ/s1600/CameraZOOM-20130309183526471.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="150" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPkV8zHVJ8KzPS4Gb9FhIMFtrpN_R-Gti6jRDNQHYL85krwK0hyur_LOKcskuzz-qEgv7zyVDo-LhUaq9YQxGXRkdpmOrhQ1ytUtx5XUxBja3S9NK6_1TqmXd3cHzm05ueaD9xLNeYoRrZ/s200/CameraZOOM-20130309183526471.jpg" width="200" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">VTC: "¡Así es más divertido!"</td></tr>
</tbody></table>
<br />
La experiencia ha sido <b>muy gratificante</b>, mucha gente pasó por el stand y nos comentaba que le había gustado mucho la conversión y que el juego seguía siendo un vicio a pesar de los años transcurridos. También hemos recibido mensajes del mismo estilo por otros medios, como Twitter, email o el propio Google Play. Incluso gente comentándonos que sus hijos y sobrinos pequeños (¡7 años!) estaban viciándose con el juego. ¿Los clásicos nunca mueren?.<br />
<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNzI9vuZqusqbl0-XV8zdnxaYfqQmItpwPDHftgZGYjMAlzavLfh7m3UYpsWghXy7jCdS6EJKiJcnfWHG-zV7W8zzstlUMYcE4ZWwcWSrYZmIWfV3EpPCia70c7Ga2Uur7IDbCzqkArHSh/s1600/IMG-20130309-WA0001.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNzI9vuZqusqbl0-XV8zdnxaYfqQmItpwPDHftgZGYjMAlzavLfh7m3UYpsWghXy7jCdS6EJKiJcnfWHG-zV7W8zzstlUMYcE4ZWwcWSrYZmIWfV3EpPCia70c7Ga2Uur7IDbCzqkArHSh/s320/IMG-20130309-WA0001.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">"Foto de familia": los dos primeros clasificados, y Adr y yo haciendo el ganso</td></tr>
</tbody></table>
<br />
Por otra parte, tuvimos un visitante especialmente ilustre en el stand... ¡¡¡<b>Álvaro Mateos, el creador del juego original</b>!!!. Muy majete, y algo sorprendido por todo lo que estábamos montando, me estuvo enseñando la versión que hizo <a href="https://itunes.apple.com/us/app/zx-west-bank/id451796188">para iPhone</a> (también hay <a href="http://www.windowsphoneapplist.com/en/west_bank-a24254.html">otra para Windows Phone</a>) y que está muy muy bien, con lo cual entre él y nosotros tenemos bastante cubiertos la mayor parte de dispositivos móviles. Añado que una de las preguntas que más nos hizo la gente en el stand fue si íbamos a hacer versión para iPhone. No, no vamos a hacer versión para iPhone, ya está hecha, es esta versión hecha por el propio Álvaro, está disponible en el Apple Store, y el interfaz es muy muy similar a la nuestra (tiene cosas de su propia cosecha, como la carga del juego en cassete). Más información en <a href="http://www.hi-score.org/"><b>su web</b></a>.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjdfNSbIgwRvyTuNLvMgYo9JNmovKTxoGy5QaINxp8Vk2r4X2og21afU4HURzCMUfe9i_lre-4BlXm7T-cGwySJl65ZVZgMGSsHvJSbRtFiK6mYINacRC56iULu4Kuup9Uicl8s5LdxVS3/s1600/CameraZOOM-20130309142007354.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjdfNSbIgwRvyTuNLvMgYo9JNmovKTxoGy5QaINxp8Vk2r4X2og21afU4HURzCMUfe9i_lre-4BlXm7T-cGwySJl65ZVZgMGSsHvJSbRtFiK6mYINacRC56iULu4Kuup9Uicl8s5LdxVS3/s320/CameraZOOM-20130309142007354.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="font-size: 13px; text-align: center;">Álvaro y yo (y una luz al fondo para que no se vea nada,<br />
¡ya le daré lo suyo al fotógrafo!)</td></tr>
</tbody></table>
<br />
La verdad es que no nos podemos quejar nada de la acogida del juego, en una sola semana desde su presentación lleva ya alrededor de <b>250 descargas</b>, y ahora mismo la han puntuado en el <a href="https://play.google.com/store/apps/details?id=com.ardent.westbank">Play Store</a> 13 personas y todas le han puesto un 5 (la máxima puntuación). El concurso también ha sido un éxito, al principio me cortaba para no hacer puntuaciones demasiado altas y copar yo el top, y ahora ya ni estoy entre los diez primeros... ¡algo que pienso remediar los próximos días, cagontó!<br />
<br />
<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="clear: left; float: right; margin-bottom: 1em; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiuixdg7t4eaEiiMJ3FhP3Q8OAzwUtbHToYcbaLk7V6t3o225NJ4Owu3IBFnRdMut5oGQXu14TtcFxIIdk5SmzJpQ3UaiSUsd9GXCpUzJplHr49dW19BCq7PRMSwWT5v6eSX9hMGTeaACDC/s1600/CameraZOOM-20130309142142628.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="150" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiuixdg7t4eaEiiMJ3FhP3Q8OAzwUtbHToYcbaLk7V6t3o225NJ4Owu3IBFnRdMut5oGQXu14TtcFxIIdk5SmzJpQ3UaiSUsd9GXCpUzJplHr49dW19BCq7PRMSwWT5v6eSX9hMGTeaACDC/s200/CameraZOOM-20130309142142628.jpg" width="200" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Stand de Ardent Monkey<br />
en RetroMadrid</td></tr>
</tbody></table>
Por otra parte, muchas publicaciones "retro" se han hecho eco del remake, ¡muchas gracias a todos!:<br />
<ul>
<li><a href="https://www.facebook.com/photo.php?fbid=576943865656656&set=a.554032377947805.131012.182965131721200&type=1&relevant_count=1">La propia RetroMadrid (tanto en Facebook como en Twitter)</a></li>
<li><a href="http://retromaniacmagazine.blogspot.com.es/2013/03/descarga-gratis-el-remake-de-west-bank.html">RetroManiac</a></li>
<li><a href="http://www.elspectrumhoy.es/a-la-retromadrid-2013-no-faltaran-ni-los-vaqueros/">El Spectrum Hoy</a></li>
<li><a href="http://www.elmundodelspectrum.com/contenido.php?id=747&d=Lanzado-el-remake-de-West-Bank-para-Android-y...%A1Concurso-en-Retromadrid!">El Mundo del Spectrum</a></li>
<li><a href="http://www.bytemaniacos.com/?p=2553">Byte Maniacos</a></li>
<li><a href="http://www.konamito.com/remake-de-west-bank-para-android/?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+konamito+(MSXBlog+de+Konamito)">MSXBlog de Konamito</a></li>
<li><a href="http://www.caad.es/noticias/nos-vemos-en-retromadrid-2013.html">CAAD</a></li>
<li><a href="http://juegosretro.tutiblogs.com/?p=2090">Juegos Retro Tutiblogs</a></li>
<li><a href="https://www.facebook.com/pages/El-Pixeblog-de-Pedja/96534023102?fref=ts">El Pixeblog de Pedja (por Facebook)</a></li>
<li>Nosotros mismos pusimos también la noticia en algún foro, como el de <a href="http://computeremuzone.com/forum/viewtopic.php?f=3&t=7144">ComputerEmuzone</a> ó especialmente <a href="http://www.fasebonus.net/foro/index.php?topic=35397.0">FaseBonus</a>, donde incluso nos ayudaron a elegir diseño para la camiseta</li>
<li>Alguna otra que seguro que se nos olvida o no hemos detectado</li>
</ul>
<div>
<br /></div>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj37S2kIIs48cKiNYLBvcZODXSOBSHL3hdtl80FSoxl_6sfn5PQq1NYhSM0UTcAET9IY77biiobrYGvsh-REgt22pmcPxjRM2T7k5pxzDrFbFoVKkzQNKh9eNLAFGx-Oko3UMy2c6r1psTE/s1600/wbrecords.png" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="150" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj37S2kIIs48cKiNYLBvcZODXSOBSHL3hdtl80FSoxl_6sfn5PQq1NYhSM0UTcAET9IY77biiobrYGvsh-REgt22pmcPxjRM2T7k5pxzDrFbFoVKkzQNKh9eNLAFGx-Oko3UMy2c6r1psTE/s200/wbrecords.png" width="200" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Tabla de puntuaciones al acabar el<br />
concurso. ¡Impresionante!</td></tr>
</tbody></table>
Aparte de esto, la <b><a href="http://www.retromadrid.com/">RetroMadrid</a></b> en sí estuvo genial, hacía años que no estaba y me lo pasé realmente bien, muy bien la organización y muy buena calidad en general en el resto de expositores, con mucha presencia de máquinas arcade y "bartop" (a las que miro con deseo aunque al final me contuve y no llegué a comprar ninguna), y muchos imancitos, llaverillos, posters y demás coñas que tanto nos gustan a los retro-frikis. Muy buena la experiencia de compatir expositor con los amigos del <b><a href="http://www.caad.es/">CAAD</a></b>, y genial haber conocido al gran <a href="http://www.elviejoarchivero.com/">Andrés Samudio</a> (y muy buena su charla, intentando no caer en tópicos).<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEik5lMkxM66SgKK4BaEsBy1UnyclDwQwoIyh_D-CTJ7K1OU-TIHw0cP8TiuBggwcCm9CWdFTmdtsSJBpD3gjZ9FIkGIdT51ajc5bye9frQUI-HDFwtttCQzdFVnpJ199f3hVRVWb0fDD1F_/s1600/cartel_peq.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEik5lMkxM66SgKK4BaEsBy1UnyclDwQwoIyh_D-CTJ7K1OU-TIHw0cP8TiuBggwcCm9CWdFTmdtsSJBpD3gjZ9FIkGIdT51ajc5bye9frQUI-HDFwtttCQzdFVnpJ199f3hVRVWb0fDD1F_/s200/cartel_peq.jpg" width="141" /></a>¿Y ahora?. Nuestro próximo reto es hacer que el juego sea <b>atractivo para las nuevas generaciones</b>, es decir, para la gente que no jugó ni conoció el juego original, ni tampoco le atrae especialmente la estética retro. Creo firmemente que la dinámica del juego es perfectamente válida para el público general, y vamos a intentar demostrarlo.<br />
<br />
Para eso, estamos preparando una versión con <b>nuevos gráficos hechos de cero</b> y nuevos sonidos y músicas. Bueno, y con ayudas para que quede clarito cómo moverse entre las puertas, ¡sigh!.<br />
<br />
Permaneced atentos al Play Store, cualquier día de estos puede aparecer una actualización del juego con la que podréis sentiros seguros para enseñársela a vuestros amigos, hermanos, padres, abuelos, hijos, sobrinos... y hasta a vuestr@s churris, <b>sin que os miren con cara rara</b>, en plan "<b>que ya tienes una edad... ¡CRECE!</b>".<br />
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
Andréshttp://www.blogger.com/profile/06010147149377176406noreply@blogger.com14tag:blogger.com,1999:blog-6416070227303513915.post-22180504775397810302013-03-06T16:15:00.002+01:002013-03-06T17:33:14.014+01:00CONCURSO West Bank RetroMadridSaca la mayor puntuación en el remake de West Bank para Android, ¡y gana <b>una estupenda camiseta</b>!.<br />
<br />
¡¡¡<b>YA</b> puedes empezar a participar, dale caña!!!<br />
<div>
<br /></div>
<div>
La camiseta se recogerá en la <b><a href="http://www.retromadrid.com/">RetroMadrid</a> este mismo Sábado</b>. ¿A qué estás esperando?. ¡No dejes ni uno vivo!</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhYgIS1VRfJ-gdpAmdAT1YGNZhp3e1glGOSLscDV1qVoiLJ_pj6mNGwKQXB_hfKp8TTHQGkPLEpBB8acM7ZcedkzFZLI50Ltvoo6SzCCbz2U8Cu1R9XK16E9fnyvtOaYc3utQPJP4hF638/s1600/poster1_peq2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhYgIS1VRfJ-gdpAmdAT1YGNZhp3e1glGOSLscDV1qVoiLJ_pj6mNGwKQXB_hfKp8TTHQGkPLEpBB8acM7ZcedkzFZLI50Ltvoo6SzCCbz2U8Cu1R9XK16E9fnyvtOaYc3utQPJP4hF638/s640/poster1_peq2.jpg" width="452" /></a></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<div>
<div style="text-align: center;">
<div class="separator" style="clear: both;">
<a href="https://play.google.com/store/apps/details?id=com.ardent.westbank"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi17aej9X8JPDooJ0enqoReYXrz2rlt2PSoVchBB-mV0p9G_x549_LsDr4Eb447KlI5HHmqZz1uP_39S9xmsivKEGYSwq_3hyIfFGv3cFktF_KhvMdJ-qEpdH4v__KzvN3ZPfmV12Jwvuiz/s1600/435140425-play_logo.png" /></a><span id="goog_1150828521"></span><span id="goog_1150828522"></span><a href="http://www.blogger.com/"></a></div>
<span style="color: #b45f06; font-family: Arial, Helvetica, sans-serif; font-size: large;"><b><u><a href="https://play.google.com/store/apps/details?id=com.ardent.westbank">Instalar West Bank</a></u></b></span></div>
</div>
<br /></div>
<div>
Más información sobre el proyecto y su desarrollo <a href="http://apagayvuelveaencender.blogspot.com.es/2013/03/proyecto-west-bank-android.html"><b>aquí</b></a>.<br />
<br /></div>
Andréshttp://www.blogger.com/profile/06010147149377176406noreply@blogger.com0tag:blogger.com,1999:blog-6416070227303513915.post-70915800586094351362013-03-03T13:37:00.003+01:002013-03-03T13:37:53.586+01:00Proyecto: West Bank AndroidEn las últimas entradas, todas muy <b>retro</b>, he ido dejando pistas de que tenía un <b>proyecto</b> en marcha. Pues bien, hoy toca desvelarlo.<br />
<br />
Durante estos últimos meses he estado programando... ¡¡¡un <b>remake</b> del <b>WEST BANK</b> para <b>Android</b>!!!.<br />
<br />
<h2>
El juego original</h2>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwf3q-bJkjEMMBinDM7egNmvxZJ2KrXJxmog4vFkl3snrhkbzE77tTrQpAJ7HU-O9BnYGbKfOdb0RscBsnYMrAKoNaS3y6rvZ0C_bbc41Xg6tKIafW71CJjST4jTMf1sJ07MvbseixAuF0/s1600/West-Bank-002.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwf3q-bJkjEMMBinDM7egNmvxZJ2KrXJxmog4vFkl3snrhkbzE77tTrQpAJ7HU-O9BnYGbKfOdb0RscBsnYMrAKoNaS3y6rvZ0C_bbc41Xg6tKIafW71CJjST4jTMf1sJ07MvbseixAuF0/s400/West-Bank-002.jpg" width="290" /></a></div>
Corría el año 1986. La compañía española pionera por excelencia, <a href="http://es.wikipedia.org/wiki/Dinamic_Software"><b>Dinamic</b></a>, estaba empezando a expandirse. Los hermanos Ruiz habían decidido no publicar sólo sus propios juegos, sino promocionar también juegos programados por otras personas. Los tiempos eran muy distintos a los actuales. Triunfaban los ordenadores de 8 bits (que normalmente se usaban como el equivalente a las consolas actuales), como el <b>ZX Spectrum</b>, el <b>Amstrad</b> y el <b>Commodore</b>, pero no existía prácticamente una industria del videojuego en España para ellos. Los juegos los hacía, normalmente, <b>un adolescente en su casa</b>, él solo o con un grupete de amigos.<br />
<br />
Los hermanos Ruiz habían demostrado desde el principio una gran habilidad para publicitar sus juegos. Ese mismo año habían tomado la que probablemente fue su decisión más importante: encargar al gran <b>Alfonso Azpiri</b> que les hiciera las portadas. Gracias a esto, estoy seguro de que a mucha gente le sonará la estupenda portada del juego incluso aunque no llegara a jugarlo en su día. [Azpiri sigue en activo y en buena forma, actualmente y junto a Forges está publicando una original y divertida línea de adaptaciones al comic de libros de terror que os recomiendo, <a href="http://coliseodigital.com/?tag=horreibols-and-terrifics-books">Horreibols and terrifics books</a>].<br />
<br />
<a href="http://computeremuzone.com/ficha.php?id=500">Rocky</a> fue el primer juego cuya portada hizo Azpiri. Y a su vez, también fue el primer juego que publicó Dinamic hecho por un programador externo: <a href="http://escena.org/wiki/page/Fanzine__issue1__Alvaro_Mateos_Herrera/"><b>Álvaro Mateos</b></a>. Pocos meses después, programado por el mismo Álvaro y con portada del mismo Azpiri, aparecía el juego que nos ocupa: <a href="http://computeremuzone.com/ficha.php?id=69"><b>West Bank</b></a>.<br />
<br />
<div class="separator" style="clear: both; text-align: right;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiRMtfDiDu7cwxl-CGPB0KtoIYZz-m-YvUF9kjMmto5iFEhqEZiq8W8cU5MHWoN-aJOrA-nQTk7Zhe8-hm3Z7Z0MumZRRtsPbUOsxmXOGCgnEzpp8-1Q2iXM1jiSVUzV0zTZtDXwPMUXMy/s1600/bank-panic.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiRMtfDiDu7cwxl-CGPB0KtoIYZz-m-YvUF9kjMmto5iFEhqEZiq8W8cU5MHWoN-aJOrA-nQTk7Zhe8-hm3Z7Z0MumZRRtsPbUOsxmXOGCgnEzpp8-1Q2iXM1jiSVUzV0zTZtDXwPMUXMy/s200/bank-panic.png" width="200" /></a></div>
<div style="text-align: left;">
Al ser la programación tan artesanal, era bastante habitual que para inspirarse el programador se basara en una máquina recreativa (o directamente la copiara), ya que ellas sí que tenían una poderosa industria, con compañías grandes detrás como Sega y Nintendo. En este caso, el juego es un clon de la recreativa de Sega <b>Bank Panic</b>, aunque debo decir que las sensaciones al jugar uno y otro, dentro de sus parecidos, son bastante distintas. Además, el West Bank incorporaba cosas de su propia cosecha, como los duelos de final de fase.<br />
<br />
El juego (tanto la recreativa como el que nos ocupa) era <b>más simple que el mecanismo de un chupete</b>. En resumen, tienes tres puertas que se van abriendo, si el personaje que aparece detrás te apunta con una pistola le <b>disparas</b>, si no lo hace le dejas tranquilico y te dejará una bolsa con dinero. Cuando haya dinero en las 12 puertas del banco, se pasa a la siguiente fase. Es un juego que prácticamente ya estaba anticuado cuando salió en su día, no olvidemos que para entonces ya habían salido virguerías como el <a href="http://www.elmundodelspectrum.com/contenido.php?id=148&d=Knight-Lore-(1984)-Ultimate">Knight Lore</a>, el <a href="http://www.elmundodelspectrum.com/contenido.php?id=178&d=The-Great-Escape-(1986)-Ocean">Great Escape</a>, el <a href="http://www.elmundodelspectrum.com/contenido.php?id=587&d=Cobra-(1986)-Ocean-Software">Cobra</a>, el <a href="http://www.videoshock.es/criticas/2012/04/batman-spectrum/#more-30237">Batman</a> o el <a href="http://www.sincuser.f9.co.uk/047/3weeks.htm">Three Weeks in Paradise</a>, todos ellos infinitamente superiores técnicamente.<br />
<br />
¿Entonces?, ¿cuál es la gracia de esto?. Muy sencillo. A pesar de lo dicho antes, el juego triunfó porque... ¡¡¡es un <b>juego DIVERTIDÍSIMO</b>!!! </div>
<br />
<h2>
El equipo: Ardent Monkey Games</h2>
<div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkmO9YW807kd7hpBny2yWBEn_t-0O4DLKP9PJVJMytW1ua6b-UhTSnMEhLwpa5676loFD-9umXOSBfkRCMxCf-VrMDyRhIsyoFYuYXTP6HdDMt9E_NvxU7yS-5LmSS1ynEd0WHe6YWXvHN/s1600/ardent_medium2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkmO9YW807kd7hpBny2yWBEn_t-0O4DLKP9PJVJMytW1ua6b-UhTSnMEhLwpa5676loFD-9umXOSBfkRCMxCf-VrMDyRhIsyoFYuYXTP6HdDMt9E_NvxU7yS-5LmSS1ynEd0WHe6YWXvHN/s400/ardent_medium2.png" width="400" /></a></div>
Ahora damos un salto al presente, o sea, "ventimuchos" años después. Probablemente no conocéis a <b>Muriel</b> (<a href="https://twitter.com/jdmuriel">@jdmuriel</a>), pero creedme si os digo que si tuviera tiempo libre para hacer un 1% de las ideas que se le ocurren continuamente... el mundo se acabaría. Normalmente busca ideas para hacernos ricos, que yo siempre le chafo, pero un buen día se le ocurre otra cosa: "<b>¿Sabes qué juego estaría muy bien para móviles?</b>. El West Bank".<br />
<br />
No es una idea que vaya a hacer a nadie precisamente rico, pero hay algo que es indudable: es un juego <b>perfecto para interfaz táctil</b>. No tienes que hacer una conversión chunga con una de esas crucetas dentro del juego que tanto se están usando. Cuando quieras disparar a un tipo, le das con el dedo. Simple.<br />
<br />
Además, es un gran juego para partidas "<b>a ratos</b>". Para echar una partidilla mientras vas en el metro o esperas al pesado de tu amigo el tardón.<br />
<br />
Por otra parte, llevaba ya tiempo con ganas de hacer algo en <b>Android</b>. La programación para móviles, todavía aunque cada vez menos, es lo que siempre me hubiera gustado que existiera cuando era estudiante. No entiendo cómo a día de hoy los aspirantes a informáticos no hacen programas o juegos en Android. Con el tiempo que le dedicaba yo a alguna basurilla de esas que hacía con el BASIC del Spectrum cuando tenía 13 años, podría haber hecho perfectamente juegos en el móvil, y más aún, encima se moverían con suavidad y serían perfectamente jugables. Incluso se puede conseguir algo de dinerillo si te lo curras bien. Ni te digo ya en la universidad. En fin, todo esto ya lo expliqué en mi entrada de presentación del blog, <a href="http://apagayvuelveaencender.blogspot.com.es/2012/09/historias-del-abuelo-cebolleta.html">programar ahora es para nenazas</a>.<br />
<br />
El caso es que al final, a pesar de mis dudas por eso de que yo tampoco tengo casi tiempo libre, me convenció.<br />
<br />
Por último necesitábamos un <b>grafista</b>. Aunque inicialmente usaríamos los gráficos originales del Spectrum, la idea es que también hubiera otros gráficos nuevos. Y además necesitaríamos dibujos o diseños para otro tipo de cosas, como por ejemplo... el propio logo del equipo.<br />
<br />
Por suerte convencimos también a mi hermano, el gran <b>Adr</b>, que es un dibujante <b>acojonante</b>. Aquí por ejemplo podéis ver una serie de tiras cómicas que hizo hace tiempo (y que estaría bien que algún día continuara, la verdad): <a href="http://neotako.blogspot.com.es/search/label/ADR"><b>Operación Dragón</b></a>... bueno, va, os pongo aquí un par de ejemplos, que mola:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJOmd9XbuPxPzDkFq24_5dTyk2p7TsOxUguS6zVL9wo2iuecxJYYiu8Td0SMAk8naFVqLlKE67WZbik1LmRP_ReR_Ux9kfIjpK8MmPNHdJx2LOOI2P_xbgt_PVIuKLCmYJbHjqfDWoW2mf/s1600/odtira9.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="296" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJOmd9XbuPxPzDkFq24_5dTyk2p7TsOxUguS6zVL9wo2iuecxJYYiu8Td0SMAk8naFVqLlKE67WZbik1LmRP_ReR_Ux9kfIjpK8MmPNHdJx2LOOI2P_xbgt_PVIuKLCmYJbHjqfDWoW2mf/s640/odtira9.jpg" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwO9Q07XIIxLkbnTEe_Dd0VdLeMgRbap2lX60uGgzubdwxH8b4NIFJDDFkXTP2W5-opX7Qruzs7MF91zOfbWO5Hg1mymTnqAe2UVIWRbb2bN_Jj-L3nvtUPT79W3PMH4v8wuzLe_evrnOl/s1600/odtira14_p.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="262" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwO9Q07XIIxLkbnTEe_Dd0VdLeMgRbap2lX60uGgzubdwxH8b4NIFJDDFkXTP2W5-opX7Qruzs7MF91zOfbWO5Hg1mymTnqAe2UVIWRbb2bN_Jj-L3nvtUPT79W3PMH4v8wuzLe_evrnOl/s640/odtira14_p.jpg" width="640" /></a></div>
<br />
Así, el equipo estaba formado. Tras arduas deliberaciones, decidimos llamarnos <b>Ardent Monkey Games</b>.<br />
<br />
<br />
<h2>
El remake</h2>
<div>
Me complace anunciaros que el remake <b>ya está listo</b> y está disponible en el Google Play Store, <b>completamente gratis</b>.<br />
<br />
<div style="text-align: center;">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://play.google.com/store/apps/details?id=com.ardent.westbank"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi17aej9X8JPDooJ0enqoReYXrz2rlt2PSoVchBB-mV0p9G_x549_LsDr4Eb447KlI5HHmqZz1uP_39S9xmsivKEGYSwq_3hyIfFGv3cFktF_KhvMdJ-qEpdH4v__KzvN3ZPfmV12Jwvuiz/s1600/435140425-play_logo.png" /></a><span id="goog_1150828521"></span><span id="goog_1150828522"></span><a href="http://www.blogger.com/"></a></div>
<span style="color: #b45f06; font-family: Arial, Helvetica, sans-serif; font-size: large;"><b><u><a href="https://play.google.com/store/apps/details?id=com.ardent.westbank">Instalar West Bank</a></u></b></span></div>
</div>
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinRNXXafpCAatxtIFmNimBYREKjOo5himN4XEjvruu99z7U2apCd7d7kLgWEH9f1rpBD2iVR59ldPo6cfNX7AOBmvaj8CLUdF_SUcYk1ezxA7cZQSq7p16bxBTF5MY5Zs9Zygynf2FdJBV/s1600/x_background2.gif" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinRNXXafpCAatxtIFmNimBYREKjOo5himN4XEjvruu99z7U2apCd7d7kLgWEH9f1rpBD2iVR59ldPo6cfNX7AOBmvaj8CLUdF_SUcYk1ezxA7cZQSq7p16bxBTF5MY5Zs9Zygynf2FdJBV/s1600/x_background2.gif" /></a><br />
Los gráficos son estos que veis aquí al lado. ¿Ein?, diréis, ¡pero si esos son <b>los de Spectrum</b>!. Pues sí, la versión disponible actualmente es un calco del juego de Spectrum, con sus mismos gráficos y sonidos.<br />
<br />
Las diferencias son: el interfaz táctil, que la puedes jugar directamente con el móvil, y que tiene una <b>tabla de puntuaciones global</b> en un servidor, que comparten todos los jugadores, y con la cual <b>los piques están asegurados</b>. Ya sé que esto hace que el juego sea sobre todo apto para el mundillo retro, pero en poco tiempo saldrá otra versión en la que permitiremos seleccionar el "skin" original o la versión con los nuevos gráficos y sonidos, con lo que el juego será más atractivo para el gran público que no ha visto un Spectrum en su vida.<br />
<br />
En resumen, las similitudes con el caso del West Bank original son muchas... es una copia descarada de un juego anterior... lo han hecho unos chalaos en su casa (aunque ya no demasiado adolescentes [ejem])... y lo más importante de todo... ¡¡¡sigue siendo <b>DIVERTÍDISIMO</b>!!!<br />
<br />
<br />
P.D.: En pocos días os cuento más, que tenemos una sorpresita preparada para la <a href="http://retromadrid.org/">RetroMadrid</a> de la semana que viene...<br />
<br />
P.D. 2: Desde aquí, me gustaría también agradecer su amabilidad a Álvaro Mateos, ya que le comentamos nuestra idea de hacer un remake y nos dio sus bendiciones. ¡Álvaro, eres grande!<br />
<br /></div>
Andréshttp://www.blogger.com/profile/06010147149377176406noreply@blogger.com11tag:blogger.com,1999:blog-6416070227303513915.post-48891015702618617512013-02-08T09:00:00.000+01:002013-02-08T09:24:02.781+01:00Ready Player One: Retro-frikismo con anabolizantesYa lo avisé en mi última entrada: <b>me siento retro</b>.<br />
<br />
En esa ocasión, <a href="http://apagayvuelveaencender.blogspot.com.es/2013/01/como-convertir-tu-netbook-en-un-zx.html">creando mi propio ZX Spectrum "netbook edition"</a>, ya mostré no sólo mi gusto por lo retro, sino que soy un frikazo de narices. Últimamente, aprovechando que he tenido unos días de vacaciones, he estado alimentando un poco más estos sentimientos leyendo la novela que hoy nos ocupa, <b>Ready Player One</b>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKOjfVEMlnagVwwfYa_R2ih0vCVyEcUUkNjfMjwlwpT31cN4x39SQUIHhr9RDcXIqpnreLuUaBgG028vfbKJVIi4iom85uXbaobYcaP9ScMkW2CH9SLonSkcSF4Y-AKqWG5PlueudJ7Xu9/s1600/uno.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKOjfVEMlnagVwwfYa_R2ih0vCVyEcUUkNjfMjwlwpT31cN4x39SQUIHhr9RDcXIqpnreLuUaBgG028vfbKJVIi4iom85uXbaobYcaP9ScMkW2CH9SLonSkcSF4Y-AKqWG5PlueudJ7Xu9/s320/uno.jpg" width="206" /></a></div>
Nos situamos, aparentemente, dentro de unos treinta y pi años. La generación nacida en los 70, esos que vivimos intensamente la cultura ochentera, somos ya los ancianos. Entre ellos, James Halliday es el mayor prototipo de <b>frikazo</b> que te puedes encontrar: encerrado en su propio mundo desde pequeño, sin amigos, y un genio de la informática. Así, este tipo creó un sistema chulo de <b>realidad virtual</b> llamado Oasis, en el que te conectas con tus gafillas, tus guantes y, si tienes pasta, incluso un traje y una plataforma con los que sientes prácticamente todo lo que le ocurre a tu avatar del mundo virtual. El sistema fue tan bueno, que unido a una crisis energética galopante y a que el mundo está hecho una mierda, <b>la gente pasa más tiempo en el mundo virtual que en el real</b>.<br />
<br />
El caso es que el tipo va y se muere, y como tiene pasta hasta las orejas, pero no tiene ningún amigo ni familiar y como he dicho antes, vive en su propio mundo, se le ocurre... crear un <b>concurso</b> dentro de la realidad virtual, que comience con unos <b>acertijos</b>. El que descifre los tres acertijos y con ello consiga las tres llaves, podrá abrir las respectivas puertas y al hacerlo accederá a unos juegos. El primero que resuelva los acertijos y supere las consiguientes pruebas, heredará toda la fortuna del tal Halliday.<br />
<br />
Ahí es cuando aparecen un montón de jugadores, los gunters, intentando desesperadamente descifrar los acertijos. Como tanto los acertijos como los juegos se basan en todas las frikadas que le gustaban al tipo en cuestión, se estudian su vida y todo lo que a este hombre le gustaba. Uno de ellos es nuestro <b>protagonista</b>, el <b>segundo gran frikazo</b> que nos vamos a encontrar, Wade - Parzival.<br />
<br />
El libro es muy entretenido, tiene fundamentalmente <b>esquema de videojuego</b>, con los personajes continuamente pensando cómo resolver los retos. Pero a la vez no faltan unos <b>malos</b>, la pérfida empresa GSS y su cabeza visible Sorrento, que quiere ganar la pasta para hacer que Oasis sea de pago y no le importa hacer todo tipo de triquiñuelas para ganarla. Y hasta tiene una friki-historia de amor algo raruna y a la vez con poca chicha.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhntEgNWJajT4GFLYQ1qqy7cLAL5vP5rXPPMyM_odXFgYTWtrHzlYyixvkXe5Yy9iHfl61WNH1y1nsYodUwmoo-NCtSjPabtHGTFtlov5qW7sCrJnlwP6pbEOmxglagHvE5eyxyRg14FmgB/s1600/uno.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhntEgNWJajT4GFLYQ1qqy7cLAL5vP5rXPPMyM_odXFgYTWtrHzlYyixvkXe5Yy9iHfl61WNH1y1nsYodUwmoo-NCtSjPabtHGTFtlov5qW7sCrJnlwP6pbEOmxglagHvE5eyxyRg14FmgB/s320/uno.jpg" width="256" /></a></div>
Sin embargo, si algo caracteriza especialmente a este libro son las continuas referencias a todo tipo de frikadas. El caso es que muchas de ellas ni siquiera son a videojuegos, películas, etc. demasiado populares, así que... obviamente en realidad son las que le gustan al <b>tercer gran frikazo</b> que vamos a mencionar: Ernest Cline, el <b>autor del libro</b>. De forma que al final y sin darnos cuenta somos nosotros, los lectores, los que nos estamos empollando en las cosas que le gustan a este tipo. Pero sin heredar una fortuna. Para que os hagáis una idea del nivel al que puede llegar este hombre, ahí tenéis una foto suya ¡con su <b>DeLorean</b>! (el coche - máquina del tiempo de <a href="http://www.imdb.com/title/tt0088763/">Regreso al Futuro</a>, recordad). Y no sólo eso, sino que lo tiene trucado mezclando otros elementos de <a href="http://www.imdb.com/title/tt0083437">El coche fantástico</a> y <a href="http://www.imdb.com/title/tt0087332">Cazafantasmas</a>. No os perdáis <a href="http://www.ernestcline.com/ecto88/"><b>esta página</b></a>, donde hay todo tipo de <b>vídeos y fotos del invento</b>.<br />
<br />
Por si nos quedaba alguna duda de las similitudes entre Cline y el ricacho Halliday, basta con ver <a href="http://www.ernestcline.com/blog/2012/06/05/three-hidden-keys-open-three-secret-gates/">esta página</a> en la que el tipo explica que... ¡creó su propio concurso, en el mundo real!. Al parecer, <b>metió un huevo de pascua en el libro</b>. Tirando del hilo, averiguas los acertijos, consigues tres llaves, abres puertas superas videojuegos... es decir, la misma estructura que el juego del libro. Al final, el premio era... ¡su DeLorean!. Desgraciadamente, chicos, el concurso ya acabó. El <b>ganador</b> fue <a href="http://www.ernestcline.com/rp1contest/leaderboard-gate3/">este tipo</a>, que se convierte así en el <b>cuarto gran frikazo</b> de este artículo.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBANMgqqRlI1ln27efn7SHjouGDzRrp0e4TcgYvrg-2QnnynXYOA9qZHATtUCK_RolkC5nztYO4m1auUQntGzoCepAL0w8YKhHErvHtJZErpkxTDKndIWDpdgV6dwO3UHMW473yUDROMTH/s1600/uno.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="221" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBANMgqqRlI1ln27efn7SHjouGDzRrp0e4TcgYvrg-2QnnynXYOA9qZHATtUCK_RolkC5nztYO4m1auUQntGzoCepAL0w8YKhHErvHtJZErpkxTDKndIWDpdgV6dwO3UHMW473yUDROMTH/s320/uno.jpg" width="320" /></a></div>
<br />
Como decía antes, el libro está lleno de referencias a todo tipo de frikadas, todas ellas reales, es decir, han existido realmente. Algunas mencionadas sólo de pasada, pero muchas de ellas formando una parte muy importante del argumento. ¿De qué tipo?, pensaréis. Básicamente, ¡de todos!.<br />
<br />
Por supuesto, hay fundamentalmente muchas referencias a <b>videojuegos</b>. Sobre todo se centra en dos vertientes: juegos de la Atari 2600, y juegos arcade de las recreativas. Entre las recreativas, clásicos como Pacman junto a otras mucho menos conocidas (al menos por mi) como Joust (juego gracias al cual, por cierto, nuestro cuarto frikazo de aquí arriba ganó su DeLorean, al conseguir un record mundial histórico para poder acceder al premio). Pero en general, casi todos los videojuegos que se mencionan son muy, muy pero que muy antiguos, básicamente de los inicios de los videojuegos. Sólo unos pocos son unos añitos más modernos, como el Black Tiger. También se mencionan los orígenes de las <a href="http://es.wikipedia.org/wiki/Aventura_conversacional">aventuras conversacionales</a>, con juegos como Colossal Cave y Zork.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjY-fm8V6BbSUceDzRfVgZqufQ8yC_eKEkBOCSE3Q2Ke2baxSWBbZImZALTC-83kG5vh5sDc7oZw48uy2qi56K2zpAX1VcN3tQzz5RnihdpH2t-mN0EGy361GyHfk8I3kah5TvzPytnGbi6/s1600/uno.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="179" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjY-fm8V6BbSUceDzRfVgZqufQ8yC_eKEkBOCSE3Q2Ke2baxSWBbZImZALTC-83kG5vh5sDc7oZw48uy2qi56K2zpAX1VcN3tQzz5RnihdpH2t-mN0EGy361GyHfk8I3kah5TvzPytnGbi6/s200/uno.jpg" width="200" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiV-fZnswpQ85XTGx3X_Vr0rEIbGL7VNtFgmCeGufBD3MvzukyYK4O0ymXmJFdo7L77MHzemZRAeN5wpokykJnKEs-nSXYBui2u8qSEJ5ZErFQox9Ghg7ThWWCUWbVu6U39-t4KrcQaONSF/s1600/uno.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="160" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiV-fZnswpQ85XTGx3X_Vr0rEIbGL7VNtFgmCeGufBD3MvzukyYK4O0ymXmJFdo7L77MHzemZRAeN5wpokykJnKEs-nSXYBui2u8qSEJ5ZErFQox9Ghg7ThWWCUWbVu6U39-t4KrcQaONSF/s200/uno.png" width="200" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOjfBKJFTZUz_i5QzIYDADCQjvFjLTDmgXqGamN6RUe7JXLC5sKk_6pMiBFWbhMySUgd6Ng8max6StwMBWo72q1rjmPMdIbNFu9Yh6xAzMsgSa-S4RxrGThrKPzWEfV-sn2owY2kjR8T70/s1600/uno.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="150" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOjfBKJFTZUz_i5QzIYDADCQjvFjLTDmgXqGamN6RUe7JXLC5sKk_6pMiBFWbhMySUgd6Ng8max6StwMBWo72q1rjmPMdIbNFu9Yh6xAzMsgSa-S4RxrGThrKPzWEfV-sn2owY2kjR8T70/s200/uno.gif" width="200" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgw3XWwT3o26dxSaZSC4vneQjD1R7CTiKVo_tbpkBOcgR2wP0woX9xfAXW-rfI0Nbpp3BBc_8kdEFwz2vFLW9HhlLFI6GipLzndXL1vTzelj_gSPY7A9KVlJWXYYYkZYhIjL6woVEq5D4V0/s1600/uno.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="125" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgw3XWwT3o26dxSaZSC4vneQjD1R7CTiKVo_tbpkBOcgR2wP0woX9xfAXW-rfI0Nbpp3BBc_8kdEFwz2vFLW9HhlLFI6GipLzndXL1vTzelj_gSPY7A9KVlJWXYYYkZYhIjL6woVEq5D4V0/s200/uno.jpg" width="200" /></a> </div>
<br />
No pueden faltar tampoco referencias a <b>películas y series</b>, no tanto a las mejores pelis ochenteras, sino más bien a una obras con ciertos tintes frikis o geeks, como <a href="http://www.imdb.com/title/tt0084827">Tron</a>, <a href="http://www.imdb.com/title/tt0071853/">Los caballeros de la mesa cuadrada</a>, <a href="http://www.imdb.com/title/tt0086567/">Juegos de guerra</a> o <a href="http://www.imdb.com/title/tt0083658">Blade Runner</a>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjgaDDOL9ZBqbwfsYJzHSqywgDv6G_RZwMPFtsWrZHWL2TPqzOjjW1_Pg-oSp-N9Xj9jW8W-V04UDBCHtRk4C-FFMzo8CAkMxK402P0VCEpeNc8kLUyghtEjSNualnQ8Ie4XaLRtxCnyv3k/s1600/cuatro.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjgaDDOL9ZBqbwfsYJzHSqywgDv6G_RZwMPFtsWrZHWL2TPqzOjjW1_Pg-oSp-N9Xj9jW8W-V04UDBCHtRk4C-FFMzo8CAkMxK402P0VCEpeNc8kLUyghtEjSNualnQ8Ie4XaLRtxCnyv3k/s200/cuatro.jpg" width="113" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjO9A9VCqPu7rfFi8h57RDheDQNgttjbp81hvig4vBnGq9IQjHPjvwH42SWqIFD3IAQZ951CLWyLLj0cm2RX_NTnMt2ij7ZptzJf81L7LEVOfgtTIRjSSa7XNiZynmlFr511WApQBn6Jg2P/s1600/tres.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjO9A9VCqPu7rfFi8h57RDheDQNgttjbp81hvig4vBnGq9IQjHPjvwH42SWqIFD3IAQZ951CLWyLLj0cm2RX_NTnMt2ij7ZptzJf81L7LEVOfgtTIRjSSa7XNiZynmlFr511WApQBn6Jg2P/s200/tres.jpg" width="108" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjcbDalPebhoXDg7nhFSh2-4w4IvuDjifE5WpSpu6Fv7O9bBO0MHD8f6Yi7imRNMBW_uxW87O58f6zGa6VKQHG_kZNhKS6pY88RbUNblH5a5gmh6vVo8WLyF5IoJVa0UASy6FGnR8xIwRvu/s1600/uno.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjcbDalPebhoXDg7nhFSh2-4w4IvuDjifE5WpSpu6Fv7O9bBO0MHD8f6Yi7imRNMBW_uxW87O58f6zGa6VKQHG_kZNhKS6pY88RbUNblH5a5gmh6vVo8WLyF5IoJVa0UASy6FGnR8xIwRvu/s200/uno.jpg" width="133" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbWhyphenhyphenudZewlh0ieWjXVpHbA-3FshcZP0J8UKSBgFNYo6vNpfJERlf949-vAfOeLlVHAs32GVsMK-Jy5JkYP5gTFvUe2912UfKfsvcajWhznw_0OOGg9qYA5CiJVP0DRvZGsxZS9XA-2ODx/s1600/dos.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbWhyphenhyphenudZewlh0ieWjXVpHbA-3FshcZP0J8UKSBgFNYo6vNpfJERlf949-vAfOeLlVHAs32GVsMK-Jy5JkYP5gTFvUe2912UfKfsvcajWhznw_0OOGg9qYA5CiJVP0DRvZGsxZS9XA-2ODx/s200/dos.jpg" width="130" /></a></div>
<br />
Por otra parte tenemos referencias a <b>juegos de rol</b>, principalmente a Dragones y Mazmorras.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilrvuOuTbquPUZBg5ynPJmcXKh-ZQiYsK4BtCoKg3QdDgYyiNslfIwXguzjnvW96ok5BkJoIqN7TclzXXAfRZCKtB9WVP2_IVw_vKX-BwNj-zJTnCIVSL7HXn2pX9MjxtXAG8UvZRkenVN/s1600/uno.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilrvuOuTbquPUZBg5ynPJmcXKh-ZQiYsK4BtCoKg3QdDgYyiNslfIwXguzjnvW96ok5BkJoIqN7TclzXXAfRZCKtB9WVP2_IVw_vKX-BwNj-zJTnCIVSL7HXn2pX9MjxtXAG8UvZRkenVN/s200/uno.jpg" width="146" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFY7EdO_RWT1IvaPt22zdNu42z6khR90ZpCdJCQ-3eQRrY2mrB9hhdgIr4w87VCkN35SNG_juks0E19Capj2yom5rEEOQ4Z5drKFHIvTzFkDZlwSqiscQGSIFE0BlDMh8KxV-lWkTCkodv/s1600/uno.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="128" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFY7EdO_RWT1IvaPt22zdNu42z6khR90ZpCdJCQ-3eQRrY2mrB9hhdgIr4w87VCkN35SNG_juks0E19Capj2yom5rEEOQ4Z5drKFHIvTzFkDZlwSqiscQGSIFE0BlDMh8KxV-lWkTCkodv/s200/uno.jpg" width="200" /></a></div>
<br />
Y si lo que te gustan son los <b>grandes robots</b>, ahí nos sobramos: los tienes prácticamente todos, con intervenciones especiales de algunos como MechaGodzilla, Leopardon o Voltron. Y puestos a poner un personaje de Mazinger-Z, para qué vamos a poner uno conocido... ¡que sea una Mazinger travestida que no conoce ni su padre! (Minerva-X).<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhk216FSGWyiLMOiYPGMJfBMVWwQq8F1tqs697x9WkJqkHNxPUT3Ok7DroGxEPFeum0QvBFut6j41cPrE6luLKSDmnfQOhiq_t8CT_gZ5RAkp2FC54Q4ara_dfVQsnnwjJLyfE_o7odBVha/s1600/dos.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhk216FSGWyiLMOiYPGMJfBMVWwQq8F1tqs697x9WkJqkHNxPUT3Ok7DroGxEPFeum0QvBFut6j41cPrE6luLKSDmnfQOhiq_t8CT_gZ5RAkp2FC54Q4ara_dfVQsnnwjJLyfE_o7odBVha/s200/dos.jpg" width="120" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjm6oIK10olvuZ7Va1fodnAPH2HhsTa7DROnQmUbe1kpGvEqR62yzhoeHk_14rU5zlBz0WGtzNDI_kz_Cb40E5f2vJSRb1xKFCx7BvfOBzJkcoUZ6qBOdzu1RBA6RMZ7AuDksPJHXbBPZ4H/s1600/minerva-x.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjm6oIK10olvuZ7Va1fodnAPH2HhsTa7DROnQmUbe1kpGvEqR62yzhoeHk_14rU5zlBz0WGtzNDI_kz_Cb40E5f2vJSRb1xKFCx7BvfOBzJkcoUZ6qBOdzu1RBA6RMZ7AuDksPJHXbBPZ4H/s200/minerva-x.jpg" width="88" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgC1jfq1IPrkkn3QiUxENytzN7h5We2cy0b8aP8xV6bGKHb3GIw04G_1tsbUxsFBpNGYUFokhSVHCSBfg3BhN1BPEHnRQI0OMO52XLiiGVmoavInbrneNigGQLYErMGWhOBVbQ0A09VVm5y/s1600/tres.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgC1jfq1IPrkkn3QiUxENytzN7h5We2cy0b8aP8xV6bGKHb3GIw04G_1tsbUxsFBpNGYUFokhSVHCSBfg3BhN1BPEHnRQI0OMO52XLiiGVmoavInbrneNigGQLYErMGWhOBVbQ0A09VVm5y/s200/tres.jpg" width="128" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBWjwCyKjaJaRvCODXugztPjK1O-LCdi7Sc5GQHCsDpUVXsI19nM1VpS1wZmgGWiq5tBTo8OiC8HqTTHs20ZoadYJgsKcgr0JHx9njnlIKhTqvm3a_JYFsO6tmF_4TxzBuaAqp-IqlTpqi/s1600/uno.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBWjwCyKjaJaRvCODXugztPjK1O-LCdi7Sc5GQHCsDpUVXsI19nM1VpS1wZmgGWiq5tBTo8OiC8HqTTHs20ZoadYJgsKcgr0JHx9njnlIKhTqvm3a_JYFsO6tmF_4TxzBuaAqp-IqlTpqi/s200/uno.jpg" width="163" /></a></div>
<br />
¿Música?. También. Alguna más conocida, sobre todo bailable, como Wham o Billy Idol, con otra más raruna y... aparentemente frikuna, como el grupo Rush.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj32JnPSXUTKNe5aSAUxpSNJSiuQEsglpIDBFK_12uEdwRggf0OgAcEDAzjf4ZMK7VHn0bjyMclslNrjOA1oyb-uT986QntqVQ9S1fZGQ-o9RMDnPXqdY8GQXBZG14h6R2sroV65I4mY1Ha/s1600/dos.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj32JnPSXUTKNe5aSAUxpSNJSiuQEsglpIDBFK_12uEdwRggf0OgAcEDAzjf4ZMK7VHn0bjyMclslNrjOA1oyb-uT986QntqVQ9S1fZGQ-o9RMDnPXqdY8GQXBZG14h6R2sroV65I4mY1Ha/s200/dos.jpg" width="143" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOGffjXY5ShLoo11runf0oXx2rU0BARu2rG1JpdbzugdEtpHxceGX-vVQ_acAWvajciMos6Iv4MhZsRuw3LN9hv-gpuKLhxJFUPQugi5wCpo2WcQLmF0RVHIfemZAIqXKKM9EcogzmnjR6/s1600/tres.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOGffjXY5ShLoo11runf0oXx2rU0BARu2rG1JpdbzugdEtpHxceGX-vVQ_acAWvajciMos6Iv4MhZsRuw3LN9hv-gpuKLhxJFUPQugi5wCpo2WcQLmF0RVHIfemZAIqXKKM9EcogzmnjR6/s200/tres.jpg" width="200" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvVQyQNO3_bC_miW9UcRc2F6k4b5UF-LFBOKnBh2o-H0c1rOQmHiwDVigIYeAZ_5LixQuV-gKHVLaUEpatdQJC18mXLT85rJ0udELP81xk1ZE32Uqwtla7pngnjpBhFlRgArvudcRUxnb7/s1600/uno.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="150" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvVQyQNO3_bC_miW9UcRc2F6k4b5UF-LFBOKnBh2o-H0c1rOQmHiwDVigIYeAZ_5LixQuV-gKHVLaUEpatdQJC18mXLT85rJ0udELP81xk1ZE32Uqwtla7pngnjpBhFlRgArvudcRUxnb7/s200/uno.jpg" width="200" /></a></div>
<br />
Y más, más referencias de todo tipo, sin parar: comics, libros... ¡cereales!...<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVpS27O14bang4KjlCbr4PVzA7bv_NzxM_FE69JKGGCck9g5x_yeuRzXlO1-bzwvE77IU_Iy7D4C5M554kH8Rc7XYRc_Jvfbc2qCNUR2u1du9nm8kag3g8b2mm9JezBNdxiF5Z57Y2voWc/s1600/dos.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVpS27O14bang4KjlCbr4PVzA7bv_NzxM_FE69JKGGCck9g5x_yeuRzXlO1-bzwvE77IU_Iy7D4C5M554kH8Rc7XYRc_Jvfbc2qCNUR2u1du9nm8kag3g8b2mm9JezBNdxiF5Z57Y2voWc/s200/dos.jpg" width="128" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJL9EgKBGjagLxEFWcDLzJuBz4xbiGeUJszZS46xtG5g-wEzxDtiWr2yDnYhLbVJXONbtIqWVoN0VFuHwdoZNCQnNxkirrzO-dVANK1sVKx_Y0M5ZrE7sgvW6lARrpQftsNW-5cYN9Rm78/s1600/uno.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJL9EgKBGjagLxEFWcDLzJuBz4xbiGeUJszZS46xtG5g-wEzxDtiWr2yDnYhLbVJXONbtIqWVoN0VFuHwdoZNCQnNxkirrzO-dVANK1sVKx_Y0M5ZrE7sgvW6lARrpQftsNW-5cYN9Rm78/s200/uno.jpg" width="156" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDHaV_M2BipaMNN6egBJq2iVmtHfVx4R5f6I-vdcjP2rqJ8Bq2M4vjgHPpmoWUTB9YL-rxHe5B_unriUwMW57NMWjKGV_UcdmEolJi4JxKI5DUyEeyDjdbV-Lp1Ull7IlghY7v4ZsF1Gvq/s1600/tres.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="130" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDHaV_M2BipaMNN6egBJq2iVmtHfVx4R5f6I-vdcjP2rqJ8Bq2M4vjgHPpmoWUTB9YL-rxHe5B_unriUwMW57NMWjKGV_UcdmEolJi4JxKI5DUyEeyDjdbV-Lp1Ull7IlghY7v4ZsF1Gvq/s200/tres.jpg" width="200" /></a></div>
<br />
En definitiva, un libro muy entretenido para cualquiera, que se lee en un suspiro... pero sobre todo, ¡<b>un libro imprescindible para todo buen friki</b>!. Especialmente frikis nacidos a principios de los 70, claro. De hecho el autor me saca un par de añitos y sólo eso la verdad es que ya se nota.<br />
<br />
Una vez acabado el libro, recomiendo hacer lo que acabo de hacer yo con este artículo: buscar las referencias que no hayamos reconocido (algunas de ellas realmente no llegaron a ser nada conocidas en España, así que dudo mucho que nadie español las reconozca todas), y ver de qué se trataba exactamente. Aunque, bueno, con este artículo ya os lo he puesto un poco más fácil (y eso que no he enlazado todo).<br />
<br />
Diablos, ¡realmente lo he disfrutado!... ups, estoy pensando... estoooo... ¡¡¡¿me convierte eso en... el <b>quinto gran frikazo</b> de este artículo?!!!...<br />
<br />
<br />
P.D.: Mi fiebre retro-friki se pasará en algún momento. Dadme tiempo... al menos hasta que pase la inminente <a href="http://retromadrid.org/">RetroMadrid</a>, para la que estoy preparando algo ;-)<br />
<br />Andréshttp://www.blogger.com/profile/06010147149377176406noreply@blogger.com0tag:blogger.com,1999:blog-6416070227303513915.post-82718491560011685272013-01-15T02:56:00.002+01:002013-01-15T03:06:23.806+01:00Cómo convertir tu netbook... ¡en un ZX Spectrum!<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhkYSjdgIhLCJTGlj0M91UMMkjdlPwPzuISrkyVKT4hlZau5rnYaYq1Cl6p24R8EW-YAHpb48X54vEE0FY_tzobhi0svsDUdAUybqFJwwrHrsOS4doqBT2uC5Rk75LKacn30AY9rusI8JuJ/s1600/eeepc-701w.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="150" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhkYSjdgIhLCJTGlj0M91UMMkjdlPwPzuISrkyVKT4hlZau5rnYaYq1Cl6p24R8EW-YAHpb48X54vEE0FY_tzobhi0svsDUdAUybqFJwwrHrsOS4doqBT2uC5Rk75LKacn30AY9rusI8JuJ/s200/eeepc-701w.jpg" width="200" /></a></div>
El <b>netbook</b>, ese mini-ordenadorcillo que te compraste hace unos años para navegar por Internet y pedaleos varios mientras estabas en el sofá. Y que ha quedado triste y anticuado desde que compraste tu flamante <b>tablet</b>, la herramienta ideal para el pedaleo y cuyo hábitat natural es el sofá, la cama y hasta el cuarto de baño (sí, yo también soy de esos).<br />
<br />
¿Se le puede dar algún uso ahora?. Bueno, los cacharrillos pequeños siempre han tenido una ventaja, la obvia: no ocupan mucho espacio. Siempre se puede hacer alguna tontería con ellos. Si no que se lo digan a la <a href="http://www.raspberrypi.org/">Raspberry Pi</a>, que se está poniendo de moda precisamente por eso, por todas las posibilidades que te da para hacer chorradillas con ella. Pero bueno, ya habrá tiempo de hablar de la Pi, que cualquier día de estos me la compro aunque sólo sea para ver si me decido a comprar la maravilla del frikeo que es el espectacular mini-arcade llamado <a href="http://www.kickstarter.com/projects/pimoroni/picade-the-arcade-cabinet-kit-for-your-raspberry-p" style="font-weight: bold;">Picade</a> (lo descubrí hace unos días y todavía babeo).<br />
<br />
Y es que últimamente me siento bastante <b>retro</b>. Ese sentimiento más bien absurdillo que imagino que surge sobre todo por la nostalgia. Llevo unas semanas leyendo el libro <a href="http://www.ochoquilates.com/">Ocho quilates</a>, y reconozco que eso está levantando mi espíritu retro, aunque más que por el de los arcades, por el del ZX Spectrum. Al fin y al cabo ya habéis visto anteriormente que <a href="http://apagayvuelveaencender.blogspot.com.es/2012/09/historias-del-abuelo-cebolleta.html">soy muy fan del Spectrum</a>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5WS9utSVTu_RQ1xReA1Ob_SOfRWFU6XYENkz7Pu6SI5asouQEK4kr7-kph_ml10bZ_ZysRqPMDDBSC4RslXL7OwoGshxWKEGgLH8Swz42OabKBEnsX7cY6eQGzxvmw5dg33a6VYBkMwDv/s1600/ZX+Spectrum.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="125" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5WS9utSVTu_RQ1xReA1Ob_SOfRWFU6XYENkz7Pu6SI5asouQEK4kr7-kph_ml10bZ_ZysRqPMDDBSC4RslXL7OwoGshxWKEGgLH8Swz42OabKBEnsX7cY6eQGzxvmw5dg33a6VYBkMwDv/s200/ZX+Spectrum.jpg" width="200" /></a></div>
Mientras me decido por la Picade, que al fin y al cabo cuesta una pasta... ¿por qué no satisfacer mis necesidades más retro con algo que esté más al alcance?. ¿Por qué no darle un uso a ese netbook que está empezando a ser pasto de las telas de araña?. Reservando los arcade de recreativas para el Picade (yum!), ¿por qué no... <b>convertir el netbook en un ZX Spectrum</b>?. Al fin y al cabo, el Spectrum tenía un teclado, como el netbook. El tamaño de la pantalla es genial para el Spectrum. El tamaño del cacharrillo en sí es hasta parecido. Y qué leche, aunque ahora ya no deja de ser más que un caprichín tonto que jamás usaré, ¡en su día era un sueño tener un Spectrum de bolsillo con el que pudiera cargar los juegos sin tener que pegarme con el cassete!.<br />
<br />
Manos a la obra. Mi netbook es un <a href="http://en.wikipedia.org/wiki/Asus_Eee_PC#Eee_700_series">Asus eeePc 701</a>. Me gustaría que tuviera un arranque dual, porque todavía me sigue viniendo bien para tomar notas en reuniones o presentaciones con el OpenOffice, para eso la verdad es que es genial, que se quiten todos los tablets. Y para que sea un Spectrum, necesito que arranque directamente como Spectrum y en pantalla completa. Así que necesito un nuevo sistema operativo, que sea ligero, que arranque lo más rápido posible y que tenga un emulador de Spectrum. Y que tenga drivers para el cacharrín. Una distribución Linux ligera, vaya.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDP8FiQf-Sh5H-YUWEJaEriKgi5CWTqgCJUv9f6aa98-3G0GbaXTb-fCdcmoMkPuAKr8MJd4UnBBGRBNFQXgAxez-i8-B-JXPeGkjna9eFKf8XIzLGaH_0Pso3La-hOrLmnU96BE-7R-vd/s1600/puppy_logo.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDP8FiQf-Sh5H-YUWEJaEriKgi5CWTqgCJUv9f6aa98-3G0GbaXTb-fCdcmoMkPuAKr8MJd4UnBBGRBNFQXgAxez-i8-B-JXPeGkjna9eFKf8XIzLGaH_0Pso3La-hOrLmnU96BE-7R-vd/s1600/puppy_logo.png" /></a></div>
Buscando por ahí encuentro que una de las distribuciones ligeras de las que más y mejor se habla es <a href="http://puppylinux.org/">Puppy</a>. Y mejor aún que eso: descubro que existe una distribución derivada llamada <b><a href="http://scottjarvis.com/page105.htm">Puppy Arcade</a></b>, que tiene incluidos emuladores para todos los cacharrillos imaginables, ¡incluyendo el Spectrum!. Y además se puede instalar directamente en un Pen Drive.<br />
<br />
Primero me lío un poco descargándome otra distribución similar que hay que es <a href="http://scottjarvis.com/page101.htm">Puppee Arcade</a>, que en teoría está adaptada a los eeePC. Pero veo que está anticuada y tiene muchos enlaces rotos. No perdáis el tiempo con ella, no creo que merezca la pena.<br />
<br />
Así que me bajo la ISO de Puppy Arcade y sigo las <a href="http://www.pendrivelinux.com/install-puppy-arcade-to-a-flash-drive-from-windows/">instrucciones</a> para instalarlo en el pen drive. Primer problema: que arranque con el USB. Me meto en la BIOS del eeePC (F2 al arrancar), cambio el orden de boot de los discos. Ojo, está en Boot -> Hard disk drives, me llevó un rato de probatinas darme cuenta.<br />
<br />
Segundo problema: al arrancar, la pantalla sale "fea". Y peor que eso, cualquier ventana que se intente abrir no aparece. Ir a Menu -> Shutdown -> Exit to prompt y te lleva a un terminal. Si lees el texto que te pone, te sugiere que si hay problemas con el vídeo ejecutes "xorgwizard". Lo ejecutas y ves que puedes elegir entre modo Xvesa, que es el que hay seleccionado, y modo Xorg. Selecciona este último, sigue las instrucciones y haz la prueba. Al acabar, ejecuta "startx". Et voilá!<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdR43NA68GdlffF1hVCsEwb3KmAEAV7JpB7nK4jtvT2aaIZixe3ShF5bfdqeMtXC6ULbGD6OaOxFVyrzpgOiCEOGNkDLZeZdDaHNkxtm9NlK-orXYZnaFUpKT8XLwZsb56WN7k3K5l67JJ/s1600/phpThumb_generated_thumbnailjpg.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdR43NA68GdlffF1hVCsEwb3KmAEAV7JpB7nK4jtvT2aaIZixe3ShF5bfdqeMtXC6ULbGD6OaOxFVyrzpgOiCEOGNkDLZeZdDaHNkxtm9NlK-orXYZnaFUpKT8XLwZsb56WN7k3K5l67JJ/s640/phpThumb_generated_thumbnailjpg.gif" width="640" /></a></div>
<br />
Tercer problema: Copio algunos juegos de Spectrum y pruebo el emulador de Spectrum, y... ¿qué es esto?... ¿¿¿no tiene modo de <b>pantalla completa</b>???. La verdad es que no me gusta un pelo el emulador. Aparte de eso, la aplicación que tiene para navegar por los juegos de los distintos sistemas de forma cómoda, tampoco es compatible con el Spectrum. Tanto cogerse una distribución especializada para esto...<br />
<br />
En este momento me temía lo peor. Al fin y al cabo, haciendo memoria recordé que no había visto jamás un emulador de Spectrum en Linux con pantalla completa. Y esta distribución no parece que admita ni ficheros deb ni rpm. Buscando un poco, encuentro que sí que existe un emulador con pantalla completa: <b><a href="http://www.rastersoft.com/fbzx.html">FBZX</a></b>. Lo pruebo en Ubuntu y parece que funciona realmente bien. Por supuesto, nada de distribuciones "pet", que es el formato que usa Puppy. Buscando un poco encuentro que sí que existe un .pet para FBZX, <a href="http://www.murga-linux.com/puppy/viewtopic.php?p=346080">aquí</a>, versión 2.1 aunque ya se va por la 2.10... pero es lo que hay.<br />
<br />
Cuarto problema: Lo instalo y no funciona. Bueno, dice que instales primero el paquete que hay encima, iNES-3.6, porque si no le faltará la librería glibc2.7. Lo instalo. Nada, mismo error.<br />
<br />
Mi piel empieza a cambiar de color un poco más. Una vez he pasado por suficientes tonalidades de violeta como para poder respirar, me decido a buscar la librería. Encuento la versión 2.10.1 <a href="http://www.murga-linux.com/puppy/viewtopic.php?p=408526&sid=a9cc18ceada6d837b42ef6f0ccb3f4b6">aquí</a>. La instalo y... ¡<b>funciona</b>!.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJBZ_2hnqlknWEkuPUtFKWO0gUUdCUxjCbxfQEh6e-DcKg32c1gStydSfEJsCR0eTaxsiuKIeykXK2cD-lnRGhgqDgPqN7EkBgaIvqn7XA3jU_k7ZHhLs1TKh2RBaISLijB6BnKVFmC3_0/s1600/zx2.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="298" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJBZ_2hnqlknWEkuPUtFKWO0gUUdCUxjCbxfQEh6e-DcKg32c1gStydSfEJsCR0eTaxsiuKIeykXK2cD-lnRGhgqDgPqN7EkBgaIvqn7XA3jU_k7ZHhLs1TKh2RBaISLijB6BnKVFmC3_0/s400/zx2.gif" width="400" /></a></div>
<br />
Quinto tema: en mi caso, prefiero instalarlo directamente en el disco duro. Voy a Apps -> Quick start y pulso "<b>Install to HD</b>". La verdad es que esperaba que arrancara más rápido, pero no se nota la diferencia, arranca igual de rápido desde el Pen Drive y desde disco, unos 30-40 segundos. Me decepcionó un poco, la verdad es que esperaba conseguir un arranque más rápido. Pero ya eran las ¡¡¡tantas!!! de la mañana y me había decidido a solucionarlo todo esa misma noche (y lo que ya no era noche).<br />
<br />
Sexto tema: sólo queda un detalle más, hacer que nada más arrancar se vaya al emulador de Spectrum, y que arranque directamente en pantalla completa. Voy a Apps -> Browse Files, me meto en el directorio <b>Startup</b>, y creo un script "fbzx_exec", con este contenido:<br />
<br />
<span style="font-family: Courier New, Courier, monospace;">#!/bin/sh</span><br />
<span style="font-family: Courier New, Courier, monospace;">fbzx -fs</span><br />
<br />
<br />
En fin, seguramente se podría haber hecho mejor. Seguramente haya algún Linux que arranque más rápido, y que sea capaz de tener una versión más nueva del FBZX. Pero por mi parte ahí se queda el tema.<br />
<br />
Así que ya está, querido lector: ¡<b>ya tienes tu ZX Spectrum de bolsillo</b>!. ¡Ya puedes convertirte en el alma de las fiestas y ligarte a las nenas!. Bueno, o por lo menos ya puedes recordar los tiempos en los que mientras esperabas 10 minutos a que se cargara un juego, mientras lo conectabas a la tele y al cassete y lo llenabas todo de cables, fantaseabas... con tener un Spectrum autónomo de bolsillo como este. El Andrés de los años 80 ha cumplido un sueño.<br />
<br />
Bueno, ¿y ahora qué puedo cargar?...<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBFzN08nFRw6y6onHmyTKPC9hyphenhyphen1ZUgCLfka1IFwJQuM1eTYHgWRhP8MzEddTgAGVVy8tEWVZP4EMsGG6cXPdIQTegZgKNiL1wtru-2hyphenhyphen-qAMEALParf60Rc53s1NwhVALPD6mAI2Od4ukj/s1600/spectrum-xp.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="255" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBFzN08nFRw6y6onHmyTKPC9hyphenhyphen1ZUgCLfka1IFwJQuM1eTYHgWRhP8MzEddTgAGVVy8tEWVZP4EMsGG6cXPdIQTegZgKNiL1wtru-2hyphenhyphen-qAMEALParf60Rc53s1NwhVALPD6mAI2Od4ukj/s400/spectrum-xp.png" width="400" /></a></div>
<br />
<br />
P.D. 1: ¿Os he dicho que al instalar todo esto se me jodió el sistema operativo principal, el Xandros, y ahora no consigo entrar con mi usuario?... bah, ¡tengo un Spectrum!, ¿a quién le importa tan nimio detalle?...<br />
<br />
<br />
P.D. 2: Ya que estamos con lo retro y el Spectrum, me queda en el tintero hablar de un proyecto que estoy desarrollando últimamente... ¡en poco tiempo en este su blog!<br />
<div>
<br /></div>
Andréshttp://www.blogger.com/profile/06010147149377176406noreply@blogger.com2tag:blogger.com,1999:blog-6416070227303513915.post-56695917609195386412012-12-31T20:43:00.000+01:002012-12-31T20:49:18.526+01:00Para el 2013, no lo dudes... ¡Apaga y vuelve a encender!Llega un nuevo año y quien más quien menos, casi todos caemos en la tentación de hacer un repaso mental del año y hacer nuestros propósitos para el siguiente. Que luego llevemos a cabo alguno de esos propósitos es harina de otro costal, claro...<br />
<br />
Por mi parte no tengo grandes propósitos, nunca he sido muy amigo de hacerlos. En cuanto a mis inquietudes informáticas, intentar aprender algo de Android, llevar a cabo algún proyecto de los que tengo en mente o a medias (que los tengo, seguro que alguno acabo haciéndolo), mirar mejor alguna de las tecnologías que están saliendo en cuanto a desarrollo web puro, como LESS-SASS ó Bootstrap, quizá mirar un poco Scala y otros lenguajes funcionales que ahora parece que se están poniendo de moda, quizá algo de BDD... ¡yo qué sé!. Sobre todo, seguir con este blog, en el que hable de lo que he dicho antes unido a otros intereses como buenas prácticas de software y mi gran pasión en esto del desarrollo, que hasta ahora no estoy sacando mucho, la reutilización.<br />
<br />
Para los demás, desde este blog tengo un mensaje ineludible. Si estás triste, desprecias a los políticos del mundo (bueno, eso lo hacemos todos), la crisis te tiene agobiado o peor aún, estás en paro y no te sientes útil, o si no consigues que te salga nada de lo que intentas, o si estás harto de la saga Crepúsculo, o si sientes que este mundo no es para ti... en definitiva, si tu vida no es tal como te gustaría y el rumbo no parece muy claro, la solución universal a todos los males del mundo está clara, atrévete... ¡¡¡<b>apaga y vuelve a encender</b>!!!.<br />
<br />
Verás lo saludable que puede resultar.<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8-ZPGbmmi69pF1JlSIJB5spMDoxnfanQ4Ko6FW2tgqF0Osfb1p-ITD6WoLwtWhFbVoN_wp9D09WxtvCDUdcJKvmLev-RjYCkPIfgAOqblDOwj0puJgh81sqo8jyB8ea33JSrba8qNk_pD/s1600/world-in-black-and-white-hands-FIN.jpg.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8-ZPGbmmi69pF1JlSIJB5spMDoxnfanQ4Ko6FW2tgqF0Osfb1p-ITD6WoLwtWhFbVoN_wp9D09WxtvCDUdcJKvmLev-RjYCkPIfgAOqblDOwj0puJgh81sqo8jyB8ea33JSrba8qNk_pD/s640/world-in-black-and-white-hands-FIN.jpg.png" width="640" /></a></div>
<br />
¡¡¡FELIZ 2013 A TODOS!!!<br />
<br />Andréshttp://www.blogger.com/profile/06010147149377176406noreply@blogger.com0tag:blogger.com,1999:blog-6416070227303513915.post-62466260840479303482012-11-29T03:50:00.000+01:002013-01-15T03:07:03.424+01:00Maven. Te quiero. Te odioQuerida... amada <b><a href="http://maven.apache.org/">Maven</a></b>:<br />
<br />
Ya sabes que nuestra relación ha sido siempre muy complicada. Hemos tenido que pasar por mil y una <b>dificultades</b>, hemos tenido que sortear cientos de obstáculos y aunque siempre parecía que lo nuestro no funcionaba, una y otra vez conseguíamos encontrar esa <b>solución mágica</b> que nos hacía superarlo.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhN8EibrPIDy-3Aa079qnvUdWxMS2EdAF1YaqeN6hch0ksOR_oUgzFcxBdJHXSxOOgW0xC19W6GrVp7no1uaOuPLRKI1RvWV9znhFXIraBcFsaaCoYx5IwInrPm0W9xix3s_yCLM_DFkY0b/s1600/celos2.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="290" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhN8EibrPIDy-3Aa079qnvUdWxMS2EdAF1YaqeN6hch0ksOR_oUgzFcxBdJHXSxOOgW0xC19W6GrVp7no1uaOuPLRKI1RvWV9znhFXIraBcFsaaCoYx5IwInrPm0W9xix3s_yCLM_DFkY0b/s320/celos2.jpg" width="320" /></a></div>
En cuanto te conocí me di cuenta al instante de que recogías muchas de las virtudes que llevaba tanto tiempo buscando. Me volvía loco tu <b>repositorio</b> y tu gestión de las <b>dependencias</b>, con ese toque de transitividad que sabías darle, como nadie había sabido hacer hasta ese momento. Y eso a pesar de que la inseguridad que conlleva la primera vez te llevaba a menudo a <b>no dejar claras tus prioridades</b>. Pasaron años hasta que fuiste capaz de organizarte para que no quedara nunca la duda sobre qué versión elegir. Sólo esto ya era suficiente para estar contigo. Todavía hoy no he visto nunca otra que te haga sombra en esto, como mucho algunas lo que hacen es copiarte sin siquiera querer ocultarlo. No sólo eso, desde el principio me aportaste algo más que necesitaba mucho en ese momento, como es la posibilidad de <b>orquestar varios proyectos</b> y tener una gestión clara de la creación y <b>gestión de sus versiones</b>. Y también facilitabas e integrabas muy bien la <b>ejecución de las pruebas unitarias</b>.<br />
<br />
No todo fue bonito, ni mucho menos. Siempre te gustó jugar conmigo, siempre te gustó <b>ponérmelo difícil</b>. Cada vez que se me ocurría proponer algún plan que se saliera de a lo que estabas acostumbrada en cuanto a la <b>construcción de los paquetes y componentes</b>, tú te ponías nerviosa y colocabas barreras para que conseguirlo fuera un suplicio. Algo que parecía muy sencillo se convertía en complicado, y a menudo tenía que buscar cómo engañarte para que te acabara gustando lo que te proponía.<br />
<br />
A esto contribuía mucho la <b>falta de comunicación</b> que teníamos. Nunca me decías cómo te sentías realmente, te ponías misteriosa y no me ayudabas a sacar las cosas adelante. Muchas veces me contabas <b>verdades a medias</b> sobre tus <b>plugins</b>, o me dabas <b>información anticuada</b> que había cambiado lo suficiente como para que ya no me valiera, y a menudo tenía que explorar en lo más profundo de tu ser, llegando hasta el mismísimo código fuente, para descubrir lo que te ocurría realmente.<br />
<br />
Parte de la culpa de todo esto la tiene seguramente mi ex-novia, <b><a href="http://ant.apache.org/">Ant</a></b>, que no tenía ninguna de tus mejores virtudes pero que si brillaba en algo era precisamente en la <b>construcción personalizada</b> de los componentes. Tú siempre has valorado más la <b>construcción estandarizada</b>, y no te lo reprocho, pero no creo que lo uno tenga por qué interferir con lo otro. De hecho mi ex, corroida por la envidia, te intentó copiar y se compró un coche llamado <a href="http://ant.apache.org/ivy/"><b>Ivy</b></a> para competir contigo en la parte más básica, la gestión de dependencias. Mi ex tiene su público, claro, pero cuanto más tiempo ha pasado más me he dado cuenta de lo anticuada que es en realidad. Ahora veo que estandarizar la construcción tiene bastantes ventajas.<br />
<br />
En cualquier caso, seguramente lo peor por lo que he tenido que pasar en nuestra relación es que te <b>integrabas muy mal</b> con mis amigos del club <b><a href="http://www.eclipse.org/">Eclipse</a></b>. No te querías ni acercar por allí, y me obligabas a hacer malabarismos para que <b>no chocarais</b> en vuestros planes. A veces coincidíais tangencialmente y teníais algún tipo de contacto, lo suficiente para aprovechar sobre todo tus maravillosas <b>dependencias</b>, pero el contacto nunca llegaba a ser realmente amistoso.<br />
<br />
Con el tiempo mi paciencia fue dando frutos, y gracias a eso te fui descubriendo nuevas sorpresas. Ese repositorio <b><a href="http://www.sonatype.org/nexus/">Nexus</a></b> que mejoraba el rendimiento y hacía de repositorio central corporativo, esos <b>arquetipos</b> que hacían que no tuviéramos que empezar siempre desde el principio, esa <a href="http://apagayvuelveaencender.blogspot.com.es/2012/10/java-distribuyendo-aplicaciones-de.html"><b>integración con herramientas como OneJar y Launch4j</b></a> que comentaba en mi artículo de hace varias semanas... y sobre todo fue un gran descubrimiento el día que se unió a nosotros nuestro fiel perro, <b><a href="http://jenkins-ci.org/">Jenkins</a></b>. Gracias a él muchas de tus incomodidades se gestionaban mejor, y perdía mucho menos tiempo con todos esos deploys que tenía que hacer tan a menudo. Debo decir que él y tú sí que <b>encajabais perfectamente</b> y parecíais hechos el uno para el otro.<br />
<br />
Pero... no quiero salirme del tema. Te escribo esta carta porque <b><span style="font-size: large;"><u>me siento engañado</u></span></b>.<br />
<br />
La otra noche pasé por el nuevo local del club <b>Eclipse</b> en la calle <b><a href="http://www.eclipse.org/juno/">Juno</a></b>. La verdad es que llevaba mucho tiempo sin conocer ninguno de los locales que habían ido abriendo por la ciudad, quizá con miedo de que tu falta de integración se acrecentara en ellos.<br />
<br />
Y cual fue mi sorpresa cuando... te vi allí, en el club. Alternando con todos, como una <b>ramera barata</b>. Dejando que cualquiera te tocara el culo sin poner ningún tipo de oposición. Hablando con todos, ayudando a todos. Con todos, hasta con <b>el más tonto de los dummies</b>. Cualquiera era capaz de manejarte, de entenderte, así de fáciles les ponías las cosas. De repente, <b>dejaste de lado todas esas dificultades</b> que me habías puesto a mi. Hacías que usarte fuera lo más fácil del mundo, que prácticamente <b>no hiciera falta saber nada</b>. Que con dos clicks tuvieras creado tu proyecto y que con otro más añadieras las dependencias que necesitaras. Por supuesto, sé que debes seguir teniendo complejidades escondidas, que irían apareciendo con el tiempo. Pero llegar a ti es ahora <b>mucho más fácil</b>.<br />
<br />
Sé que no te diste cuenta, que me confundiste con cualquier otro de los múltiples acompañantes que tuviste, pero esa noche... esa noche yo también te usé. No pude evitarlo. Ya no soy importante para ti... debería matarte, o al menos abandonarte para no volver a verte jamás. Los celos me carcomen, no puedo soportarlos. Pero ya <b>no puedo vivir sin ti</b>. Es mucho lo que me das.<br />
<br />
A partir de ahora seré uno más en tu vida, otro usuario anónimo que entra y sale pasando desapercibido. Pero quiero que sepas que nuestra historia fue muy especial durante mucho tiempo y que no te olvidaré jamás. No es una carta de despedida, pero sí que es la última vez que te hablaré como alguien especial y cercano a ti.<br />
<br />
Te quiero. Te odio.<br />
<br />
<br />
P.D.: Tengo una nueva vecinita llamada <b><a href="http://www.gradle.org/">Gradle</a></b> que me está intentando seducir. Sabe qué teclas tocar, ya que afirma que reúne tus ventajas con las de mi ex. Por ahora me resisto, he sufrido demasiado y no me siento con fuerzas para empezar otra vez, pero como un día me dé por conocerla mejor igual te acabas olvidando de mi para siempre...<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgyv2XmEgVrzDgFVtqX1NVjvKXNmvz9tWaRwAJK_grc1oFMcCBiSb2MeJKbBAi-LIKszjQm7eHHKyYNz380JvBqXI7xcZaoW8jeSpQ0l1eOLSNY8ISuMYN6Sv14FoZi9DRxWjD63q67CqPw/s1600/celos1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="362" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgyv2XmEgVrzDgFVtqX1NVjvKXNmvz9tWaRwAJK_grc1oFMcCBiSb2MeJKbBAi-LIKszjQm7eHHKyYNz380JvBqXI7xcZaoW8jeSpQ0l1eOLSNY8ISuMYN6Sv14FoZi9DRxWjD63q67CqPw/s400/celos1.jpg" width="400" /></a></div>
<br />Andréshttp://www.blogger.com/profile/06010147149377176406noreply@blogger.com6tag:blogger.com,1999:blog-6416070227303513915.post-18621757217186274612012-11-14T23:50:00.000+01:002013-01-16T02:02:49.400+01:00Metodologías ágiles. ¿Me las creo o no me las creo?<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgci4U7AnS7PPD9BtT1pxLdxCo-YqXYD0lq6WejEdoSH_uJpCqQyX1WcaaxM2a2qvnghEEEiQ7snOscwcDNnagCXjkgq1J-MS5VOSM14ROANhDW9ljykfstm3fs23KYCLbTz6E3LJ32WDcZ/s1600/Flash-logo-dc-comics-251206_1024_768.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="150" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgci4U7AnS7PPD9BtT1pxLdxCo-YqXYD0lq6WejEdoSH_uJpCqQyX1WcaaxM2a2qvnghEEEiQ7snOscwcDNnagCXjkgq1J-MS5VOSM14ROANhDW9ljykfstm3fs23KYCLbTz6E3LJ32WDcZ/s200/Flash-logo-dc-comics-251206_1024_768.jpg" width="200" /></a></div>
Últimamente parece que los congresos y otros saraos sobre <b>metodologías ágiles</b> de desarrollo aparecen de debajo de las piedras. Están de moda, está claro. Ante todo, debo reconocer que aunque realmente me encantaría haber podido hacerlo, hasta ahora no he participado nunca en un proyecto en el que se siga alguna metodología ágil. Así que en este artículo parto del desconocimiento y diré irremediablemente un montón de tonterías. En cualquier caso, ya adelanto que las metodologías ágiles me generan tanto entusiasmo como dudas.<br />
<br />
En el año 2001, <a href="http://en.wikipedia.org/wiki/Kent_Beck">Kent Beck</a> (que básicamente quería vender su libro) convocó a unas cuantas mentes pensantes del desarrollo software y, con una cerveza en la mano, les dijo algo así como: "Señores, ¿están tan hartos como yo de tanta tontería?". El resto se miraron unos a otros, pensando cada uno en ese sufrimiento que les acarreaba el día a día en el trabajo: la incomprensión de sus jefes, ese documento que no vale para nada y nunca se acaba, el echarse las culpas unos a otros... Así que cogieron la petaca de whisky, la apuraron de un trago y todos al unísono gritaron: "¡¡¡Cambiemos el mundo!!!". Vale, seguramente no fue exactamente de esta forma, pero ey, si yo fuera a hacer una película sobre el tema la haría así, ¿qué pasa?.<br />
<br />
El caso es que dice la leyenda que estos 17 tipos se pusieron de acuerdo para redactar los <b>4 principios maestros</b> del desarrollo ágil, recogidos en lo que vinieron a llamar el <a href="http://es.wikipedia.org/wiki/Manifiesto_%C3%A1gil">manifiesto ágil</a> (por cierto, cualquiera que haya estado en una reunión de su comunidad de vecinos sabrá que el que 17 tipos se pongan de acuerdo en algo en una tarde es cuanto menos difícil de creer, pero atribuyamos el mérito al alcohol y créamoslo, que al fin y al cabo da un poco igual si sucedió así o no). Los 4 principios tienen la forma "X mola más que Y", que no es que Y no mole, que si hay que ir se va, pero es que X es la leche y es lo que hay que potenciar. Estos son los 4 principios o valores.<br />
<br />
<h3>
1. Viva la gente (la hay donde quiera que vas)</h3>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4n7Jw00JIX4LjRSSosW5x1CtuT8EqX0rIm-JU-cqJwamzH2soFZ-aKrD-BN33U-pyZ9lc8pAHZwbHubr7xdPqRbF325G82N37Lxw6S_AsmPFt6A7QjFi-gnhNrno0hwsT6HEgrTFArMFq/s1600/agil1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="242" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4n7Jw00JIX4LjRSSosW5x1CtuT8EqX0rIm-JU-cqJwamzH2soFZ-aKrD-BN33U-pyZ9lc8pAHZwbHubr7xdPqRbF325G82N37Lxw6S_AsmPFt6A7QjFi-gnhNrno0hwsT6HEgrTFArMFq/s640/agil1.png" width="640" /></a></div>
<br />
Como comentaba en mi primer <a href="http://apagayvuelveaencender.blogspot.com.es/2012/09/en-busca-del-uml-perdido.html">artículo sobre UML</a>, unos años atrás las mentes pensantes del desarrollo de software se estrujaban las meninges buscando una metodología que hiciera el desarrollo tan fácil que cualquier mequetrefe fuera capaz de hacerlo con los ojos cerrados. Se pretendía que el desarrollo no fuera un proceso creativo, sino que siguiendo unos pasos bien definidos se pudiera casi automatizar.<br />
<br />
Pero esto no es cierto. Lo cierto es que para hacer un buen diseño, que sea flexible y mantenible, <b>tienes que ser creativo</b>. Tienes que pensar. Y está demostrado que un buen desarrollador cunde más a largo plazo que muchos malos.<br />
<br />
Por otra parte, también está demostrado que el rendimiento de una persona que está <b>motivada</b> con lo que hace es infinitamente superior al de la que no lo está. Esto tiene muchas implicaciones. No es fácil estar motivado. Tienes que sentir que controlas completamente el software que estás haciendo, que lo conoces bien, que tienes tu parte de responsabilidad sobre él. Tienes que hacer tareas creativas, no tareas aburridas.<br />
<br />
Y aquí llega mi primera duda. Porque la vida real... ¿es así?. ¿No aparecen día sí y día también <b>tareas soporíferamente aburridas</b>, que no se pueden atajar haciendo de otra forma y que además no hay más remedio que hacerlas?. ¿No hay un montón de gente que se ha metido en el desarrollo porque da de comer, pero que realmente ni se sienten especialmente motivados ni les interesa sentirse así, sino que se prefieren limitarse a "cumplir órdenes"?. ¿Dónde encaja todo esto en las metodologías ágiles?.<br />
<br />
<h3>
2. Muerte al papel (efecto Fahrenheit 451)</h3>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjgMbTGOvku8kqSHuOKMzrFSnUCR4YGeOUXGPIoAApl7XVmJdG5NhkGaE-KRw6O-m7knV6FCKQOsprJGfFAJOzRwZBbVvhdZ5LU-SQ0_EimFM4B7C6cqT3DKJUngFgXo8ii_I6XIVt36Ifp/s1600/agil2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjgMbTGOvku8kqSHuOKMzrFSnUCR4YGeOUXGPIoAApl7XVmJdG5NhkGaE-KRw6O-m7knV6FCKQOsprJGfFAJOzRwZBbVvhdZ5LU-SQ0_EimFM4B7C6cqT3DKJUngFgXo8ii_I6XIVt36Ifp/s640/agil2.png" width="640" /></a></div>
<br />
Tradicionalmente creo que ha habido dos grandes problemas con la documentación. El primero es que muchas metodologías "de las antiguas" requerían una <b>cantidad indecente</b> de documentación. Yo personalmente he trabajado en proyectos en los que el equipo que había se tiraba más de un año haciendo toneladas de documentación, y cuando se querían dar cuenta no habían hecho nada de software real y el tiempo se estaba acabando. Al final resulta que se tiene que hacer todo el desarrollo corriendo y sin que la mayor parte de la documentación existente ayudase demasiado. Es una pérdida de tiempo y de energías, y además, desmotiva.<br />
<br />
Pero el segundo problema creo que es aún peor, y tiene que ver con el paso del tiempo. Ocurre porque <b>el software y la documentación son entidades diferentes</b>. Están disociadas. Llega un momento en que, una vez entregada la primera fase del proyecto, dentro del mantenimiento se modifica el software pero no la documentación. ¿Para qué sirve una documentación que no está actualizada?.<br />
<br />
Para resolver esto, en mi opinión lo que hay que hacer es <b>integrar la documentación en el propio software</b>. Olvidar la idea del "documento". Un gran ejemplo de esto es el JavaDoc. Pero creo que no basta con eso. Creo que aún nos falta subir más de nivel de abstracción. En mi <a href="http://apagayvuelveaencender.blogspot.com.es/2012/10/java-y-el-uml-maldito.html">segundo artículo sobre UML</a> ya mencionaba la importancia de que los diagramas UML estuvieran integrados con el código Java, usando lo que se llamó (entre otros nombres) "live round-trip". Y aún podría ir más allá, porque también tengo mis propias ideas sobre el análisis de requisitos integrado con el código. Pero eso ya lo contaré en otra ocasión (me queda mucho de lo que hablar hasta llegar ahí)...<br />
<br />
En este punto de la documentación, la verdad es que mis dudas son menores. Lo único que me pregunto es: ¿la gente estará siendo capaz de <b>medir bien</b> y ser racional con la documentación que se produce para el software?. En esto de la documentación, yo casi siempre lo que he visto han sido extremos: o te obligan a documentar demasiado, o no se documenta nada. Es decir, ¿se estará usando esto como excusa para no documentar nada de nada?. ¿Ni unos mínimos JavaDoc, ni una mínima documentación de intenciones, nada de nada?.<br />
<br />
<h3>
3. El cliente es tu amigo</h3>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTGd0DfKXhZin-Gj912YHLMEa7MVyvW-e34FS2CyJPMojh-kNH0jR6mAOcZ-KjSd650SXBfge_T7B37l6I41_Iy_XGyhMZGyo4fSoNU2yDuSWiXl9j5mkImYI7izWc9YPM3owMwam9Onod/s1600/agil3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="244" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTGd0DfKXhZin-Gj912YHLMEa7MVyvW-e34FS2CyJPMojh-kNH0jR6mAOcZ-KjSd650SXBfge_T7B37l6I41_Iy_XGyhMZGyo4fSoNU2yDuSWiXl9j5mkImYI7izWc9YPM3owMwam9Onod/s640/agil3.png" width="640" /></a></div>
<br />
Tengo que reconocer que la idea es muy buena. Es difícil que el software que se produzca satisfaga al cliente y cumpla sus necesidades <b>cuando el cliente no está ahí siempre que haya alguna duda</b>. Si hay que esperar a que haya una reunión para preguntarle, todo se retrasa. Muchas veces se tira "por el camino del medio", acertando en algunas ocasiones y en otras no. Muchas veces esas reuniones, cuando por fin llegan, se estiran y estiran y cuando sales te das cuenta de que no le has preguntado nada de lo que necesitabas saber (y que te duele la cabeza, además). Pero también muchas, muchas veces, el cliente se para a mirar lo que llevas hecho cuando sólo quedan dos semanas para la puesta en producción. Y entonces decide cambiarlo todo.<br />
<br />
La idea, como digo, es buenísima, que el cliente participe dentro del propio desarrollo, que haya una comunicación frecuente con él y pueda resolver todas las dudas rápidamente. Pero... ¿es realista en la mayor parte de las ocasiones?. ¿De verdad los clientes se prestan a colaborar en los proyectos?. En mi experiencia, muchos clientes tienen su propio trabajo que sacar adelante, y consideran que no tienen tiempo para eso. Consideran que es tu problema. No entienden la importancia de ese tema. Ya te han contado qué es lo que necesitan, así que déjales en paz. Por supuesto, hay clientes y clientes. Pero me surgen muchas dudas sobre la <b>resistencia que presentarán muchos clientes</b> en contra de esa colaboración.<br />
<br />
<h3>
4. Be water, my friend</h3>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjH_BfgZMXUwgNDmkoYa6MPgo7dqVGYyjPZ1Ny16mcMReGNp2GUlEykQhi4VSxf3IU6emzO8X99-D45m4Um9_0DCoWOgMADsFuY6evsTAxlkOayjgtDy2xqCKw_LVOz1YuUBageMKBxDa4c/s1600/agil4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="244" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjH_BfgZMXUwgNDmkoYa6MPgo7dqVGYyjPZ1Ny16mcMReGNp2GUlEykQhi4VSxf3IU6emzO8X99-D45m4Um9_0DCoWOgMADsFuY6evsTAxlkOayjgtDy2xqCKw_LVOz1YuUBageMKBxDa4c/s640/agil4.png" width="640" /></a></div>
<br />
Ya he comentado en alguna ocasión que el desarrollo de un producto de software es un <b>proceso de aprendizaje</b>. Según se va profundizando en él, mejor se va entendiendo, y al hacerlo se van descubriendo nuevas implicaciones del desarrollo. Cosas nuevas que hay que hacer, o cosas que cuestan mucho más de lo que se había pensado al principio porque obligan a cambiar otras cosas o no se pueden plantear como se tenía previsto. Esto hace que los planes a largo plazo (e incluso a medio, y diría que muchas veces hasta a corto) sean difíciles de seguir, porque lo normal es que se descubran cosas nuevas sobre la marcha, y en ese caso siempre <b>hay que acabar sacrificando algo</b>. O el proyecto sale menos rentable, o se resiente la calidad del producto, o (más a menudo de lo que debería, sobre todo en consultoras) lo que se sacrifica es el tiempo de los programadores, que acaban haciendo horas no retribuidas como campeones, apelando al "compromiso con la empresa".<br />
<br />
En cualquiera de los casos, se propaga un <b>sentimiento de culpabilidad</b>: "alguien ha hecho algo mal". "Esto no debe seguir así". "A partir de ahora vamos a hacer las cosas bien, y vamos a... planificar más cosas y mejor".<br />
<br />
Las metodologías ágiles afrontan este problema dándole más importancia a la "<b>respuesta al cambio</b>" que al plan. Esto tiene una implicación enorme sobre la forma de trabajar de las empresas con sus clientes: requiere <b>cambiar la forma en la que se hacen los contratos con el cliente</b>. Ya no valen contratos cerrados, tipo "me haces todas estas funcionalidades en este tiempo y yo te pago esto". Nos vamos a una facturación por tiempo trabajado. Por un lado eso invalida directamente este tipo de desarrollos con determinado tipo de contrataciones, por ejemplo, cualquier proyecto con la administración pública, que tiene que ser cerrado por definición. Aparte de eso, ¿cuál es el problema de esto?. Que requiere una gran <b>confianza</b>. Confianza del cliente hacia la empresa del desarrollo, para que no piense "estos me están queriendo timar, me están cobrando una barbaridad para lo que están haciendo". Confianza del gestor de la empresa de desarrollo con el equipo que va a programarlo, para que no piense "estos se están pasando el día tocándose las narices, y el cliente se va a cabrear y nos va a dejar tirados".<br />
<br />
<br />
¿Y en el fondo, no es ese el principal problema que tienen las metodologías ágiles? (aparte del hecho de que hay un conjunto grande de gente y/o situaciones para las que sencillamente no valen). Que requieren confianza. Que requieren querer hacerlo. Confianza del programador en el resto del equipo, confianza en que se está haciendo lo correcto, confianza en que la dirección lo va a soportar, confianza en que el cliente lo va a apoyar. Confianza de la dirección en el equipo de desarrollo, confianza en que va a funcionar bien, confianza en que al cliente le va a gustar. En definitiva, <b>requieren que todos los implicados crean en lo que se está haciendo</b>, desde el cliente que pone el dinero hasta el becario que echa una mano con lo que sea. Requieren que todos crean en el trabajo de ese equipo y de todos y cada uno de sus componentes.<br />
<br />
¿Y sabéis qué?. Que yo me creo todo eso. Creo en la sinergia. Creo en que cada persona es capaz finalmente de <b>asumir responsabilidades por sí misma</b>, cuando se le otorga la confianza para que lo haga.<br />
<br />
Pero no estoy seguro de que el mundo esté preparado para ello. Me parece un cambio de orientación demasiado grande y que afecta a demasiadas partes. Tengo muchas dudas. Me cuesta creer que las metodologías ágiles se estén usando de forma generalizada.<br />
<br />
Así que si estás leyendo esto y has tenido ocasión de trabajar en algún proyecto siguiendo una metodología ágil, por favor, <b>deja un comentario y comparte tu experiencia</b>. Cuéntanos cómo convenciste a tus clientes y a tus jefes. Yo estoy dispuesto a apurar mi petaca de whisky y gritar: "¡Cambiemos el mundo!".<br />
<br />
<br />
NOTA: Sí, los chistecillos son míos, haciendo un poco el tonto con el Inkscape juntando personajes que he cogido de por aquí y por allá (he procurado que fueran todos de dominio público). La mayor parte proceden de <a href="http://openclipart.org/">Open ClipArt</a>.Andréshttp://www.blogger.com/profile/06010147149377176406noreply@blogger.com12tag:blogger.com,1999:blog-6416070227303513915.post-37163049546375172982012-10-30T01:32:00.000+01:002013-01-15T03:08:25.600+01:00Breezi: la herramienta con la que tu abuela podrá crear la web de su club de ganchillo<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjH_cgwRhiQfE-tQTILhIeA9yMsgibrGo-raXg9UNOt6S6-O8NSsD9Ym1ZVx9u5IK1E9uOEu6-cA5pxVU6e3Nzxk-XoVArvrSa_otgC2lQjtaUjIKWTwLMH539oVxTsj8BfaYljfAAgE_TF/s1600/fight-club.jpg" imageanchor="1" style="clear: right; display: inline !important; float: right; margin-bottom: 1em; margin-left: 1em; text-align: center;"><img border="0" height="150" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjH_cgwRhiQfE-tQTILhIeA9yMsgibrGo-raXg9UNOt6S6-O8NSsD9Ym1ZVx9u5IK1E9uOEu6-cA5pxVU6e3Nzxk-XoVArvrSa_otgC2lQjtaUjIKWTwLMH539oVxTsj8BfaYljfAAgE_TF/s200/fight-club.jpg" width="200" /></a><br />
Puede parecer que esto de los creadores WYSIWYG (o sea, editores visuales) de HTML no es nada nuevo. El <a href="http://www.adobe.com/es/products/dreamweaver.html"><b>Dreamweaver</b></a> es quizá el editor de webs que llegó a ser más popular, de hecho hace unos años era una de las herramientas más pirateadas por los desarrolladores. Lo cierto es que con el Dreamweaver podías más o menos hacer webs aunque no tuvieras ni idea, pero llegaba un momento en que no era tan fácil. Ese momento en el que sentías que la herramienta no te dejaba hacer lo que querías, todo se embarullaba y perdías por completo el control sobre tu creación. Las tablas dentro de tablas dentro de tablas dentro de tablas no había nadie que las manejara ya, de repente tenían vida propia. Ya no podías cambiar lo que habías hecho, ya no estabas pensando en cómo quedaba mejor la web. Ya no sabías por qué salía ese hueco ahí ni qué podías hacer para quitarlo. Eso se había convertido en una guerra contra la herramienta. Sólo puede quedar uno.<br />
<br />
En cualquier caso, lo que acabó matando a Dreamweaver del todo (aunque la herramienta sigue existiendo, pero su popularidad ya no tiene comparación con la que tuvo) fue el declive del diseño de <i>layouts</i> con tablas y la popularización del diseño basado en CSS. Hacer un diseñador de layouts basados en CSS que resulte intuitivo es mucho más complejo, e incluso muchos podrían pensar que es imposible hacer uno que no requiera de ningún tipo de conocimiento de HTML y CSS.<br />
<br />
En este contexto, aparece <b><a href="http://breezi.com/">Breezi</a></b>. Y Breezi es... la leche. Así de claro. Hace unos días la estuve probando, y hacía tiempo que no probaba algo que me haya entusiasmado tanto. Todo está tan bien pensado y queda tan natural que parece fácil. Pero no lo es, ni mucho menos.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_XcXNgUTqgVAhAgRa97VwUrfveNwWkrPtiCIc3lxRomnu-8RPv2ZU-oaslJt_H5RNga-GTXK1H3vbqm4FpaCFoRRUU6lq4jZu_wh_FErDMoaplLxwWgF_CgQ99qmI7fNqz7ep4YDZHVs1/s1600/salsalon.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_XcXNgUTqgVAhAgRa97VwUrfveNwWkrPtiCIc3lxRomnu-8RPv2ZU-oaslJt_H5RNga-GTXK1H3vbqm4FpaCFoRRUU6lq4jZu_wh_FErDMoaplLxwWgF_CgQ99qmI7fNqz7ep4YDZHVs1/s1600/salsalon.jpg" /></a>Para mis pruebas quise hacer algo para lo que no tuviera que ir creando imágenes ni logotipos ni fotos, porque no soy diseñador y como tenga que ponerme yo a hacer dibujillos podía tirarme meses. Además quería basarme a ser posible en un caso real, un rediseño de una web sería genial. Así que mi planteamiento fue... ¿cómo haría yo un rediseño de la web de... mi <b>escuela de baile</b>? (sí, amigos, también bailo, o lo intento, ¿a que soy una caja de sorpresas?). Por cierto, si os gusta el baile, queréis aprender y vivís en Madrid, ya estáis tardando en ir a esta academia, porque es muy buena y no sólo aprendes mucho sino que además te lo pasas a lo grande: escuela de baile <b><a href="http://www.salsalon.com/">Sálsalon</a></b>. Como podéis ver su web se está quedando un poco antigüilla, así que me pareció perfecta para las pruebas (sé que están trabajando en cambiarla, y digo yo que la harán diseñadores de verdad, no informaticuchos sin gusto estético como yo).<br />
<br />
Por lo pronto, Breezi es una <b>aplicación web</b>, que además <b>incluye el hosting</b>. Esto quiere decir que cuando tengas hecha tu web no tienes por qué andar pegándote con servidores FTP ni otras zarandajas. Pulsas el botón de "Publicar" y automáticamente tu web está en Internet, en la dirección "midominio.breezi.com". Si no quieres pagar nada, puedes hacer una web pequeña que esté en esa dirección y que tenga un máximo de 3 páginas, insuficiente en el mayor parte de los casos pero potencialmente suficiente para algunas empresas pequeñas que sólo quieren tener un pequeño escaparate, sin demasiadas necesidades informativas. Si quieres hacer una web completa y que tenga su propia dirección, puedes hacerlo por 150 dólares al año. Teniendo en cuenta que esto incluye el hosting, no me parece ninguna barbaridad. Existe también una modalidad de pago a dólar por cada hora de uso del editor, que puede ser muy interesante si no queremos gastar mucho dinero y queremos apurar (esta modalidad puede dar mucho lugar a la picaresca, así creo que se puede considerar muy española). Pero dejemos a un lado el vil metal y vamos al lío.<br />
<br />
En cuanto a los <b>layouts</b>, Breezi permite crearlos usando un diseño basado en cuatro elementos:<br />
<br />
<ul>
<li>El primer elemento son los <b>bloques</b> principales, que son contenedores horizontales que vienen ya creados por defecto para facilitar las cosas: cabecera, introducción, cuerpo y pie.</li>
<li>Dentro de cada uno de ellos se pueden crear <b>secciones</b>, que vuelven a ser bloques horizontales que se añaden libremente</li>
<li>Dentro de cada sección se pueden crear varias <b>columnas</b>, que son bloques verticales. Se pueden ir creando, eliminando y redimensionando sobre la marcha</li>
<li>Dentro de cada columna se van apilando de forma vertical los componentes de contenido, que Breezi llama <b>aplicaciones</b>. El nombre me parece un poco engañoso, la verdad, quedaros conque son unidades prediseñadas de contenido. Quizá hubiera quedado más claro si las hubieran llamado <i>widgets.</i></li>
</ul>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0gbwZNkgtx_R0o5FyfLGId4I_ricnRyUv_2MY8_uSyW-lJoLNwoYlgI_YK5HgZoqbkzZpJwzCqISdHUTtvIURvWnoJ40Qz6Cbpyk8hkGgXofwvvWjVjwS6GeFk4Ihgo2qWWYlUL_oedLr/s1600/breezi_layouts.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="346" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0gbwZNkgtx_R0o5FyfLGId4I_ricnRyUv_2MY8_uSyW-lJoLNwoYlgI_YK5HgZoqbkzZpJwzCqISdHUTtvIURvWnoJ40Qz6Cbpyk8hkGgXofwvvWjVjwS6GeFk4Ihgo2qWWYlUL_oedLr/s400/breezi_layouts.png" width="400" /></a></div>
<div>
<br /></div>
<div>
Todo esto está muy bien, pero evidentemente crear una página desde cero siempre es complicado, y Breezi lo sabe. Así que nada más crear una página, lo primero que te da para elegir son un montón de <b>plantillas prediseñadas</b>, para que puedas partir del layout que se parezca más a lo que tengas en la cabeza e ir modificándolo sobre la marcha. Se agradecen detalles como que estas plantillas vengan en blanco y negro y sin grandes suposiciones sobre el estilo gráfico (aunque también tienen otras que incluyen el diseño, para los más vagos). También se agradece que no sean layouts vacíos, sino que incluyan textos, noticias u otros elementos de contenido que se suelen utilizar en las páginas. Esta es una de las grandes maravillas de Breezi, te da siempre ya prediseñado lo que más se suele utilizar, y luego te permite cambiarlo.</div>
<div>
<br /></div>
<div>
<div>
En cuanto a la personalización del <b>estilo</b> cada elemento, uno de los problemas típicos que han tenido siempre los editores gráficos es cómo hacer que el usuario pueda elegir correctamente cuál personalizar. Es decir, si un bloque tiene dentro una sección que tiene dentro una columna que tiene dentro una aplicación, ¿cómo puedo hacer que cada una tenga un botón distinto para personalizarla?. La opción por la que opta me parece inteligente: separar cada botón de personalización de los contenedores adyacentes para que puedan pulsarse por separado: uno aparece en horizontal, otro en vertical, otro en diagonal, otro más separado... Para cada elemento podrás personalizar sus márgenes y espaciados y podrás ponerles bordes, sombreados...</div>
</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjn3dCLyHyrugsk0_siLpofG1GLadT8cUWo6_VzfF8Aru7Fgt4RTr3EbvsoSJ5uT4ooUxTAj06Gew-ea9h3oha_F753xS7U316N6SPM2pFOHAm15nmCqZVHQlLQxYitcv5dshax6EdywUHu/s1600/breezy_pantalla1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="491" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjn3dCLyHyrugsk0_siLpofG1GLadT8cUWo6_VzfF8Aru7Fgt4RTr3EbvsoSJ5uT4ooUxTAj06Gew-ea9h3oha_F753xS7U316N6SPM2pFOHAm15nmCqZVHQlLQxYitcv5dshax6EdywUHu/s640/breezy_pantalla1.png" width="640" /></a></div>
<div>
<br /></div>
<div>
Una vez tenemos nuestro layout más o menos definido (o fusilado directamente de la plantilla), comenzamos a meter contenido. Para eso tenemos las <b>aplicaciones</b>. Una aplicación puede ser desde un <b>menú</b> hasta combinaciones de <b>texto</b> e <b>imágenes</b>, pasando por <b>botones</b>, <b>formularios</b> de contacto, <b>galerías</b>, <b>noticias</b>, conjuntos de iconos sociales... Cada aplicación tiene un botón para configurarla en general, como por ejemplo editar los elementos del menú, o las imágenes que aparecerán en la galería. Además, cada aplicación estará compuesta por varios elementos que se pueden configurar por separado. En el caso de los textos, por supuesto tendremos el inevitable editor con sus fuentes (incluyendo las fuentes de Google, por cierto), negritas, colores, etc. A cada elemento de una aplicación se le puede dar estilo por separado, dependiendo los estilos disponibles del tipo de elemento en cada caso.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQDj491bwSiSfGCqGI_qQ87Ja9_18IB6evv5b1TP8l4IUdiT3jtpBjDA5hALa6pnN4PAneQPrvHzXrAcrW44Tu8a6khDc1q-njrTtAeEAYfpaZJ6Vw7vOrxPqrkByxN3RiCNUGuwqiCEow/s1600/captura3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="272" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQDj491bwSiSfGCqGI_qQ87Ja9_18IB6evv5b1TP8l4IUdiT3jtpBjDA5hALa6pnN4PAneQPrvHzXrAcrW44Tu8a6khDc1q-njrTtAeEAYfpaZJ6Vw7vOrxPqrkByxN3RiCNUGuwqiCEow/s320/captura3.png" width="320" /></a></div>
<div>
<br /></div>
<div>
Otra de las cosas que más me ha gustado es que <b>los contenidos se adaptan al tamaño de su contenedor</b>. Esto es especialmente chulo en el caso de las <b>imágenes</b>. Cuando añades una imagen, esta calcula el tamaño que tiene disponible y te permite seleccionar qué parte de la imagen es la que quieres mostrar, redimensionándola si es necesario y sin deformarla salvo que le digas explícitamente que la quieres así. Sin apenas darte cuenta, has adaptado la imagen en unos segundos.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiEWs7F7W7xsJun9Z75hLs5i-ykCUGRx3Qw-yM5xVLnPxX3KYSSHwh7gSE6Y5PAlIfXHRj62ABJcJFD9s5i1GE9zBekggg8W67lH_MZ8mCnlswwKzyxH2wA46ErZtRpES7Ostq-A_l4VSqZ/s1600/breezi2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="246" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiEWs7F7W7xsJun9Z75hLs5i-ykCUGRx3Qw-yM5xVLnPxX3KYSSHwh7gSE6Y5PAlIfXHRj62ABJcJFD9s5i1GE9zBekggg8W67lH_MZ8mCnlswwKzyxH2wA46ErZtRpES7Ostq-A_l4VSqZ/s320/breezi2.png" width="320" /></a></div>
<div>
<br /></div>
<div>
En fin, lo más importante que puedo decir es que en todo momento tenía la sensación de que el tiempo lo estaba empleando en jugar con el diseño, no en que el diseño jugara conmigo. Sobre todo, tenía la sensación de que no me estaba pegando con la herramienta, sino que en todo momento <b>Breezi me estaba ayudando</b> a sacar el diseño adelante. El resultado no es precisamente espectacular, porque ya he dicho que no soy diseñador, pero teniendo en cuenta mis grandes limitaciones sí que llegó a sorprenderme. En unas horas, ya tenía hecha una página de inicio casi completa, a pesar de que tuve que ir aprendiendo a usar la herramienta sobre la marcha. Podéis verlo en salsalon.breezi.com (no lo he puesto como enlace a propósito, para evitar que aparezca en los buscadores y engañe a algún incauto).</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWvadWet6fj8NDu7fiyr_r2G1DdHoaV0gsa4fM1wneajFp7zidWTShyphenhyphenIZ_X4edy7kEJxumNk__G1MHge3wG-mSDVaTiUE1GuNztsHLD7k9Oyzf5GvkVmfOHQPIS1xpl452QELk9TlV9GFX/s1600/breezi_salsalon.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="440" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWvadWet6fj8NDu7fiyr_r2G1DdHoaV0gsa4fM1wneajFp7zidWTShyphenhyphenIZ_X4edy7kEJxumNk__G1MHge3wG-mSDVaTiUE1GuNztsHLD7k9Oyzf5GvkVmfOHQPIS1xpl452QELk9TlV9GFX/s640/breezi_salsalon.png" width="640" /></a></div>
<div>
<br /></div>
<div>
Cabe añadir también que puedes <b>exportar</b> la web resultante, para que se sincronice con Dropbox o con un FTP. Es decir, puedes publicar la web en otro servidor sin problema alguno, incluso con la opción gratuita. Y que la web resultante <b>funcionará bien en todos los navegadores</b>, y si accedes con un móvil te das cuenta de que sin querer acabas de crear un <b>diseño <i>responsive</i></b> (que no sé cómo narices se traduce, si es que tiene traducción).</div>
<div>
<br /></div>
<div>
Por supuesto, no es oro todo lo que reluce. Al ejecutarse todo en el navegador y con un porrón de Javascript, se necesita un ordenador con cierta potencia para que vaya fluido. Y consume un montón de memoria. También es obvio que es más limitado que el HTML escrito a mano. Por último, el código que se genera es inevitablemente sucio, aunque no tanto como podría haber sido. Pero creo que todo estas limitaciones son inevitables en un editor WYSIWYG. También debo reconocer que no he probado otras herramientas del mismo tipo, como <a href="http://www.weebly.com/">Weebly</a>, <a href="https://sidengo.com/">Sidengo</a> ó <a href="http://www.wix.com/">Wix</a> (aunque si he probado esta es precisamente porque es la que me dio mejor pinta). Por último, esta herramienta apenas tiene unos meses, así que todavía puede mejorar aún más con el tiempo (o estropearse, que ejemplos hay miles).</div>
<div>
<br /></div>
<div>
En resumen, Breezi tiene dos cosas que son alucinantes: una, que es una gran herramienta para hacer un <b>prototipo</b> y ayudarte a pensar en el diseño de tu web, y dos... que gracias a ella <b>hasta tu abuela</b> es capaz de hacer una web chula, y dejar en pañales tu último intento de meterte a diseñador. Mejor no se la enseñes, que corres el riesgo de quedarte sin "cocretas" y lentejas para siempre.</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
Nota: No recibo comisión (ni jamones) ni de <b>Breezi</b> ni de <b>Sálsalon</b>, ¡de verdad!. Sé que prometí en la columna de la derecha que iba a gruñir mucho, y ahora voy y salgo con esta entrada pelota... imperdonable, lo sé. Prometo ser más capullo la próxima vez... </div>
<div>
<br /></div>
Andréshttp://www.blogger.com/profile/06010147149377176406noreply@blogger.com7tag:blogger.com,1999:blog-6416070227303513915.post-23195153760871573082012-10-17T19:27:00.000+02:002012-10-17T19:27:32.736+02:00Java y el UML malditoEn la entrada de hace unas semanas, <a href="http://apagayvuelveaencender.blogspot.com.es/2012/09/en-busca-del-uml-perdido.html"><b>En busca del UML perdido</b></a>, contaba cómo apareció el diseño orientado a objetos, por qué es bueno, y por qué el UML abrió un camino importante para su popularización. Y dejaba en el aire que aunque la programación orientada a objetos sí había triunfado con los años, sin embargo el diseño orientado a objetos no lo había hecho... ¿por qué?.<br />
<br />
Voy a centrarme en <b>Java</b>, porque al fin y al cabo en general ha sido el lenguaje dominante durante estos años (lo de que además haya sido el lenguaje que he estado usando yo durante este tiempo es una casualidad nimia y sin importancia, claro).<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjU3vmIKTPDlUnjkeBRKV89VfIyOJvXzNN9nH9I-3MDGfqjQ7CbqTeUr-wWC8T1vxnGooshKmbqmRNWOfOuYCtjq-QuU8CdFc0EiDWucoBT73amZ1f33Zjfy21U14CPYS7ZWzvXfzLg1fJ8/s1600/angelitos1gh.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="131" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjU3vmIKTPDlUnjkeBRKV89VfIyOJvXzNN9nH9I-3MDGfqjQ7CbqTeUr-wWC8T1vxnGooshKmbqmRNWOfOuYCtjq-QuU8CdFc0EiDWucoBT73amZ1f33Zjfy21U14CPYS7ZWzvXfzLg1fJ8/s200/angelitos1gh.jpg" width="200" /></a></div>
Los profesores de Ingeniería del Software nos decían (y supongo que nos seguirán diciendo) que el lenguaje final en el que se fuera a programar no importaba, que el diseño se tenía que abstraer de eso y ser genérico, y que luego ya se preocuparía otro de programar en el lenguaje de programación que fuera lo que se había diseñado.<br />
<br />
Así, las primeras herramientas UML que aparecieron, entre las que destacaba el <b><a href="http://www-01.ibm.com/software/awdtools/developer/rose/">Rational Rose</a></b> (que para eso se había gastado Rational el dinero en fomentar la creación de UML), eran herramientas orientadas fundamentalmente a <b>la documentación</b>. Es decir, el producto que se obtenía al usarlas era un documento, que era el resultado del proceso de diseño, y que se entregaría al programador para que lo siguiera como guía al programar.<br />
<br />
¿Qué pasó?. Pues que eso de que el lenguaje final no importe es la primera <b>gran mentira</b> del diseño. Vale, es verdad que eso es posible, pero sencillamente <b>no es práctico</b>.<br />
<br />
Para empezar, si tenemos ya un diseño de clases, nos conviene que la herramienta sea capaz de generarnos el código Java a partir del diseño, porque eso nos va a quitar un montón de trabajo absurdo y aburrido. Así surgió la <b>generación de código</b>. Tanto el Rational Rose como otros productos por el estilo que había entonces, como el <a href="http://www.visual-paradigm.com/product/vpuml/">Paradigm</a>, empezaron a implantar la generación de código en C++... y por supuesto también en Java.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhD7Kf1uyEpywixJ7l869UjutlSCI-JDcmJVsQbQJnx8Yh9WghxpqoTzHUhRWnClfGAIhV9BOo490xVUA6SGHwq-CIMs5zhdffd8zBLXFlj3rxhegrk4z0gafWaXLHL7qJ-l1Df2Cbbtjo/s1600/03505e22a63e9e0a559647bc6800cfd8CASE_RationalRose1.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="231" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhD7Kf1uyEpywixJ7l869UjutlSCI-JDcmJVsQbQJnx8Yh9WghxpqoTzHUhRWnClfGAIhV9BOo490xVUA6SGHwq-CIMs5zhdffd8zBLXFlj3rxhegrk4z0gafWaXLHL7qJ-l1Df2Cbbtjo/s320/03505e22a63e9e0a559647bc6800cfd8CASE_RationalRose1.gif" width="320" /></a></div>
<br />
Pero no bastaba con eso. Hay otro problema importante, que se presenta porque como ya comenté el planteamiento del modelo en cascada no suele ser realista. Lo recordamos: el analista Calculín hace el diseño en UML sin pensar en cómo se va a programar, y luego el programador-fontanero Mario (Bros., of course) lo tiene que convertir en Java y preocuparse porque todo eso funcione. Al final Mario Bros. acaba modificando cosas sobre el diseño inicial, porque según se va profundizando en el desarrollo de la aplicación, se van aprendiendo más cosas sobre ella, cosas que pueden afectar mucho al diseño. ¿Qué pasa entonces con ese diseño?. ¿Se tiene que modificar también, según cambiamos cosas en el programa?. ¿Vamos a hacer trabajo doble?. <b>Qué coñazo</b>, ¿no?.<br />
<br />
Las herramientas entonces empezaron a implantar otra funcionalidad interesante. Como somos capaces de generar Java a partir de UML, si luego algo cambia en Java... hagamos una función que modifique automáticamente el diseño UML a partir de las modificaciones hechas en Java. A eso le llamaron con el bonito nombre de <b>ingeniería inversa</b> ("reverse engineering").<br />
<br />
Todo esto de diseñar en UML - generar Java - modificar Java - volver a UML - volver a Java, etc. al final era, la verdad, un auténtico cacao. Cacao incrementado además porque cada cosa se hacía <b>en una herramienta distinta</b>. A algún comercial de mente despierta se le ocurrió arreglar el problema, ¡cómo no!... poniéndole un nombre chulo al tema (una de las grandes soluciones en todo manual del buen comercial). Así surgio, ¡ta-chán!, la... ¡¡¡<b>round-trip engineering</b>!!! (nuestro traductor a español dimitió el mismo día en el que le dijeron que tenía que traducir algo así y lo único que se le ocurrió fue llamarlo "ingeniería de rosquilla"). Si alguna vez, querido lector, has intentado trabajar en la sincronización bidireccional de dos sistemas que se pueden actualizar por separado, sin duda sabrás que la palabra que mejor puede definir eso es que es un infierno. Se le puede añadir algún calificativo, como el típico "fucking" si hablamos en inglés, o cualquiera de los múltiples equivalentes que existen en el rico castellano, pero vamos, creo que se entiende el tema. Es realmente complicado saber qué lado se modificó antes, qué lado manda, asegurarte de que al generar hacia un lado no se pierde nada que ya teníamos hecho, etc. Es complicado de programar, pero también es complicado de mantener y complicado de entender.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNzbP96AXX5gr9dTfV40r254mP2KIJDx7Xmrnx7CcMU05-9mBMZndO6sPzy6jozPX1Tws6TeYeOwmQ-Hf8gAl29xfUUwXlNF3XCS5rM4ylaSESBPXPKgDsXgYYCbRJFanETNkLorJ5VVaB/s1600/wickie.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="152" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNzbP96AXX5gr9dTfV40r254mP2KIJDx7Xmrnx7CcMU05-9mBMZndO6sPzy6jozPX1Tws6TeYeOwmQ-Hf8gAl29xfUUwXlNF3XCS5rM4ylaSESBPXPKgDsXgYYCbRJFanETNkLorJ5VVaB/s200/wickie.jpg" width="200" /></a></div>
En ese momento, a alguien se le enciende una bombilla en la cabeza... y si nos dejamos de complicar la vida, y más importante aún, dejamos de complicársela al pobre programador... ¿¿¿y si hacemos que haya <b>un sólo modelo</b>???. O sea, ¿y si hacemos que el modelo UML esté representado con el propio código Java?. Creas una clase en Java, la tienes en UML. Modificas algo en un lado, lo tienes en el otro sin tener que hacer nada. Creas una clase en UML, la tienes en Java. No tienes que ejecutar una ingeniería directa ni una ingeniería inversa. Más importante aún, no tienes que ejecutar una "rosquilla" de esas chungas. Sobre todo, eliminamos de un plumazo todas las dificultades que conlleva una sincronización bidireccional. Lo que vemos en UML es lo mismo que vemos en Java. Modificamos cada vez lo que nos sea más cómodo en ese momento. Así surgió una herramienta llamada <b>Together</b>.<br />
<br />
Together era una gran herramienta de desarrollo. Podías editar Java a la vez que editabas UML. No se consideraba que el diseño era una cosa distinta a lo que se programaba, se consideraba que el diseño era una <b>vista</b> distinta del mismo modelo. Los ficheros Java contenían el modelo de clases UML completo. Cuando hacías un diagrama, el diagrama se guardaba en un fichero aparte, pero sólo se guardaba el diseño del diagrama, es decir, <b>el modelo final era el modelo Java</b>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_I8kzeZnksS-NmWdoxbdlw-T_V8Amxf317nevDJv3V1tFMHA7aSEXSMiG2h_MpJRYPtH35GorjjaQBb0zECQ0wlLo19344IVx5MKeaZMjnqJsBf9x0obNErI_rDGZJk1qLjMlMZtlcV50/s1600/LiveSourceJava.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="373" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_I8kzeZnksS-NmWdoxbdlw-T_V8Amxf317nevDJv3V1tFMHA7aSEXSMiG2h_MpJRYPtH35GorjjaQBb0zECQ0wlLo19344IVx5MKeaZMjnqJsBf9x0obNErI_rDGZJk1qLjMlMZtlcV50/s400/LiveSourceJava.png" width="400" /></a></div>
<br />
Si sabes un poco de UML y de Java te puedes dar cuenta de cuál es el problema principal. El modelo de clases de UML y el de Java son diferentes. Hay elementos que son idénticos en ambos casos, como puedan ser las clases, pero hay otros cuya correspondencia no es tan sencilla. Por ejemplo, asociaciones, composiciones, relaciones 1-N... Para esos casos, hay que definir un <b>mapeo</b> entre Java y UML. Pero ese mapeo es posible. Aún con eso, sigue habiendo información que nos puede resultar interesante en el diseño UML pero que en Java se pierda. Para eso Java tiene uno de esos elementos geniales que a alguien un día se le ocurrió crear aunque no dejen de ser un parche: las <b>annotations</b> (anotaciones). Vale, estamos hablando de finales de los 90, aún no existían las anotaciones, pero sí que existían en la forma de "comentarios Javadoc". Al fin y al cabo eran lo mismo. Pero en TogetherSoft, los creadores de la herramienta, también tenían sus comerciales molones, y rápidamente le pusieron un nombre a todo esto: le llamaron tecnología "<b>LiveSource</b>".<br />
<br />
¿Por qué Together no llegó a triunfar si era una herramienta tan buena?. Lo primero de todo, como IDE no llegaba a ser tan bueno como un IDE de Java de los que existían entonces. En aquella época el IDE que triunfaba era sobre todo el <a href="http://es.wikipedia.org/wiki/JBuilder">Borland JBuilder</a>, creado en el 95 y que estaba realmente bien. Eso era un peso importante, porque si tienes que elegir entre un "gran" IDE Java y un "buen" IDE Java que-además-tiene-UML, la decisión no es tan fácil. Además, en mi opinión había algunos problemas con el mapeo Java-UML, que al fin y al cabo es el problema fundamental. Algunas decisiones me parecían bastante discutibles.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjacjixxuuuNc16MfdKORgqArXA5XpnQE1dE9UGBCZyF_QO1QxrQTlPOLKc2NmrDzP7v4pHDS3MmMAgOHCObNKwG9JDMOjaUTwP5jszA6DxDFMF-NGjlA2zVU1yUIIvQPq0mxI8hLvN0M0U/s1600/logotog.gif" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjacjixxuuuNc16MfdKORgqArXA5XpnQE1dE9UGBCZyF_QO1QxrQTlPOLKc2NmrDzP7v4pHDS3MmMAgOHCObNKwG9JDMOjaUTwP5jszA6DxDFMF-NGjlA2zVU1yUIIvQPq0mxI8hLvN0M0U/s1600/logotog.gif" /></a>Sin embargo, no creo que ninguno de ellos fuera el mayor problema. El mayor problema que se encontró Together fue puramente <b>comercial</b>. Por un lado, TogetherSoft no era una marca con peso suficiente como para hacer grandes campañas comerciales, no llegó a hacerse tan popular como llegó a ser el Rational Rose. Por otro, y más importante... Together nació en 1999 (o 1998, no estoy seguro)... y con el paso de los años hemos visto cómo surgió <a href="http://netbeans.org/"><b>Netbeans</b></a> primero (en 1999), y <a href="http://www.eclipse.org/"><b>Eclipse</b></a> después (la versión 1.0 es del 2001), y que al final fue el que se llevó el gato al agua y se convirtió en el IDE Java más usado. Ambas triunfaron no por ser mejores que JBuilder, sino porque mientras que esta era de pago, las otras dos eran -y siguen siendo- gratuitas. Ahora mismo, el modelo de sacar un producto gratuito para que domine el mercado y acabar teniendo ganancias por dar soporte a empresas y cursos se sabe que puede funcionar (siempre que el producto sea realmente bueno), pero por aquel entonces era difícil ver a compañías de desarrollo que apostaran por él. El caso es que Together era de pago. Es más, por lo que recuerdo era aparentemente cara, de esas que no dicen su precio en la web (sí, siempre usé una versión pirata...). ¿Por qué iba nadie a pagar por esa herramienta existiendo IDEs que son mejores para el desarrollo Java y que además son gratis?.<br />
<br />
Rational Rose había llegado a tener cierta popularidad, es más, muchas empresas compraron licencias del producto, pero en el fondo no dejaba de ser un producto <b>fallido</b> desde el momento en el que <b>se separaba el diseño del código</b>. Era un gran producto académico, no tan bueno para el mundo real. Y costaba una pasta. Las nuevas versiones se centraban más en que hiciera cada vez más cosas, más que en que lo que hiciera lo hiciera bien y fuera práctico. La gente se cansó de él, y sólo las empresas que tenían que justificar la producción de un documento de diseño siguieron utilizándolo... y cada vez menos, pasándose en muchas ocasiones a herramientas con las que dibujar cajitas y diagramas, como Visio, Flowchart o sobre todo los mismísimos Word o Powerpoint. <b>Together</b> era un gran producto, pero nunca llegó a ser popular. Demasiado ambicioso en el momento equivocado. Como curiosidad, puedo añadir que Rational acabó siendo comprada por IBM (autores de Eclipse), y Together acabó siendo comprada por Borland (los del JBuilder, y la mejor empresa para desarrolladores hasta ese momento... a esa la mató el software libre, claro). Ambos productos siguen existiendo, pero... ¿conocéis a alguien que los use?.<br />
<br />
Pasaron los años y el UML languideció. La <b>cascada</b> y un <b>puñado de dólares</b> lo sepultaron.<br />
<br />
¿Qué hubiera pasado si el comercial de TogetherSoft en lugar de perder el tiempo pensando en nombres molones para su tecnología, hubiera ofrecido el producto gratis?. Estoy convencido de que la historia hubiera sido distinta, y ese tipo estaría ahora tumbado en una hamaca hecha de billetes de dólar (bueno, igual está así de todas formas, a saber). La herramienta seguramente habría seguido creciendo, pero en lugar de buscar motivos comerciales, habría buscado funcionar cada vez mejor. Como le pasó a Eclipse especialmente los primeros años. Y ahora UML estaría posiblemente en un trono. O no... (pero yo pienso que sí!).<br />
<br />
Se puede decir que en los 2000, sin haber acabado nunca de despegar, UML se fue difuminando cada vez más. Se necesitaban nuevas herramientas. Comenzaron a aparecer "plugins" de UML para Netbeans y/o Eclipse, la mayor parte de ellos siguiendo el modelo de Rational, es decir: orientado a la documentación, y de pago. También surgió alguna herramienta de UML gratuita, como <a href="http://argouml.tigris.org/">ArgoUML</a>, pero por un lado en general seguían estando orientadas a la documentación, y por otro el acabado normalmente no era suficiente como para convencer a nadie para que las usara.<br />
<br />
En el año 2002 (o quizá 2001), aparece un plugin para Eclipse llamado "EclipseUML" y creado por una empresa llamada <a href="http://www.omondo.com/"><b>Omondo</b></a>. Las intenciones de Omondo eran muy buenas, el plugin es gratuito y siguen la filosofía "LiveSource" de Together, es decir, el modelo UML se guarda en las propias clases Java. Omondo rebautizó esta técnica como "live round-trip". Las primeras versiones no tenían tanta funcionalidad como tenía el Together, pero al estar integradas con Eclipse, el IDE de Java seguía siendo el mejor. Y lo cierto es que el editor de UML no estaba mal y cumplía muy bien con lo mínimo que se le podía pedir. ¿Esperanza?.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiD3PTpQKV70_qebUJm7NV_PTwieLwpsZKP3dBJtGUB0v9xHPsJFjw_3qv945VYucrFtDz_PuN33x-UVOmuIcetbBiTbigT4g_G4l3SryJbS4fXUr472kQjACbzCL4NaqxPyKjjiFc10BHD/s1600/tio-gilito.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="157" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiD3PTpQKV70_qebUJm7NV_PTwieLwpsZKP3dBJtGUB0v9xHPsJFjw_3qv945VYucrFtDz_PuN33x-UVOmuIcetbBiTbigT4g_G4l3SryJbS4fXUr472kQjACbzCL4NaqxPyKjjiFc10BHD/s200/tio-gilito.jpg" width="200" /></a></div>
Pero todo se fue al traste en cuanto alguien se dio cuenta de que eso que estaban haciendo ellos, hasta ese momento se estaba cobrando. El dólar volvió a aparecer. Así, el producto empezó a ofrecer una versión gratuita y otra de pago. Una de las "pequeñas" diferencias entre ellas era... que la versión gratuita no se podía usar en proyectos que estuvieran bajo control de versiones, es decir, CVS, Subversion, etc... espera... ¿¿¿pero qué proyecto medianamente serio no está en control de versiones???. Si esto ya de por sí es casi casi volver a caer en los mismos errores del pasado (hay una ventaja importante, y es que seguimos dentro de Eclipse), de repente a los señores de Omondo se les ocurre que por si acaso eso no es suficiente para hundir del todo el producto, mejor darle un empujoncito. Así, en un momento dado por cada versión nueva del plugin que sacaban, cambiaban el formato de los ficheros de diagramas. Es decir, si cambiabas la versión del plugin, tenías que <b>volver a dibujar</b> todos los diagramas. Como además la versión del plugin estaba ligada a la versión de Eclipse, si querías actualizar Eclipse tenías que actualizar el plugin. Ni sé, ni quiero saber, qué habrá sido del plugin de Omondo. Sólo sé que cuando he visto alguna vez su página me ha parecido que volvían a haber cada vez más y más funcionalidades "avanzadas". ¿Repitiendo más errores del pasado?.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-tX64P4MGFuzNfDncLJMtQYNRZExSAbT-F_Uy7n9hgBmAdT6ykBrmQ9EquHZSQYzyCo4efokuR2VyxfJtn6fjhaGYJkx9Y_PRR_-6yH9ImYYveYuo693CPPTskI89hC90ddMSsisTXeHE/s1600/classdiagram.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" height="300" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-tX64P4MGFuzNfDncLJMtQYNRZExSAbT-F_Uy7n9hgBmAdT6ykBrmQ9EquHZSQYzyCo4efokuR2VyxfJtn6fjhaGYJkx9Y_PRR_-6yH9ImYYveYuo693CPPTskI89hC90ddMSsisTXeHE/s400/classdiagram.gif" width="400" /></a></div>
<br />
<br />
También ha habido alguna aproximación diferente, limitada pero interesante. Por ejemplo <a href="http://www.umlgraph.org/"><b>UMLGraph</b></a>, que propone algo radicalmente distinto: en lugar de dibujar nosotros los diagramas, esta herramienta los <b>generará automáticamente</b> y los meterá dentro del JavaDoc. El modelo por tanto es también el modelo Java, usando también anotaciones para enriquecer la información UML. Esta aproximación me parece muy interesante como herramienta complementaria, pero no tanto como herramienta única.<br />
<br />
Han aparecido también otros plugins gratuitos con la idea del LiveSource, como por ejemplo <a href="http://green.sourceforge.net/">Green UML</a>, pero el problema de este plugin es... el que dice el nombre, que está verde cual aceituna bañada en rayos gamma (aunque confiamos en que florezca y se convierta en una linda mariposilla). Otros plugins son gratuitos pero siguen con la idea del diseño como documento y la mandanga del roundtrip, como <a href="http://www.papyrusuml.org/">Papyrus</a> ó el propio plugin oficial de Eclipse <a href="http://wiki.eclipse.org/MDT-UML2">MDT / UML2</a>.<br />
<br />
Es frustrante, porque teniendo en cuenta la arquitectura modular de Eclipse y que tiene módulos para tanto para hacer fácilmente diagramas como para manejar el código fuente de Java a cualquier nivel, lo cierto es que hoy por hoy <b>sería fácil</b> hacer un editor de UML con LiveSource. Ahí tenemos el ejemplo del Green UML, ¡que surgió como un proyecto hecho por estudiantes en la Universidad! (no tengo claro si fue para un proyecto de fin de carrera o para una tesis, pero imagino que fue para algo así).<br />
<br />
¿Está todo perdido?. ¿Caemos una y otra vez en los mismos errores?. ¿Qué es lo mínimo que debería tener una herramienta UML para que sea práctica al trabajar en proyectos Java?. ¿No existe ninguna ahora mismo que apunte a eso, todo son fracasos?. ¡Quiero usar una!. ¿Andrés, eres tan abuelo cebolleta que no eres capaz más que de hablar del pasado?. La respuesta a todas estas cuestiones, en la tercera parte de esta serie sobre UML, que como no podía ser de otra forma se llamará "<b>UML y la última cruzada</b>". En pocas semanas en este humilde blog.<br />
<br />Andréshttp://www.blogger.com/profile/06010147149377176406noreply@blogger.com5