First commit 24/10/1997

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

323
4R.CPP Normal file
View File

@ -0,0 +1,323 @@
/**************************************************************************\
|* *|
|* 4 en Raya *|
|* *|
|* Algoritmo de combate dise¤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 mi ficha
int X, Y; // Puntos de avance en el tiempo.
char Enemigo;
char ok, Turno;
// ¨ 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) );
// ¨ Podemos ganar en este turno ?
if ( GanaTurno( &x, &y, QuienSoy ) )
{
*( TableroOriginal + ANCHO_TABLERO*y + x ) = QuienSoy;
return;
}
// ¨ 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 -----------
// -- ¨ Tengo mas lugares donde poner ? (si esta jugada no es buena)
if ( Turno > (ANCHO_TABLERO*ALTO_TABLERO) )
{
// ­­ Que le vamos hacer !!, puede ganar el contrario
ok = 1;
} else {
// Si pongo aqui: ¨ Gana el siguiente turno el enemigo ? 1==NO :: 0==SI
if ( (ok = !GanaTurno( &X, &Y, Enemigo ) ) )
{
// Vale, el enemigo no ganar  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;
// ...¨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¢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, ¨ GANAMOS ?
FichasHints = 0;
for ( i = 0; i < ANCHO_TABLERO; i++ ) // Revisamos todos los huecos
if ( Pos_Y[i] != -1 )
{
//°²Û X
//°²Û ¨ Posibilidad de ganar en HORIZONTAL ? X X
//°²Û X * * - *
//°²Û 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;
}
//°²Û Insertando la ficha gano ---> -
//°²Û *
//°²Û ¨ Posibilidad de ganar en VERTICAL ? * X
//°²Û * * 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;
}
}
//°²Û Insertando la ficha gano ÄÄÄÄÄÄÄÄÄ¿ *
//°²Û * - * X
//°²Û ¨ Posibilidad de ganar en DIAGONAL 1 ? X * X X X
//°²Û * * 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;
}
//°²Û Insertando la ficha gano ÄÄÄÄÄÄÄ*Ä¿ X
//°²Û X X - X X
//°²Û ¨ Posibilidad de ganar en DIAGONAL 2 ? X * X * X
//°²Û 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  cual es la posici¢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¢n de fichas, en
// la media luna de posiciones que me rodean. FREC_MAX -> max. pos. de ganar.
//
// Realmente en este algoritmo, se podr¡an tener algunas jugadas estratgicas
// 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;
}

323
4RAYA.CPP Normal file
View File

@ -0,0 +1,323 @@
/**************************************************************************\
|* *|
|* 4 en Raya *|
|* *|
|* Algoritmo de combate dise¤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 mi ficha
int X, Y; // Puntos de avance en el tiempo.
char Enemigo;
char ok, Turno;
// ¨ 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) );
// ¨ Podemos ganar en este turno ?
if ( GanaTurno( &x, &y, QuienSoy ) )
{
*( TableroOriginal + ANCHO_TABLERO*y + x ) = QuienSoy;
return;
}
// ¨ 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 -----------
// -- ¨ Tengo mas lugares donde poner ? (si esta jugada no es buena)
if ( Turno > (ANCHO_TABLERO*ALTO_TABLERO) )
{
// ­­ Que le vamos hacer !!, puede ganar el contrario
ok = 1;
} else {
// Si pongo aqui: ¨ Gana el siguiente turno el enemigo ? 1==NO :: 0==SI
if ( (ok = !GanaTurno( &X, &Y, Enemigo ) ) )
{
// Vale, el enemigo no ganar  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;
// ...¨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¢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, ¨ GANAMOS ?
FichasHints = 0;
for ( i = 0; i < ANCHO_TABLERO; i++ ) // Revisamos todos los huecos
if ( Pos_Y[i] != -1 )
{
//°²Û X
//°²Û ¨ Posibilidad de ganar en HORIZONTAL ? X X
//°²Û X * * - *
//°²Û 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;
}
//°²Û Insertando la ficha gano ---> -
//°²Û *
//°²Û ¨ Posibilidad de ganar en VERTICAL ? * X
//°²Û * * 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;
}
}
//°²Û Insertando la ficha gano ÄÄÄÄÄÄÄÄÄ¿ *
//°²Û * - * X
//°²Û ¨ Posibilidad de ganar en DIAGONAL 1 ? X * X X X
//°²Û * * 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;
}
//°²Û Insertando la ficha gano ÄÄÄÄÄÄÄ*Ä¿ X
//°²Û X X - X X
//°²Û ¨ Posibilidad de ganar en DIAGONAL 2 ? X * X * X
//°²Û 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  cual es la posici¢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¢n de fichas, en
// la media luna de posiciones que me rodean. FREC_MAX -> max. pos. de ganar.
//
// Realmente en este algoritmo, se podr¡an tener algunas jugadas estratgicas
// 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;
}

BIN
EGAVGA.BGI Normal file

Binary file not shown.

690
OSC.CPP Normal file
View File

@ -0,0 +1,690 @@
/**************************************************************************\
|* *|
|* 4 en Raya *|
|* *|
|* Algoritmo de combate dise¤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 7
#define NO_HAY_NADIE 0
#define JUGADOR1 1
#define JUGADOR2 2
#define PROFUNDIDAD_DE_JUEGO 5
int Post_X, Post_Y;
class Conecta4
{
private:
char StatusError;
char QuienSoy;
char *TableroOriginal;
char *CopiaDelTablero;
char AveriguaQuienSoy(void);
void PosiblesLugares( char Pos_Y[ANCHO_TABLERO] );
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);
};
/////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
///NOTA LOS VALORES DE X E Y OSCILAN ENTRE 1-7
//BIBLIOTECAS EMPLEADAS
#include<dos.h>
#include<graphics.h>
#include<stdlib.h>
#include<stdio.h>
#include<conio.h>
#include<process.h>
//DECLARACION DE FUNCIONES
void InicializaSVGA(void);
void dibujamalla();
void dibujacoordenada();
int comprueba();
void algoritmojugador1();
void algoritmojugador2();
//VARIABLES GLOBALES
int x=0;
int y=0;
int jugador=1;
char coordenada[7][7];
int huge DetectVGA256(){ return 2; }
//FUNCION PRINCIPAL
void main()
{
/////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
char buffer[80];
Conecta4 JugadorJD( &coordenada[0][0] );
if ( JugadorJD.Error() != NULL )
return;
/////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
int a,b,resultado;
char o='0';
//inicializa graficos
InicializaSVGA();
while(o!='q')
{
clearviewport();
resultado=0;
//inicializa coordenadas a cero
for (a=0;a<7;a++)
for (b=0;b<7;b++)
coordenada[a][b]=0;
//dibuja malla
dibujamalla();
//dibuja circulo en coordenada
while(resultado!=1&&resultado!=2)
{
//JUEGAN AMBOS JUGADORES
if(jugador==1) algoritmojugador1();
///////////////////////////////////////////////////////////////////////////////
else {
JugadorJD.JuegaTurno(); x = Post_X; y = Post_Y;
bar( 0, 0, 100, 30 );
sprintf( buffer, "%d, %d", x, y );
outtextxy( 10, 10, buffer );
// sound(150);delay(200);nosound();
// getch();
// x++; y++;
}
//////////////////////////////////////////////////////////////////////////////
//algoritmojugador2();
//COMPRUEBA LAS COORDENADAS CORRECTAS
if((x<7&&y<7&&x>-1&&y>-1) )//&&coordenada[x][y]==0&&((coordenada[x][y-1]!=0)||y==0))
{
dibujacoordenada();
if(jugador==1) {coordenada[x][y]=1;jugador=2;}
else {coordenada[x][y]=2;jugador=1;}
resultado=comprueba();
}
else {
bar( 100, 0, 600, 30 );
sprintf( buffer, "COORDENADA ERRONEA PRODUCIDA POR EL JUGADOR:%d",(int)jugador );
outtextxy( 110, 10, buffer );
}
}
//dice quien gano
if(jugador==2) sprintf( buffer, "GANO EL JUGADOR1");
else sprintf( buffer, "GANO EL JUGADOR2");
bar( 100, 0, 600, 30 );
outtextxy( 110, 10, buffer );
//cierra el modo grafico
o=getch();
};
closegraph();
}
//DIBUJA CIRCULO EN COORDENADA
void dibujacoordenada()
{
int a,c=0;
x=x+1;y=y+1;
while(c<=(8-y))
{
//elije color segun jugador
if(jugador==1) setcolor(1);
else setcolor(5);
//dibuja circulo
for(a=0;a<20;a++)
circle(50 * x+110,50 * c+50,a);
delay(250);
//borra circulo
if(c+1<=(8-y))
{
setcolor(0);
for(a=0;a<20;a++)
circle(50 * x+110,50 * c+50,a);
}
c=c+1;
}
x=x-1;
y=y-1;
}
//DIBUJA LA MALLA DEL JUEGO
void dibujamalla()
{
int a;
setcolor(15);
for(a=135;a<500;a=a+50)
line(a,75,a,425);
for(a=75;a<426;a=a+50)
line(135,a,485,a);
}
//INICIALIZA MODO GRAFICO EN SVGA
void InicializaSVGA(void) {
int Gd = DETECT, Gm;
int Drv, errorcode;
installuserdriver("Svga256",DetectVGA256);
initgraph(&Gd,&Gm,"c:\\program\\borlandc\\bgi");
/* read result of initialization */
errorcode = graphresult();
if (errorcode != grOk) /* an error occurred */
{
cprintf("Graphics error: %s\n", grapherrormsg(errorcode));
cprintf("Presione una tecla para finalizar:");
getch();
exit(1); /* return with error code */
}
}
//COMPRUEBA SI HA GANADO ALGUIEN Y DEVUELVE UN VALOR
int comprueba()
{
int w=0,suma=0,suma1=0,suma2=0,suma3=0,cx1,cy1;
cy1=0;cx1=0;
//LECTURA DEL ARRAY HORIZONTAL Y VERTICAL
while(cy1<8&&suma!=4&&suma1!=4&&suma2!=4&&suma3!=4)
{
suma=0;suma1=0;suma2=0;suma3=0;cx1=0;
while(cx1<8&&suma!=4&&suma1!=4&&suma2!=4&&suma3!=4)
{
if(coordenada[cx1][cy1]==0) {suma=0;suma1=0;}
if(coordenada[cx1][cy1]==1) {suma++;suma1=0;}
if(coordenada[cx1][cy1]==2) {suma1++;suma=0;}
if(coordenada[cy1][cx1]==0) {suma2=0;suma3=0;}
if(coordenada[cy1][cx1]==1) {suma2++;suma3=0;}
if(coordenada[cy1][cx1]==2) {suma3++;suma2=0;}
cx1++;
}
cy1++;
}
//LECTURA EN DIAGONAL Y DIAGONAL INVERSA
if(suma<4&&suma1<4&&suma2<4&&suma3<4) {cx1=1;cy1=1;suma=0;suma1=0;suma2=0;suma3=0;}
while(cy1<8&&suma!=4&&suma1!=4&&suma2!=4&&suma3!=4)
{
suma=0;suma1=0;suma2=0;suma3=0;cx1=1;
while(cx1<8&&suma!=4&&suma1!=4&&suma2!=4&&suma3!=4)
{
if(coordenada[cx1][cy1]==0) {suma=0;suma1=0;suma2=0;suma3=0;}
if(coordenada[cx1][cy1]==1) {suma++;suma1=0;}
if(coordenada[cx1][cy1]==2) {suma1++;suma=0;}
if(coordenada[cy1][cx1]==1) {suma2++;suma3=0;}
if(coordenada[cy1][cx1]==2) {suma3++;suma2=0;}
cx1++;
}
cy1++;
}
//DA [0] SI NO GANO NADIE,[1] SI GANO EL JUGADOR1,[2] SI GANO EL JUGADOR2
if(suma==4||suma2==4) w=1;
if(suma1==4||suma3==4) w=2;
return w;
}
//ALGORITMO DE JD
void algoritmojugador1()
{
//PRIMER MOVIMIENTO CENTRAL
int c=0,suma=0,suma1=0,suma2=0,suma3=0,cx1=0,cy1=0,a=0;
//LECTURA DEL ARRAY HORIZONTAL Y VERTICAL
while(cy1<7&&suma!=4&&suma1!=4&&suma2!=4&&suma3!=4)
{
suma=0;suma1=0;suma2=0;suma3=0;cx1=0;
while(cx1<7&&suma!=4&&suma1!=4&&suma2!=4&&suma3!=4)
{
if(coordenada[cx1][cy1]==0) {suma=0;suma1=0;}
if(coordenada[cx1][cy1]==1) {suma++;suma1=0;}
if(coordenada[cx1][cy1]==2) {suma1++;suma=0;}
if(coordenada[cy1][cx1]==0) {suma2=0;suma3=0;}
if(coordenada[cy1][cx1]==1) {suma2++;suma3=0;}
if(coordenada[cy1][cx1]==2) {suma3++;suma2=0;}
//MOVIMIENTO DE DEFENSA
if(suma1==3&&cx1<6)
if(coordenada[cx1+1][cy1]==0)
{x=cx1+1;y=cy1;a=1;}
if(suma3==3&&cx1<6)
if(coordenada[cy1][cx1+1]==0)
{x=cy1;y=cx1+1;a=1;}
//MOVIMIENTO DE ATAQUE
if(suma==3&&cx1<6)
if(coordenada[cx1+1][cy1]==0)
{x=cx1+1;y=cy1;a=1;}
if(suma2==3&&cx1<6)
if(coordenada[cy1][cx1+1]==0)
{x=cy1;y=cx1+1;a=1;}
cx1++;
}
cy1++;
}
if(((suma<3&&suma1<3&&suma2<3&&suma3<3)||(coordenada[x][y-1]==0))&&a==0)
{
randomize();
x=(rand() %3) +2;
while(coordenada[x][c]!=0)
{
c=c+1;
}
y=c;
}
}
//ALGORITMO DE OSCAR
void algoritmojugador2()
{
int c=0;
randomize();
x=rand() %7;
while(coordenada[x][c]!=0)
{
c=c+1;
}
y=c;
}
/**************************************************************************\
|* *|
|* 4 en Raya *|
|* *|
|* Algoritmo de combate dise¤ado por JD, capaz de profundizar en *|
|* jugadas defensivas/ofensivas. *|
|* *|
|* *|
|* *|
\**************************************************************************/
// #include <mem.h>
char Conecta4::AveriguaQuienSoy(void)
{
return ( QuienSoy = JUGADOR2 );
}
void Conecta4::JuegaTurno( void )
{
int x, y; // Punto, donde pondr mi ficha
int X, Y; // Puntos de avance en el tiempo.
char *tmp;
char Enemigo;
char ok, Turno;
// ¨ 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, TableroOriginal, sizeof( char ) * (TAMANYO_DEL_TABLERO) );
// ¨ Podemos ganar en este turno ?
if ( GanaTurno( &x, &y, QuienSoy ) )
{
*( TableroOriginal + ANCHO_TABLERO*x + y ) = QuienSoy;
////////////////////////////////////////////////////////////////////////////////////
Post_X = x; Post_Y = y;
////////////////////////////////////////////////////////////////////////////////////
return;
}
// ¨ Tengo que defender en este turno ?
if ( GanaTurno( &x, &y, Enemigo ) )
{
*( TableroOriginal + ANCHO_TABLERO*x + y ) = QuienSoy;
////////////////////////////////////////////////////////////////////////////////////
Post_X = x; Post_Y = y;
////////////////////////////////////////////////////////////////////////////////////
return;
}
ok = 0; Turno = 0;
// Tengo libertad en este turno para colocar la ficha donde quiera...
do {
AlgInteligente( &x, &y, QuienSoy );
*( CopiaDelTablero + ANCHO_TABLERO*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 -----------
// -- ¨ Tengo mas lugares donde poner ? (si esta jugada no es buena)
if ( Turno > ANCHO_TABLERO )
{
// ­­ Que le vamos hacer !!, puede ganar el contrario
ok = 1;
} else {
// Si pongo aqui: ¨ Gana el siguiente turno el enemigo ? 1==NO :: 0==SI
if ( (ok = !GanaTurno( &X, &Y, Enemigo ) ) )
{
// Vale, el enemigo no ganar  en el siguiente turno, pero...
// ...que tal si nos adelantamos un poquito en el tiempo.
AlgInteligente( &X, &Y, Enemigo );
*( CopiaDelTablero + ANCHO_TABLERO*X + Y ) = 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...
tmp = ( CopiaDelTablero + ANCHO_TABLERO*X + Y );
AlgInteligente( &X, &Y, QuienSoy );
*( CopiaDelTablero + ANCHO_TABLERO*X + Y ) = QuienSoy;
// ...¨y el enemigo?
if ( GanaTurno( &X, &Y, Enemigo ) )
{
// Parece que el enemigo gana, y no me la va a dar, asi de facil.
// Si se puede poner ahora, tapo la jugada
if ( *( TableroOriginal + ANCHO_TABLERO*X + ( (Y-1)<0 ? 0 : (Y-1) ) ) == NO_HAY_NADIE )
{
ok = 1;
x = X; y = Y;
} else {
// De lo contrario, realizo otra jugada. (Alg int. debe intervenir)
ok = 0;
}
*( CopiaDelTablero + ANCHO_TABLERO*X + Y ) = NO_HAY_NADIE;
*tmp = NO_HAY_NADIE;
} else {
// Juega mejor colega, por que a mi no me ganas.
ok = 1;
}
}
} else {
// El enemigo ganar¡a directamente, deshacemos el movimiento.
*( CopiaDelTablero + ANCHO_TABLERO*x + y ) = NO_HAY_NADIE;
}
}
Turno++;
} while ( !ok );
// Este el el punto de inserci¢n optimo.
*( TableroOriginal + ANCHO_TABLERO*x + y ) = QuienSoy;
////////////////////////////////////////////////////////////////////////////////////
Post_X = x; Post_Y = y;
////////////////////////////////////////////////////////////////////////////////////
}
// 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;
char Pos_Y[ANCHO_TABLERO];
PosiblesLugares( Pos_Y );
// Si metemos la ficha en algun lugar, ¨ GANAMOS ?
FichasHints = 0;
for ( i = 0; i < ANCHO_TABLERO; i++ ) // Revisamos todos los huecos
if ( Pos_Y[i] != -1 )
{
//°²Û X
//°²Û ¨ Posibilidad de ganar en HORIZONTAL ? X X
//°²Û X * * - *
//°²Û Insertando la ficha gano ----------^
FichasHints = 0;
for ( j = i-1; j>=0; j--)
{
QueHay = *( CopiaDelTablero + j * ANCHO_TABLERO + Pos_Y[i] );
if ( QueHay == JUGADOR_DUMMY )
FichasHints++;
else break;
}
for ( j = i+1; j<ANCHO_TABLERO; j++)
{
QueHay = *( CopiaDelTablero + j * ANCHO_TABLERO + Pos_Y[i] );
if ( QueHay == JUGADOR_DUMMY )
FichasHints++;
else break;
}
// Bingo, Aqui ganamos
if ( FichasHints >= 3 )
{
*Pos_x = i;
*Pos_y = Pos_Y[i];
return 1;
}
//°²Û Insertando la ficha gano ---> -
//°²Û *
//°²Û ¨ Posibilidad de ganar en VERTICAL ? * X
//°²Û * * X X X
// Solo es posible si mi altura actual es >= 3
if ( Pos_Y[i] >= 3 )
{
FichasHints = 0;
for ( j = Pos_Y[i]-1; j >= 0; j-- )
{
QueHay = *( CopiaDelTablero + i * ANCHO_TABLERO + j );
if ( QueHay == JUGADOR_DUMMY )
FichasHints++;
else break;
}
if ( FichasHints >= 3 )
{
*Pos_x = i;
*Pos_y = Pos_Y[i];
return 1;
}
}
//°²Û Insertando la ficha gano ÄÄÄÄÄÄÄÄÄ¿ *
//°²Û * - * X
//°²Û ¨ Posibilidad de ganar en DIAGONAL 1 ? X * X X X
//°²Û * * X X X
FichasHints = 0;
k = i - 1;
for ( j = Pos_Y[i]-1; j >= 0 && k >= 0; j--, k-- )
{
QueHay = *( CopiaDelTablero + k * ANCHO_TABLERO + j );
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 + k * 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;
}
//°²Û Insertando la ficha gano ÄÄÄÄÄÄÄ*Ä¿ X
//°²Û X X - X X
//°²Û ¨ Posibilidad de ganar en DIAGONAL 2 ? X * X * X
//°²Û X * * X *
FichasHints = 0;
k = i + 1;
for ( j = Pos_Y[i]-1; j >= 0 && k < ANCHO_TABLERO; j--, k++ )
{
QueHay = *( CopiaDelTablero + k * ANCHO_TABLERO + j );
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 + k * 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;
}
}
// Este turno no puede ser ganado, DIRECTAMENTE!!!
return 0;
}
// El algoritmo inteligente es el nucleo de pensamiento de mi OBJETO
// decidir  cual es la posici¢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¢n de fichas, en
// la media luna de posiciones que me rodean. FREC_MAX -> max. pos. de ganar.
//
// Realmente en este algoritmo, se podr¡an tener algunas jugadas estratgicas
// 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 )
{
char Pos_Y[ANCHO_TABLERO];
char Frec_Y[ANCHO_TABLERO], Frec_abs;
char i, j;
PosiblesLugares( Pos_Y );
// ? ?
// Por cada casilla, vemos la frecuencia de apariciones ? * ?
// en la media luna que hay por debajo y arriba! ? ? ?
for ( i = 0; i < ANCHO_TABLERO; i++ )
{
Frec_Y[i] = 0;
if ( Pos_Y[i] != -1 )
{
for ( j = ( ( Pos_Y[i] - 1 ) < 0 ? 0 : ( Pos_Y[i] - 1 ) ); j <= ( (Pos_Y[i] + 1) >= ALTO_TABLERO ? (ALTO_TABLERO-1) : (Pos_Y[i] + 1) ); j++ )
{
if ( (i-1) >= 0 &&
*( CopiaDelTablero + (i-1) * ANCHO_TABLERO + j ) == JUGADOR_DUMMY )
Frec_Y[i] ++;
if ( (i+1) <= (ANCHO_TABLERO-1) &&
*( CopiaDelTablero + ( (i+1)>=ANCHO_TABLERO ? (ANCHO_TABLERO-1) : (i+1) ) * ANCHO_TABLERO + j ) == JUGADOR_DUMMY )
Frec_Y[i] ++;
}
if ( *( CopiaDelTablero + ( i * ANCHO_TABLERO + ( (Pos_Y[i]-1) < 0 ? 1 : (Pos_Y[i]-1) ) ) ) == JUGADOR_DUMMY )
Frec_Y[i] ++;
}
}
// Coloco mi ficha en la posici¢n con mayor frecuencia:
Frec_abs = -1;
for ( i = 0; i < ANCHO_TABLERO; i++ )
if ( Frec_Y[i] > Frec_abs || (Frec_Y[i] == Frec_abs && Pos_Y[i] < *Pos_y) )
{
Frec_abs = Frec_Y[i];
*Pos_x = i;
*Pos_y = Pos_Y[i];
}
}
void Conecta4::PosiblesLugares( char Pos_Y[ANCHO_TABLERO] )
{
// char Pos_Y[ANCHO_TABLERO];
int i, j;
// 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 + i * ANCHO_TABLERO + j ) == NO_HAY_NADIE )
{
Pos_Y[i] = j;
break;
}
}
}
}
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;
}

BIN
OSC.EXE Normal file

Binary file not shown.

9
README.md Normal file
View File

@ -0,0 +1,9 @@
#4RAYA
*24/10/1997*
ToDo: wwtcf?
![screenshot](/4RAYA.png "Screenshot")

BIN
SVGA256.BGI Normal file

Binary file not shown.

20
TCOMPROB.CPP Normal file
View File

@ -0,0 +1,20 @@
#include <stdio.h>
char t[7][7];
void main (void)
{
int x, y;
char *d;
d = &t[0][0];
for ( x=0; x<7; x++)
for ( y=0; y<7; y++)
{
t[x][y] = 7*y + x;
if ( t[x][y] != *( d + 7*x + y ) )
printf ( "DISTINTOS\n" );
}
}

BIN
TCOMPROB.EXE Normal file

Binary file not shown.