miércoles, 6 de enero de 2021

Pasar primera misión del Assasin's Creed Brotherhood, defender la fortaleza a cañonazos

  Hola a todos, feliz año, bueno comenzaré con un repaso breve del por qué de ésta publicación. Primero que todo mis más grandes decepciones para el equipo de desarrollo de Cyberpunk 2077, los más chapuzas del mundo, por su culpa no puedo completar la historia del juego por un maldito bug. En serio no necesitamos desarrolladores chapuzas que hacen mierdas de juegos injugables o aplicaciones que petan, para eso ya están los becarios o personal en práctica o yendo más lejos un experimento con chimpancés adiestrados para programar cosas básicas porque no creo que fuera el caso, rechazado por compañías desarrolladoras de juegos por mi inexperiencia en el sector me frustra y desagrada mucho ver cosas cómo éstas de nivel mierder. Bueno después de desahogarme un poco os cuento, desinstalé el Cyberpunk 2077 y me descargué por Steam un juego que tuve en una plataforma de Play que no llegué a completarlo y que me quedó pena no hacerlo, Assasin's Creed Brotherhood. De nuevo en mis manos pero ésta vez en PC vuelvo a jugarlo con el fin de acabar la historia que comencé.

El juego recuerdo en su día que no era muy complicado pero mi sorpresa fue jugarlo recientemente en PC. No se si es que le han subido la dificultad o que con la edad me he vuelto más torpe jugando pero la primera secuencia después de echarle un polvo a la Caterina Sforza nos levantamos de la cama con cañonazos sobre nuestra cabeza.



La misión comienza corriendo a tú caballo para dirigirte a lo alto de la muralla para defenderla del implacable ataque de los malditos Borgia ¿por qué dejaste con vida a ese español desgraciado?


La misión aparentemente es sencilla, destruir los cañones que asedian la muralla. Según se desarrolla la misión nos mostrará a un lado, a la izquierda de la pantalla, un marcador con los ciudadanos totales que se encuentran dentro de la fortaleza y al lado el número restante por escapar o evacuar. Yo ésta misión no la recordaba bien desde la última vez que la jugué, hace mil años por ahí, pero no recuerdo que fuera tan increíblemente difícil.

El problema que se nos presenta es que es imposible acabar con todos los cañones en el tiempo dado que es el tiempo que tardan los cañones en cargarse la fortaleza. Es más, yo no he conseguido a día de hoy acabar con todos los cañones aunque si, después de decenas de intentos, la superé.

El truco amigo mío consiste, para superar la misión, en retrasar la destrucción de la fortaleza. No es necesario acabar con todos los cañones pero si con los potencialmente peligrosos para la fortaleza y que aceleran la destrucción de ésta. Dichos cañones que debes priorizar su destrucción son todos los de la izquierda, empezando siempre por los que tengas en frente y luego los que se encuentren a tú izquierda, luego saltará una secuencia donde te quedas sin el cañón de la izquierda, que es el que debes acudir primero, y deberás irte al cañón de la derecha destruyendo primero los cañones que estén apuntando hacia a ti, en frente. Si observas bien los cañones giran y apuntarán, algunos muy arriba con lo que tendrán disparos muy oblicuos (parabólicos, como el de un mortero) de riesgo bajo para las murallas, pasando los disparos sobre tú cabeza, pero los peligrosos serán aquellos con un ángulo bajo y situados próximos a la muralla, que realizarán disparos directos con mucha precisión y continuados. De esa forma dando prioridad a los cañones que aceleran la destrucción de la muralla ganaremos el tiempo suficiente para la evacuación completa marcada en el objetivo y podremos superar la misión.

En algunos foros hablan de activar la sincronización vertical, acabar con TODOS los cañones o hacer pequeñas trampas para engañar el reloj del juego pero eso son memeces (trolleo puro), no hagáis caso a eso y seguir el consejo que os indico.


Por cierto, aprovecho para recomendar encarecidamente el Assasin's Creed Odyssey. Es un juegazo, con buenos gráficos, historia divertida, RPG, decisiones que afectan al desarrollo del juego, sexo, buena música, buena optimización, un mundo abierto increíblemente grande, misiones navales... super recomendado

domingo, 25 de octubre de 2020

Hilos y listas en Java

 El otro día en un desarrollo cualquiera un compañero debía resolver un problema en una tarea con Katalon, recorriendo una lista de registros que se usarían en llamadas vía API REST. El problema es que le parecía lento e incluso me indicaba que tendía a petar.

Al final en una reunión con los sabios de equipo se propuso optimizar usando hilos, crear paralelamente varios procesos, un pool, que fuera atacando a la lista y procesando llamadas. Se lo hice así improvisando en "tiempo real" XD un ejemplo con una declaración anónima en un bucle que repetía mientras la lista contuviera algo, para ello le sustituí el List por un LinkedList que una de sus peculiaridades es que usa métodos para gestionar la lista como una pila, dispones del método pop para obtener el elemento y de paso eliminarlo de la lista, algo que ya te ahorra bastante trabajo.

El ejemplo funcionó pero no se estaba teniendo en cuenta algunas cosas cómo el control de hilos que se generaba, aunque si es cierto que se usaba una variable que contaba los hilos, pero en resumen la concurrencia era un desastre, una chapuza

Días después en mi día libre he realizado un ejemplo mejor con alternativas al uso de la clase base por excelencia, Thread.

Lo único que sobra es la variable boleana busy que se puso con el pretexto de evitar el acceso concurrente (a la vez de la lista) por varios hilos ejecutados en paralelo. Al final la sustituí por la instrucción syncronized pero me olvidé de quitar el boleano que ya no se usaba.



martes, 25 de junio de 2019

Sombra Circular Para Imagen

Seguramente maquetando más de alguno se habrá vuelto loco a la hora de hacer una sombra circular a un icono, normalmente flotante. Para resolverlo la práctica más sencilla es tomando una sombra de tipo bitmap y posicionarla debajo de la imagen. Ésto podría servirnos si se plantea compatibilidad con navegadores viejos o que no soportan CSS3.


CSS3


En CSS3 disponemos de una serie de nuevas funcionalidades en las que se encuentra box-shadow , que sirve para crear sombras. Las sombras son para las etiquetas, que son cuadradas, pero ésto no es problema si lo combinamos con la propiedad border-radius, en la cual podemos indicar cuanto de redondo queremos que sean las esquinas de la etiqueta. La sombra generada se adaptará a la silueta de la etiqueta.

Algunas veces puede que la imagen escogida no encaje bien, para solucionar eso habría que prescindir de la etiqueta img y trabajar con el background-image, para asignar una imagen, el background-size, para configurar el tamaño de la imagen (no de la etiqueta) y por último hacer un background-position : center.

sábado, 15 de junio de 2019

La Chica De Junio


 Con ustedes Naomi Wu, alias sexycyborg, quien es además conocida por diversas facetas entre ellas la de promocionar productos electrónicos chinos en youtube. Es una apasionada de la tecnología, la impresión 3D y cuando puede luce palmito cosplayer sexy también. Inteligente y sexy, para mi la mujer perfecta 😍


viernes, 14 de junio de 2019

Framework Minimalista MVC En Php

 Bueno, antes de comenzar hablar sobre el tema de la entrada o publicación quisiera hablar de otra cosa, más que nada para desahogarme un poco, porque es un tema que me ha repateado desde que he comenzado recientemente en el mundo corporativista de las empresas. Yo anteriormente vengo de realizar desarrollos freelance/autónomo, en teoría un portafolio debería ser prueba inequívoca de que sabes moverte en el mundo de la programación y si a eso le sumas que tienes estudios oficiales relacionados con el desarrollo de aplicaciones pues yo creo que no cabe duda que es así. El proyecto que presento es prueba de que ésto no es así, las empresas exigen a los candidatos a un puesto de trabajo pruebas y entrevistas que para mi rayan un poco el absurdo, si a eso le sumas que después de exigir una prueba ya no es que te rechacen por hacerla mal desde el punto personal de la persona que se encarga de seleccionar sino peor aun, no te comunique en que punto del proceso te encuentras, no conteste o se haga el loco. Yo desde las dos pruebas realizadas, bastante complicadas por cierto, nunca volveré a realizar ninguna más. Para entender lo absurdo de la cuestión, usted cuando contrata un electricista o un fontanero ¿le hace alguna prueba? le dice, mire monte un grifo antes de contratarlo y si ya, pues ya veremos si lo contratamos(hay como diez fontaneros haciendo la prueba, montando grifos para demostrar su pericia). Pues eso pasa o me ha pasado.

 Éste proyecto como antes comenté fue para demostrar que estaba al tanto del funcionamiento de un modelo MVC en este caso con Php, no bastaba que supiera Laravel o Symfony, quería demostrar que además de saber trabajar con los frameworks más conocidos también sabía como funcionaban interiormente, que no sólo me dedico a picar código (que de vez en cuando lo hago), sino que también puedo hacer uno. Claro que hacer un framework bien hecho con todas sus tonterías toma mucho trabajo y como siempre ¿por qué reinventar la rueda? pues eso, aquí como lo que se mostró el otro día en la versión front es puramente de propósito educativo. Y bueno, si alguien les pide una prueba para algún trabajo como a mi pues por qué no copiarlo.

Framework MVC y enrutador


 Un marco MVC, modelo, vista y controlador, es un marco actualmente muy extendido en los grandes desarrollos, como contamos en la entrada anterior es un patrón de diseño que mejora la organización y mantenimiento del programa obteniendo mejores resultados en tecnologías que soportan la programación orientada a objetos como es el caso de java

 Normalmente los frames de desarrollo web que soportan MVC disponen de un sistema para enrutar, ésto significa que permiten definir rutas que son direccionadas desde la página principal a sus convenientes vistas. Ésto se realiza mapeando asociativamente las rutas con las vitas o controladores de vistas. Para éste caso, como se muestra abajo, se ha usado vistas con código embebido, pero perfectamente podría haber sido un controlador compuesto por una clase con varios métodos y que retornara una página tal como hacen por ejemplo Spring o Symfony 4.
$request = filter_input(INPUT_SERVER,'REQUEST_URI'); 
$rutas = ["/"         => "indice"  , // MAPA
          "/login"    => "login"   ,
          "/registro" => "registro",
          "/salir"    => "salir"   ,
          "/admin"    => "admin"   ,
          "/home"     => "home"    ];

if (array_key_exists($request, $rutas)!=false){
   require "Vistas/$rutas[$request].php"; // Redireccionamos

Estructura de ficheros


 Para una buena organización es recomendable o mejor dicho deseable sobre todo para este propósito disponer de una estructura intuitiva de directorios. Lejos de lo que algunos puedan imaginar, al final los controladores, vistas y modelos son simplemente ficheros que internamente tendrán quizás que disponer de un código adicional según el caso pero que suelen ser clases o código que deberá estar anclado en el espacio de trabajo(namespace, package, etc...) de la aplicación para poder estar localizado cuando sea requerido.

 En mi caso opté por crear una estructura similar a las empleadas por muchos frames Php conocidos, en la raíz el index.php (el enrutador) y luego tres directorios principales, modelos, vistas y controladores. 


Sobre el proyecto


 Para este ejemplo sólo se usaba un modelo, un usuario, y varios controladores que permiten llevar el registro de la cuenta de un usuario y acceso, con posibilidad de trabajar con roles. El sistema incluye control de sesiones artesanal, en plan cutre, y un sistema de verificación vía correo electrónico que provee la librería PHPMailer.

 El proyecto como siempre disponible en mi Github, cualquier duda hacérmela saber e intentaré en la medida de lo posible aclararla. No olviden que si quieren probarla deben configurar la información de la base de datos y correo electrónico.

 Bueno ésto es todo, ahora posiblemente me desapareceré un par de meses buenos trabajando con otras cosas que si tengo posibilidad ya contaré en siguientes entradas. Mañana puede que publique la chica del mes 😁que ya llevo tiempo sin presentar a ninguna y en este blog también se habla de mujeres y a quien no le guste que se aguante 😤

miércoles, 12 de junio de 2019

FrameWork Sencillo En VanillaScript O Algo Parecido


 Buenas, pues aquí estamos, a piñón con el desarrollo Web, aunque no es de mis pasiones a pesar de haberlo estudiado, más que nada porque no había otra cosa que estudiar, pues es importante para mi de cara al trabajo que desempeñaré. Espero que con experiencia algún día pueda saltar a otras ramas del desarrollo.

 Vale, pues lo que les traigo hoy aquí, es un sencillo framework con propósito meramente educativo, no se trata de reinventar la rueda, pero es importante tener un conocimiento de como funcionan esas cosas tipo Vue JS, React, Angulares y demás, que intentan facilitar el desarrollo en el frontend por medio de un marco de trabajo modular, que permita implementar la aplicación de forma organizada y modificar los módulos de éste sin mucho costo.

Etiquetado personalizado y componentes


 Este tipo de frames, los citados anteriormente, destacan por el uso de los llamados componentes, digamos que la filosofía es llevar la programación orientada objetos a límites insospechables en el front integrando objetos que tengan parte lógica, funcional, propiedades o atributos y una vista o plantilla que les confiera en resumen una independencia del resto de componentes pero que permita integrarse conjuntamente con todo.

 En el ejemplo que mostraré abajo de nuestro componente se trata simplemente de una estructura, que bien podría ser una clase, que muestra las características descritas. 


{ "etiqueta": {
                body: {
                    campo1: 'soy el campo1',
                    campo2: 'soy el campo2'
                },
                template: "<h1> {{ campo1 }} / {{ campo2 }} </h1>" }

 Como se puede apreciar arriba, hemos definido una propiedad template para nuestro componente que define como será visualmente, la plantilla, así como un nombre de etiqueta que representará al componente tanto en nuestro html como cuando nos queramos referir a éste en el programa.

 Dentro de la propiedad body estarán los atributos de la plantilla, que estarán vinculados al render, de esta forma se diseñará para que cuando trabajemos con el componente nos olvidemos de la parte que actualiza el html. Prácticamente ésto nos permitirá ocuparnos solamente de la funcionalidad del componente.

 En muchos de los frames se facilitan instrucciones embebidas en las etiquetas, tipo como for o if, ésto no está contemplado en la publicación porque simplemente no he querido generar mucha complejidad. Para los que estén interesados en saber como se haría les diré que simplemente se trata de definir propiedades a las etiquetas y en los valores se toma el resto de instrucciones y los valores o argumentos. Claro que después hay que incluirlo, pero no es difícil. Ejemplo:

<etiqueta for="let i=0 to 10"></etiqueta>


Estructura principal e integración de los componentes

 Como vamos a tener todo organizado vamos a definir nuestro marco de trabajo, framework, con el nombre de app aunque podría ser cualquier nombre. Nuestro marco de trabajo incluirá una parte donde se indicarán los componentes, llamada igual, que existirán en el programa, instanciados en la página. Digamos que la parte del código es lo que representa o define el componente mientras que su instancia la llevará a cabo el motor del frame al examinar la página del programa.

 Por último la parte del main, es el ámbito donde trabajaremos con las estancias que estarán generadas como se dijo por el frame, invisible para nosotros. En dicha parte es donde definiremos el programa y el comportamiento de los componentes, por ejemplo definir un evento para que haga algo, como un click, o cualquier cosa.

 Ejemplo de la página:

<head>
    <meta>
    <style>
        etiqueta {
            background: red;
            display: block;
        }
    </style>
</head>

<body>
    <h1>Hola mundo</h1>
    <etiqueta></etiqueta>
    <etiqueta></etiqueta>
</body>

 El código en nuestro script:


app = {
    componentes: [{
        "etiqueta": {
            body: {
                campo1: 'soy el campo1',
                campo2: 'soy el campo2'
            },
            template: "<h1> {{ campo1 }} / {{ campo2 }} </h1>"
        }
    }],
    main() {
        this.etiqueta[0].campo1 = "Soy un frame sencillo sin mucha ambición";
        this.etiqueta[1].click = function() {
            alert("Hola holita");
        };
    }
}


Para no complicar la cosa, el motor genera las instancias en un array con el nombre de la etiqueta. Por ejemplo si agregáramos otro componente llamado listado y sólo hubiera una instancia en la página simplemente accederíamos a ella en el programa como listado[0]. En el caso que exponemos en el ejemplo observamos que tenemos un componente etiqueta definido en componentes y en la página tenemos dos instancias de este por eso accedemos con etiqueta[0] para el primero, orden descendente (luego veremos por qué), y al segundo componente accedemos por etiqueta[1].


Motor del framework


 El engine o motor es la parte que no se ve, es la que normalmente se llama por medio del enlace pertinente. Lo ideal sería crearse un código ofuscado del motor y vincularlo, así la página estaría más clara y sólo trabajaríamos con la estructura del frame.

 Para desarrollar este muy sencillo framework sólo vamos a requerir de una función recursiva que nos permitirá navegar por los nodos de forma amistosa. A la función le vamos a pasar el nombre de la etiqueta que queramos localizar y asignarle una acción.

// Herramienta
function buscaTag(nodo, tag, action, retorno) {
    tag = tag.toUpperCase();
    nodo.childNodes.forEach((item) => {
        if (tag == item.nodeName) {
            if (retorno) return action(item);
            action(item);
        }
        buscaTag(item, tag, action);
    });
}



 Luego habrá que inicializar el framework. En esta parte se comprueban los componentes disponibles y se instancian los componentes para que estén accesibles en el programa. En el código he usado la función eval(), para instanciar, pero puede hacerse de otra forma, eso es a gusto del consumidor.


// inicializadomos!!
buscaTag(document.getRootNode(), "html", function(item) {
    app.html = item;
}, true);
// Examinamos los componentes disponibles y creamos las instancias de estos
app.componentes.forEach(componente => {
    var i = 0;
    var nombreComponente = Object.keys(componente)[0];
    app[nombreComponente] = [];

    // Instanciamos componentes
    buscaTag(document.getRootNode(), nombreComponente, function(item) {
        item.id = nombreComponente + i;
        eval("app." + nombreComponente + "[" + i + "]=" + JSON.stringify(componente[nombreComponente].body));
        i++;
    }, false);
});
// Ejecutamos el programa
app.main();

 Y por último tenemos la parte que actualiza periódicamente. Como podrán observar las propiedades renderizables de las plantillas se buscan por medio de una sencilla expresión regular y luego se sustituye con el valor acorde que tenga el componente en ese momento. Aunque parezca todo muy estático podemos comprobar por ejemplo mediante la consola del navegador como es posible acceder a la aplicación por medio del objeto app y modificar la función click() de cualquiera de los dos componentes existentes en el ejemplo o cambiar el contenido de los campos que en un segundo estará todo actualizado.


// Actualizamos!! (cada segundo)
window.setInterval(() => {
    /////////////////////////////////////////////////////
    app.componentes.forEach(componente => {
        var nombreComponente = Object.keys(componente)[0],
            appComponente = componente[nombreComponente],
            i = 0;

        buscaTag(app.html, nombreComponente, function(item) {
            componente = app[nombreComponente][i];
            componente["render"] = appComponente.template;

            // sustituimos los atributos por sus valores
            Object.keys(appComponente.body).forEach(atributo => {
                componente.render = componente.render.replace(
                    new RegExp("({{)+[\\s](" + atributo + ")+[\\s]+(}})", "g"), componente[atributo]);
            });

            // introducimos el render
            let etiqueta = document.getElementById(nombreComponente + i);
            if (etiqueta.innerHTML !== componente.render) {
                etiqueta.innerHTML = componente.render;
            }

            // Añadimos propiedades especiales como eventos ...
            var elementoDom = document.getElementById(item.id);
            elementoDom.parentNode.replaceChild(item.cloneNode(true), item); // Eliminamos eventos
            if (app[nombreComponente][i].click !== undefined) {
                document.getElementById(item.id).addEventListener("click", app[nombreComponente][i].click);
            }

            i++;
        }, false);
    });
}, 1000);

 Como ven todo ésto de los frameworks no es magia y sólo se trata de una especie de patrón de diseño para organizar mejor el desarrollo y mantenimiento de la aplicación. Quizás en otra ocasión con tiempo pueda mostraros lo mismo pero en la parte del backend, en Php of course.

  Si quieren cacharrear subo el fichero a mi espacio Github para que piquen y hagan experimentos, que lo disfruten y me dicen si quieren que la próxima entrada sea el framework de Php o comenten alguna sugerencia. Bye.

sábado, 3 de febrero de 2018

La chica de febrero

 Lleva mucha ropa porque hace frío todavía, aquí por lo menos en el hemisferio norte. Habrá que esperar a la primavera señores.