Elabore un juego como el rompecabezas deslizante, se debe tener en cuenta que la matriz puede ser de 3x3 hasta 9x9.

Para que el jugador pueda ganar, debe tener el rompecabezas en el siguiente orden:

#include <iostream>
#include "Tablero.h"
/*
* incluire la clase unistd.h para poder utilizar el metodo usleep() para que el programa "duerma"
* y realize una pequeña animacion por unos segundos que le asigne como parametro
*/
#include <unistd.h>
// defino dos constantes, 1 para la dimension minima que sera 3 y la otra para la dimension maxima que sera 9
#define DIM_MIN 3
#define DIM_MAX 9
using namespace std;
// funciones prototipo, las funciones prototipo solo le dicen al compilador que utilizare esta funcion o metodo
// pero mas tarde
void dibujar(Tablero *obj);
void creditos();
int main(void)
{
// se crea un objeto de la clase Tablero (Instanciaciación)
Tablero *obj = new Tablero();
int dim;
// con el ciclo do..while me asegurare de que se ingrese una dimension adecuada
do
{
// pido en pantalla que se digite la dimension del tablero
cout << "Digite dimension del tablero" << endl;
cout << ">> ";
// guardo la dimension en la variable dim
cin >> dim;
obj->setDimension(dim);
// si la dimension que digito el usuario es menor que la dimension minima ó si la dimension es mayor que la dimension maxima
if (dim < DIM_MIN || dim > DIM_MAX)
{
// entonces se mostrara en pantalla que debe ingresaar una dimension valida
cout << "El tablero debe tener una dimension entre " << DIM_MIN << "x" << DIM_MIN << " y " << DIM_MAX << "x" << DIM_MAX << "." << endl;
}
}
// repetira esto hasta que el usuario ingrese una dimension valida
while(dim < DIM_MIN || dim > DIM_MAX);
// limpiare la pantalla
obj->limpiar();
// mostrare los creditos
creditos();
// inicializare el tablero
obj->iniciar();
// repetire todas las intrucciones dentro del ciclo while hasta que el usuario gane el juego
while (true)
{
// limpio la pantalla
obj->limpiar();
// dibujo el estado actual del tablero
dibujar(obj);
// compruebo si el usuario ha ganado el juego
if (obj->gano())
{
// si gana el juego, mostrara el texto en pantalla y rompera el programa
cout << " Has ganado!" << endl;
break;
}
// pido un movimiento al usuario
cout << "Digita el numero del cuadro a donde quieres moverte" << endl;
cout << ">> ";
// creo la variable de tipo entero mov (movimiento)
int mov;
// y guardo el movimeinto que ingreso el usuario en la variable mov
cin >> mov;
// se movera si es posible, pero sino entonces mostrara un mensaje de movimiento invalido
if (!obj->mover(mov))
{
cout << "\nEste movimiento no se puede hacer." << endl;
// dormira por 500000 microsegundos
usleep(500000);
}
usleep(500000);
}
}
/**
* Imprimo el tablero en su estado actual.
*/
void dibujar(Tablero *obj)
{
// recorreré toda la matriz con el ciclo for
for (int i = 0; i < obj->getDimension(); i++)
{
for (int j = 0; j < obj->getDimension(); j++)
{
// si el valor que esta en la posicion i , j es 0, entonces:
if (obj->getTablero(i, j) == 0)
{
// imprimire la barrita que indica la posicion en donde se encuentra el usuario actualmente
cout << "\t _";
}
else
{
// sino, imprimire los datos que hay en el arreglo identados \t
cout << "\t|" << obj->getTablero(i, j) << "|";
}
}
// dare dos saltos de linea para que se vea mas estetico la tabla del juego
cout << endl << endl;
}
}
void creditos()
{
// 0 1 2 3 4 5 6 7
char sim[8] = {201, 205, 187, 186, 200, 188, 204, 185};
cout << sim[0];
for (int i = 0; i < 51; i++)
cout << sim[1];
cout << sim[2] << endl;
cout << sim[3] << " BIENVENIDO AL JUEGO ROMPECABEZAS DESLIZANTE " << sim[3] << endl;
cout << sim[6];
for (int i = 0; i < 51; i++)
cout << sim[1];
cout << sim[7] << endl;
cout << sim[3] << " " << sim[3] << endl;
cout << sim[3] << " CREADO POR OMAR FLOREZ (Vlph7_7) " << sim[3] << endl;
cout << sim[3] << " " << sim[3] << endl;
cout << sim[4];
for (int i = 0; i < 51; i++)
cout << sim[1];
cout << sim[5] << endl;
usleep(900000);
}
#ifndef TABLERO_H
#define TABLERO_H
// defino dos constantes, 1 para la dimension minima que sera 3 y la otra para la dimension maxima que sera 9
#define DIM_MIN 3
#define DIM_MAX 9
class Tablero
{
public:
Tablero();
virtual ~Tablero();
void limpiar();
void iniciar();
bool mover(int mov);
bool gano();
void setTablero(int fil, int col, int val);
int getTablero(int fil, int col);
void setDimension(int val);
int getDimension();
protected:
private:
// declaro una matriz o un vector multidimensional y le asigno las dimension maxima que haya ingresado el usuario
int tablero[DIM_MAX][DIM_MAX];
// declaro la variable d, sera la dimension que ingresara el usuario
int d;
};
#endif // TABLERO_H
#include "Tablero.h"
// incluire la clase stdlib.h para poder utilizar el metodo system() y poder limpiar la pantalla con el parametro "cls"
#include <stdlib.h>
Tablero::Tablero()
{
//ctor
}
Tablero::~Tablero()
{
//dtor
}
/**
* Limpio la pantalla
*/
void Tablero::limpiar()
{
system("cls");
}
/**
* Inicializa el tablero del juego con los movimientos numerados desde 1 a d *d - 1
* (es decir llena la matriz con valores, pero en realidad no los imprime)
*/
void Tablero::iniciar()
{
// declaro la variable total de tipo entero y le asignare el numero total de espacios de la matriz
int total = getDimension() * getDimension();
// agrego los espacios o los cuadros en el tablero
for (int i = 0; i < getDimension(); i++)
{
for (int j = 0; j < getDimension(); j++)
{
// decremento el valor de total en 1 y se lo asigno al arreglo tablero en la posicion actual de i , j
setTablero(i, j, --total);
}
}
// debo intercambiar 2 y 1 si el número de espacios en total del arreglo es par
if ((getDimension() * getDimension()) % 2 == 0)
{
setTablero(d-1, d-3, 1);
setTablero(d-1, d-2, 2);
}
}
/**
* Si el cuadro esta al lado del espacio vacio _ entonces movera
* el cuadro y devolvera true, sino devolvera false
*/
bool Tablero::mover(int mov)
{
// compruebo si el movimiento es valido
if (mov > getDimension() * getDimension() - 1 || mov < 1)
{
return false;
}
// recorreré el tablero con el ciclo for desde las filas y columnas
int fil = 0, col = 0;
for (int i = 0; i < getDimension(); i++)
{
for (int j = 0; j < getDimension(); j++)
{
// si el cuadro que esta en posicion i , j del tablero es igual al movimeinto que ingreso el usuario
if (getTablero(i,j) == mov)
{
// entonces le asignare a fil el valor de i
fil = i;
// y a col le asignare el valor de j
col = j;
}
}
}
// compruebo los espacios cercanos, si se logra encontrar uno se devolvera true de lo contrario devolvera false
if (fil - 1 >= 0 && getTablero(fil-1, col) == 0)
{
setTablero(fil-1, col, getTablero(fil, col));
setTablero(fil, col, 0);
return true;
}
else if (fil + 1 < getDimension() && getTablero(fil+1, col) == 0)
{
setTablero(fil+1, col, getTablero(fil, col));
setTablero(fil, col, 0);
return true;
}
else if (col - 1 >= 0 && getTablero(fil, col-1) == 0)
{
setTablero(fil, col-1, getTablero(fil, col));
setTablero(fil, col, 0);
return true;
}
else if (col + 1 < d && getTablero(fil, col+1) == 0)
{
setTablero(fil, col+1, getTablero(fil, col));
setTablero(fil, col, 0);
return true;
}
return false;
}
/**
* Devolvere true si se gana el juego,
* Sino devolvere false.
*/
bool Tablero::gano()
{
// declaro una variable de tipo entero contador y la inicializo en 0
int contador = 0;
// revisaré cada cuadro para asegurarme de que esté en orden
for (int i = 0; i < getDimension(); i++)
{
for (int j = 0; j < getDimension(); j++)
{
// compruebo si el último punto es correcto y si no es el valor correcto
if (++contador != (d * d) && getTablero(i, j) != contador)
{
// si eso es verdadero entonces devolvere false y el jugador aun no habra ganado
return false;
}
}
}
// devolvere true y el jugador ganara el juego
return true;
}
// implementacion de los metodos Setters y Getters de los atributos de la clase Tablero
void Tablero::setTablero(int fil, int col, int val)
{
tablero[fil][col] = val;
}
int Tablero::getTablero(int fil, int col)
{
return tablero[fil][col];
}
void Tablero::setDimension(int val)
{
d = val;
}
int Tablero::getDimension()
{
return d;
}
//Se importa paquete JOptionPane para dibujar un cuadro de dialogo en pantalla
//que muestre información o para llenar información.
import javax.swing.JOptionPane;
public class Main
{
// imprimo el tablero en su estado actual.
public static String dibujar(Tablero obj)
{
// declaro la variable datos de tipo string la utilizare para acumular todo el tablero
String datos = "";
// recorreré toda la matriz con el ciclo for
for (int i = 0; i < obj.getDimension(); i++)
{
for (int j = 0; j < obj.getDimension(); j++)
{
// imprimo el tablero si el valor que esta esta en la posicion i , j es 0
if (obj.getTablero(i, j) == 0)
{
// le asigno a datos el valor de datos mas la barrita _ que indica la posicion en donde se encuentra el usuario actualmente
datos = datos + " _ ";
}
else
{
// si el numero que esta en el tablero enta entre el rango de 1 y 9
if (obj.getTablero(i, j) > 0 && obj.getTablero(i, j) < 10)
{
/**
* entonces le dare un espacio mas a los cuadros, por que los numeros 1,2,3,..9
* se veran de esta forma |1| |2| pero si hay un numero como el |10| entonces quedan mal esteticamente
* en Java no he encontrado una forma de poder identar esto, ni siquiera con el \t
*/
datos = datos + " | " + String.valueOf(obj.getTablero(i, j)) + " |";
}
else
{
// sino lo imprimo normal sin el espacio despues del "|"
datos = datos + " |" + String.valueOf(obj.getTablero(i, j)) + "|";
}
}
}
// doy un salto de linea
datos = datos + "\n";
}
return datos;
}
public static String creditos()
{
String datos = "";
datos = datos + "=====================================================================\n";
datos = datos + "============ BIENVENIDO AL JUEGO ROMPECABEZAS DESLIZANTE ============\n";
datos = datos + "=====================================================================\n";
datos = datos + "=====================================================================\n";
datos = datos + "================ CREADO POR OMAR FLOREZ (Vlph7_7) ===================\n";
datos = datos + "=====================================================================\n";
return datos;
}
public static void main(String[] args)
{
// se crea un objeto de la clase Tablero (Instanciaciación)
Tablero obj = new Tablero();
int dim;
// con el ciclo do..while me asegurare de que se ingrese una dimension adecuada
do
{
// pido en pantalla que se digite la dimension del tablero y la guardo en dim
dim = Integer.parseInt(JOptionPane.showInputDialog("Digite dimension del tablero:"));
// encapsulo la variable dim
obj.setDimension(dim);
// si la dimension que digito el usuario es menor que la dimension minima ó si la dimension es mayor que la dimension maxima
if (dim < 3 || dim > 9)
{
// entonces se mostrara en pantalla que debe ingresar una dimension valida
JOptionPane.showMessageDialog(null, "El tablero debe tener una dimension entre 3x3 y 9x9. \n");
}
}
// repetira esto hasta que el usuario ingrese una dimension valida
while(dim < 3 || dim > 9);
// mostrare los creditos
JOptionPane.showMessageDialog(null, creditos());
// inicializare el tablero
obj.iniciar();
// repetire todas las intrucciones dentro del ciclo while hasta que el usuario gane el juego
while (true)
{
// compruebo si el usuario ha ganado el juego
if (obj.gano())
{
// si gana el juego, mostrara el texto en pantalla y rompera el programa
JOptionPane.showMessageDialog(null, " Has ganado! \n");
break;
}
// creo la variable de tipo entero mov (movimiento)
int mov;
// pido un movimiento al usuario y guardo el movimiento que ingreso el usuario en la variable mov
mov = Integer.parseInt(JOptionPane.showInputDialog(dibujar(obj) + "\nDigita el numero del cuadro a donde quieres moverte:"));
// se movera si es posible, pero sino entonces mostrara un mensaje de movimiento invalido
if (!obj.mover(mov))
{
JOptionPane.showMessageDialog(null, "Este movimiento no se puede hacer.");
}
}
}
}
public class Tablero
{
// declaro las variable constantes DIM_MIX y le asigno 3 y DIM_MAX y le asigno 9
private final int DIM_MIN = 3;
private final int DIM_MAX = 9;
// declaro una matriz o un vector multidimensional y le asigno las dimension maxima que haya ingresado el usuario
private int [][] tablero = new int[DIM_MAX][DIM_MAX];
// declaro la variable d , sera la dimension que ingresara el usuario
private int d;
/**
* Se inicializa el tablero del juego con los movimientos numerados desde 1 a d *d - 1
* (es decir llena la matriz con valores, pero en realidad no los imprime)
*/
public void iniciar()
{
// declaro la variable total de tipo entero y le asignare el numero total de espacios de la matriz
int total = getDimension() * getDimension();
// agrego los espacios o los cuadros en el tablero
for (int i = 0; i < getDimension(); i++)
{
for (int j = 0; j < getDimension(); j++)
{
// decremento el valor de total en 1 y se lo asigno al arreglo tablero en la posicion actual de i , j
setTablero(i, j, --total);
}
}
// debo intercambiar 2 y 1 si el número de espacios en total del arreglo es par
if ((getDimension() * getDimension()) % 2 == 0)
{
setTablero(d-1, d-3, 1);
setTablero(d-1, d-2, 2);
}
}
/**
* Si el cuadro esta al lado del espacio vacio _ entonces movera
* el cuadro y devolvera true, sino devolvera false
*/
public boolean mover(int mov)
{
// compruebo si el movimiento es valido
if (mov > getDimension() * getDimension() - 1 || mov < 1)
{
return false;
}
// recorreré el tablero con el ciclo for desde las filas y columnas
int fil = 0, col = 0;
for (int i = 0; i < getDimension(); i++)
{
for (int j = 0; j < getDimension(); j++)
{
// si el cuadro que esta en posicion i , j del tablero es igual al movimeinto que ingreso el usuario
if (getTablero(i,j) == mov)
{
// entonces le asignare a fil el valor de i
fil = i;
// y a col le asignare el valor de j
col = j;
}
}
}
// compruebo los espacios cercanos, si se logra encontrar uno se devolvera true de lo contrario devolvera false
if (fil - 1 >= 0 && getTablero(fil-1, col) == 0)
{
setTablero(fil-1, col, getTablero(fil, col));
setTablero(fil, col, 0);
return true;
}
else if (fil + 1 < getDimension() && getTablero(fil+1, col) == 0)
{
setTablero(fil+1, col, getTablero(fil, col));
setTablero(fil, col, 0);
return true;
}
else if (col - 1 >= 0 && getTablero(fil, col-1) == 0)
{
setTablero(fil, col-1, getTablero(fil, col));
setTablero(fil, col, 0);
return true;
}
else if (col + 1 < d && getTablero(fil, col+1) == 0)
{
setTablero(fil, col+1, getTablero(fil, col));
setTablero(fil, col, 0);
return true;
}
return false;
}
/**
* Devolvere true si se gana el juego,
* Sino devolvere false.
*/
public boolean gano()
{
// declaro una variable de tipo entero contador y la inicializo en 0
int contador = 0;
// revisaré cada cuadro para asegurarme de que esté en orden
for (int i = 0; i < getDimension(); i++)
{
for (int j = 0; j < getDimension(); j++)
{
// compruebo si el último punto es correcto y si no es el valor correcto
if (++contador != (d * d) && getTablero(i, j) != contador)
{
// si eso es verdadero entonces devolvere false y el jugador aun no habra ganado
return false;
}
}
}
// devolvere true y el jugador ganara el juego
return true;
}
// implementacion de los metodos Setters y Getters de la clase Tablero
public void setTablero(int fil, int col, int val)
{
tablero[fil][col] = val;
}
public int getTablero(int fil, int col)
{
return tablero[fil][col];
}
public void setDimension(int val)
{
d = val;
}
public int getDimension()
{
return d;
}
}