commit 1a08d45c8201370115771264538e5356ebdf7ae5 Author: jdg Date: Sun Sep 12 19:47:27 2021 +0200 First commit 24/10/1997 diff --git a/4R.CPP b/4R.CPP new file mode 100644 index 0000000..b22c806 --- /dev/null +++ b/4R.CPP @@ -0,0 +1,323 @@ + /**************************************************************************\ +|* *| +|* 4 en Raya *| +|* *| +|* Algoritmo de combate dise¤ado por JD, capaz de profundizar en *| +|* jugadas defensivas/ofensivas. *| +|* *| +|* *| +|* *| + \**************************************************************************/ + + #include + + 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= 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= 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= 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 estrat‚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; + } + + + diff --git a/4RAYA.CPP b/4RAYA.CPP new file mode 100644 index 0000000..b22c806 --- /dev/null +++ b/4RAYA.CPP @@ -0,0 +1,323 @@ + /**************************************************************************\ +|* *| +|* 4 en Raya *| +|* *| +|* Algoritmo de combate dise¤ado por JD, capaz de profundizar en *| +|* jugadas defensivas/ofensivas. *| +|* *| +|* *| +|* *| + \**************************************************************************/ + + #include + + 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= 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= 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= 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 estrat‚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; + } + + + diff --git a/EGAVGA.BGI b/EGAVGA.BGI new file mode 100644 index 0000000..8001631 Binary files /dev/null and b/EGAVGA.BGI differ diff --git a/OSC.CPP b/OSC.CPP new file mode 100644 index 0000000..a3ff920 --- /dev/null +++ b/OSC.CPP @@ -0,0 +1,690 @@ + /**************************************************************************\ +|* *| +|* 4 en Raya *| +|* *| +|* Algoritmo de combate dise¤ado por JD, capaz de profundizar en *| +|* jugadas defensivas/ofensivas. *| +|* *| +|* *| +|* *| + \**************************************************************************/ +#include + + //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 +#include +#include +#include +#include +#include + +//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 + + 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= 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= 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= 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 estrat‚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 ) + { + 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; + } diff --git a/OSC.EXE b/OSC.EXE new file mode 100644 index 0000000..654bd6d Binary files /dev/null and b/OSC.EXE differ diff --git a/README.md b/README.md new file mode 100644 index 0000000..b962cd5 --- /dev/null +++ b/README.md @@ -0,0 +1,9 @@ +#4RAYA + + +*24/10/1997* + +ToDo: wwtcf? + + +![screenshot](/4RAYA.png "Screenshot") diff --git a/SVGA256.BGI b/SVGA256.BGI new file mode 100644 index 0000000..f74bc72 Binary files /dev/null and b/SVGA256.BGI differ diff --git a/TCOMPROB.CPP b/TCOMPROB.CPP new file mode 100644 index 0000000..ba80e73 --- /dev/null +++ b/TCOMPROB.CPP @@ -0,0 +1,20 @@ +#include + +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" ); + } + +} \ No newline at end of file diff --git a/TCOMPROB.EXE b/TCOMPROB.EXE new file mode 100644 index 0000000..f8a04da Binary files /dev/null and b/TCOMPROB.EXE differ