Uso do Static

Galera estou fazendo um jogo de truco para faculdade e gostaria de saber se estou indo bem, se estou fazendo uso correto do static, quero que meu jogo esteja bem feito (no meu nível de conhecimento).

Observação: Os métodos de imprimir são apenas para ir testando o que eu for fazendo.

package truco;
import java.util.*;
public class Baralho {
	
	static List<Carta> cartasDentro = new ArrayList<Carta>();
	static List<Carta> cartasFora = new ArrayList<Carta>();
	List<String> naipList = new ArrayList<String>();
	List<String> numList = new ArrayList<String>();
	
	
	public Baralho(int n){
		
	}
	public Baralho(){
		
		naipList.add("Ouro");
		naipList.add("Copas");
		naipList.add("Espada");
		naipList.add("Paus");
		
		numList.add("2");
		numList.add("3");
		numList.add("4");
		numList.add("5");
		numList.add("6");
		numList.add("7");
		numList.add("A");
		numList.add("K");
		numList.add("J");
		numList.add("Q");	
		
		for (String num: numList){
			for (String naip: naipList){
				cartasDentro.add(new Carta(num,naip));
			}
		}	
	}
	
	public Carta distribuirCarta(){
		
		Carta c= cartasDentro.remove(0);
		cartasFora.add(c);
		return c;
	}
	
	public void embaralhar() {
	    cartasDentro.addAll(cartasFora);
	    cartasFora.clear();
	    Collections.shuffle(cartasDentro); 
	}
	
	public void imprime(){ 
		
		System.out.println(naipList);
		System.out.println(numList);
		
		for(Carta p: cartasDentro){
			System.out.println(p.cartaFinal());
		}
	}
}

package truco;

public class Carta{
	
	public Carta(){
		
	}
	
	private String num;
	private String naip;

	public Carta(String num, String naip){
		this.num=num;
		this.naip=naip;
	}

	public String getNum() {
		return num;
	}

	public String getNaip() {
		return naip;
	}
	
	public String cartaFinal(){
		return getNum()+getNaip();
	}
}

package truco;

public class Mesa {

	public static void main(String[] args) {
		
		Baralho baralho = new Baralho();
		
		baralho.embaralhar();
		
		Jogador j1 = new Jogador();
		Jogador j2 = new Jogador();
		Jogador j3 = new Jogador();
		Jogador j4 = new Jogador();
		//baralho.imprime();
		
		j1.cartaJogador();
		j1.imprime();
		
		j2.cartaJogador();
		j2.imprime();
		
		j3.cartaJogador();
		j3.imprime();
		
		j4.cartaJogador();
		j4.imprime();
		
		baralho.imprime();
	}
}

package truco;
import java.util.*;

public class Jogador{
	
	List<Carta> cartasJogador = new ArrayList<Carta>();
	
	Baralho temp = new Baralho(2);
	
	public void cartaJogador(){
		for (int i = 0; i < 3; i++) {
			cartasJogador.add(temp.distribuirCarta());
		}
	}
	
	public void imprime(){
		for(Carta p: cartasJogador){
			System.out.println(p.cartaFinal());
		}
		System.out.println();
	}
}

Eu usei static nas LIST para não sobrescrever porem não sei se é uma boa pratica e se tem outra forma e tambem criei outro construtor de baralho, para que todo o procedimento que a classe MESA quando instancia um baralho não seja refeito pela classe Jogador quando instancia um baralho tambem (tanto a mesa quando o jogador precisa ter acesso ao baralho, mas de formas diferentes).

Não vou avaliar linha por linha, mas minha recomendação é usar static somente se realmente precisar. No seu caso, parece que você usou por ser mais fácil, que não costuma ser uma boa justificativa. cartasDentro e cartasFora podem ser atributos private da classe Baralho, acessíveis através de métodos como descartar( Carta c ), por exemplo.

naipList e numList é que podem ser estáticos, já que são usados somente no construtor da classe Baralho. Melhor ainda, torne-os variáveis dentro do construtor da classe Baralho (já que são usados somente ali). Sua classe fica sem membros estáticos, e o código mais simples.

Você tem um construtor na classe Baralho que não faz nada ( public Baralho(int n) ) . Remova-o.

Não entendi bem o propósito de cartasFora. Por que o baralho precisa controlar as cartas que estão nas mãos dos jogadores? O Baralho, até onde entendo, só precisa controlar as cartas no momento da distribuição. Depois disso, as cartas ainda no Baralho são irrelevantes.

Para imprimir as cartas, considere sobrescrever o método toString() na classe Carta.

Por que o Jogador tem um Baralho como membro? Ele só precisa receber três cartas no início da partida. Algo assim:

class Jogador{
  private List minhasCartas;

  public void receberCarta( Carta c ){
    minhasCartas.add(c);
  }
}

Daí, antes de começar a partida, cada jogador recebe três cartas do baralho na mesa (já embaralhado).

Baralho baralho = new Baralho();

baralho.embaralhar();

Jogador jogador1 = new Jogador();
Jogador jogador2 = new Jogador();
Jogador jogador3 = new Jogador();
Jogador jogador4 = new Jogador();

// pegarCartaDoTopo() remove a carta de índice 0 do baralho e a retorna
for (i = 0; i < 3; i++){
  jogador1.receberCarta(baralho.pegarCartaDoTopo());
  jogador2.receberCarta(baralho.pegarCartaDoTopo());
  jogador3.receberCarta(baralho.pegarCartaDoTopo());
  jogador4.receberCarta(baralho.pegarCartaDoTopo());
}

Recomendo você voltar um pouco e, antes de escrever o código, pensar como o jogo funciona no mundo real, isto é, como uma partida funciona. Por exemplo:

  • a cada rodada, quem distribui as cartas?
  • a cada rodada, quem recebe a primeira carta?
  • dá para mudar a ordem que as cartas são distribuídas?
  • depois de distribuídas as cartas, preciso do baralho para mais alguma coisa?
  • como é definida a manilha (carta mandante/mais forte)?
  • como repetir uma rodada inteira da forma mais econômica? Devolvo as cartas para o baralho existente ou o recrio do zero?
  • fica mais fácil de gerenciar o jogo se os jogadores estiverem num array ao invés de serem atributos como jogador1, jogador2 e etc?
  • como definir a ordem de jogo (o próximo jogador é à direita ou à esquerda do atual)?

Pequena observação: acho que naipe (com e no final) fica melhor que naip. Não muda nada no código, mas enfim… :grin:

Abraço.

5 curtidas

Então estou melhorando aos poucos, mas funciona da seguinte forma. A lista carta dentro tem todo baralho montado todas as cartas, na medida que é distribuído a carta para o jogador ela vai para cartasFora pois o próximo jogador não pode sair com as mesmas caras então as cartas são retiradas da listas cartasDentro e passada para cartasFora. Depois quando termina a primeira rodada as cartasFora voltam para o baralho com o metodo embaralhar(); . Quanto ao construtor defaut eu coloquei ele pois mesa e jogador faz acessos diferentes ao baralho. O jogador precisa de suas cartas e a distribuição é feita em um método na classe baralho, e na classe baralho o construtor “padrão” (que nao recebe parametro), ele inicializa o baralho quando é instanciado. Mas você me deu uma ideia, a classe mesa vai tratar o jogador da mesma forma que o baralho trata carta. vou ver se vai dar certo. e Muito obrigado pelas dicas. Para complicar mais ainda depois de tudo isso vou ter que passar tudo para interface gráfica.

Você falou sobre tratar os jogadores em um array, mas o professor pediu tudo separado e tals. E como to aprendendo ainda POO e JAVA, pode ser que saia uns negocio bem errado, mas to procurando melhorar, esse já é o 3 fez que refaço o jogo, sempre que aprendo algo novo eu aplico e melhoro.

OBS: os metodos para imprimir são apenas para testar o que eu for fazendo.

Ficou melhor agora ?!

List< Jogador> jogadores = new ArrayList< Jogador>();

jogadores.add(new Jogador(baralho.distribuirCarta(),baralho.distribuirCarta(),baralho.distribuirCarta()));

Agora a classe Jogador tem um construtor que recebe 3 cartas como parâmetro.

e na classe jogador tem um array que guarda as cartas.

Importante: não existe um jeito único ou certo de se fazer esse jogo (ou um programa qualquer). Se essa abordagem funciona e é compreensível para você, tudo bem.

Entendi. Então ao invés de você recriar o baralho do zero ( usando new Baralho(), por exemplo), você manda as cartas de uma lista para outra quando o jogo acaba. Não vejo essa abordagem como necessária, pois você poderia pegar as cartas do próprio jogador e devolver para o baralho após cada rodada. Mas, como comentei no começo, se te serve, está ok.

Ao usar cartasDentro.remove(0), você já tira uma carta do Baralho, então não existe o risco de outro jogador pegar a mesma carta, pois ela não está mais disponível.

[quote=“Douglas_Fonseca, post:5, topic:353018”]
Você falou sobre tratar os jogadores em um array, mas o professor pediu tudo separado e tals[/quote]
Se ele exige e tira pontos por desobediência, faça como ele pede. Se não, faça do jeito que achar melhor, mas saiba explicar para ele por que você fez do jeito que fez. Minha sugestão de array me pareceu mais coerente para esse caso, por isso sugeri.

Sim, é uma boa abordagem. Continue daí e veja onde essa abordagem te leva.

Abraço.

2 curtidas