-
Notifications
You must be signed in to change notification settings - Fork 0
/
Jogo.java
315 lines (270 loc) · 9.3 KB
/
Jogo.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
// Usado para a ArrayList de players
import java.util.ArrayList;
// Para poder reiniciar o jogo a partir do JMenuItem
import javax.swing.JMenuItem;
/**
* Implementa as mecânicas e regras do jogo Ludo.
*
* @author Alan Moraes / [email protected]
* @author Victor Koehler / [email protected]
* @author Lucas Isaac / [email protected]
* @author Luciano Pereira / [email protected]
*/
public class Jogo {
// Tabuleiro do jogo
private final Tabuleiro tabuleiro;
// Dados do jogo.
private final Dado[] dados;
private boolean dadosRolados = false; // guardam se os dados já foram rolados no turno
private ArrayList<Player> players; // possui os jogadores da partida
private TurnManager turnManager; // gerenciador de turnos
private JMenuItem menuNovo; // segura o gatilho para reiniciar o jogo
/**
* Construtor padrão do Jogo Ludo. Isto é, um jogo de Ludo convencional com dois
* dados. menuNovo é passado como argumento para o jogo ser reiniciável
*/
public Jogo(JMenuItem menuNovo) {
this(2);
this.menuNovo = menuNovo;
}
/**
* Construtor do Jogo Ludo para inserção de um número arbitrário de dados.
*
* @param numeroDados Número de dados do jogo.
*/
public Jogo(int numeroDados) {
this.tabuleiro = new Tabuleiro();
this.dados = new Dado[numeroDados];
for (int i = 0; i < this.dados.length; i++) {
// remover parâmetro do construtor para dado não batizado
this.dados[i] = new Dado();
}
inicializaJogo();
}
/**
* Construtor do Jogo Ludo para inserção de dados arbitrários. Útil para inserir
* dados "batizados" e fazer testes.
*
* @param dados Dados
*/
public Jogo(Dado[] dados) {
this.tabuleiro = new Tabuleiro();
this.dados = dados;
assert dados.length > 0; // TO BE REMOVED
inicializaJogo();
}
private void inicializaJogo() {
// Inicialização do Jogo
// Ininicialização das guaritas
Guarita guaritaVermelha;
Guarita guaritaVerde;
Guarita guaritaAzul;
Guarita guaritaAmarela;
// atribui as guaritas do tabulheiro às suas respectivas guaritas
guaritaVermelha = tabuleiro.getGuarita("VERMELHO");
guaritaVerde = tabuleiro.getGuarita("VERDE");
guaritaAzul = tabuleiro.getGuarita("AZUL");
guaritaAmarela = tabuleiro.getGuarita("AMARELO");
// Colocando as peças nas suas respectivas guaritas
for (CasaGuarita casaGuarita : guaritaVermelha.getTodasAsCasas()) {
Castelo novaPeca = new Castelo("VERMELHO");
novaPeca.mover(casaGuarita);
}
for (CasaGuarita casaGuarita : guaritaVerde.getTodasAsCasas()) {
Castelo novaPeca = new Castelo("VERDE");
novaPeca.mover(casaGuarita);
}
for (CasaGuarita casaGuarita : guaritaAzul.getTodasAsCasas()) {
Castelo novaPeca = new Castelo("AZUL");
novaPeca.mover(casaGuarita);
}
for (CasaGuarita casaGuarita : guaritaAmarela.getTodasAsCasas()) {
Castelo novaPeca = new Castelo("AMARELO");
novaPeca.mover(casaGuarita);
}
// Cria-se os jogadores
Player playerVermelho = new Player(0, guaritaVermelha.getTodasAsCasas(), "VERMELHO");
Player playerAzul = new Player(1, guaritaAzul.getTodasAsCasas(), "AZUL");
Player playerAmarelo = new Player(2, guaritaAmarela.getTodasAsCasas(), "AMARELO");
Player playerVerde = new Player(3, guaritaVerde.getTodasAsCasas(), "VERDE");
// adiciona os jogadores a um ArrayList para melhor controle
players = new ArrayList<Player>();
players.add(playerVermelho);
players.add(playerAzul);
players.add(playerAmarelo);
players.add(playerVerde);
// cria-se o gerenciador de turnos
turnManager = new TurnManager();
}
/**
* Método invocado pelo usuário através da interface gráfica ou da linha de
* comando para jogar os dados. Aqui deve-se jogar os dados e fazer todas as
* verificações necessárias.
*/
public void rolarDados() {
// TODA VEZ QUE O USURIO CLICAR NO DADO DESENHADO NA INTERFACE GRÁFICA,
// ESTE MÉTODO SERÁ INVOCADO.
// dados são rolados, há não ser que já foram rolados no atual turno
if (!dadosRolados) {
for (Dado dado : dados) {
dado.rolar();
}
dadosRolados = true;
}
}
/**
* Método invocado pelo usuário através da interface gráfica ou da linha de
* comando quando escolhida uma peça. Aqui deve-se mover a peça e fazer todas as
* verificações necessárias.
*
* @param casa Casa escolhida pelo usuário/jogador.
*/
public void escolherCasa(Casa casa) {
// TODA VEZ QUE O USUÁRIO CLICAR EM UMA CASA DESENHADA NA INTERFACE GRÁFICA,
// ESTE MÉTODO SERÁ INVOCADO.
// Perguntamos à casa se ela possui uma peça e
// Vemos se os dados foram rolados no turno atual
// Se não possuir ou os dados não foram rolados, não há nada para se fazer.
if (!casa.possuiPeca() || !dadosRolados) {
return;
}
// Perguntamos à casa qual é a peça.
Castelo castelo = casa.getPeca();
// Pegamos o jogador da vez
Player player = players.get(turnManager.getWhoIsNow());
// verificamos se a peça perternce ao jogador da vez
// se não for, a peça não se move e o jogo não continua
if (player.isThisPlayer(castelo)) {
if (estaTravado(player, dados)) {
turnManager.next();
dadosRolados = false;
return;
}
// curupira controla se a peça
// andará para frente ou para trás,
// nas casas seguras
boolean curupira;
// Percorreremos N casas.
Casa proximaCasa = casa.proximaCasa(castelo, curupira = false, dados);
if (casa.equals(proximaCasa)) {
ArrayList<Castelo> castelos = players.get(turnManager.getWhoIsNow()).getCastelo();
for (Castelo casteloJogador : castelos) {
Casa casaCastelo = casteloJogador.getCasa();
if (!casaCastelo.proximaCasa(castelo, curupira = false, dados).equals(casaCastelo))
return;
}
}
castelo.mover(proximaCasa);
// permite que os dados sejam rolados de novo
// já que, como a peça já se mecheu, o próximo turno vai começar
dadosRolados = false;
// caso o jogador tire uma dupla nos dados, ele pode jogar de novo
if (dados[0].getValor() != dados[1].getValor())
turnManager.next(); // finaliza o turno e começa o próximo
}
}
/**
* Retorna o jogador que deve jogar os dados ou escolher uma peça.
*
* @return Cor do jogador.
*/
public String getJogadorDaVez() {
Player player = players.get(turnManager.getWhoIsNow());
return player.getColor();
}
public String getJogadorAnterior() {
Player player = players.get(turnManager.getWhoWasBefore());
return player.getColor();
}
public boolean estaTravado(Player jogador, Dado[] dados) {
int somaDados = dados[0].getValor() + dados[1].getValor();
for (Castelo peca : jogador.getCastelo()) {
Casa proximaCasa = peca.getCasa();
if (!peca.getCasa().ehCasaFinal() && !peca.getCasa().pertenceGuarita()) {
boolean curupira = false;
for (int i = 0; i < somaDados && proximaCasa != null; i++) {
// caso a peça esteja na entrada da casa segura
// ele entra lá
if (proximaCasa.ehEntradaZonaSegura() && (proximaCasa.getCasaSegura().getCor() == peca.getCor()))
proximaCasa = proximaCasa.getCasaSegura();
// caso a peça já esteja na casa final
// isso vai acionar curupira e faz a peça
// andar para trás
else if (proximaCasa.ehCasaFinal()) {
// caso a peça já esteja na casa final
// não há nada há fazer
if (i == 0) {
proximaCasa = null;
break;
}
curupira = true;
proximaCasa = proximaCasa.getCasaAnterior();
}
// faz a peça retroceder até a primeira casa segura
// caso a peça "passou direto" pela casa final
else if (curupira && proximaCasa.getCasaAnterior() != null)
proximaCasa = proximaCasa.getCasaAnterior();
// a peça atingiu a primeira casa segura,
// curupira é desacionar curupira, para
// a peça voltar a se mover para frente
else if (curupira && proximaCasa.getCasaAnterior() == null) {
proximaCasa = proximaCasa.getCasaSeguinte();
curupira = false;
}
// em nenhum caso especial, a peça se move normalmente
else
proximaCasa = proximaCasa.getCasaSeguinte();
}
if (proximaCasa.possuiPeca() && !proximaCasa.ehCasaFinal()) {
if (!jogador.isThisPlayer(proximaCasa.getPeca()) && !peca.equals(proximaCasa.getPeca())) {
return false;
}
if (peca.equals(proximaCasa.getPeca()))
return false;
} else
return false;
}
if (peca.getCasa().pertenceGuarita()) {
if (dados[0].getValor() == dados[1].getValor()) {
// verifica se há uma peça na casa inicial
proximaCasa = tabuleiro.getCasaInicio(jogador.getColor());
Castelo pecaProxima = proximaCasa.getPeca();
if (pecaProxima != null) {
if (!jogador.isThisPlayer(pecaProxima)) {
return false;
}
} else
return false;
}
}
}
return true;
}
/**
* O tabuleiro deste jogo.
*
* @return O tabuleiro deste jogo.
*/
public Tabuleiro getTabuleiro() {
return tabuleiro;
}
/**
* Retorna o i-ésimo dado deste jogo entre 0 (inclusivo) e N (exclusivo).
* Consulte getQuantidadeDeDados() para verificar o valor de N (isto é, a
* quantidade de dados presentes).
*
* @param i Indice do dado.
* @return O i-ésimo dado deste jogo.
*/
public Dado getDado(int i) {
return dados[i];
}
/**
* Obtém a quantidade de dados sendo usados neste jogo.
*
* @return Quantidade de dados.
*/
public int getQuantidadeDados() {
return dados.length;
}
}