Versión: 0.47, de 10-Jul-2011


38. Una lista con las mejores puntuaciones. Cómo guardarla y recuperarla. (*)

En casi cualquier juego existe una "tabla de records", que guarda las mejores puntuaciones. Las características habituales son:

Para conseguirlo, podemos crear una clase auxiliar, como hicimos con la consola de depuración, que también se podrá aplicar a cualquier otro juego. Esa clase debería tener un método para "Cargar" desde fichero (o el constructor se podría encargar), otro para "Grabar" en fichero, otro para "Introducir" un nuevo record (su puntuación y su nombre asociado) y otro para "Obtener" un record (tanto la puntuación como el nombre, de modo que las podamos mostrr en pantalla).


Vamos con ello...

El fichero de cabecera podría ser así:

/*------------------------------*/
/*  Intro a la programac de     */
/*  juegos, por Nacho Cabanes   */
/*                              */
/*   TablaRecords.h:            */
/*     Clase "TablaRecords"     */
/*     Fichero de cabecera      */
/*                              */
/*  Comprobado con:             */
/*  - DevC++ 4.9.9.2(gcc 3.4.2) */
/*    y Allegro 4.03 - WinXP    */
/*------------------------------*/
 
#ifndef TablaRecords_h
#define TablaRecords_h
 
class TablaRecords {
 
    int cantidad;
 
 
 public:
 
    TablaRecords();
    TablaRecords(int tamanyo);
 
    void insertar(char* nombre, int puntos);
    void guardar();
    void leer();
 
    int getCantidad();
    char* getNombre( int i );
    int getPuntuacion( int i );
 
};
#endif
 

Y el desarrollo podría ser:

/*------------------------------*/
/*  Intro a la programac de     */
/*  juegos, por Nacho Cabanes   */
/*                              */
/*   TablaRecords.cpp:          */
/*     Clase "TablaRecords"     */
/*     Fichero de desarrollo    */
/*                              */
/*  Comprobado con:             */
/*  - DevC++ 4.9.9.2(gcc 3.4.2) */
/*    y Allegro 4.03 - WinXP    */
/*------------------------------*/
 
#include "TablaRecords.h"
#include <fstream>
using namespace std;
 
const int MAXRECORD = 10;
int tamanyo;
string *nombres;
int *puntuaciones;
 
 
TablaRecords::TablaRecords()
{
    int i;
    tamanyo = MAXRECORD;
 
    nombres = new string[tamanyo];
    for (i=0; i<tamanyo; i++)
		nombres[i] = " ";
 
    puntuaciones = new int[tamanyo];
    for (i=0; i<tamanyo; i++)
		puntuaciones[i] = 0;
}
 
 
TablaRecords::TablaRecords(int nuevoTamanyo)
{
    int i;
    tamanyo = nuevoTamanyo;
 
    nombres = new string[tamanyo];
    for (i=0; i<tamanyo; i++)
		nombres[i] = " ";
 
    puntuaciones = new int[tamanyo];
    for (i=0; i<tamanyo; i++)
		puntuaciones[i] = 0;
 
}
 
 
void TablaRecords::insertar(char* nombre, int puntos)
{
    int posicion = 0;
    int i;
 
    // Primero busco la posicion
    for (i=tamanyo-1; i >= 0; i--)
        if (puntos > puntuaciones[i])
			posicion = i;
 
    // Y despues desplazo a partir de ella
    for (i=tamanyo-2; i >= posicion; i--)
    {
        puntuaciones[i+1] = puntuaciones[i];
        nombres[i+1] = nombres[i];
    }
 
    puntuaciones[posicion] = puntos;
    nombres[posicion] = nombre;
}
 
 
void TablaRecords::guardar()
{
    fstream ficheroRecords;
    ficheroRecords.open ( "records.dat" , ios::out);
    for (int i=0; i < tamanyo; i++)
    {
        ficheroRecords << nombres[i];
        ficheroRecords << endl;
        ficheroRecords << puntuaciones[i];
        ficheroRecords << endl;
    }
    ficheroRecords.close();
}
 
 
void TablaRecords::leer()
{
	// Propuesto como ejercicio
}
 
 
int TablaRecords::getCantidad()
{
    return tamanyo;
}
 
 
char* TablaRecords::getNombre( int i )
{
	if (i < tamanyo)
		return const_cast<char *>( nombres[i].c_str() );
	else 
		return " ";
}
 
 
int TablaRecords::getPuntuacion( int i )
{
	if (i < tamanyo)
		return puntuaciones[i];
	else 
		return 0;
}
 
 

Para probarlo, no es necesario hacerlo desde dentro de un juego. De hecho, puede ser preferible crear un pequeño programa de prueba, que introduzca datos, los lea, los guarde en disco, etc. Podría ser algo como:

// Prueba de la clase TablaRecords
 
#include "TablaRecords.h"
#include <iostream>
using namespace std;
 
int main()
{
    int i;
    TablaRecords *tr;
 
    tr = new TablaRecords(8);
 
    cout << "Tabla de records vacia:\n";
 
    for (i=0; i < tr->getCantidad(); i++)
        cout << tr->getNombre(i) << " : "
             << tr->getPuntuacion(i) << "\n";
 
    tr->insertar("nombre1", 50);
    tr->insertar("nombre2", 100);
    tr->insertar("nombre3", 75);
    tr->insertar("nombre4", 200);
 
    cout << "Tabla de records con datos:\n";
 
    for (i=0; i < tr->getCantidad(); i++)
        cout << tr->getNombre(i) << " "
             << tr->getPuntuacion(i) << "\n";
 
    return 0;
}
 

Este programa daría un resultado como:


Tabla de records vacia:
  : 0
  : 0
  : 0
  : 0
  : 0
  : 0
  : 0
  : 0
Tabla de records con datos:
nombre4 200
nombre2 100
nombre3 75
nombre1 50
  0
  0
  0
  0

Todavía no es totalmente aplicable a nuestros juegos, porque aún no tenemos ninguna forma de que el usuario introduzca su nombre, de modo que sólo podríamos guardar y mostrar puntuaciones numéricas. Más adelante lo solucionaremos...

Anterior Siguiente