Oct 06

AjedrezPlus – Estrategia con las Posiciones tácticas

Ante esta segunda parte de AjedrezPlus objetivo 2024, dedicada a las posiciones tácticas de partidas reales he pensado en una estrategia que voy a tratar de implementar.

Se trata de hacerlo en dos fases:

Fase 1: Selección completa de problemas

Fase 2: Publicación de los problemas

En la primera fase se trata de recopilar todos los problemas a publicar, documentarlos en la hoja excel y preparar las bases de posiciones y partidas con estos problemas.

Se trata de recopilar unos 209 problemas.

En la segunda fase me dedicaré a publicar en el blog de AjedrezPlus y en AjedrezenMadrid los problemas seleccionados.

Tal vez para probar la viabilidad de este procedimiento haga una pequeña prueba con unos cuantos problemas, y si lo veo efectivo lo realizaré hasta el final de esta segunda parte del proyecto AjedrezPlus objetivo 2024.

 

Oct 06

Posiciones tácticas en el Blog AjedrezPlus sin partida

Lo importante del apartado de posiciones tácticas en AjedrezPlus son las posiciones, eso no me debe hacer perder la perspectiva y encorsetar mi trabajo.

He llegado a la conclusión de que obligar a que cada posición táctica esté respaldada por una partida completa es una limitación inaceptable.

El razonamiento de esta política de publicación es que hay una gran cantidad de posiciones tácticas fantásticas de las que no se conocen (o yo no las tengo) las partidas completas. Y ese no puede ser motivo para dejarlas a un lado. Me parece un desperdicio innecesario.

La solución es tan sencilla como no enlazar a ninguna partida si no se tiene la partida completa. Ya se planteaba así en los primeros problemas del blog, así que por lo tanto no es nada nuevo.

A los usuarios de esta sección se les presentan problemas tácticos ocurridos en partidas reales, y la partida completa es un pequeño plus al problema. Conocer el origen de la posición y su desarrollo completo no cabe duda de que es algo enriquecedor, pero es sólo eso, un pequeño añadido al objetivo principal que es la posición y su correspondiente solución.

Técnicamente hablando mantendré para trabajar las dos bases de datos (posicionesBlog y posicionesBlogPartidas) pero salvando en la de partidas la misma posición que en la de posiciones, para que la numeración entre ambas siga siendo la misma.

Oct 03

Fin de la primera etapa en AjedrezPlus 2024

Ayer terminé la primera etapa de mi proyecto de publicar problemas en AjedrezPlus hasta 2024.

En concreto he programado publicaciones de los problemas de Mate en 2 hasta el 11 de abril de 2024. Es un problema por semana, así que son aproximadamente unos 235 problemas a día de hoy, hasta la fecha de publicación del último.

Pienso que este tipo de problema es el más sencillo de publicar de los tres que planteo, y sospecho que el que menos gusta a los visitantes de la web por su dificultad y «truculencia» en ocasiones. Los otros dos, Táctica y Red de mate, serán un trabajo más duro debido a que la elaboración de cada problema es más compleja.

Mi objetivo sigue siendo conseguir que en marzo de 2020 tenga todos los problemas programados hasta cuatro años vista (2024). Fecha en la que, si mi salud me lo permite, estaré ya jubilado y podré retomar éste proyecto. Pudiendo en esos cuatro años dedicarme a otras cosas.

Por otro lado sigo trabajando, dentro del apartado de test de AjedrezPlus en dos nuevos grupos de problemas, concretamente en el de Finales de Torres, que está muy avanzado, y el de la Defensa Holandesa Sistema Muro de Piedra con Negras, que estoy empezando en estos días. Lo que no sé es cuando los podré publicar ya que ahora no son prioritarios y sólo les dedico tiempo cuando no estoy muy saturado con los problemas de Táctica y Red de mate para 2024.

Ago 31

Primera página con CodeIgniter

Modificaciones en application\config

database.phpautoload.phproutes.phpconfig.php
...
$db['default']['hostname'] = 'localhost';
$db['default']['username'] = 'root';
$db['default']['password'] = '';
$db['default']['database'] = 'aem';
$db['default']['dbdriver'] = 'mysql';
$db['default']['dbprefix'] = '';
$db['default']['pconnect'] = TRUE;
$db['default']['db_debug'] = TRUE;
$db['default']['cache_on'] = FALSE;
$db['default']['cachedir'] = '';
$db['default']['char_set'] = 'utf8';
$db['default']['dbcollat'] = 'utf8_general_ci';
$db['default']['swap_pre'] = '';
$db['default']['autoinit'] = TRUE;
$db['default']['stricton'] = FALSE;
...
...
$autoload['libraries'] = array('database');
...
...
$route['default_controller'] = "Torneos";
...
...
$config['base_url'] = 'http://localhost/aem3';
...

Páginas del modelo MVC

controllers/torneos.phpviews/home.phpmodels/torneo_model.php
<?php
class Torneos extends CI_Controller {
   function index(){
      //cargo el helper de url, con funciones para trabajo con URL del sitio
      $this->load->helper('url');

      //cargo el modelo de artículos
      $this->load->model('Torneo_model');

      //pido los ultimos torneos al modelo
      $ultimosTorneos = $this->Torneo_model->dame_ultimos_torneos();

      //creo el array con datos de configuración para la vista
      $datos_vista = array('rs_torneos' => $ultimosTorneos);

      //cargo la vista pasando los datos de configuacion
      $this->load->view('home', $datos_vista);
   }
}
?>
<html>
<head>
  <meta charset="UTF-8" />
  <title>Portada de mi sitio</title>
</head>
<body>
<h1>Bienvenido a mi web</h1>
<p>Estos son los &uacute;ltimos torneos publicados.</p>
<?php
while ($fila = mysql_fetch_array($rs_torneos)){
   echo '<p>';
   echo '<a href="' . site_url('/torneos/muestra/' . $fila['cdgo_torneo']) . '">' . $fila['nombre_torneo'] . '</a>';
   echo '</p>';
}
?>

</body>
</html>
<?php
class Torneo_model extends CI_Model {

   function __construct(){
      parent::__construct();
   }

   function dame_ultimos_torneos(){
      $ssql = "select * from tabla_torneos order by cdgo_torneo desc limit 10";
      return mysql_query($ssql);
   }
}
?>

 

controllers/torneos.php
<?php
class Torneos extends CI_Controller {
   function index(){
      //cargo el helper de url, con funciones para trabajo con URL del sitio
      $this->load->helper('url');

      //cargo el modelo de artículos
      $this->load->model('Torneo_model');

      //pido los ultimos torneos al modelo
      $ultimosTorneos = $this->Torneo_model->dame_ultimos_torneos();

      //creo el array con datos de configuración para la vista
      $datos_vista = array('rs_torneos' => $ultimosTorneos);

      //cargo la vista pasando los datos de configuacion
      $this->load->view('home', $datos_vista);
   }
}
?>

Un controlador en CodeIgniter es un archivo que contiene el código de una clase, de programación orientada a objetos, que colocamos en un directorio específico del esquema de carpetas de nuestro sitio. Tiene un nombre cualquiera, que se asociará con una URL de nuestra aplicación web.

Por ejemplo, esta podría ser una URL de nuestra aplicación:

midominio.com/index.php/torneos

En la URL anterior podemos ver que la palabra «torneos» determina la página que queremos ver dentro de nuestra aplicación. Pues bien, para poder atender esta solicitud nosotros vamos a tener que crear un archivo llamado torneos.php (el controlador) dentro del directorio que aloja los controladores de nuestra aplicación.

Por tanto, cuando CodeIgniter detecta una URL como esta, intentará acceder al archivo articulos.php, para cargarlo, procesarlo y de ese modo mostrar la página con los contenidos de esta sección.

Cuando ese controlador no se encuentre entre los archivos de controladores de CodeIgniter, simplemente se mostrará un error 404 de página no encontrada. Si se encontró el controlador, como se decía, se carga y se procesa para mostrar la página.

Los controladores en CodeIgniter se guardan en la carpeta «system/application/controllers/», que se encuentra dentro de los archivos de CodeIgniter.

Analizando el controlador

  • En nombre del archivo de controlador, en este caso torneos.php, va en minúsculas.
  • El nombre de la clase que implementa el controlador se tiene que llamar igual que el nombre del archivo, pero fijaros que tiene obligatoriamente la primera letra en mayúscula. Por eso aparece como class Articulo extends Controller.
  • Todos los controladores tienen que extender la clase «Controller» (que también tiene la primera letra «C» en mayúscula), que está creada dentro de CodeIgniter y en principio no necesitamos modificarla para nada.

Una vez creado el archivo, podemos acceder con el navegador al controlador, con una URL como esta:

http://luismaseda.com/aem3/index.php/torneos

Un momento ¿Qué significa extender una clase?

class Torneos extends CI_Controller

Frecuentemente son necesarias clases con variables y funciones semejantes a los de otra clase ya existente. De hecho, es una buena práctica definir una clase genérica que pueda ser utilizada en todos sus proyectos y adaptar esta clase a las necesidades de cada uno de sus proyectos específicos.

Para facilitar esto, las clases pueden ser extensiones de otras clases. La clase extendida (Torneos) tiene todas las variables y funciones de la clase base (CI_Controller) y aquello que se agregue en la definición extendida (Torneos). No es posible disminuir una clase, es decir, remover la definición de cualquier función o variable existente. Una clase extendida siempre es dependiente de una sóla clase base, es decir, la herencia múltiple no está soportada. Las clases son extendidas utilizando la palabra clave ‘extends’.

En el caso de class Torneos extends CI_Controller se define una clase llamada Torneos que contiene todas las variables y funciones de CI_Controller más una función adicional $index().

Hemos colocado una función index(), que es la que se llamará cuando se acceda a este controlador tal cual. Dentro de index estamos invocando una vista.

Nota:
¡Las clases deben de estar definidas antes de ser utilizadas! Si se desea que la clase Torneos extienda a la clase CI_Controller, se tendrá que definir primero la clase CI_Controller. Si se quiere crear otra clase llamada Calendario basada en la clase Torneos se tiene que definir primero Torneos.

Resumiendo: el orden en que las clases se definen es importante.

Controlador por defecto

Hay que hablar sobre el controlador por defecto, que es el que se invoca en CodeIgniter cuando no se especifica ningún nombre de directorio y por tanto ningún controlador, en la siguiente URL:
midomino.com/index.php/

O bien en esta otra:

midominio.com/

Esto, que sería la home de la aplicación CodeIgniter, y eventualmente la home del dominio, si es que hemos instalado el framework en la raíz del directorio de publicación, invoca también un controlador, que es el controlador por defecto.

El nombre del controlador predeterminado (Default Controller) puede ser variable, siendo el desarrollador el encargado de configurarlo en uno de los archivos de configuración de CodeIgniter, que se encuentra en el fichero «application/config/routes.php».

En ese archivo simplemente tenemos que buscar el valor $route[‘default_controller’] y asignarle el nombre de la clase donde está el controlador que queramos que se invoque. Como es el nombre de una clase de un controlador tendremos que escribirlo con la primera letra en mayúscula.

$route[‘default_controller’] = ‘Torneos’;

Si observamos el valor de esta variable de configuración, tal como está en el momento inicial, después de la instalación de CodeIgniter, veremos que el controlador por defecto está en la clase «Welcome», archivo application/controllers/welcome.php

Ahora, si ponemos la siguiente URL en nuestro navegador

http://luismaseda.com/aem3/

tendrá el mismo funcionamiento que poniendo:

http://luismaseda.com/aem3/index.php/torneos

Importante: Estamos diciendo que los controladores tienen funciones, pero en realidad deberíamos llamarles métodos, porque los controladores son clases y las clases tienen métodos y no funciones.


views/home.php
<html>
<head>
  <meta charset="UTF-8" />
  <title>Portada de mi sitio</title>
</head>
<body>
<h1>Bienvenido a mi web</h1>
<p>Estos son los &uacute;ltimos torneos publicados.</p>
<?php
while ($fila = mysql_fetch_array($rs_torneos)){
   echo '<p>';
   echo '<a href="' . site_url('/torneos/muestra/' . $fila['cdgo_torneo']) . '">' . $fila['nombre_torneo'] . '</a>';
   echo '</p>';
}
?>

</body>
</html>

Los controladores deciden qué hacer cuando se recibe una solicitud y las vistas deciden cómo mostrar los resultados. Por decirlo de otra forma, la lógica de nuestra aplicación residirá en el controlador y la vista mantendrá el aspecto de nuestra página, el diseño de la página que se mostrará al usuario.

Una vista se carga en el controlador mediante:

$this->load->view(‘nombreDeLaVista’);

En ‘nombreDeLaVista’ tendremos que indicar el nombre del archivo donde hemos guardado la vista, pero sin el «.php». En nuestro controlador se hizo mediante:

$this->load->view(‘home’, $datos_vista);

en la que también se cargó una variable con datos para ser utilizados por la vista: $datos_vista

Podemos ver cómo hacemos un recorrido a los registros de últimos torneos traídos desde la base de datos con ayuda del modelo y enviados a la vista por medio del controlador. Además, vemos que se está utilizando la función site_url() que pertenece al helper «url» que habíamos cargado en el controlador.

El resultado nos muestra los últimos torneos que se habían cargados en la base de datos, en la tabla_torneos, con un enlace a varias páginas, donde se muestra cada uno de los torneos (no creadas todavía).

models/torneo_model.php
<?php
class Torneo_model extends CI_Model {

   function __construct(){
      parent::__construct();
   }

   function dame_ultimos_torneos(){
      $ssql = "select * from tabla_torneos order by cdgo_torneo desc limit 10";
      return mysql_query($ssql);
   }
}
?>

Los modelos en el MVC son los módulos que tienen como responsabilidad el acceso y control de los datos que hay en bases de datos y mantienen encapsuladas todas las particularidades y complejidades de los accesos a las tablas para realizar cualquier tipo de operación.

En el patrón MVC, los modelos son una de las partes fundamentales, pero en el caso de CodeIgniter, su uso es sólo opcional. El desarrollador es el responsable de decidir si le viene bien el uso de los modelos o si prefiere realizar sus aplicaciones haciendo cualquier tipo de operación sobre la base de datos en los propios controladores.

Los modelos en la práctica son clases, de programación orientada a objetos, que tienen sus métodos o funciones, a los que se puede invocar desde los controladores para hacer operaciones con la base de datos.

Los modelos en CodeIgniter se construyen extendiendo la clase CI_Model y tenemos que nombrarlos con la primera letra en mayúsculas. Dentro del modelo que estamos creando tenemos que definir obligatoriamente un constructor, donde tenemos que hacer una llamada al constructor de la clase de la que hereda (clase parent, llamada __construct).

function __construct(){
parent::__construct();
}

Un modelo se carga en el controlador mediante:

$this->load->model(‘Nombre_model’);

Si queremos cargar varios modelos de una sola vez, podemos hacerlo pasando un array con todos los modelos que deseamos cargar:

$this->load->model(array(‘Torneo_model’,’Noticia_model’));

En nuestro controlador se hizo mediante:

$this->load->model(‘Torneo_model’);

Una vez cargado un modelo, sus métodos para el acceso a los datos estarán disponibles en nuestro controlador, a través del propio objeto controlador, el nombre del modelo que queremos accionar y la función que queremos invocar dentro del modelo.

$this->load->model->funcion_del_modelo();

database.php
...
$db['default']['hostname'] = 'localhost';
$db['default']['username'] = 'root';
$db['default']['password'] = '';
$db['default']['database'] = 'aem';
$db['default']['dbdriver'] = 'mysql';
$db['default']['dbprefix'] = '';
$db['default']['pconnect'] = TRUE;
$db['default']['db_debug'] = TRUE;
$db['default']['cache_on'] = FALSE;
$db['default']['cachedir'] = '';
$db['default']['char_set'] = 'utf8';
$db['default']['dbcollat'] = 'utf8_general_ci';
$db['default']['swap_pre'] = '';
$db['default']['autoinit'] = TRUE;
$db['default']['stricton'] = FALSE;
...
autoload.php
...
$autoload['libraries'] = array('database');
...
routes.php
...
$route['default_controller'] = "Torneos";
...
config.php
...
$config['base_url'] = 'http://localhost/aem3';
...
Ago 14

CSS3

id, clases, pseudo-clases

Conceptos básicos: CSS es un lenguaje que trabaja junto con HTML para proveer estilos visuales a los elementos del documento, como tamaño, color, fondo, bordes, etc.

Importante:
-moz (Mozilla) o -kevit (Chrome, Safari, Opera)

Estructura en Bloque

  • Cuando hablamos de estructura, nos referimos a la manera en la que un sitio web está dispuesto.
  • Cada navegador implementa una estructura por defecto.

Block

Son posicionados uno sobre otro hacia abajo en la página. (por defecto en los navegadores).

Inline-block

Son posicionados lado a lado, uno al lado del otro en la misma línea, sin ningún salto de línea a menos que no haya más espacio horizontal para ubicarlos.

Modelo de caja

Todas las reglas que especifican la disposición en la que será organizada una página web se le denomina «Modelo de Caja»

Conceptos

CSS3

  • Sobreescribe los estilos básicos del navegador
  • Puede crear nuevos estilos
  • Se pueden combinar los estilos para hacer cosas geniales

Estilos en línea

<p style=»font-size: 20px>Esto es un párrafo</p>

  • Forma
    • Simple
    • Rudimentaria
    • Poco práctica
    • Pero puede ser útil para una vista rápida de un estilo que deseemos implementar

Estilos embebidos

Una mejor alternativa es insertar los estilos en la cabecera del documento y luego usar referencias para afectar los elementos HTML correspondientes

<!DOCTYPE html>
<html lang="es">
    <head>
        <meta charset="UTF-8">
        <title>Elementos en bloque</title>
        <style>
           p { font-size: 20px }
        </style>
    </head>
    <body>
        <p>Esto es un párrafo</p>
    </body>
</html>

Archivos externos

  • Tiene más ventajas que el método de estilos embebidos
  • Facilita la actualización de los extilos
  • Se implementa mediante la etiqueta <link>
<!DOCTYPE html>
<html lang="es">
    <head>
        <meta charset="UTF-8">
        <title>Elementos en bloque</title>
        <link rel="stylesheet" type="text/css" href="css/estilos.css">
    </head>
    <body>
        <p>Esto es un párrafo</p>
    </body>
</html>

estilos.css

p{
    font-size:: 20px;
}

Selector Universal

Este selector representa cada uno de los elementos en el cuerpo del documento, y es útil cuando necesitamos establecer ciertas reglas básicas

*{
margin: 0;
}
p:nth-child(2){
background: #999999;
}

Referencia por etiqueta
Referencia por la palabra clave del elemento

Referencia por id

Problema
Supongamos que desemos implementar dos estilos diferentes a una misma etiqueta
La respuesta más simple es hacer uso de un id

<body>
<p id="articulo">Texto para el artículo</p>
<p id="aside">Texto para el aside</p>

estilos.css

p#articulo{
    font-size:: 20px;
}

p#aside{
    color:: red;
}

Para referenciar un elemento en particular usando el atributo id desde nuestro archivo CSS la regla debe ser declarado con el símbolo # delante del valor que usamos para identificar el elemento.

Notas para las referencias en id

  • Es una referencia sumamente específica, ya que no debe de haber más de un elemento con el nombre del id
  • Normalmente se emplean los id para elementos estructurales
  • Suele emplearse más en JavaScript
  • CSS3 nos proporciona referencias más flexibles

Referencias con el atributo class

  • Este atributo es más flexible
  • Puede ser asignado a cada elemento HTML en el documento que comparte un diseño similar

Se emplea de forma similar que el id sólo que:
– En HTML, en vez de colocar id se coloca class

<p class="principal">Texto para el artículo</p>
<p class="aside">Texto para el aside</p>

En CSS3, en vez de colocar #, se coloca un punto (.)

.principal{
    font-size:: 20px;
}

.aside{
    color:: red;
}

Un dato
¿porqué colocar un punto antes de la referencia?
La razón es que con las clases podemos construir referencias más complejas

p.principal{
    font-size:: 20px;
}

p.aside{
    color:: red;
}

De esta manera, sólo las etiquetas <p>, se verán afectadas por esta clase.

Referenciando por cualquier otro atributo

  • Las nuevs especificaciones de CSS3 nos permite referenciar por cualquier otro atributo:
    <p name=»especial»>Referencia por cualquier otro atributo</p>
  • El CSS3 sería:
         p[name="especial"] {
             font-size: 20px;
             color: red;
         }

Referencias locas

p[name^="mi"] {
    font-size: 20px
}

(^) Será asignada a todo elemento <p> que contenga un atributo name con un valor comenzado en «mi».

p[name$="mi"] {
    font-size: 40px
}

(^) Será asignada a todo elemento <p> que contenga un atributo name con un valor finalizado en «mi».

p[name*="mi"] {
    font-size: 60px
}

(^) Será asignada a todo elemento <p> que contenga un atributo name con un valor que incluye el texto «mi».

Referenciando con pseudo clases

Consideremos el siguiente código

<!DOCTYPE html>
<html lang="es">
    <head>
        <meta charset="UTF-8">
        <title>Estilos con pseudo clases</title>
        <link rel="stylesheet" type="text/css" href="css/estilos.css">
    </head>
    <body>
        <div id="wrapper">
            <p class="miestilo1">Párrafo1</p>
            <p class="miestilo2">Párrafo2</p>
            <p class="miestilo3">Párrafo3</p>
            <p class="miestilo4">Párrafo4</p>
        </div>
    </body>
</html>

La etiqueta <div> agrupa a varias etiquetas <p>.
La etiqueta <div> se considera una etiqueta padre.
Las etiquetas <p> son hijos de la etiqueta <div> y hermanos entre si.

Las pseudo clases nos permiten hacer referencias considerando la estructura del documento

p:nth-child(2)
{
background: #999999;
}

En este caso p es el elemento clave
La referencia nth-child() nos permite encontrar un hijo específico
El 2 nos indica a que elemento hermano nos referimos
A continuación se coloca el estilo que queramos utilizar

Odd – even

Son dos palabras reservadas.

Odd afecta a los elementos hijos que poseen un número impar.
Even afecta a los elementos hijos que poseen un número par.

Haciendo uso de odd y even, se facilita muchísimo la tarea de alternar estilos en una serie de elementos contínuos.

*{
margin: 0px;
}

p:nth-child(odd)
{
background: #999999;
}
p:nth-child(even)
{
background: #cccccc;
}

Otras pseudo clases

Existen otras importantes pseudo clases relacionadas con esta última, como

  • firstchild – Referencia sólo al primer hijo
  • last-child – Referencia al último hijo
  • only-child – Referencia a elementos padres que sólo tienen un hijo

Pseudo clase not()

  • Se emplea para realizar una negación
  • Tiene el mismo alcance que un selector universal
    *{
    margin: 0px;
    }
    :not(p){
    margin: 0px;
    }
  • Dentro de los paréntesis podemos colocar la referencia que queramos

En este caso estamos indicando con un selector universal * un margen de 0px (es decir sin margen) a todos los elementos de la página.
Con la pseudo clase :not(p) le indicamos que a los elementos p no les afecte el margen de 0px, de tal manera que utilizarán las características por defecto del navegador o las que nosotros deseemos.

Nuevos selectores

Estos selectores usan los símbolos <, + y div>p.mitexto2{
color: #990000;
}
Le decimos es este elemento( p.mitexto2) sea afectado siempre que tenga como padre un elemento div

p.mitexto2 + p{
color: #990000;
}
El elemento <p> inmediatamente inferior al elemento p con la clase (mitexto), se verá afectado por los estilos.

p.mitexto2 ~ p{
color: #990000;
}

El estilo será aplicado a todos los elementos <p> que son hermanos y se encuentran luego del elemento <p> identificado con el valor mitexto2 en su atributo class.