-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathBlackjackSolitaire.java
306 lines (286 loc) · 9.91 KB
/
BlackjackSolitaire.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
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;
public class BlackjackSolitaire {
//create a deck
Deck gameDeck;
//create a board
Board gameBoard;
//create an arrayList to hold the positions on the board that have been already chosen so that the user can not replace a placed card.
ArrayList<String> assignedBoardPositions;
//create an array list populated with 4 positions
ArrayList<String> trash = new ArrayList<String>(Arrays.asList("17","18","19","20"));
//create a variable that counts the number of times you place a card in the discard pile (trash).
int discardCounter = 0;
//create scanner class to receive input
Scanner scan;
//create int variable that will be assigned to userInput
int playerInput;
//create variable to hold current card.
Card currentCard = null;
//constructor for game
public BlackjackSolitaire() {
//create deck and board to play the game
gameDeck = new Deck();
gameBoard = new Board();
//assign an array list to hold the assigned positions while playing
assignedBoardPositions = new ArrayList<String>();
//assign scanner for user input
scan = new Scanner(System.in);
}
public void play() {
//We want to to continue play by repeating these steps until all the board positions are filled. Limit is 15 because we zero-index.
while(assignedBoardPositions.size() < 16) {
//show the state
gameBoard.show();
//show the discard pile.
showTrash();
//deal a card
currentCard = gameDeck.dealCard();
//print out the card's display icon
System.out.println("Your card is: " + currentCard.getCardIcon());
//prompt the user to make a move
System.out.println("Pick a position");
//receive that input and assign it to a variable
int playerInput = scan.nextInt();
//evaluate the input according to the rules of the game.
evaluateInput(playerInput);
}
gameBoard.show();
score();
}
//quarantine the possibilities of userInput
public void evaluateInput(int input) {
playerInput = input;
/*
* Only allow input for a board position that is:
* (1) not already used.
* (2) between 0 and 21, not inclusive.
* prompt user with appropriate directions
*/
while( !( (checkIfAcceptableRange(playerInput) && checkIfNotPlayed(playerInput)) ) ) {
if(!(checkIfAcceptableRange(playerInput))) {
System.out.println("That position doesn't exist. Pick again");
playerInput = scan.nextInt();
}
else if(!(checkIfNotPlayed(playerInput))) {
System.out.println("You already placed a card there. Pick another please!");
playerInput = scan.nextInt();
}
}
/*if player wants to place the card in the discard pile, see if the trash is full
* if it isn't, then move to trash
*/
if((playerInput > 16) && (playerInput < 21) ) {
evaluateTrashInput(playerInput);
}
else {
String stringInput = Integer.toString(playerInput);
makeMove(stringInput, currentCard);
assignedBoardPositions.add(stringInput);
}
}
//check if the input is within acceptable range.
public boolean checkIfAcceptableRange(int choice) {
int intInput = choice;
if((intInput > 0) && (intInput < 21)) {
return true;
}
return false;
}
//check if input is already played
public boolean checkIfNotPlayed(int input) {
String stringInput = Integer.toString(input);
if(assignedBoardPositions.contains(stringInput)) {
return false;
}
return true;
}
//evaluate discard function
public void evaluateTrashInput(int playerInput) {
int intInput = playerInput;
String stringedInput = Integer.toString(playerInput);
//Allow a maximum of 4 cards to be added to the trash. Check if trash is full.
if( (4 - discardCounter > 0)) {
//if not full, check to see if the discard position is available
if( trash.contains(stringedInput) ) {
//move to that position
moveToTrash(stringedInput);
}
//make the user chose an empty position in the trash
else {
while(!trash.contains(stringedInput)) {
System.out.println("You can't change your mind. Input another space in the trash");
stringedInput = Integer.toString(scan.nextInt());
}
moveToTrash(stringedInput);
}
}
else {
//when the trash is full, make the user input a valid position on the board.
while( (!checkIfNotPlayed(intInput) || !(intInput < 17) )) {
System.out.println("Make a valid move on board");
intInput = scan.nextInt();
}
String forcedInput = Integer.toString(intInput);
makeMove(forcedInput, currentCard);
assignedBoardPositions.add(forcedInput);
}
}
//take an input and move the current card to that position in the trash.
public void moveToTrash(String stringedInput) {
trash.set(trash.indexOf(stringedInput), currentCard.getCardIcon());
discardCounter++;
}
//show the trash contents.
public void showTrash() {
System.out.println("\n");
//loop through trash
for(int i = 0; i < trash.size(); i++) {
//print out what we have
System.out.print(trash.get(i)+ " ");
}
//print out the number of choices we have left. There is a max of 4.
System.out.print("You have "+ (4 - discardCounter) + " available discard spaces left. \n");
}
//score the game when the board is full and print out score
public void score() {
int sum = 0;
sum += scoreRows();
sum += scoreCols();
System.out.println("The score of the game is: " + sum);
}
//general function used to sum an array of cards
public int sumArrayOfCards(Card[] cards) {
int sum =0;
for(Card card : cards) {
if(card != null) {
sum+= card.getValue();
}
}
return sum;
}
//general function to check if there is an ace in an array of cards.
public boolean checkForAce(Card[] cards) {
for(Card card : cards) {
if(card != null) {
if(card.getCardIcon().charAt(0) == 'A') {
return true;
}
}
}
return false;
}
//get the sum of the rows of the gameBoard.
public int scoreRows() {
int scoreOfAllRows = 0;
int rowSum;
boolean hasAce;
for(int i = 0; i < 4; i++) {
Card[] row = gameBoard.board[i];
//sum the row
rowSum = sumArrayOfCards(row);
//check for ace
hasAce = checkForAce(row);
//if we do have an ace and the sum of the row is less than 12 we will always want to utilize the ace as 11 points, not 1 points
if( (hasAce) && (rowSum < 12) ) {
rowSum += 10;
}
//sanity check for proper scoring
//System.out.println("The score of row " +i+ " is " + pointChecker(rowSum, false));
//add it to row
scoreOfAllRows +=pointChecker(rowSum, false);
}
return scoreOfAllRows;
}
// get sumCols individually. The commented code is sanity checking.
public int scoreCols() {
int scoreOfAllCols = 0;
//column 0
scoreOfAllCols += scoreEndCol(gameBoard.board[0][0], gameBoard.board[1][0]);
//System.out.println("The score of col " +0+ " is " + scoreEndCol(gameBoard.board[0][0], gameBoard.board[1][0]));
//column 4
scoreOfAllCols += scoreEndCol(gameBoard.board[0][4], gameBoard.board[1][4]);
//System.out.println("The score of col " +4+ " is " + scoreEndCol(gameBoard.board[0][4], gameBoard.board[1][4]));
//column 1
scoreOfAllCols += scoreMiddleCol(gameBoard.board[0][1], gameBoard.board[1][1], gameBoard.board[2][1], gameBoard.board[3][1]);
//System.out.println("The score of col "+1+ " is "+scoreMiddleCol(gameBoard.board[0][1], gameBoard.board[1][1], gameBoard.board[2][1], gameBoard.board[3][1]));
//column 2
scoreOfAllCols += scoreMiddleCol(gameBoard.board[0][2], gameBoard.board[1][2], gameBoard.board[2][2], gameBoard.board[3][2]);
//System.out.println("The score of col "+2+ " is "+scoreMiddleCol(gameBoard.board[0][2], gameBoard.board[1][2], gameBoard.board[2][2], gameBoard.board[3][2]));
//column 3
scoreOfAllCols += scoreMiddleCol(gameBoard.board[0][3], gameBoard.board[1][3], gameBoard.board[2][3], gameBoard.board[3][3]);
//System.out.println("The score of col "+3+ " is "+scoreMiddleCol(gameBoard.board[0][3], gameBoard.board[1][3], gameBoard.board[2][3], gameBoard.board[3][3]));
return scoreOfAllCols;
}
//take sum of an 2-card array used for the end columns.
public int scoreEndCol(Card top, Card bottom) {
Card[] topAndBottom = {top,bottom};
int sum = top.getValue() + bottom.getValue();
boolean hasAce = checkForAce(topAndBottom);
if( (hasAce) && (sum < 12) ) {
sum += 10;
}
int scoreOfEndCol = pointChecker(sum, true);
return scoreOfEndCol;
}
//take sum of a 4-card array. Used for middle columns.
public int scoreMiddleCol(Card first, Card second, Card third, Card fourth) {
int scoreOfMiddleCol;
int sum = 0;
Card[] middleCol = {first, second, third, fourth};
for(Card card : middleCol) {
sum += card.getValue();
}
boolean hasAce = checkForAce(middleCol);
if((hasAce) && (sum < 12)) {
sum+= 10;
}
scoreOfMiddleCol = pointChecker(sum, false);
return scoreOfMiddleCol;
}
//converts array sums to appropriate points
public int pointChecker(int sum, boolean twoCards) {
//allows for special point system when we have blackjack in two cards
if(twoCards) {
if(sum == 21) {
return 10;
}
}
if(sum == 21) {
return 7;
}
if(sum == 20) {
return 5;
}
if(sum == 19) {
return 4;
}
if(sum == 18) {
return 3;
}
if(sum == 17) {
return 2;
}
if(sum < 17) {
return 1;
}
return 0;
}
//place the card on the board
public void makeMove(String input, Card currentCard) {
//loop through board
for(int i=0; i<4; i++) {
for(int j=0; j<5; j++) {
//pass the cards that are not displayed
if(gameBoard.board[i][j] == null) {
continue;
}
//if we have a display card that matches the user input, place the current card in that position of the board.
if(gameBoard.board[i][j].getCardIcon().contentEquals(input)) {
gameBoard.board[i][j] = currentCard;
}
}
}
}
}