Package prop.hex.domini.controladors.IA.auxiliars

Source Code of prop.hex.domini.controladors.IA.auxiliars.CamiMinim

package prop.hex.domini.controladors.IA.auxiliars;

import prop.cluster.domini.models.estats.EstatCasella;
import prop.hex.domini.models.Casella;
import prop.hex.domini.models.TaulerHex;

import java.util.List;
import java.util.PriorityQueue;

/**
* Busca el camí de cost mínim per arribar d'una punta a una altra del tauler, horitzontal o verticalment depenent de
* quin jugador sigui. Aplica l'algorítme de Dijkstra, el cost de cada casella depen del jugador i del contingut de
* la casella.
*
* @author Marc Junyent Martín (Grup 7.3, Hex)
*/
public final class CamiMinim
{

  /**
   * Tauler sobre el que es fa la cerca.
   */
  private TaulerHex tauler;

  /**
   * Jugador per al que es fa la cerca.
   */
  private EstatCasella jugador;

  /**
   * Guardem els valors parcials del cost del cami mínim. El nom resistencies ve donat pel concepte de que cada
   * casella es una resistencia el valor de la qual varia segons el jugador que l'evalui i el seu contingut.
   */
  private int[][] resistencies_parcials;

  /**
   * Número més gran que qualsevol camí que es pogués generar en el tauler, però suficientment petit per no causar
   * overflow.
   */
  private static int infinit = 1000000;

  /**
   * @param tauler  Tauler sobre el que buscar
   * @param jugador Per a quin jugador volem buscar
   */
  public CamiMinim( TaulerHex tauler, EstatCasella jugador )
  {
    this.tauler = tauler;
    this.jugador = jugador;
    resistencies_parcials = new int[tauler.getMida()][tauler.getMida()];
    for ( int fila = 0; fila < tauler.getMida(); fila++ )
    {
      for ( int columna = 0; columna < tauler.getMida(); columna++ )
      {
        resistencies_parcials[fila][columna] = infinit;
      }
    }
  }

  /**
   * Busca el camí de cost mínim aplicant l'algoritme de Dijkstra
   *
   * @return retorna el camí de cost mínim (Resistencia mínima).
   */
  public int evalua()
  {
    PriorityQueue<ResistenciaCasella> cua_caselles = new PriorityQueue<ResistenciaCasella>();

    /**
     * Omplim la cua_caselles amb les caselles d'un canto, el superior si és jugador_B o l'esquerra si és A.
     */
    if ( jugador == EstatCasella.JUGADOR_A )
    {
      for ( int fila = 0; fila < tauler.getMida(); fila++ )
      {
        resistencies_parcials[fila][0] = resistenciaCasella( new Casella( fila, 0 ) );
        cua_caselles.add( new ResistenciaCasella( new Casella( fila, 0 ), resistencies_parcials[fila][0] ) );
      }
    }
    else
    {
      for ( int columna = 0; columna < tauler.getMida(); columna++ )
      {
        resistencies_parcials[0][columna] = resistenciaCasella( new Casella( 0, columna ) );
        cua_caselles
            .add( new ResistenciaCasella( new Casella( 0, columna ), resistencies_parcials[0][columna] ) );
      }
    }

    /**
     * Fem Dijkstra sobre la cua_caselles.
     */
    while ( !cua_caselles.isEmpty() )
    {
      ResistenciaCasella actual = cua_caselles.poll();

      List<Casella> veins = tauler.getVeins( actual.getCasella() );
      for ( Casella vei : veins )
      {
        if ( resistencies_parcials[vei.getFila()][vei.getColumna()] >
             actual.getResistencia() + resistenciaCasella( vei ) )
        {
          resistencies_parcials[vei.getFila()][vei.getColumna()] =
              actual.getResistencia() + resistenciaCasella( vei );
          cua_caselles.add( new ResistenciaCasella( vei,
              resistencies_parcials[vei.getFila()][vei.getColumna()] ) );
        }
      }
    }

    /**
     * Mirem la cantonada inferior o dreta (depenent del jugador) i ens quedem amb el mínim valor de totes les
     * caselles que hi ha, aquest serà el mínim valor per creuar el tauler.
     */
    int min = infinit;

    if ( jugador == EstatCasella.JUGADOR_A )
    {
      for ( int fila = 0; fila < tauler.getMida(); fila++ )
      {
        if ( resistencies_parcials[fila][tauler.getMida() - 1] < min )
        {
          min = resistencies_parcials[fila][tauler.getMida() - 1];
        }
      }
    }
    else
    {
      for ( int columna = 0; columna < tauler.getMida(); columna++ )
      {
        if ( resistencies_parcials[tauler.getMida() - 1][columna] < min )
        {
          min = resistencies_parcials[tauler.getMida() - 1][columna];
        }
      }
    }

    return min;
  }

  /**
   * Retorna la resistencia d'una casella donada.
   *
   * @param casella
   * @return resistencia d'aquesta casella (0 si és del jugador, 1 si està buida o inf. altrament.
   */
  private int resistenciaCasella( Casella casella )
  {
    EstatCasella estat = tauler.getEstatCasella( casella );
    if ( estat == jugador )
    {
      return 0;
    }
    else if ( estat == EstatCasella.BUIDA )
    {
      return 1;
    }
    else
    {
      return infinit;
    }
  }
}
TOP

Related Classes of prop.hex.domini.controladors.IA.auxiliars.CamiMinim

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.