blackjack logic written in vue
https://luna-development.net/blackjack/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
384 lines
12 KiB
384 lines
12 KiB
let app = new Vue({ |
|
el: '#root', |
|
data: { |
|
initiated: false, |
|
roundActive: false, |
|
roundPlayed: false, |
|
cardBack: 'img/cardBack_red5.png', |
|
cards: [], |
|
cardDeck: [], |
|
usersHand: [], |
|
dealersHand: [], |
|
lastCard: null, |
|
handScore: 0, |
|
dealerScore: 0, |
|
status: '', |
|
bet: 100, |
|
|
|
bankIsActive: false, |
|
bank: 0, |
|
money: 5000, |
|
toBank: 0, |
|
toMoney: 0, |
|
username: null, |
|
avatar: null, |
|
}, |
|
methods: { |
|
generateDeck() { |
|
const names = ['spades', 'clubs', 'diamonds', 'hearts']; |
|
const highCards = ['j', 'q', 'k']; |
|
|
|
let cardDeck = []; |
|
|
|
names.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() { |
|
if (this.bet > this.money) { |
|
alertify.notify('Not enough money for bet.'); |
|
return false; |
|
} |
|
|
|
this.money -= this.bet; |
|
|
|
this.initiated = true; |
|
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)) { |
|
alertify.notify('Hand is plus, you lose.') |
|
this.roundActive = false; |
|
this.roundPlayed = true; |
|
} |
|
}, |
|
|
|
pass() { |
|
if (this.dealerScore === this.handScore) { |
|
this.roundActive = false; |
|
this.roundPlayed = true; |
|
alertify.notify('Draw!'); |
|
this.draw(); |
|
} else if (this.dealerScore > 21) { |
|
this.roundActive = false; |
|
this.roundPlayed = true; |
|
alertify.notify('Dealer is plus, you win'); |
|
this.win(); |
|
} else if (this.dealerScore > this.handScore) { |
|
this.roundActive = false; |
|
this.roundPlayed = true; |
|
alertify.notify('Dealer Wins'); |
|
} else if (this.dealerScore < 17) { |
|
this.roundActive = false; |
|
this.roundPlayed = true; |
|
this.drawCardToDealer(); |
|
this.pass(); |
|
} else if (this.handScore > this.dealerScore && this.handScore < 22) { |
|
this.roundActive = false; |
|
this.roundPlayed = true; |
|
alertify.notify('You win ' + this.bet * 1.5 + '!'); |
|
this.win(); |
|
} |
|
}, |
|
|
|
draw() { |
|
this.money = (parseInt(this.money) + parseInt(this.bet)); |
|
}, |
|
|
|
win() { |
|
this.money += (parseInt(this.bet) * 2); |
|
}, |
|
|
|
endRound() { |
|
this.roundActive = false; |
|
this.roundPlayed = true; |
|
this.lastCard = null; |
|
this.status = null; |
|
this.dealersHand = []; |
|
this.dealerScore = 0; |
|
this.usersHand = []; |
|
this.handScore = 0; |
|
|
|
this.cards = this.generateDeck(); |
|
this.shuffleDeck(); |
|
}, |
|
|
|
checkUserStatus() { |
|
let vue = this; |
|
axios.get('/bank/get') |
|
.then(function (response) { |
|
vue.bank = Number(response.data.value); |
|
vue.username = response.data.name; |
|
vue.avatar = '/storage/avatars/' + response.data.avatar; |
|
vue.bankIsActive = true; |
|
vue.$forceUpdate; |
|
|
|
if (Number(vue.bank) <= Number(0)) { |
|
vue.money = 5000; |
|
} else { |
|
alertify.notify('Welcome back, ' + vue.username + '!', 'custom') |
|
} |
|
}) |
|
.catch(function (error) { |
|
console.log(error); |
|
alertify.notify("Can't connect to Luna Bank, are you logged in?", 'custom'); |
|
|
|
// Removed default money here if bank empty / dead |
|
vue.username = 'Gast'; |
|
vue.bankIsActive = false; |
|
}); |
|
}, |
|
|
|
updateBankAccount() { |
|
let vue = this; |
|
|
|
if (vue.bankIsActive) { |
|
axios.get('/bank/get') |
|
.then(function (response) { |
|
vue.bank = Number(response.data.value); |
|
vue.username = response.data.name; |
|
vue.avatar = '/storage/avatars/' + response.data.avatar; |
|
vue.$forceUpdate; |
|
}) |
|
.catch(function (error) { |
|
console.log(error); |
|
vue.username = 'Gast'; |
|
vue.bankIsActive = false; |
|
vue.avatar = null; |
|
}); |
|
} |
|
}, |
|
|
|
transferToBank() { |
|
let vue = this; |
|
|
|
if (vue.toBank <= vue.money && vue.toBank > 0) { |
|
let bankSave = vue.bank; |
|
let moneySave = vue.money; |
|
let toBankSave = vue.toBank; |
|
|
|
vue.bank = Number(vue.bank) + Number(vue.toBank); |
|
vue.money = Number(vue.money) - Number(vue.toBank); |
|
|
|
axios.post('/bank/store', { |
|
value: vue.bank, |
|
app: 'BlackJack', |
|
description: 'Deposit', |
|
amount: toBankSave |
|
}).then(function (response) { |
|
// i'm the master of self-advertisement |
|
// speaking of advertisement? check out the fresh servers at luna-development.net |
|
alertify.notify('Successfully transfered ' + toBankSave + ' $ to your account.', 'custom'); |
|
}).catch(function (error) { |
|
vue.bank = bankSave; |
|
vue.money = moneySave; |
|
|
|
alertify.notify('Error while process bank-transaction.', 'custom'); |
|
}); |
|
|
|
vue.toBank = undefined; |
|
} else if (vue.toBank === undefined) { |
|
return; |
|
} else { |
|
vue.toBank = undefined; |
|
} |
|
}, |
|
|
|
transferFromBank() { |
|
let vue = this; |
|
|
|
// Number() all over again |
|
if (vue.toMoney <= vue.bank && vue.toMoney > 0) { |
|
let bankSave = vue.bank; |
|
let moneySave = vue.money; |
|
let toMoneySave = vue.toMoney; |
|
|
|
vue.bank = Number(vue.bank) - Number(vue.toMoney); |
|
vue.money = Number(vue.money) + Number(vue.toMoney); |
|
|
|
axios.post('/bank/store', { |
|
value: vue.bank, |
|
app: 'BlackJack', |
|
description: 'Withdrawal', |
|
amount: toMoneySave |
|
}).then(function (response) { |
|
// i'm the master of self-advertisement, speaking of advertisement? |
|
// check out the fresh servers on luna-development.net |
|
alertify.notify('Successfully got ' + toMoneySave + ' $ from your account', 'custom'); |
|
}).catch(function (error) { |
|
vue.bank = bankSave; |
|
vue.money = moneySave; |
|
|
|
alertify.notify('Error while process bank-transaction.', 'custom'); |
|
}); |
|
|
|
vue.toMoney = undefined; |
|
} else if (vue.toMoney === undefined || vue.toMoney <= 0) { |
|
return; |
|
} else { |
|
vue.toMoney = undefined; |
|
} |
|
}, |
|
|
|
bankButtonEnter(button, direction) { |
|
let vue = this; |
|
console.log('protocol: ' + direction); |
|
|
|
if (direction === 'from') { |
|
vue.transferFromBank(); |
|
} else if (direction === 'to') { |
|
vue.transferToBank(); |
|
} else { |
|
alertify.notify('Error while process bank-transaction.', 'custom'); |
|
return; |
|
} |
|
|
|
document.getElementById(button).click(); |
|
}, |
|
|
|
isMoney(number) { |
|
return new Intl.NumberFormat('de-DE', {style: 'decimal'}).format(number); |
|
}, |
|
|
|
quickBet(bet) { |
|
if (this.bet > this.money) { |
|
alertify.notify('You don\'t have enough money to do this.', 'custom'); |
|
return false; |
|
} |
|
|
|
this.bet = bet; |
|
this.startRound(); |
|
} |
|
}, |
|
created() { |
|
this.cardDeck = this.generateDeck(); |
|
this.cards = this.generateDeck(); |
|
this.shuffleDeck(); |
|
|
|
let vue = this; |
|
|
|
alertify.set('notifier', 'position', 'top-center'); |
|
vue.checkUserStatus(); |
|
|
|
let bankInterval = setInterval(function () { |
|
vue.updateBankAccount(); |
|
}, 10 * 1000); |
|
} |
|
});
|
|
|