First commit 24/10/1997

This commit is contained in:
2021-09-12 19:47:27 +02:00
commit 1a08d45c82
9 changed files with 1365 additions and 0 deletions

323
4RAYA.CPP Normal file
View File

@ -0,0 +1,323 @@
/**************************************************************************\
|* *|
|* 4 en Raya *|
|* *|
|* Algoritmo de combate dise<73>ado por JD, capaz de profundizar en *|
|* jugadas defensivas/ofensivas. *|
|* *|
|* *|
|* *|
\**************************************************************************/
#include <mem.h>
char Tablero[7][7]; // [FILA][COLUMNA]
#define TAMANYO_DEL_TABLERO 7*7
#define ANCHO_TABLERO 7
#define ALTO_TABLERO 3
#define NO_HAY_NADIE 0
#define JUGADOR1 1
#define JUGADOR2 2
#define PROFUNDIDAD_DE_JUEGO 5
class Conecta4
{
private:
char StatusError;
char QuienSoy;
char *TableroOriginal;
char *CopiaDelTablero;
char AveriguaQuienSoy(void);
char GanaTurno( int *Pos_x, int *Pos_y, char JUGADOR_DUMMY );
void AlgInteligente( int *Pos_x, int *Pos_y, char JUGADOR_DUMMY );
public:
Conecta4(char *DirTablero);
~Conecta4();
void JuegaTurno(void);
char *Error(void);
};
void Conecta4::JuegaTurno( void )
{
int x, y; // Punto, donde pondr<64> mi ficha
int X, Y; // Puntos de avance en el tiempo.
char Enemigo;
char ok, Turno;
// <20> Quien soy YO ?
if ( QuienSoy == -1 )
AveriguaQuienSoy();
if ( QuienSoy == JUGADOR1 )
Enemigo = JUGADOR2;
else
Enemigo = JUGADOR1;
// Realizamos una copia del Tablero para las profudizaciones
memcpy( CopiaDelTablero, Tablero, sizeof( char ) * (TAMANYO_DEL_TABLERO) );
// <20> Podemos ganar en este turno ?
if ( GanaTurno( &x, &y, QuienSoy ) )
{
*( TableroOriginal + ANCHO_TABLERO*y + x ) = QuienSoy;
return;
}
// <20> Tengo que defender en este turno ?
if ( GanaTurno( &x, &y, Enemigo ) )
{
*( TableroOriginal + ANCHO_TABLERO*y + x ) = QuienSoy;
return;
}
ok = 0; Turno = 0;
// Tengo libertad en este turno para colocar la ficha donde quiera...
do {
AlgInteligente( &x, &y, QuienSoy );
// Me adelanto en el tiempo para ver que pasa si pongo la ficha hay...
// --------- OK == 0 JUGADA MALA :::: OK == 1 JUGADA BUENA -----------
// -- <20> Tengo mas lugares donde poner ? (si esta jugada no es buena)
if ( Turno > (ANCHO_TABLERO*ALTO_TABLERO) )
{
// <20><> Que le vamos hacer !!, puede ganar el contrario
ok = 1;
} else {
// Si pongo aqui: <20> Gana el siguiente turno el enemigo ? 1==NO :: 0==SI
if ( (ok = !GanaTurno( &X, &Y, Enemigo ) ) )
{
// Vale, el enemigo no ganar<61> en el siguiente turno, pero...
// ...que tal si nos adelantamos un poquito en el tiempo.
AlgInteligente( &X, &Y, Enemigo );
*( CopiaDelTablero + ANCHO_TABLERO*Y + X ) = Enemigo;
// Ahora juego yo...
if ( GanaTurno( &X, &Y, QuienSoy ) )
{
// Vale tengo asegurado el ganar dos turnos mas hacia adelante.
ok = 1;
} else {
// Dentro de dos turnos no gano, pero...
AlgInteligente( &X, &Y, QuienSoy );
*( CopiaDelTablero + ANCHO_TABLERO*Y + X ) = QuienSoy;
// ...<2E>y el enemigo?
if ( GanaTurno( &X, &Y, Enemigo ) )
{
// Parece que el enemigo gana, y no me la va a dar, asi de facil.
ok = 0;
} else {
// Juega mejor colega, por que a mi no me ganas.
ok = 1;
}
}
}
}
Turno++;
} while ( !ok );
// Este el el punto de inserci<63>n optimo.
*( TableroOriginal + ANCHO_TABLERO*y + x ) = QuienSoy;
}
// Comprobamos si el JUGADOR_DUMMY puede ganar este turno (Dev: Pos ganadora)
char Conecta4::GanaTurno( int *Pos_x, int *Pos_y, char JUGADOR_DUMMY )
{
int i, j, k;
int Lug_X, FichasHints;
char QueHay;
int Pos_Y[ANCHO_TABLERO];
// Posibles lugares donde meter la ficha
for ( i = 0; i < ANCHO_TABLERO; i++ )
{
// Por defecto, no es posible usar esta columna...
Pos_Y[i] = -1;
for ( j = 0; j < ALTO_TABLERO; j++ )
{
if ( *( CopiaDelTablero + j * ANCHO_TABLERO + i ) == NO_HAY_NADIE )
{
Pos_Y[i] = j;
break;
}
}
}
// Si metemos la ficha en algun lugar, <20> GANAMOS ?
FichasHints = 0;
for ( i = 0; i < ANCHO_TABLERO; i++ ) // Revisamos todos los huecos
if ( Pos_Y[i] != -1 )
{
//<2F><><EFBFBD> X
//<2F><><EFBFBD> <20> Posibilidad de ganar en HORIZONTAL ? X X
//<2F><><EFBFBD> X * * - *
//<2F><><EFBFBD> Insertando la ficha gano ----------^
for ( j = i-1; j>=0; j--)
{
QueHay = *( CopiaDelTablero + Pos_Y[i] * ANCHO_TABLERO + j );
if ( QueHay == JUGADOR_DUMMY )
FichasHints++;
else break;
}
for ( j = i+1; j<ANCHO_TABLERO; j++)
{
QueHay = *( CopiaDelTablero + Pos_Y[i] * ANCHO_TABLERO + j );
if ( QueHay == JUGADOR_DUMMY )
FichasHints++;
else break;
}
// Bingo, Aqui ganamos
if ( FichasHints >= 3 )
{
*Pos_x = i;
*Pos_y = Pos_y[i];
return 1;
}
//<2F><><EFBFBD> Insertando la ficha gano ---> -
//<2F><><EFBFBD> *
//<2F><><EFBFBD> <20> Posibilidad de ganar en VERTICAL ? * X
//<2F><><EFBFBD> * * X X X
// Solo es posible si mi altura actual es >= 3
if ( Pos_Y[i] >= 3 )
{
for ( j = Pos_Y[i]-1; j >= 0; j-- )
{
QueHay = *( TableroOriginal + Pos_Y[i] * ANCHO_TABLERO + i );
if ( QueHay == JUGADOR_DUMMY )
FichasHints++;
else break;
}
if ( FichasHints >= 3 )
{
*Pos_x = i;
*Pos_y = Pos_y[i];
return 1;
}
}
//<2F><><EFBFBD> Insertando la ficha gano <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ *
//<2F><><EFBFBD> * - * X
//<2F><><EFBFBD> <20> Posibilidad de ganar en DIAGONAL 1 ? X * X X X
//<2F><><EFBFBD> * * X X X
k = i - 1;
for ( j = Pos_Y[i]-1; j >= 0 && k >= 0; j--, k-- )
{
QueHay = *( CopiaDelTablero + j * ANCHO_TABLERO + k );
if ( QueHay == JUGADOR_DUMMY )
FichasHints++;
else break;
}
k = i + 1;
for ( j = Pos_Y[i]+1; j<ALTO_TABLERO && k < ANCHO_TABLERO; j++, k++ )
{
QueHay = *( CopiaDelTablero + j * ANCHO_TABLERO + k );
if ( QueHay == JUGADOR_DUMMY )
FichasHints++;
else break;
}
// Bingo, Aqui ganamos
if ( FichasHints >= 3 )
{
*Pos_x = i;
*Pos_y = Pos_y[i];
return 1;
}
//<2F><><EFBFBD> Insertando la ficha gano <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>*Ŀ X
//<2F><><EFBFBD> X X - X X
//<2F><><EFBFBD> <20> Posibilidad de ganar en DIAGONAL 2 ? X * X * X
//<2F><><EFBFBD> X * * X *
k = i + 1;
for ( j = Pos_Y[i]-1; j >= 0 && k < ANCHO_TABLERO; j--, k++ )
{
QueHay = *( CopiaDelTablero + j * ANCHO_TABLERO + k );
if ( QueHay == JUGADOR_DUMMY )
FichasHints++;
else break;
}
k = i - 1;
for ( j = Pos_Y[i]+1; j<ALTO_TABLERO && k >= 0; j++, k-- )
{
QueHay = *( CopiaDelTablero + j * ANCHO_TABLERO + k );
if ( QueHay == JUGADOR_DUMMY )
FichasHints++;
else break;
}
// Bingo, Aqui ganamos
if ( FichasHints >= 3 )
{
*Pos_x = i;
*Pos_y = Pos_y[i];
return 1;
}
}
// Este turno no puede ser ganado, DIRECTAMENTE!!!
return 0;
}
// El algoritmo inteligente es el nucleo de pensamiento de mi OBJETO
// decidir<69> cual es la posici<63>n mas acertada, (EN EL TURNO ACTUAL), para
// ganar la partida...
//
// Partimos del supuesto que no nos es posible ganar directamente en este
// turno y al enemigo tan poco le es posible en el siguiente. Por lo cual,
// tenemos un total de ANCHO_TABLERO casillas donde poner nuestra ficha.
//
// Actualmente, solo compruebo la frecuencia de aparici<63>n de fichas, en
// la media luna de posiciones que me rodean. FREC_MAX -> max. pos. de ganar.
//
// Realmente en este algoritmo, se podr<64>an tener algunas jugadas estrat<61>gicas
// ya prefijadas. Despues de jugar unas cuantas partidas con un HUMANO, nos
// daremos cuenta que solo existen unas Xx jugadas estrategicas que se basan,
// como mucho, en dos turnos adelante en el tiempo, de aqui mi control de
// estos dos turnos en el tiempo...
// Fdo:
// Jose-David.Guillen@cs.us.es
void Conecta4::AlgInteligente( int *Pos_x, int *Pos_y, char JUGADOR_DUMMY )
{
}
Conecta4::Conecta4(char *DirTablero)
{
StatusError = 0;
QuienSoy = -1;
TableroOriginal = DirTablero;
if ( ( CopiaDelTablero = new char [TAMANYO_DEL_TABLERO] ) == NULL )
StatusError = 1;
}
Conecta4::~Conecta4()
{
delete [] CopiaDelTablero;
}
char *Conecta4::Error(void)
{
char *MensajesError[40] = { "No hay suficiente Memoria",
"No quedan huecos libres",
"Error Desconocido" };
if ( StatusError )
return MensajesError[StatusError];
else
return NULL;
}