Skip to content

Commit 96c4047

Browse files
committed
solution to chapter 7, question 1
1 parent ea6d973 commit 96c4047

File tree

9 files changed

+387
-76
lines changed

9 files changed

+387
-76
lines changed

src/chapter7/BlackJackCard.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import {Card} from './Card.js'
2+
3+
export class BlackJackCard extends Card {
4+
constructor(c, s) {
5+
super(c, s);
6+
}
7+
8+
value() {
9+
if (this.isAce()) {
10+
return 1;
11+
} else if (this.faceValue >= 11 && this.faceValue <= 13) {
12+
return 10;
13+
} else {
14+
return this.faceValue;
15+
}
16+
}
17+
18+
minValue() {
19+
if (this.isAce()) {
20+
return 1;
21+
} else {
22+
return this.value();
23+
}
24+
}
25+
26+
maxValue() {
27+
if (this.isAce()) {
28+
return 11;
29+
} else {
30+
return this.value();
31+
}
32+
}
33+
34+
isAce() {
35+
return this.faceValue == 1;
36+
}
37+
38+
isFaceCard() {
39+
return this.faceValue >= 11 && this.faceValue <= 13;
40+
}
41+
}
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
import {Suit} from './Suit.js'
2+
import {Deck} from './Deck.js'
3+
import {BlackJackHand} from './BlackJackHand.js'
4+
import {BlackJackCard} from './BlackJackCard.js'
5+
6+
export class BlackJackGameAutomator {
7+
constructor(numPlayers){
8+
this.deck = undefined;
9+
10+
this.hands = [];
11+
for (let i = 0; i < numPlayers; i++) {
12+
this.hands.push(new BlackJackHand());
13+
}
14+
}
15+
16+
//underscore for psuedo private
17+
static get _HIT_UNTIL() {
18+
return 16;
19+
}
20+
21+
dealInitial() {
22+
this.hands.forEach(hand => {
23+
let card1 = this.deck.dealCard();
24+
let card2 = this.deck.dealCard();
25+
if (card1 == null || card2 == null) {
26+
return false;
27+
}
28+
hand.addCard(card1);
29+
hand.addCard(card2);
30+
});
31+
return true;
32+
}
33+
34+
getBlackJacks() {
35+
let winners = [];
36+
for (let i = 0; i < this.hands.length; i++) {
37+
if (this.hands[i].isBlackJack()) {
38+
winners.push(i);
39+
}
40+
}
41+
return winners;
42+
}
43+
44+
playHandIndex(i) {
45+
let hand = this.hands[i];
46+
return this.playHand(hand);
47+
}
48+
49+
playHand(hand) {
50+
while (hand.score() < this._HIT_UNTIL) {
51+
let card = this.deck.dealCard();
52+
if (card == null) {
53+
return false;
54+
}
55+
hand.addCard(card);
56+
}
57+
return true;
58+
}
59+
60+
playAllHands() {
61+
this.hands.forEach(hand => {
62+
if (!this.playHand(hand)) {
63+
return false;
64+
}
65+
});
66+
return true;
67+
}
68+
69+
getWinners() {
70+
let winners = [];
71+
let winningScore = 0;
72+
for (let i = 0; i < this.hands.length; i++) {
73+
let hand = this.hands[i];
74+
if (!hand.busted()) {
75+
if (hand.score() > winningScore) {
76+
winningScore = hand.score();
77+
winners = [];
78+
winners.push(i);
79+
} else if (hand.score() == winningScore) {
80+
winners.push(i);
81+
}
82+
}
83+
}
84+
return winners;
85+
}
86+
87+
initializeDeck() {
88+
let cards = [];
89+
for (let i = 1; i <= 13; i++) {
90+
for (let j = 0; j <= 3; j++) {
91+
let suit = Suit.getSuitFromValue(j);
92+
let card = new BlackJackCard(i, suit);
93+
cards.push(card);
94+
}
95+
}
96+
97+
this.deck = new Deck();
98+
this.deck.setDeckOfCards(cards);
99+
this.deck.shuffle();
100+
}
101+
102+
printHandsAndScore() {
103+
this.hands.forEach((hand, i) => {
104+
process.stdout.write("Hand " + i + " (" + hand.score() + "): ");
105+
hand.print();
106+
console.log("");
107+
});
108+
}
109+
}

src/chapter7/BlackJackHand.js

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import {Hand} from './Hand.js'
2+
3+
export class BlackJackHand extends Hand {
4+
score() {
5+
let scores = this.possibleScores();
6+
let maxUnder = Number.MIN_VALUE;
7+
let minOver = Number.MAX_VALUE;
8+
for (let score of scores) {
9+
if (score > 21 && score < minOver) {
10+
minOver = score;
11+
} else if (score <= 21 && score > maxUnder) {
12+
maxUnder = score;
13+
}
14+
}
15+
return maxUnder == Number.MIN_VALUE ? minOver : maxUnder;
16+
}
17+
18+
possibleScores() {
19+
let scores = [];
20+
if (this.cards.length == 0) {
21+
return scores;
22+
}
23+
for (let card of this.cards) {
24+
this.addCardToScoreList(card, scores);
25+
}
26+
return scores;
27+
}
28+
29+
addCardToScoreList(card, scores) {
30+
if (scores.length == 0) {
31+
scores.push(0);
32+
}
33+
let length = scores.length;
34+
for (let i = 0; i < length; i++) {
35+
let score = scores[i];
36+
scores[i] = score + card.minValue();
37+
if (card.minValue() != card.maxValue()) {
38+
scores.push(score + card.maxValue());
39+
}
40+
}
41+
}
42+
43+
busted() {
44+
return this.score() > 21;
45+
}
46+
47+
is21() {
48+
return this.score() == 21;
49+
}
50+
51+
isBlackJack() {
52+
if (this.cards.length != 2) {
53+
return false;
54+
}
55+
let first = this.cards[0];
56+
let second = this.cards[1];
57+
return (first.isAce() && second.isFaceCard()) || (second.isAce() && first.isFaceCard());
58+
}
59+
}

src/chapter7/Card.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import {Suit} from './Suit.js'
2+
3+
export class Card{
4+
constructor(c, s){
5+
this.available = true;
6+
this.faceValue = c;
7+
this.suit = s;
8+
}
9+
10+
suit(){
11+
return this.suit;
12+
}
13+
14+
isAvailable(){
15+
return this.available;
16+
}
17+
18+
markUnavailable(){
19+
this.available = false;
20+
}
21+
22+
markAvailable(){
23+
this.available = true;
24+
}
25+
print() {
26+
let faceValues = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K'];
27+
process.stdout.write(faceValues[this.faceValue - 1]);
28+
switch (this.suit) {
29+
case Suit.Club:
30+
process.stdout.write("c");
31+
break;
32+
case Suit.Heart:
33+
process.stdout.write("h");
34+
break;
35+
case Suit.Diamond:
36+
process.stdout.write("d");
37+
break;
38+
case Suit.Spade:
39+
process.stdout.write("s");
40+
break;
41+
}
42+
process.stdout.write(" ");
43+
}
44+
}

src/chapter7/Deck.js

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
export class Deck{
2+
constructor(c, s){
3+
this.dealtIndex = 0;
4+
this.cards = [];
5+
}
6+
7+
setDeckOfCards(deckOfCards) {
8+
this.cards = deckOfCards;
9+
}
10+
11+
randomInt(n) {
12+
return Math.round(Math.random() * n);
13+
}
14+
15+
randomIntInRange(min, max) {
16+
return this.randomInt(max + 1 - min) + min;
17+
}
18+
19+
shuffle() {
20+
for (let i = 0; i < this.cards.length; i++) {
21+
let j = this.randomIntInRange(i, this.cards.length - i - 1);
22+
23+
let card1 = this.cards[i];
24+
let card2 = this.cards[j];
25+
26+
this.cards[i] = card2;
27+
this.cards[j] = card1;
28+
}
29+
}
30+
31+
remainingCards() {
32+
return this.cards.length - this.dealtIndex;
33+
}
34+
35+
dealHand(number) {
36+
if (remainingCards() < number) {
37+
return null;
38+
}
39+
40+
let hand = [];
41+
let count = 0;
42+
while (count < number) {
43+
let card = dealCard();
44+
if (card != null) {
45+
hand[count] = card;
46+
count++;
47+
}
48+
}
49+
50+
return hand;
51+
}
52+
53+
dealCard() {
54+
if (this.remainingCards() == 0) {
55+
return null;
56+
}
57+
let card = this.cards[this.dealtIndex];
58+
card.markUnavailable();
59+
this.dealtIndex++;
60+
61+
return card;
62+
}
63+
64+
print() {
65+
this.cards.forEach(card => card.print());
66+
}
67+
}

src/chapter7/Hand.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import {Card} from './Card.js'
2+
3+
export class Hand extends Card{
4+
constructor(c, s){
5+
super();
6+
this.cards = [];
7+
}
8+
9+
score(){
10+
return cards.reduce((aggregate, card) => aggregate + card.value());
11+
}
12+
13+
addCard(card){
14+
this.cards.push(card);
15+
}
16+
17+
print(){
18+
this.cards.forEach(card => card.print());
19+
}
20+
}

src/chapter7/Suit.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export const Suit = {
2+
Club : 0,
3+
Diamond : 1,
4+
Heart : 2,
5+
Spade : 3,
6+
getSuitFromValue: (value) => Suit[Object.keys(Suit).find(key => Suit[key] == value)]
7+
}

0 commit comments

Comments
 (0)