Embaralhar cartas [RESOLVIDO]

Galera,

Já pesquisei no Google, aqui no fórum e não consegui vencer a minha ignorancia! Como eu faria um método para embaralhar um HashMap de cartas?

Eu tinha achado uns tutos falando do método shuffle() de Collections, mas ele não funciona quando uso HasMap, só funciona com ArrayList. É isso mesmo?

O gargalo do meu código está no método “public void embaralharCartas()”.

[size=9]P.S: Não reparem na documentação, é a primeira vez que eu estou fazendo comentários assim, então se tiver muito ruim, peguem leve! Rsrsrsrs. Brincadeira. Pode escraxar![/size]

[code]import java.util.Collections;
import java.util.HashMap;
import java.util.List;

/**

  • Classe responsável pela criação de um baralho.

/
public class Baralho {
/
*
* HashMap de Carta
* @access private
* @var Carta
*/
private HashMap<String, Carta> cartas = new HashMap<String, Carta>();

/**
 * Construtor da classe Baralho.<p>
 * Inicializa o Atributo <b>cartas</b>.
 */
public Baralho(){        

    //naipe de copas
    this.cartas.put("acopas", new Carta("Copas","acopas.gif", 14, 11));
    this.cartas.put("2copas", new Carta("Copas","2copas.gif", 2, 0));
    this.cartas.put("3copas", new Carta("Copas","3copas.gif", 3, 0));
    this.cartas.put("4copas", new Carta("Copas","4copas.gif", 4, 0));
    this.cartas.put("5copas", new Carta("Copas","5copas.gif", 5, 0));
    this.cartas.put("6copas" ,new Carta("Copas","6copas.gif", 6, 0));
    this.cartas.put("7copas", new Carta("Copas","7copas.gif", 7, 10)) ;
    this.cartas.put("jcopas", new Carta("Copas","jcopas.gif", 12, 3));
    this.cartas.put("qcopas", new Carta("Copas","qcopas.gif", 11, 2));
    this.cartas.put("kcopas", new Carta("Copas","kcopas.gif", 13, 4));

    //naipe de paus
    this.cartas.put("apaus", new Carta("Paus","apaus.gif", 14, 11));
    this.cartas.put("2paus", new Carta("Paus","2paus.gif", 2, 0));
    this.cartas.put("3paus", new Carta("Paus","3paus.gif", 3, 0));
    this.cartas.put("4paus", new Carta("Paus","4paus.gif", 4, 0));
    this.cartas.put("5paus", new Carta("Paus","5paus.gif", 5, 0));
    this.cartas.put("6paus" ,new Carta("Paus","6paus.gif", 6, 0));
    this.cartas.put("7paus", new Carta("Paus","7paus.gif", 7, 10)) ;
    this.cartas.put("jpaus", new Carta("Paus","jpaus.gif", 12, 3));
    this.cartas.put("qpaus", new Carta("Paus","qpaus.gif", 11, 2));
    this.cartas.put("kpaus", new Carta("Paus","kpaus.gif", 13, 4));

    
}
/**
 * Método que retorna um Hashmap com o baralho completo.
 * @return Baralho completo.
 * @access public
 */
public HashMap getBaralho(){
    return this.cartas;
}
/**
 * Método que recupera uma carta específica do baralho da chave do HasMap
 * @param chave Chave do HashMap.
 * @return Objeto Carta.
 * @access public
 */
public Carta getCarta(String chave){
    return this.cartas.get(chave);
}

/**
 * Método que embaralha as cartas
 * @return HashMap de cartas.
 * @access public
 */
public void embaralharCartas(){
    //Aqui que o bicho pega!!!Socorrroo!!
}

}
[/code]

Classe Carta:

[code]public class Carta {

/**
 * Valor de pontuação da carta.
 * @access private
 * @var int
 */
private int valorPontuacao;
/**
 * Número de ordem da carta em relação ao baralho convencional. No caso do jogo Sueca esta ordem é alterada
 * para respeitar as regras do jogo.
 * @access private
 * @var int
 */
private int numeroCarta;
/**
 * Indica qual o naipe da carta.
 * @access private
 * @var String
 */
private String naipe;

/**
 * Recebe o nome do arquivo de imagem que representa a carta na interface gráfica.
 * @access private
 * @var String
 */
private String nomeDoArquivo;

/**
 * Construtor da classe Carta.
 * Inicializa as variáveis de classe com os valores passados pelo parâmetro.
 * @param naipe Passa um String com o valor do naipe da carta.
 * @param nomeDoArquivo Passa um String com o valor do nome do arquivo de imagem.
 * @param numeroCarta Passa um Int com o número de ordem da carta em relação ao baralho convencional.
 * @param valorPontuacao Passa um Int com o valor de pontos que a carta representa.
 */

public Carta(String naipe,String nomeDoArquivo, int numeroCarta, int valorPontuacao){
    this.naipe = naipe;
    this.numeroCarta = numeroCarta;
    this.valorPontuacao = valorPontuacao;
    this.nomeDoArquivo = nomeDoArquivo;
}

/**
 * Método que retorna o Valor de Pontuação de uma Carta.
 * @return Valor de Pontuação do tipo.
 */
public int getValorPontuacao(){
    return this.valorPontuacao;
}

/**
 * Método que retorna o Número de Ordem da carta.
 * @return Número da Carta do tipo.
 */
public int getNumeroCarta(){
    return this.numeroCarta;
}

/**
 * Método que retorna o Naipe da carta.
 * @return Naipe da carta.
 */
public String getNaipe(){
    return this.naipe;
}

/**
 * Método que retorna o Nome do Arquivo que representa a carta na interface gráfica.
 * @return Nome do Arquivo.
 */
public String getnomeDoArquivo(){
    return this.nomeDoArquivo;
}

}
[/code]

Classe principal:

[code]import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;

public class Principal {
public static void main(String[] args) {
Baralho baralho = new Baralho();
int contador =0;

    baralho.embaralharCartas(); //Só para testar, eu queria que a cada execução, me retornasse um baralho embaralhado.
    
    //cria o iterator
    Iterator it = baralho.getBaralho().keySet().iterator();
    
     while (it.hasNext()) {
        //pega as chaves
        String chave = (String) it.next();
        //pega os valores
        Carta valor = (Carta) baralho.getBaralho().get(chave);
        System.out.println(contador+"Naipe: "+valor.getNaipe()
                +"| Nome do Arquivo: "+valor.getnomeDoArquivo()
                +"| Numero da Carta: "+valor.getNumeroCarta()
                +"| Valor da Pontuacao: "+valor.getValorPontuacao()
                );
        contador++;
    }
}

}
[/code]

Boa noite Galera !

Amigo… não esta faltando a classe Carta ?

[]s

Ops,

Desculpe mas tinha achado desnecessário postar aqui.

Jé editei o post anterior!

Boa noite Galera,

Olha não sou bom com HashMap, mas quando você inclui uma carta você faz:

this.cartas.put(“acopas”, new Carta(“Copas”,“acopas.gif”, 14, 11));

Ou seja, existe a String “acopas” que identifica a carta As de Copas, suponho.

Quando você conseguir embaralhar o baralho original vai precisar reinserir as cartas na nova ordem, então não vai precisar dessa String “acopas” de novo ?
Não seria necessário esse atributo na sua classe Carta ?

[]s

Cara dê uma olhada http://java.sun.com/j2se/1.5.0/docs/guide/language/enums.html

ola . eu vi um post aqui no guj, o de poker. e resolvi construir um . então estou lidando com cartas.
é o seguinte para embaralhar, estou usando apenas o math.random.
fiz tudo de forma diferente, são 52 cartas, cada uma tem um numero… atraves do numero eu vejo que carta é, e uso um imageIcon para mostra-la…

Estou vendo uma extensão orientação a objetos, mas talvez vc possa fazer tudo de forma diferente. Claro talvez agora não seja possivel, mas diga se o que eu respondi ajuda alguma coisa.

ja tenho um jar que identifica um par ou dois pares, distribui as cartas e troca cartas, a medida que seleciono chekcboxes, está ficando bem interessante.
se vc ou alguém quiser olhar podemos dar um jeito.

Quero colocar tudo isso num applet, mas vou abrir um post, sobre este assunto.
se interessar posso falar mais da minha maneira e mostrar algum codigo. valeu. boa sorte.
em breve eu trago meu programa mais arrumado, e o seu pode mostrar depois? para que as cartaS?

Boa madrugada Galera,

Alguém sabe se da para pegar um elemento do HashMap através de um indice ?

Por exemplo:

Se eu tenho um HashMap como esse de cartas, da para pegar uma carta com algo como cartas.get(0) ?
Onde cartas é o HashMap<String, Carta>.

[]s

Bom dia Galera,

Amigo, não sei se estou enganado… mas eu estava pesquisando sobre HashMap e li o seguinte:

“Uma observação importante em relação à classe HashMap é que esta não honra nenhuma ordem específica de seus elementos, ou seja, a ordem dos pares chave-valor em uma operação de exibição pode ser bem diferente da ordem de inserção.”

Cheguei nisso porque montei esse método para embaralhar as cartas:

    public void embaralharCartas(){
        //O que estaria aqui?
    	HashMap<String, Carta> cartasSorteadas =  new HashMap<String, Carta>();
    	Random r = new Random();
    	List<Carta> listCartas = new ArrayList<Carta>(cartas.values());    	
    	
    	int i = 0;
    	Carta cartaSorteada;
    	
    	while (cartasSorteadas.size() < this.k) {
    		i = r.nextInt(cartas.size());
    		cartaSorteada = listCartas.get(i);
    		if (! (cartasSorteadas.containsValue(cartaSorteada))) {
    			cartasSorteadas.put(cartaSorteada.getNomeDaCarta(), cartaSorteada);
    			
    		}
    	}
    	
    	this.cartas = cartasSorteadas;
    	
    }

No entanto notei que a saida no final era diferente da sequencia de cartas sorteadas no método acima…
Sendo assim, o embaralhamento gerado pelo método era simplesmente perdido, porque a ordem do Hash não obedece a ordem de inserção.
Então, acho que você deveria tentar implentar utilizando outra classe que não o Hash, você precisa fazer buscas pela chave ?

[]s

Para que precisa de um HashMap de cartas? Não vejo utilidade nisso. Usa um ArrayList e já podes fazer o shuffle.

É. Eu não conhecia isso ainda! É uma boa opção. Vou estudar.

[quote=Zeed01]
Alguém sabe se da para pegar um elemento do HashMap através de um indice ? [/quote]
HashMap não tem possibilidade de ser acessado por indice. Só por chave!

Não tenho “necessidade” de pegar por índice não. Seria uma opção também, não vejo problema não. Inclusive a primeira vez que eu fiz estas classes, fiz usando ArrayList.

Eu pensei num Hashmap pelo seguinte: Em determinado momento no jogo, os valores da carta e sua pontuação não são importantes, então, com o HashMap, eu já poderia tratar as comparações da carta já pelo indice, sem a necessidade de a todo momento chamar métodos do objeto da coleção.

Mas eu fiz usando ArrayList também e funcionou direitinho o shuffle. Ai me deu a curiosidade de saber como seria um shuflle usando Hashmap. Sacou?

É. Eu não conhecia isso ainda! É uma boa opção. Vou estudar.

[quote=Zeed01]
Alguém sabe se da para pegar um elemento do HashMap através de um indice ? [/quote]
HashMap não tem possibilidade de ser acessado por indice. Só por chave!

É isso mesmo que eu quero. Na minha abstração não interessa em nenhum momento a ordem de inserção. Mas como o texto cita a palavra “pode” e isso não garante que sempre é assim. Então de qualquer jeito eu teria que fazer um método de embaralhar.

Mas confesso que eu não sabia desta caracteristica. Onde encontrou? Queria ler este material.

Não tenho “necessidade” de pegar por índice não. Seria uma opção também, não vejo problema não. Inclusive a primeira vez que eu fiz estas classes, fiz usando ArrayList.

Eu pensei num Hashmap pelo seguinte: Em determinado momento no jogo, os valores da carta e sua pontuação não são importantes, então, com o HashMap, eu já poderia tratar as comparações da carta já pelo indice, sem a necessidade de a todo momento chamar métodos do objeto da coleção.

Mas eu fiz usando ArrayList também e funcionou direitinho o shuffle. Ai me deu a curiosidade de saber como seria um shuflle usando Hashmap. Sacou?

Cara por que vc esta usando um map?

Qual o problema em passar essa string para a classe carta e trocar seus Map para um List?

[quote=Felagund]Cara por que vc esta usando um map?

Qual o problema em passar essa string para a classe carta e trocar seus Map para um List?[/quote]

Na verdade não tem problema nenhum. Concordo que, neste caso, um ArrayList me atenderia sem prejuizo.Mas, como estou estudando collections, me deu curiosidade de saber como seria um shuffle para HashMap.

:smiley:

[quote=pvrsouza][quote=Felagund]Cara por que vc esta usando um map?

Qual o problema em passar essa string para a classe carta e trocar seus Map para um List?[/quote]

Na verdade não tem problema nenhum. Concordo que, neste caso, um ArrayList me atenderia sem prejuizo.Mas, como estou estudando collections, me deu curiosidade de saber como seria um shuffle para HashMap.

:smiley: [/quote]

Tecnicamente, não tem como vc fazer shuffle num map, pois ele é baseado em chaves, ou seja a chave dele nunca vai mudar, para a chave “asdecopa”, vai ser sempre a mesma carta.

Se não me engano em listas ele altera os indices, ou seja o que era o indice 0, apos o shuffle não é mais.

Nem sei se os maps podem ser considerados collections :stuck_out_tongue:

Pelo que eu entendi:

[list]Collections é o Framework.[/list]
[list]Map é uma interface.[/list]
[list]HashMap implementa a interface Map.[/list]

Já que o HashMap faz parte do Collections Framework, não faz dele um collecttion semanticamente?

Vou tentar fazer um cast tipo assim:

List cartas…blá blá blá.

Quando acabar eu posto aqui.

[quote=pvrsouza]Galera,

Já pesquisei no Google, aqui no fórum e não consegui vencer a minha ignorancia! Como eu faria um método para embaralhar um HashMap de cartas?

Eu tinha achado uns tutos falando do método shuffle() de Collections, mas ele não funciona quando uso HasMap, só funciona com ArrayList. É isso mesmo?
[/quote]

É isso mesmo. Existe uma razão para só funcionar com essa classe , com List e não com Map.
O problema é o seu modelo. Vc não precisa de um Map. Use uma lista de objetos Carta.

Mais sobre como sortear objetos em java.

[quote=sergiotaborda][quote=pvrsouza]Galera,

Já pesquisei no Google, aqui no fórum e não consegui vencer a minha ignorancia! Como eu faria um método para embaralhar um HashMap de cartas?

Eu tinha achado uns tutos falando do método shuffle() de Collections, mas ele não funciona quando uso HasMap, só funciona com ArrayList. É isso mesmo?
[/quote]

É isso mesmo. Existe uma razão para só funcionar com essa classe , com List e não com Map.
O problema é o seu modelo. Vc não precisa de um Map. Use uma lista de objetos Carta.

Mais sobre como sortear objetos em java.[/quote]

Brigadão Sergio!!!

Vou dar uma estudada mais profunda!

Brigado a todos pelo empenho e disponibilidade!

Boa noite Galera,

Se o HashMap não pode ser acessado por índice, algo como hashMap.get(1), com você pensa em fazer o embaralhamento ?
Já que o HashMap não implementa o método shuffle.

[]s

Já desisti do HashMap. Estou usando um ArrayList.
:smiley: