@ -0,0 +1,17 @@ |
|||||||
|
body { |
||||||
|
background-color: #0f0f0f; |
||||||
|
color: white; |
||||||
|
} |
||||||
|
|
||||||
|
.container { |
||||||
|
padding-top: 3em; |
||||||
|
} |
||||||
|
|
||||||
|
.playing-card { |
||||||
|
max-width: 100%; |
||||||
|
} |
||||||
|
|
||||||
|
#status { |
||||||
|
color: darkred; |
||||||
|
text-align: center; |
||||||
|
} |
After Width: | Height: | Size: 729 B |
After Width: | Height: | Size: 4.5 KiB |
After Width: | Height: | Size: 827 B |
After Width: | Height: | Size: 4.4 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 730 B |
After Width: | Height: | Size: 4.3 KiB |
After Width: | Height: | Size: 829 B |
After Width: | Height: | Size: 4.4 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 729 B |
After Width: | Height: | Size: 4.3 KiB |
After Width: | Height: | Size: 826 B |
After Width: | Height: | Size: 4.4 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 3.4 KiB |
After Width: | Height: | Size: 2.6 KiB |
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.3 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 3.4 KiB |
After Width: | Height: | Size: 3.3 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 2.6 KiB |
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 3.3 KiB |
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 2.6 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 3.2 KiB |
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 2.6 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 3.2 KiB |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 2.6 KiB |
After Width: | Height: | Size: 3.2 KiB |
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 3.3 KiB |
@ -0,0 +1,57 @@ |
|||||||
|
<!doctype html> |
||||||
|
<html lang="en"> |
||||||
|
<head> |
||||||
|
<meta charset="UTF-8"> |
||||||
|
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> |
||||||
|
<meta http-equiv="X-UA-Compatible" content="ie=edge"> |
||||||
|
<title>BlackJack ♠</title> |
||||||
|
<link rel="stylesheet" href="css/bootstrap.min.css"> |
||||||
|
<link rel="stylesheet" href="css/app.css"> |
||||||
|
<link rel="icon" href="favicon.ico"> |
||||||
|
</head> |
||||||
|
<body> |
||||||
|
<div class="container" id="root"> |
||||||
|
<div class="row"> |
||||||
|
<div class="col-md-12"> |
||||||
|
<button @click="testRound" v-if="!roundActive">Start round</button> |
||||||
|
<button @click="drawAnotherCard" v-if="roundActive">Draw</button> |
||||||
|
<button @click="pass" v-if="roundActive">Pass</button> |
||||||
|
<button @click="endRound" v-if="roundActive">End round</button> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<!-- <div class="row">--> |
||||||
|
<!-- <div class="col-md-1" v-for="card in cards">--> |
||||||
|
<!-- <img :src="card.asset" :alt="card.symbol + '_' + card.points" class="playing-card">--> |
||||||
|
<!-- </div>--> |
||||||
|
<!-- </div>--> |
||||||
|
|
||||||
|
<div class="row"> |
||||||
|
<div class="col-md-6"> |
||||||
|
<h4>Dealer <template v-if="!roundActive">({{ dealerScore }})</template></h4> |
||||||
|
<div class="row"> |
||||||
|
<div class="col-md-4" v-for="(card, index) in dealersHand"> |
||||||
|
<img :src="index > 0 ? card.asset : roundActive ? cardBack : card.asset" :alt="card.symbol + '_' + card.points" class="playing-card"> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="col-md-6"> |
||||||
|
<h4>Hand ({{ handScore === 21 && usersHand.count < 2 ? 'BlackJack' : handScore > 21 ? 'Plus! ' + handScore : handScore }})</h4> |
||||||
|
<div class="row"> |
||||||
|
<div class="col-md-4" v-for="card in usersHand"> |
||||||
|
<img :src="card.asset" :alt="card.symbol + '_' + card.points" class="playing-card"> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="row"> |
||||||
|
<div class="col-md-12" id="status"> |
||||||
|
<h1 v-text="status"></h1> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</body> |
||||||
|
<script src="js/vue.js"></script> |
||||||
|
<script src="js/app.js"></script> |
||||||
|
</html> |
@ -0,0 +1,205 @@ |
|||||||
|
let app = new Vue({ |
||||||
|
el: '#root', |
||||||
|
data: { |
||||||
|
roundActive: false, |
||||||
|
cardBack: 'img/cardBack_red5.png', |
||||||
|
cards: [], |
||||||
|
cardDeck: [], |
||||||
|
usersHand: [], |
||||||
|
dealersHand: [], |
||||||
|
lastCard: null, |
||||||
|
handScore: 0, |
||||||
|
dealerScore: 0, |
||||||
|
status: '', |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
generateDeck() { |
||||||
|
const symbolNames = ['spades', 'clubs', 'diamonds', 'hearts']; |
||||||
|
const highCards = ['j', 'q', 'k']; |
||||||
|
|
||||||
|
let cardDeck = []; |
||||||
|
|
||||||
|
symbolNames.forEach((symbolName) => { |
||||||
|
for (let cardPoints = 1; cardPoints <= 10; cardPoints++) { |
||||||
|
let cardSymbol = cardPoints; |
||||||
|
let points = cardPoints; |
||||||
|
let isAnAce = false; |
||||||
|
|
||||||
|
if (cardPoints === 1) { |
||||||
|
points = 11; |
||||||
|
cardSymbol = 'a'; |
||||||
|
isAnAce = true; |
||||||
|
} |
||||||
|
|
||||||
|
cardDeck.push({ |
||||||
|
ace: isAnAce, |
||||||
|
points: points, |
||||||
|
symbol: cardSymbol, |
||||||
|
asset: 'img/' + symbolName + cardSymbol + '.png' |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
highCards.forEach((highCard) => { |
||||||
|
cardDeck.push({ |
||||||
|
ace: false, |
||||||
|
points: 10, |
||||||
|
symbol: symbolName, |
||||||
|
asset: 'img/' + symbolName + highCard + '.png' |
||||||
|
}) |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
return cardDeck; |
||||||
|
}, |
||||||
|
|
||||||
|
shuffleDeck() { |
||||||
|
let shuffledDeck = this.cards; |
||||||
|
let cardCount = shuffledDeck.length, t, i; |
||||||
|
|
||||||
|
while (cardCount) { |
||||||
|
i = Math.floor(Math.random() * cardCount--); |
||||||
|
t = shuffledDeck[cardCount]; |
||||||
|
shuffledDeck[cardCount] = shuffledDeck[i]; |
||||||
|
shuffledDeck[i] = t; |
||||||
|
} |
||||||
|
|
||||||
|
this.cards = shuffledDeck; |
||||||
|
}, |
||||||
|
|
||||||
|
drawCardToUser() { |
||||||
|
let vue = this; |
||||||
|
|
||||||
|
let drawnCard = vue.cards.shift(); |
||||||
|
vue.usersHand.push(drawnCard); |
||||||
|
|
||||||
|
if (drawnCard.ace && vue.handScore > 10) { |
||||||
|
drawnCard.points = 1; |
||||||
|
} |
||||||
|
|
||||||
|
if ((vue.handScore + drawnCard.points) > 21) { |
||||||
|
let aceCount = this.handIncludesAces(this.usersHand); |
||||||
|
console.log(aceCount + ' aces should be decreased in value'); |
||||||
|
} |
||||||
|
|
||||||
|
vue.handScore += drawnCard.points; |
||||||
|
}, |
||||||
|
|
||||||
|
drawCardToDealer() { |
||||||
|
let vue = this; |
||||||
|
|
||||||
|
let drawnCard = vue.cards.shift(); |
||||||
|
vue.dealersHand.push(drawnCard); |
||||||
|
|
||||||
|
if (drawnCard.ace && vue.dealerScore > 10) { |
||||||
|
drawnCard.points = 1; |
||||||
|
} |
||||||
|
|
||||||
|
if ((vue.dealerScore + drawnCard.points) > 21) { |
||||||
|
let aceCount = this.handIncludesAces(this.dealersHand); |
||||||
|
console.log(aceCount + ' aces should be decreased in value'); |
||||||
|
} |
||||||
|
|
||||||
|
vue.dealerScore += drawnCard.points; |
||||||
|
}, |
||||||
|
|
||||||
|
handIncludesAces(hand) { |
||||||
|
let aceCount = 0; |
||||||
|
|
||||||
|
hand.forEach((card) => { |
||||||
|
if (card.ace === true) { |
||||||
|
aceCount++; |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
return aceCount; |
||||||
|
}, |
||||||
|
|
||||||
|
handHasBlackJack(score) { |
||||||
|
return score === 21; |
||||||
|
}, |
||||||
|
|
||||||
|
isPlus(score) { |
||||||
|
return score > 21; |
||||||
|
}, |
||||||
|
|
||||||
|
startRound() { |
||||||
|
this.endRound(); |
||||||
|
|
||||||
|
this.roundActive = true; |
||||||
|
|
||||||
|
this.drawCardToUser(); |
||||||
|
this.drawCardToDealer(); |
||||||
|
this.drawCardToUser(); |
||||||
|
this.drawCardToDealer(); |
||||||
|
|
||||||
|
if (this.handHasBlackJack(this.dealerScore)) { |
||||||
|
this.dealerWon(); |
||||||
|
} |
||||||
|
|
||||||
|
if (this.handScore === 21) { |
||||||
|
this.pass(); |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
drawAnotherCard() { |
||||||
|
this.drawCardToUser(); |
||||||
|
|
||||||
|
if (this.isPlus(this.handScore)) { |
||||||
|
this.status = 'Hand is plus, you lose.'; |
||||||
|
this.roundActive = false; |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
pass() { |
||||||
|
if (this.dealerScore === this.handScore) { |
||||||
|
this.roundActive = false; |
||||||
|
this.status = 'Draw!' |
||||||
|
} else if (this.dealerScore > 22) { |
||||||
|
this.roundActive = false; |
||||||
|
this.status = 'Dealer is plus, you win'; |
||||||
|
} else if (this.dealerScore > this.handScore) { |
||||||
|
this.roundActive = false; |
||||||
|
this.status = 'Dealer Wins'; |
||||||
|
} else if (this.dealerScore < 17) { |
||||||
|
this.roundActive = false; |
||||||
|
this.drawCardToDealer(); |
||||||
|
this.pass(); |
||||||
|
|
||||||
|
// this.status = 'Dealer drawing not yet implemented';
|
||||||
|
} else if (this.handScore > this.dealerScore && this.handScore < 22) { |
||||||
|
this.roundActive = false; |
||||||
|
this.status = 'You win!'; |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
endRound() { |
||||||
|
this.roundActive = false; |
||||||
|
this.lastCard = null; |
||||||
|
this.status = null; |
||||||
|
this.dealersHand = []; |
||||||
|
this.dealerScore = 0; |
||||||
|
this.usersHand = []; |
||||||
|
this.handScore = 0; |
||||||
|
|
||||||
|
this.cards = this.generateDeck(); |
||||||
|
this.shuffleDeck(); |
||||||
|
}, |
||||||
|
|
||||||
|
dealerWon() { |
||||||
|
console.log('House wins') |
||||||
|
}, |
||||||
|
|
||||||
|
userWon() { |
||||||
|
console.log('You win') |
||||||
|
}, |
||||||
|
|
||||||
|
testRound() { |
||||||
|
this.startRound(); |
||||||
|
} |
||||||
|
}, |
||||||
|
created() { |
||||||
|
this.cardDeck = this.generateDeck(); |
||||||
|
this.cards = this.generateDeck(); |
||||||
|
this.shuffleDeck(); |
||||||
|
} |
||||||
|
}); |