prac1_remoz_daton.tMano.java Source code

Java tutorial

Introduction

Here is the source code for prac1_remoz_daton.tMano.java

Source

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package prac1_remoz_daton;

import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang3.StringUtils;

/**
 *
 * @author Daton
 */
public class tMano {
    enum enumManos {
        ESCALERA_REAL, ESCALERA_COLOR, POKER, FULL, COLOR, ESCALERA, TRIO, DOBLE_PAREJA, PAREJA, CARTA_ALTA;
    }

    //lista de cartas: 5 como mucho.. tal como dictan las reglas del poker
    private tListaCartas _listaCartas;
    //cartas representante de la mano (lo estrictamente minimo)
    private tListaCartas _cartasRep;
    //lista de draws (dos cartas)
    private List<tMano> _listaDraws;
    //chapuza para no usar herencia... en fin ...
    boolean _esDraw;
    //la primera mano de mayor Rango (sin contar el palo)
    tCarta _cartaMax;
    enumManos _tipoMano;
    tBaraja _Baraja;

    public tMano(List<tCarta> listaCartas) {
        _esDraw = false;
        _listaDraws = null;
        _Baraja = new tBaraja();
        _cartaMax = listaCartas.get(0);
        _cartasRep = new tListaCartas();
        _listaCartas = new tListaCartas();
        for (int i = 0; i < 5; i++) {
            this._listaCartas.add(listaCartas.get(i));
        }
        analizar();
    }

    //peso de la mano
    public int toInt() {
        int unLong = enumManos.values().length;
        switch (_tipoMano) {
        case ESCALERA_REAL:
            return unLong;
        case ESCALERA_COLOR:
            return unLong - 1;
        case POKER:
            return unLong - 2;
        case FULL:
            return unLong - 3;
        case COLOR:
            return unLong - 4;
        case ESCALERA:
            return unLong - 5;
        case TRIO:
            return unLong - 6;
        case DOBLE_PAREJA:
            return unLong - 7;
        case PAREJA:
            return unLong - 8;
        case CARTA_ALTA:
            return unLong - 9;
        default:
            return -1;
        }
    }

    public boolean equals(Object unObjeto) {
        if (unObjeto == null)
            return false;
        if (!(unObjeto instanceof tMano))
            return false;
        if (((tMano) unObjeto)._tipoMano != this._tipoMano)
            return false;
        boolean enc = (this._listaCartas.size() == ((tMano) unObjeto)._listaCartas.size());
        int i = 0;
        //COMPLETAR! esta parte hay que rehacerla
        while (enc && i < this._listaCartas.size()) {
            enc = ((tMano) unObjeto)._listaCartas.get(i).equals(this._listaCartas.get(i));
        }
        return enc;
    }

    public String toString() {
        StringBuffer unBuffer = new StringBuffer();
        for (int i = 0; i < 5; i++)
            unBuffer.append(this._listaCartas.get(i).toString());

        String unString = "";
        switch (_tipoMano) {
        case ESCALERA_REAL:
            unString = " Escalera Real";
            break;
        case ESCALERA_COLOR:
            unString = " Escalera de Color";
            break;
        case POKER:
            unString = " Poker";
            break;
        case FULL:
            unString = " Full";
            break;
        case COLOR:
            unString = " Color";
            break;
        case ESCALERA:
            unString = " Escalera";
            break;
        case TRIO:
            unString = " Trio";
            break;
        case DOBLE_PAREJA:
            unString = " Doble Pareja";
            break;
        case PAREJA:
            unString = " Pareja";
            break;
        case CARTA_ALTA:
            unString = " Carta Alta";
            break;
        default:
            unString = "";
        }
        unBuffer.append(unString);

        StringBuffer otroBuffer = new StringBuffer().append(" de ");
        switch (_tipoMano) {
        case ESCALERA_REAL:
            otroBuffer.append(_cartasRep.get(0).damePalo().toString());
            break;
        case ESCALERA_COLOR:
            otroBuffer.append(_cartasRep.get(0).damePalo().toString());
            break;
        case POKER:
            otroBuffer.append(_cartasRep.get(0).dameRango().toString());
            break;
        case FULL:
            otroBuffer.append(_cartasRep.get(0).dameRango().toString()).append(" y de ")
                    .append(_cartasRep.get(1).dameRango().toString());
            break;
        case COLOR:
            otroBuffer.append(_cartasRep.get(0).damePalo().toString());
            break;
        case ESCALERA:
            otroBuffer.append(_cartasRep.get(0).dameRango().toString());
            break;
        case TRIO:
            otroBuffer.append(_cartasRep.get(0).dameRango().toString());
            break;
        case DOBLE_PAREJA:
            otroBuffer.append(_cartasRep.get(0).dameRango().toString()).append(" y de ")
                    .append(_cartasRep.get(1).dameRango().toString());
            break;
        case PAREJA:
            otroBuffer.append(_cartasRep.get(0).dameRango().toString());
            break;
        case CARTA_ALTA:
            otroBuffer.append(_cartaMax.dameRango().toString());
            break;
        default:
            ;
        }
        unBuffer.append(otroBuffer);

        if (!_esDraw)
            unBuffer.append(this.dameDraws());

        return unBuffer.toString();
    }

    //inspirado en  http://rosettacode.org/wiki/Poker_hand_analyser
    private void analizar() {

        _cartasRep.clear();

        if (this._listaCartas.isEmpty())
            return;

        int nRangos = tRango.enumRango.toArrayChar().length;
        int[] contadorRangos = new int[nRangos];
        for (int i = 0; i < nRangos; i++)
            contadorRangos[i] = 0;
        long contadorEscalera = 0;
        boolean esEscalera = false;
        long contadorColor = 0;
        boolean esColor = false;
        int total = 0;

        //parseo las cinco cartas y las reflejo en 
        //contadores y estructuras
        for (int i = 0; i < _listaCartas.size(); i++) {
            tCarta unaCarta = _listaCartas.get(i);
            if (unaCarta.dameRango().toInt() > _cartaMax.dameRango().toInt())
                _cartaMax = unaCarta;
            tRango unRango = unaCarta.dameRango();
            contadorRangos[unRango.toInt()]++;

            contadorEscalera |= (1 << unRango.toInt());
            //son todas las cartas del mismo color?
            contadorColor |= (1 << unaCarta.damePalo().toString().toCharArray()[0]);
        }

        //desplazar  los bits lo ms a la derecha posible
        while (contadorEscalera % 2 == 0)
            contadorEscalera >>= 1;

        //escalera real, o escalera con un As es 00011111 ; 
        //A-2-3-4-5 es 1111000000001
        esEscalera = (contadorEscalera == 0b11111) || (contadorEscalera == 0b1111000000001);

        // unsets right-most 1-bit, which may be the only one set
        //?deshabilita el bit que vale 1,  de ms a la derecha, que debe de ser el nico activado??
        esColor = (contadorColor & (contadorColor - 1)) == 0;

        if (esColor && esEscalera) {
            this._tipoMano = enumManos.ESCALERA_REAL;
            _cartasRep.add(_listaCartas.get(0));
            return;
        }
        //evaluo todo lo que sea menor que escalera..
        //construyendo _cartasRep.
        //ojo, que en multiples cartas no nos interesan los colores.
        Integer otroRango = null;
        tCarta unaCarta = null;
        for (int i = 0; i < nRangos; i++) {
            //Daton .. uff... tengo que crear una carta con su rango..
            //por el momento creo una carta con mismo rango, pero todos con corazn
            otroRango = i;
            unaCarta = new tCarta(tRango.enumRango.toArrayChar()[i], 'h');
            if (contadorRangos[i] == 4) {
                this._tipoMano = enumManos.POKER;
                _cartasRep.add(unaCarta);
                return;
            }

            if (contadorRangos[i] == 3) {
                _cartasRep.add(unaCarta);
                total += 3;
            } else if (contadorRangos[i] == 2) {
                _cartasRep.add(unaCarta);
                total += 2;
            }

        }

        if (total == 5) {
            this._tipoMano = enumManos.FULL;
            //_cartasRep ya rellenada durante el parseo                
            return;
        }
        if (esColor) {
            this._tipoMano = enumManos.COLOR;
            //vaco _cartasRep y lo meto una carta
            _cartasRep.clear();
            _cartasRep.add(_listaCartas.get(0));
            return;
        }

        if (esEscalera) {
            this._tipoMano = enumManos.ESCALERA;
            _cartasRep.add(_cartaMax);
            return;
        }

        if (total == 3) {
            this._tipoMano = enumManos.TRIO;
            //_cartasRep ya rellenada durante el parseo
            return;
        }

        if (total == 4) {
            this._tipoMano = enumManos.DOBLE_PAREJA;
            //_cartasRep ya rellenada durante el parseo
            return;
        }

        if (total == 2) {
            this._tipoMano = enumManos.PAREJA;
            //_cartasRep ya rellenada durante el parseo
            return;
        }

        //e.o.c.. slo nos queda carta alta
        //_cartasRep ya rellenada durante el parseo        
        _tipoMano = enumManos.CARTA_ALTA;

    }

    private void generarDraws() {
        if (_esDraw)
            return;
        if (!_esDraw) {
            _listaDraws = new ArrayList<>();
            analizarConComodines(_listaCartas.toString());
        }
    }

    tListaManos dameDraws() {
        //si no es una mano, sino un draw
        if (_esDraw)
            return null;

        //si es una mano normal
        if (_listaDraws == null)
            generarDraws();
        return new tListaManos(_listaDraws, 0);

    }

    private void insertaDraw(tMano unDraw) {
        //listaDraw slo tendr dos elementos como mucho
        //si vaco
        if (_listaDraws.isEmpty())
            _listaDraws.add(unDraw);
        //si un elemento
        else if (_listaDraws.size() == 1) {
            //actualizo si mejor
            if (unDraw.toInt() > _listaDraws.get(0).toInt())
                _listaDraws.set(0, unDraw);
            else
                _listaDraws.add(unDraw);
        }
        //si dos eleentos o ms
        else if (_listaDraws.size() > 1) {
            //actualizo si mejor
            if (unDraw.toInt() > _listaDraws.get(0).toInt())
                _listaDraws.set(0, unDraw);
            else if (unDraw.toInt() > _listaDraws.get(1).toInt())
                _listaDraws.set(1, unDraw);
        }

    }

    /*
    Ah_Ac_2h_As_Ad
        
    ww_ww_2h_As_Ad
    Ah_ww_ww_As_Ad
    Ah_Ac_ww_ww_Ad
    Ah_Ac_2h_ww_ww
        
    ww_Ac_ww_As_Ad
    Ah_ww_2h_ww_Ad
    Ah_Ac_ww_As_ww
        
    ww_Ac_2h_ww_Ad
    Ah_ww_2h_As_ww
        
    ww_Ac_2h_As_ww
    */
    private String dameUnaCadenaDraw(int n) {
        //debug
        String otroString = _listaCartas.toString();
        String unString = _listaCartas.toString();

        switch (n) {
        case 0:
            unString = new StringBuffer().append(otroString).append("www").toString();
            //new StringBuffer().append("wwww").append(unString.substring(7)).toString();
            break;
        case 1:
            unString = new StringBuffer().append(unString.subSequence(0, 3)).append("wwww")
                    .append(unString.substring(11)).toString();
            break;
        case 2:
            unString = new StringBuffer().append(unString.subSequence(0, 7)).append("wwww")
                    .append(unString.substring(15)).toString();
            break;

        case 3:
            unString = new StringBuffer().append(unString.subSequence(0, 11)).append("wwww").toString();
            break;

        case 4:
            unString = new StringBuffer().append("ww").append(unString.subSequence(8, 11)).append("ww")
                    .append(unString.substring(11)).toString();
            break;

        case 5:
            unString = new StringBuffer().append(unString.subSequence(0, 3)).append("ww")
                    .append(unString.subSequence(9, 11)).append("ww").append(unString.substring(15)).toString();
            break;

        case 6:
            unString = new StringBuffer().append(unString.subSequence(0, 7)).append("ww")
                    .append(unString.subSequence(13, 15)).append("ww").toString();
            break;

        case 7:
            unString = new StringBuffer().append(unString.subSequence(0, 3)).append("ww")
                    .append(unString.subSequence(13, 15)).append("ww").append(unString.subSequence(17, 19))
                    .toString();
            break;

        case 8:
            unString = new StringBuffer().append(unString.subSequence(0, 7)).append("ww")
                    .append(unString.subSequence(13, 15)).append("ww").toString();
            break;

        case 9:
            unString = new StringBuffer().append("ww").append(unString.subSequence(3, 17)).append("ww").toString();
            break;
        }

        System.out.println(unString);
        System.out.println(otroString);
        return unString;
    }

    /*
       //http://stackoverflow.com/questions/767759/occurrences-of-substring-in-a-string
    String unString="WW";
    int nComodines=StringUtils.countMatches(unaMano, unString);
    assert(nComodines>2);        
    */
    private void analizarConComodines(String unaCadenaMano) {
        //listaDraw slo tendr dos elementos
        _listaDraws.clear();
        //me hago un clon malo
        tMano unaMano = bitchBrian(_listaCartas, _listaCartas.get(0), 0);

        //INCOMPLETO @Daton ....para optimizar, hago solo dos comparaciones
        for (int i = 0; i < 10; i++) {
            tMano unDraw = analizarConComodinesR(unaMano, dameUnaCadenaDraw(i), null);
            unDraw._esDraw = true;
            insertaDraw(unDraw);
        }

    }

    //clonador malo.. para crear draws
    private tMano bitchBrian(tListaCartas unaLista, tCarta unaCarta, int r) {
        List<tCarta> otraLista = new ArrayList<>();
        for (int i = 0; i < unaLista.size(); i++) {
            if (i != r)
                otraLista.add(unaLista.get(i));
            else
                otraLista.add(unaCarta);
        }
        tMano unaMano = new tMano(otraLista);
        unaMano._esDraw = true;
        return unaMano;
    }

    //esta parte tiene complejidad cbica.
    //es ridiculo.
    // a mejorar!
    private tMano analizarConComodinesR(tMano unaMano, String unaCadenaMano, tMano mejorMano) {
        //caso Recursivo
        tCarta punteroBaraja = null;
        for (int i = 0; i < unaCadenaMano.length() - 1; i = i + 2) {
            if (unaCadenaMano.substring(i, i + 2) == "ww")
                for (int j = 0; j < unaMano._Baraja.size(); j++) {
                    punteroBaraja = unaMano._Baraja.get(j);
                    if (!unaMano._listaCartas.contains(punteroBaraja))
                        mejorMano = bitchBrian(unaMano._listaCartas, punteroBaraja, i / 2);
                }
        }
        ;
        //caso base
        if (mejorMano == null || unaMano.toInt() > mejorMano.toInt())
            return unaMano;
        else
            return mejorMano;
    }
}