Juego de Ajedrez en Visual C++

Por:latindev, enviado 14 mar 2004

Dibujar el tablero

Para dibujar el tablero de ajedrez dentro de la vista creada tenemos que tener en cuenta los parámetros siguientes:
  1. Etiquetas de filas y columnas.
  2. Margen entre el borde de la ventana y la cuadrícula del tablero.
  3. Tamaño de la celda del tablero.
ajedrez-11.jpg
Imagen 6: Parámetros para dibujar el tablero de ajedrez


Para dibujar el tablero necesitaremos definir 3 valores fijos que no cambiarán y nos servirán para dibujar el tablero cada vez que lo necesitemos.

Code: Seleccionar todo
  1. #define MARGEN 30

  2. #define TAMCELDA 60

  3. #define CELDAS  8



El siguiente paso es crear la función que dibujará el tablero, para ello debemos abrir la vista de clases, hacer clic derecho sobre la clase y elegir “Agregar->Función” luego aparecerá un dialogo como el de la imagen 7. No se deben olvidar de agregar un parámetro del tipo CDC* para que podamos dibujar los elementos.

ajedrez-12.jpg
Imagen 7: Agregar Función DibujarTablero

La función DibujarTablero

A continuación una descripción del algoritmo utilizado para dibujar el trablero de ajedréz.

  1. Crea inicialmente los objetos necesarios para darle color al fondo y a las líneas del tablero de ajedrez (CPen, CBrush)
  2. Luego dibuja celda por celda (for anidado de 8 iteraciones cada uno)
    1. Al inicio de la iteración se calcula las dimensiones de la celda en base a los valores de i y j y los parámetros definidos inicialmente (margen y tamaño de celda) estos valores calculados son almacenados en la variable rcCelda de tipo RECT.
    2. Para dibujar una celda oscura o blanca se verifica si es par o no, de esa forma se intercalan los colores, según estos valores se utiliza el Brush indicado junto a la función CDC::Rectangle.
    3. Se aprovecha el valor de rcCelda para calcular la posición de las etiquetas que están contenidas en la variable m_vEtiquetas de tipo std::vector.
Segun el algoritmo anterior podemos escribir el siguiente código:

Code: Seleccionar todo
  1. void CAjedrezView::DibujarTablero(CDC* pDC)

  2. {

  3.     //Definición de colores y fondos

  4.     RECT rcCelda;

  5.     CBrush brNegro,brSeleccion;

  6.     brNegro.CreateSolidBrush(0xf36d4d);

  7.     brSeleccion.CreateSolidBrush(RGB(255,240,108));

  8.  

  9.     CPen penAzulMarino,penAmarillo;

  10.     penAzulMarino.CreatePen(PS_SOLID,3,0x00640000);

  11.     penAmarillo.CreatePen(PS_SOLID,4,0x0000EEEE);

  12.  

  13.     CPen *penAnterior = pDC->SelectObject(&penAzulMarino);

  14.     pDC->SetBkMode(TRANSPARENT);

  15.  

  16.     for(int i = 0 ; i < CELDAS ; i++)

  17.     {

  18.         for(int j = 0 ; j < CELDAS ; j++)

  19.         {

  20.             rcCelda.left  = j*TAMCELDA + MARGEN;

  21.             rcCelda.top   = i*TAMCELDA + MARGEN;  

  22.             rcCelda.right = rcCelda.left + TAMCELDA;

  23.             rcCelda.bottom = rcCelda.top + TAMCELDA;

  24.  

  25.             if( i%2 == 0 )

  26.             {

  27.                 if(j%2 != 0)

  28.                 {

  29.                         CBrush *pFondoAnterior = pDC->SelectObject(&brNegro);

  30.                         pDC->Rectangle(&rcCelda);

  31.                         pDC->SelectObject(pFondoAnterior);

  32.                 }

  33.                 else

  34.                 {

  35.                     pDC->Rectangle(&rcCelda);

  36.                 }

  37.             }

  38.             else

  39.             {

  40.                 if(j%2 == 0)

  41.                 {

  42.                         CBrush *pFondoAnterior = pDC->SelectObject(&brNegro);

  43.                         pDC->Rectangle(&rcCelda);

  44.                         pDC->SelectObject(pFondoAnterior);

  45.                 }

  46.                 else

  47.                 {

  48.                     pDC->Rectangle(&rcCelda);

  49.                 }

  50.             }

  51.            

  52.             //Dibujando las etiquetas

  53.             if(j == 0 || j == 7)

  54.             {

  55.                 rcCelda.left  = j==0?MARGEN-15:rcCelda.right;

  56.                 rcCelda.right = j==0?MARGEN:rcCelda.right + 15;

  57.                 pDC->DrawText(m_vEtiquetas[i],

  58.                     &rcCelda,

  59.                     DT_CENTER|DT_VCENTER|DT_SINGLELINE);

  60.                

  61.                 //Restaurando valores para que no

  62.                 //afecte el pintado de las etiquetas verticales

  63.                 rcCelda.left  = j*TAMCELDA + MARGEN;

  64.                 rcCelda.right = rcCelda.left + TAMCELDA;

  65.             }

  66.             if(i == 0 || i == 7)

  67.             {

  68.                 rcCelda.top    = i==0?MARGEN-20:rcCelda.bottom;

  69.                 rcCelda.bottom = i==0?MARGEN:rcCelda.bottom + 20;

  70.                 pDC->DrawText(m_vEtiquetas[j+8],

  71.                     &rcCelda,

  72.                     DT_CENTER|DT_VCENTER|DT_SINGLELINE);

  73.             }

  74.  

  75.         }

  76.     }

  77.     pDC->SelectObject(penAnterior);

  78. }


Este código debe invocarse desde la función OnDraw, la función OnDraw ya esta establecida y recibe como parámetro también un objeto CDC, el mismo debe pasar como parámetro de la función DibujarTablero.
Code: Seleccionar todo
  1. #include "memdc.h"

  2.  

  3. ...

  4.  

  5. void CAjedrezView::OnDraw(CDC* pDC)

  6. {

  7.     CAjedrezDoc* pDoc = GetDocument();

  8.     ASSERT_VALID(pDoc);

  9.     if (!pDoc)

  10.         return;

  11.  

  12.     CMemDC memdc(pDC);

  13.     DibujarTablero(&memdc);

  14. }


La clase CMemDC es una herramienta para crear un mapa de bits en segundo plano para ir dibujando en él y al final pintar el mapa de bits sobre la ventana para así evitar el parpadeo que se produce al pintar objeto por objeto, esta técnica se le conoce como Double Buffering.

Pueden descargar el archivo memdc.h de codeproject.com, esta clase fue escrita por Keith Rule (keithr@europa.com)

Para que la técnica de double buffering quede completa debemos agregar la función asociada al evento WM_ERASEBKGND que decide si se va a eliminar el fondo antes de pintar nuevamente el tablero.

El código de la función generada se debe ver como sigue:

Code: Seleccionar todo
  1. BOOL CAjedrezView::OnEraseBkgnd(CDC* pDC)

  2. {

  3.     return FALSE;

  4. }



Luego de terminar de escribir la función pueden compilar y verán un resultado como el de la imagen 8.

ajedrez-14.jpg
Imagen 8: Tablero Dibujado por la Función

Archivos Adjuntos

  • Ajedrez.zip 84,86 KiB
    Código fuente Ajedréz Visual C++ 2005

Otros Artículos en esta sección

  • Ventana de Inicio (Splash) en Visual C++
    Ventana que se muestra al inicio de una aplicación mientras cargan todos elementos de nuestro programa, con esto podemos hacer nuestras aplicaciones Visual C++ mas presentables.
    Por: latindev, 2004-09-19
  • NSChart - Visual C++
    Chart para visual c++, control que visualiza gráficos de barra y sectores en un dialogo MFC, puedes utilizarlo en tus aplicaciones para enriquecerlo mostrando histogramas y gráficos de sectores.
    Por: latindev, 2004-07-26
  • Juego de la Serpiente en Visual C++
    Se trata de un juego donde hay una serpiente que esta en constante movimiento, cuando come algo crece, el juego termina cuando la serpiente ya no tiene espacio.
    Por: latindev, 2004-03-27
¿Alguna duda? Sientete libre de hacer tus pruntas en nuestro:
foro de Visual C++ »