Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <cstdlib>
- #include <vector>
- #include <queue>
- #include "player.h"
- #include "environment.h"
- using namespace std;
- const double masinf=9999999999.0, menosinf=-9999999999.0;
- // Constructor
- Player::Player(int jug){
- jugador_=jug;
- }
- // Actualiza el estado del juego para el jugador
- void Player::Perceive(const Environment & env){
- actual_=env;
- }
- double Puntuacion(int jugador, const Environment &estado){
- double suma=0;
- for (int i=0; i<7; i++)
- for (int j=0; j<7; j++){
- if (estado.See_Casilla(i,j)==jugador){
- if (j<3)
- suma += j;
- else
- suma += (6-j);
- }
- }
- return suma;
- }
- // Funcion de valoracion para testear Poda Alfabeta
- double ValoracionTest(const Environment &estado, int jugador){
- int ganador = estado.RevisarTablero();
- if (ganador==jugador)
- return 99999999.0; // Gana el jugador que pide la valoracion
- else if (ganador!=0)
- return -99999999.0; // Pierde el jugador que pide la valoracion
- else if (estado.Get_Casillas_Libres()==0)
- return 0; // Hay un empate global y se ha rellenado completamente el tablero
- else
- return Puntuacion(jugador,estado);
- }
- // ------------------- Los tres metodos anteriores no se pueden modificar
- void FichasVerticales(const Environment &E, int jugador,int fila, int columna,int &verticales){
- verticales = 0;
- for(int i=1;fila-i>=0;i++){
- if(E.See_Casilla(fila-i,columna)!=jugador) break;
- else if(E.See_Casilla(fila-i,columna)==jugador)
- verticales++;
- }
- for(int i=1;fila+i<7;i++){
- if(E.See_Casilla(fila+i,columna)!=jugador) break;
- else if(E.See_Casilla(fila+i,columna)==jugador)
- verticales++;
- }
- }
- void FichasHorizontales(const Environment &E, int jugador,int fila, int columna,int &horizontales){
- horizontales = 0;
- for(int i=1;columna-i>=0;i++){
- if(E.See_Casilla(fila,columna-i)!=jugador)break;
- else if(E.See_Casilla(fila,columna-i)==jugador)
- horizontales++;
- }
- for(int i=0;columna+i<7;i++){
- if(E.See_Casilla(fila,columna+i)!=jugador)break;
- else if(E.See_Casilla(fila,columna+i)==jugador)
- horizontales++;
- }
- }
- void FichasDiagonales(const Environment &E, int jugador,int fila, int columna,int &diagonales){
- diagonales = 0;
- for(int i=1;i<4;i++){
- if(fila+i == 7 || columna+i== 7)break;
- if(E.See_Casilla(fila-i,columna-i)!=jugador)break;
- if(E.See_Casilla(fila-i,columna-i)==jugador)
- diagonales++;
- }
- for(int i=1;i<4;i++){
- if(fila+i == -1 || columna+i== 7)break;
- if(E.See_Casilla(fila-i,columna+i)!=jugador)break;
- else if(E.See_Casilla(fila-i,columna+i)==jugador)
- diagonales++;
- }
- for(int i=1;i<4;i++){
- if(fila+i == 7 || columna-i== -1)
- break;
- if(E.See_Casilla(fila+i,columna-i)!=jugador)break;
- if(E.See_Casilla(fila+i,columna-i)==jugador)
- diagonales++;
- }
- for(int i=1;i<4;i++){
- if(fila+i == -1 || columna-i== 7)
- break;
- if(E.See_Casilla(fila-i,columna-i)!=jugador)break;
- if(E.See_Casilla(fila-i,columna-i)==jugador)
- diagonales++;
- }
- }
- double Heuristica(const Environment &E, int jugador){
- double puntuacion = 0;
- int verticales = 0, horizontales = 0, diagonales = 0;
- for(int i=0;i<7;i++){
- for(int j=0;j<7;j++){
- FichasVerticales(E,jugador,i,j,verticales);
- FichasHorizontales(E,jugador,i,j,horizontales);
- FichasDiagonales(E,jugador,i,j,diagonales);
- puntuacion += 100*verticales + 100*horizontales + 100*diagonales;
- }
- }
- return puntuacion;
- }
- // Funcion heuristica (ESTA ES LA QUE TENEIS QUE MODIFICAR)
- double Valoracion(const Environment &estado, int jugador){
- int rival;
- int ganador = estado.RevisarTablero();
- double puntuacion = 0;
- if(jugador == 1)
- rival = 2;
- else
- rival = 1;
- if (ganador==jugador)
- return 99999999.0; // Gana el jugador que pide la valoracion
- else if (ganador!=0)
- return -99999999.0; // Pierde el jugador que pide la valoracion
- else if (estado.Get_Casillas_Libres()==0)
- return 0; // Hay un empate global y se ha rellenado completamente el tablero
- else
- puntuacion -=Heuristica(estado,jugador);
- puntuacion +=Heuristica(estado,rival);
- }
- // Esta funcion no se puede usar en la version entregable
- // Aparece aqui solo para ILUSTRAR el comportamiento del juego
- // ESTO NO IMPLEMENTA NI MINIMAX, NI PODA ALFABETA
- void JuegoAleatorio(bool aplicables[], int opciones[], int &j){
- j=0;
- for (int i=0; i<8; i++){
- if (aplicables[i]){
- opciones[j]=i;
- j++;
- }
- }
- }
- double PodaAlfaBeta(const Environment &E, int jugador, int profundidad,
- Environment::ActionType accion, double alfa, double beta,double &nodos){
- if(profundidad == 0 || E.JuegoTerminado()){
- return Valoracion(E,jugador);
- }
- nodos++;
- bool acciones[8];
- int hijos = E.possible_actions(acciones);
- int ultima_accion = -1;
- Environment::ActionType anterior;
- double valor;
- Environment nodoHijo = E.GenerateNextMove(ultima_accion);
- if(profundidad%2==0){
- for(int i=0;i<hijos;i++){
- valor = PodaAlfaBeta(nodoHijo,jugador,profundidad-1,anterior,alfa,beta,nodos);
- if(valor>alfa){
- alfa = valor;
- accion = static_cast<Environment::ActionType>(ultima_accion);
- }
- if(beta<=alfa)
- break;
- nodoHijo = E.GenerateNextMove(ultima_accion);
- }
- return alfa;
- }
- else{
- for(int i=0;i<hijos;i++){
- valor = PodaAlfaBeta(nodoHijo,jugador,profundidad-1,anterior,alfa,beta,nodos);
- if(valor<beta){
- beta = valor;
- accion = static_cast<Environment::ActionType>(ultima_accion);
- }
- if(beta<=alfa)
- break;
- nodoHijo = E.GenerateNextMove(ultima_accion);
- }
- return beta;
- }
- }
- // Invoca el siguiente movimiento del jugador
- Environment::ActionType Player::Think(){
- const int PROFUNDIDAD_MINIMAX = 6; // Umbral maximo de profundidad para el metodo MiniMax
- const int PROFUNDIDAD_ALFABETA = 8; // Umbral maximo de profundidad para la poda Alfa_Beta
- Environment::ActionType accion; // acci�n que se va a devolver
- bool aplicables[8]; // Vector bool usado para obtener las acciones que son aplicables en el estado actual. La interpretacion es
- // aplicables[0]==true si PUT1 es aplicable
- // aplicables[1]==true si PUT2 es aplicable
- // aplicables[2]==true si PUT3 es aplicable
- // aplicables[3]==true si PUT4 es aplicable
- // aplicables[4]==true si PUT5 es aplicable
- // aplicables[5]==true si PUT6 es aplicable
- // aplicables[6]==true si PUT7 es aplicable
- // aplicables[7]==true si BOOM es aplicable
- double valor; // Almacena el valor con el que se etiqueta el estado tras el proceso de busqueda.
- double alpha, beta; // Cotas de la poda AlfaBeta
- int n_act; //Acciones posibles en el estado actual
- double nodos = 0;
- n_act = actual_.possible_actions(aplicables); // Obtengo las acciones aplicables al estado actual en "aplicables"
- int opciones[10];
- // Muestra por la consola las acciones aplicable para el jugador activo
- //actual_.PintaTablero();
- cout << " Acciones aplicables ";
- (jugador_==1) ? cout << "Verde: " : cout << "Azul: ";
- for (int t=0; t<8; t++)
- if (aplicables[t])
- cout << " " << actual_.ActionStr( static_cast< Environment::ActionType > (t) );
- cout << endl;
- /*
- //--------------------- COMENTAR Desde aqui
- cout << "\n\t";
- int n_opciones=0;
- JuegoAleatorio(aplicables, opciones, n_opciones);
- if (n_act==0){
- (jugador_==1) ? cout << "Verde: " : cout << "Azul: ";
- cout << " No puede realizar ninguna accion!!!\n";
- //accion = Environment::actIDLE;
- }
- else if (n_act==1){
- (jugador_==1) ? cout << "Verde: " : cout << "Azul: ";
- cout << " Solo se puede realizar la accion "
- << actual_.ActionStr( static_cast< Environment::ActionType > (opciones[0]) ) << endl;
- accion = static_cast< Environment::ActionType > (opciones[0]);
- }
- else { // Hay que elegir entre varias posibles acciones
- int aleatorio = rand()%n_opciones;
- cout << " -> " << actual_.ActionStr( static_cast< Environment::ActionType > (opciones[aleatorio]) ) << endl;
- accion = static_cast< Environment::ActionType > (opciones[aleatorio]);
- }
- //--------------------- COMENTAR Hasta aqui
- */
- //--------------------- AQUI EMPIEZA LA PARTE A REALIZAR POR EL ALUMNO ------------------------------------------------
- // Opcion: Poda AlfaBeta
- // NOTA: La parametrizacion es solo orientativa
- alpha = menosinf;
- beta = masinf;
- valor = PodaAlfaBeta(actual_, jugador_, PROFUNDIDAD_ALFABETA, accion, alpha, beta,nodos);
- cout << "Valor MiniMax: " << valor << " Accion: " << actual_.ActionStr(accion) << endl;
- return accion;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement