forked from rocketacademy/basics-blackjack
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscript.js
More file actions
436 lines (395 loc) · 13.2 KB
/
Copy pathscript.js
File metadata and controls
436 lines (395 loc) · 13.2 KB
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
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
// Blackjack Project
/* RULES */
/* There will be two players.
One human and one computer (for the Base solution).
The computer will always be the dealer.
Each player gets dealt two cards to start.
The player goes first, and decides if they want to hit (draw a card) or stand (end their turn).
The dealer has to hit if their hand is below 17.
Each players' score is the total of their card ranks. Jacks/Queen/Kings are 10. Aces can be 1 or 11.
The player who is closer to, but not above 21 wins the hand.
*/
// MAKE DECK OF CARDS
var makeDeck = function (cardDeck) {
var cardDeck = [];
var suits = ["hearts", "diamonds", "clubs", "spades"];
var suitIndex = 0;
while (suitIndex < suits.length) {
var currentSuit = suits[suitIndex];
var rankCounter = 1;
// rankCounter starts from 1, otherwise it would start from 0
while (rankCounter <= 13) {
var cardName = rankCounter;
// set cardName as rankCounter. i.e. 2 of hearts will have 2 as name and 2 as rank
if (cardName == 1) {
cardName = "ace";
} else if (cardName == 11) {
cardName = "jack";
} else if (cardName == 12) {
cardName = "queen";
} else if (cardName == 13) {
cardName = "king";
}
var pointInHand = rankCounter;
// create new key called point to use later to sum up the hands
if (pointInHand == 1) {
pointInHand = 11;
} else if (pointInHand == 11) {
pointInHand = 10;
} else if (pointInHand == 12) {
pointInHand = 10;
} else if (pointInHand == 13) {
pointInHand = 10;
}
var card = {
name: cardName,
suit: currentSuit,
rank: rankCounter,
point: pointInHand,
};
cardDeck.push(card);
rankCounter += 1;
}
suitIndex += 1;
}
return cardDeck;
};
// Get a random index ranging from 0 (inclusive) to max (exclusive).
var getRandomIndex = function (max) {
return Math.floor(Math.random() * max);
};
// the length of card deck will be used as "max". Hence 42 cards is the total/max number of cards in the deck
// SHUFFLE CARDS
var shuffleCards = function (cardDeck) {
// Loop over the card deck array once
var currentIndex = 0;
while (currentIndex < cardDeck.length) {
var randomIndex = getRandomIndex(cardDeck.length);
var randomCard = cardDeck[randomIndex];
var currentCard = cardDeck[currentIndex];
// Swap positions of randomCard and currentCard in the deck
cardDeck[currentIndex] = randomCard;
cardDeck[randomIndex] = currentCard;
currentIndex = currentIndex + 1;
}
return cardDeck;
};
// SUM OF HAND.
function sumCardsInArray(inputArray) {
var outputSum = 0;
var acesInHand = 0;
for (let sumCounter = 0; sumCounter < inputArray.length; sumCounter += 1) {
var indexCard = inputArray[sumCounter];
if (indexCard.rank == 1) {
// count number of aces
acesInHand += 1;
outputSum += inputArray[sumCounter];
} else {
outputSum += inputArray[sumCounter];
}
}
if (outputSum > 21 && acesInHand > 0) {
var aceCounter = 0;
while (aceCounter < acesInHand) {
sum -= 10;
// If the sum is less than TWENTY_ONE before converting all Ace values from
// 11 to 1, break out of the loop and return the current sum.
if (outputSum <= 21) {
break; // break keyword causes the loop to finish
}
aceCounter = aceCounter + 1;
}
}
return outputSum;
}
// CHECK FOR BLACKJACK
var isBlackjack = function (hand) {
return hand.length === 2 && sumCardsInArray(hand) == 21;
};
// CHECK FOR BUST
var isBust = function (sumOfCards) {
if (sumOfCards > 21) {
return true;
}
};
// DRAW TWO CARDS WHEN STARTING
var drawTwoCards = function () {
for (let drawCardsCounter = 0; drawCardsCounter < 2; drawCardsCounter++) {
// draw one card for each player
dealerCard = shuffledDeck.pop();
playerCard = shuffledDeck.pop();
// push card into array for cards and array for points
dealerArr.push(dealerCard);
dealerHandArr.push(dealerCard.point);
playerArr.push(playerCard);
playerHandArr.push(playerCard.point);
// dealerHandArr.push(5);
// playerHandArr.push(10.5);
}
};
// DEAL ONE CARD FOR PLAYER
var playerHit = function () {
playerCard = shuffledDeck.pop();
playerArr.push(playerCard);
playerHandArr.push(playerCard.point);
};
// DEAL ONE CARD FOR DEALER
var dealerHit = function () {
dealerCard = shuffledDeck.pop();
dealerArr.push(dealerCard);
dealerHandArr.push(dealerCard.point);
};
// RESET GAME
var resetGame = function () {
playerArr = [];
playerHandArr = [];
dealerArr = [];
dealerHandArr = [];
dealerChoseToStand = false;
playerChoseToStand = false;
dealerBust = false;
playerBust = false;
gameMode = GAME_MODE_START;
shuffledDeck = shuffleCards(makeDeck());
};
// OUPUT PLAYER'S HAND
var generatePlayerOutput = function () {
var playerTotalValue = sumCardsInArray(playerHandArr);
var PLAYER_OUTPUT_MSG = `<b><u>YOUR HAND</u></b><br>`;
for (var i = 0; i < playerArr.length; i += 1) {
PLAYER_OUTPUT_MSG += `${playerArr[i].name} of ${playerArr[i].suit}<br>`;
}
PLAYER_OUTPUT_MSG += `<b>Your hand totals to ${playerTotalValue}.</b><br><br>`;
return PLAYER_OUTPUT_MSG;
};
// OUPUT DEALER'S HAND
var generateDealerOutput = function () {
var dealerTotalValue = sumCardsInArray(dealerHandArr);
var DEALER_OUTPUT_MSG = `<b><u>DEALER'S HAND</u></b><br>`;
for (var i = 0; i < dealerArr.length; i += 1) {
DEALER_OUTPUT_MSG += `${dealerArr[i].name} of ${dealerArr[i].suit}<br>`;
}
DEALER_OUTPUT_MSG += `<b>The dealer's hand totals to ${dealerTotalValue}.</b><br><br>`;
return DEALER_OUTPUT_MSG;
};
// GIFS
var playerWinGif =
'<img src ="https://media.tenor.com/OaYYWO9efBIAAAAC/rich-money.gif"/>';
var playerLosesGif =
'<img src = "https://media.tenor.com/lgDnQxXr8XIAAAAC/spongebob.gif"/>';
var playerChoiceGif =
'<img src = "https://media.tenor.com/8Qbw56-IuPgAAAAC/sponge-bob-square-pants-sponge-bob.gif"/>';
var playerNervousGif =
'<img src ="https://media.tenor.com/pB-cPZmiMeEAAAAC/stress-spongebob.gif"/>';
var itsATieGif =
'<img src = "https://media.tenor.com/gRQbmeKOOb0AAAAC/spongebob-patrick.gif"/>';
var hitIt =
'<img src = "https://media.tenor.com/ceLVRjW6w8gAAAAC/patrick-star-smash.gif"/>';
// GLOBAL VARIABLES
var dealerArr = [];
var playerArr = [];
var dealerHandArr = [];
var playerHandArr = [];
var deck = makeDeck();
var shuffledDeck = shuffleCards(deck);
var GAME_MODE_START = "DEAL_TWO_CARDS_EACH";
var GAME_MODE_PLAYER_MOVE = "PLAYER_CHOOSE_HIT_OR_STAND";
var GAME_MODE_DEALER = "DEALER_HIT_OR_STAND";
var GAME_MODE_EVALUATE = "EVALUATE_WINNING_CONDITIONS";
var dealerLimit = 17;
// initialise game mode to enter num dice mode
var gameMode = GAME_MODE_START;
// player choice to stand is false at the start
var playerChoseToStand = false;
var dealerChoseToStand = false;
// both players bust is false at the start
var playerBust = false;
var dealerBust = false;
// MAIN FUNCTION
var main = function (input) {
if (gameMode == GAME_MODE_START) {
drawTwoCards();
// call function to sum cards
var dealerSum = sumCardsInArray(dealerHandArr);
var playerSum = sumCardsInArray(playerHandArr);
var genericOutput = `This is the dealer's cards points: ${dealerHandArr} and the total hand is ${dealerSum}. <br/> <br/> This is the player's cards: ${playerHandArr} and the total hand is ${playerSum} <br/><br/>`;
// If both has blackjack, it's a tie. If either gets blackjack, that player wins in the first round.
if (isBlackjack(playerHandArr) && isBlackjack(dealerHandArr)) {
gameMode = GAME_MODE_START;
resetGame();
return (
generatePlayerOutput() +
generateDealerOutput() +
` Both players got Blackjack! It's a tie. Play again.`
);
}
if (isBlackjack(playerHandArr)) {
var myOutputValue =
generatePlayerOutput() +
generateDealerOutput() +
`Player gets blackjack. Player wins the game!<br></br>` +
playerWinGif;
gameMode = GAME_MODE_START;
resetGame();
return myOutputValue;
}
if (isBlackjack(dealerHandArr)) {
var myOutputValue =
generatePlayerOutput() +
generateDealerOutput() +
`Dealer gets blackjack <br></br>` +
playerLosesGif;
gameMode = GAME_MODE_START;
resetGame();
return myOutputValue;
}
// If neither players got blackjack in the first round, the game state changes to ask the player to hit or stand
gameMode = GAME_MODE_PLAYER_MOVE;
return (
generatePlayerOutput() +
generateDealerOutput() +
`Enter "h" to hit or "s" to stand.`
);
}
// Start new state: Player's move to hit or stand
if (gameMode == GAME_MODE_PLAYER_MOVE) {
if (input != "h" && input != "s") {
return "Enter 'h' for hit or 's' for stand to proceed";
}
if (input == "h") {
playerHit();
var playerSum = sumCardsInArray(playerHandArr);
var dealerSum = sumCardsInArray(dealerHandArr);
//Dealer needs to choose to hit or stand after the player
if (isBust(playerSum)) {
gameMode = GAME_MODE_DEALER;
playerBust = true;
myOutputValue =
generatePlayerOutput() +
generateDealerOutput() +
`You've chosen to hit and gone bust! 💣 Let's see what the dealer does. <br><br>` +
playerNervousGif;
return myOutputValue;
}
gameMode = GAME_MODE_DEALER;
myOutputValue =
hitIt +
`<br><br> You've chosen to hit. <br><br> The hands are now: <br><br>` +
generatePlayerOutput() +
generateDealerOutput();
return myOutputValue;
}
playerChoseToStand = true;
gameMode = GAME_MODE_DEALER;
myOutputValue =
`You've chosen to stand. <br><br> The hands remain: <br><br>` +
generatePlayerOutput() +
generateDealerOutput();
return myOutputValue;
}
// Dealer needs to hit if their cards are under 17
if (gameMode == GAME_MODE_DEALER) {
if (sumCardsInArray(dealerHandArr) < dealerLimit) {
dealerHit();
var dealerSum = sumCardsInArray(dealerHandArr);
gameMode = GAME_MODE_EVALUATE;
if (isBust(dealerSum)) {
dealerBust = true;
myOutputValue =
generatePlayerOutput() +
generateDealerOutput() +
`Dealer choses to hit and gone bust! 💣`;
return myOutputValue;
}
return (
"Dealer hit. <br><br> The hands are now: <br>" +
generatePlayerOutput() +
generateDealerOutput()
);
}
dealerChoseToStand = true;
gameMode = GAME_MODE_EVALUATE;
return `Dealer chose to stand.`;
}
// EVALUATE WIN CONDITIONS
if (gameMode == GAME_MODE_EVALUATE) {
var playerSum = sumCardsInArray(playerHandArr);
var dealerSum = sumCardsInArray(dealerHandArr);
if (playerBust == true && dealerBust == true) {
myOutputValue =
generatePlayerOutput() +
generateDealerOutput() +
`Both players hands' bust! 💣💣 Restart game by hitting Submit.<br><br>` +
itsATieGif;
resetGame();
gameMode = GAME_MODE_START;
return myOutputValue;
} else if (
playerSum == dealerSum &&
playerChoseToStand == true &&
dealerChoseToStand == true
) {
myOutputValue =
generatePlayerOutput() +
generateDealerOutput() +
`Both players have chose to stand and are tied! Click Submit to play again <br><br>` +
itsATieGif;
resetGame();
gameMode == GAME_MODE_START;
return myOutputValue;
} else if (dealerBust == true) {
myOutputValue =
generatePlayerOutput() +
generateDealerOutput() +
`Dealer has bust! 💣 You win!<br></br>` +
playerWinGif;
gameMode = GAME_MODE_START;
resetGame();
return myOutputValue;
} else if (playerBust == true) {
myOutputValue =
generatePlayerOutput() +
generateDealerOutput() +
`You've bust! 💣 Dealer wins! Click Submit to play again.<br></br>` +
playerLosesGif;
gameMode = GAME_MODE_START;
resetGame();
return myOutputValue;
} else if (
playerChoseToStand == true &&
dealerChoseToStand == true &&
dealerSum > playerSum
) {
myOutputValue =
generatePlayerOutput() +
generateDealerOutput() +
`You lose! <br> Dealer has the hand closer to 21 and wins! <br></br> Click Submit to play again. <br></br>` +
playerLosesGif;
gameMode = GAME_MODE_START;
resetGame();
return myOutputValue;
} else if (
playerChoseToStand == true &&
dealerChoseToStand == true &&
dealerSum < playerSum
) {
myOutputValue =
generatePlayerOutput() +
generateDealerOutput() +
`You win! Click Submit to play again <br></br>` +
playerWinGif;
gameMode = GAME_MODE_START;
resetGame();
return myOutputValue;
} else if (playerChoseToStand == false) {
myOutputValue =
generatePlayerOutput() +
generateDealerOutput() +
`Your turn to hit or stand. Enter 'h' for hit or 's' for stand. <br><br>` +
playerChoiceGif;
gameMode = GAME_MODE_PLAYER_MOVE;
return myOutputValue;
} else gameMode = GAME_MODE_DEALER;
return `You've chosen to stand. It is the dealer's turn now.`;
}
};