-
Notifications
You must be signed in to change notification settings - Fork 0
/
BigTwo.java
350 lines (313 loc) · 9.86 KB
/
BigTwo.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
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
import java.util.ArrayList;
/**
* This class is use to mode and launch the Big Two card game.
*
* @author Chan Sze Wing
*/
public class BigTwo implements CardGame{
private int numOfPlayers = 4;
private Deck deck = new Deck();
private ArrayList<CardGamePlayer> playerList = new ArrayList<CardGamePlayer>(this.numOfPlayers);
private ArrayList<Hand> handOnTable = new ArrayList<Hand>();
private int currentPlayerIdx;
private BigTwoGUI ui;
private BigTwoClient client;
/**
* Create a Big Two card game and create 4 players and a UI object
*/
public BigTwo() {
for (int i = 0; i < this.numOfPlayers; i++) {
CardGamePlayer temp = new CardGamePlayer();
this.playerList.add(temp);
}
this.ui = new BigTwoGUI(this);
this.client = new BigTwoClient(this, this.ui);
}
/**
* Returns the number of players
*
* @return an integer of the number of players
*/
public int getNumOfPlayers() {
return this.numOfPlayers;
}
/**
* Return the deck of cards
*
* @return a deck object representing the deck of cards
*/
public Deck getDeck() {
return this.deck;
}
/**
* Return a list of player
*
* @return an arrayList of player
*/
public ArrayList<CardGamePlayer> getPlayerList() {
return this.playerList;
}
/**
* Return a list of hands played on the table
*
* @return a arrayList hands representing the hands played on the table,
* with the last hand the most recent one on the table
*/
public ArrayList<Hand> getHandsOnTable() {
return this.handOnTable;
}
/**
* Return the index of the current player
*
* @return an integer of the index of the current player
*/
public int getCurrentPlayerIdx() {
return currentPlayerIdx;
}
public BigTwoClient getClient() {
return client;
}
public BigTwoGUI getGUI() {
return ui;
}
/**
* Return a valid hand from a list of cards
*
* @param player the player who holds the cards
* @param cards the list of card indices selected by the player
* @return the object of the specific hand type compose by the cards, or
* null if no valid hand can be composed
*/
public static Hand composeHand(CardGamePlayer player, CardList cards) {
if (cards.size() == 1) {
return (new Single(player, cards));
}
else if ((cards.size() == 2) && ((new Pair(player, cards)).isValid())) {
return (new Pair(player, cards));
}
else if ((cards.size() == 3) && ((new Triple(player, cards)).isValid())) {
return (new Triple(player, cards));
}
else if ((cards.size() > 5)) {
return null;
}
else {
if ((new StraightFlush(player, cards)).isValid()) {
return (new StraightFlush(player, cards));
}
else if ((new Quad(player, cards)).isValid()) {
return (new Quad(player, cards));
}
else if ((new FullHouse(player, cards)).isValid()) {
return (new FullHouse(player, cards));
}
else if ((new Flush(player, cards)).isValid()) {
return (new Flush(player, cards));
}
else if ((new Straight(player, cards)).isValid()) {
return (new Straight(player, cards));
}
else {
return null;
}
}
}
/**
* Start / Restart the game
*
* @param deck the shuffled deck of card
*/
public void start(Deck deck) {
// remove all cards from table
this.handOnTable.removeAll(this.handOnTable);
// remove all cards from players
for (int i = 0; i < this.numOfPlayers; i++) {
this.playerList.get(i).removeAllCards();
}
// distribute cards to player & find player who holds the Three of Diamonds
for (int i = 0; i < deck.size(); i += 4) {
for (int j = 0; j < this.numOfPlayers; j++) {
if ((deck.getCard(i+j).getRank() == 2) && (deck.getCard(i+j).getSuit() == 0)) {
this.currentPlayerIdx = j;
this.ui.setActivePlayer(j);
}
this.playerList.get(j).addCard(deck.getCard(i+j));
}
}
for (int i = 0; i < this.numOfPlayers; i++) {
this.playerList.get(i).getCardsInHand().sort();
}
this.ui.repaint();
this.ui.promptActivePlayer();
}
/**
* Make a move by a player with a list of card indices
*
* @param playerIdx the index of the player
* @param cardIdx the list of card indices selected by the player for the move
*/
public void makeMove(int playerIdx, int[] cardIdx) {
CardGameMessage message = new CardGameMessage(CardGameMessage.MOVE, -1, cardIdx);
this.client.sendMessage(message);
return;
}
/**
* Check is the move made by a player valid
*
* @param playerIdx the index of the player
* @param cardIdx the list of card indices selected by the player for the move
*/
public void checkMove(int playerIdx, int[] cardIdx) {
// invalid move message
String warning = "Not a legal move!!!\n";
// get last hand on table
Hand table_hand;
if (this.handOnTable.size() > 0 ) {
table_hand = this.handOnTable.get(this.handOnTable.size()-1);
}
else {
table_hand = null;
}
// player index to player
CardGamePlayer player = this.playerList.get(playerIdx);
// pass
if (cardIdx == null) {
// first player or player of last hand --> canNOT pass
if ((this.getHandsOnTable().size() == 0) || (table_hand.getPlayer() == player)) {
this.ui.invalidMove();
this.ui.repaint();
return;
}
else {
this.ui.printMsg("{Pass}\n");
this.currentPlayerIdx = (this.currentPlayerIdx + 1) % this.numOfPlayers;
this.ui.disable();
this.ui.setActivePlayer(this.currentPlayerIdx);
this.ui.repaint();
this.ui.promptActivePlayer();
return;
}
}
else {
// list of card indices to cardlist
CardList player_card = new CardList();
for (int i = 0; i < cardIdx.length; i++) {
player_card.addCard(this.playerList.get(playerIdx).getCardsInHand().getCard(cardIdx[i]));
}
// transform cardlist to a specific type of hand
Hand player_hand = composeHand(player, player_card);
// invalid card combination
if (player_hand == null) {
this.ui.invalidMove();
this.ui.repaint();
return;
}
// valid card combination
else {
// fist hand
if ((this.getHandsOnTable().size() == 0)) {
// check if first hand includes the Three of Diamonds
if (player_hand.contains((new BigTwoCard(0, 2)))) {
player.removeCards(player_hand);
this.ui.printMsg(String.format("{%1$s} %2$s\n", player_hand.getType(), player_hand.toString()));
this.handOnTable.add(player_hand);
this.currentPlayerIdx = (this.currentPlayerIdx + 1) % this.numOfPlayers;
this.ui.disable();
this.ui.setActivePlayer(this.currentPlayerIdx);
this.ui.repaint();
this.ui.promptActivePlayer();
return;
}
else {
this.ui.invalidMove();
this.ui.repaint();
return;
}
}
// other rounds
else {
// all other player pass and loop back
if ((table_hand.getPlayer() == player)) {
player.removeCards(player_hand);
this.handOnTable.add(player_hand);
this.ui.printMsg(String.format("{%1$s} %2$s\n", player_hand.getType(), player_hand.toString()));
// end of game
if (this.endOfGame()) {
this.ui.repaint();
this.ui.endGame();
return;
}
// game continues
this.currentPlayerIdx = (this.currentPlayerIdx + 1) % this.numOfPlayers;
this.ui.disable();
this.ui.setActivePlayer(this.currentPlayerIdx);
this.ui.repaint();
this.ui.promptActivePlayer();
return;
}
// invalid due to different num of cards from the hand on table
else if (table_hand.size() != player_hand.size()) {
this.ui.invalidMove();
this.ui.repaint();
return;
}
// same num of cards as the hand on table
else {
// player's hand beats the hand on table
if (player_hand.beats(table_hand)) {
player.removeCards(player_hand);
this.handOnTable.add(player_hand);
this.ui.printMsg(String.format("{%1$s} %2$s\n", player_hand.getType(), player_hand.toString()));
// end of game
if (this.endOfGame()) {
this.ui.repaint();
this.ui.endGame();
return;
}
// game continues
this.currentPlayerIdx = (this.currentPlayerIdx + 1) % this.numOfPlayers;
this.ui.disable();
this.ui.setActivePlayer(this.currentPlayerIdx);
this.ui.repaint();
this.ui.promptActivePlayer();
return;
}
// player's hand does NOT beats the hand on table
else {
this.ui.invalidMove();
this.ui.repaint();
return;
}
}
}
}
}
}
/**
* Check if the game ends (i.e. any one of the players have no more cards)
*
* @return true if game ends, otherwise false
*/
public boolean endOfGame() {
for (int i = 0; i < this.numOfPlayers; i++) {
if (this.playerList.get(i).getNumOfCards() == 0) {
return true;
}
}
return false;
}
/**
* Start the BigTwo game
*
* @param args not used
*/
public static void main(String[] args) {
BigTwo game = new BigTwo();
// input user name
game.getClient().setPlayerName(game.getGUI().inputName());
// make a connection to server
game.getClient().connect();
// set the client in the gui as this client
game.getGUI().setClient(game.getClient());
}
}