├── img
├── 10-chip.png
├── 25-chip.png
├── 50-chip.png
├── Clubs-2.png
├── Clubs-3.png
├── Clubs-4.png
├── Clubs-5.png
├── Clubs-6.png
├── Clubs-7.png
├── Clubs-8.png
├── Clubs-9.png
├── favicon.ico
├── 100-chip.png
├── Clubs-10.png
├── Clubs-Ace.png
├── Diamond-2.png
├── Diamond-3.png
├── Diamond-4.png
├── Diamond-5.png
├── Diamond-6.png
├── Diamond-7.png
├── Diamond-8.png
├── Diamond-9.png
├── Hearts-10.png
├── Hearts-2.png
├── Hearts-3.png
├── Hearts-4.png
├── Hearts-5.png
├── Hearts-6.png
├── Hearts-7.png
├── Hearts-8.png
├── Hearts-9.png
├── Spades-10.png
├── Spades-2.png
├── Spades-3.png
├── Spades-4.png
├── Spades-5.png
├── Spades-6.png
├── Spades-7.png
├── Spades-8.png
├── Spades-9.png
├── card_back.png
├── pile-chip.png
├── Clubs-Jack.png
├── Clubs-King.png
├── Clubs-Queen.png
├── Diamond-10.png
├── Diamond-Ace.png
├── Diamond-Jack.png
├── Diamond-King.png
├── Hearts-Ace.png
├── Hearts-Jack.png
├── Hearts-King.png
├── Hearts-Queen.png
├── Spades-Ace.png
├── Spades-Jack.png
├── Spades-King.png
├── Spades-Queen.png
├── blank-chip.png
├── chip_red_top.png
├── Diamond-Queen.png
└── chip_yellow_top.png
├── css
├── keyframes.css
└── style.css
├── js
├── game-win-logic.js
├── button-actions.js
├── main.js
├── game-play-logic.js
└── cards.js
├── README.md
└── index.html
/img/10-chip.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/10-chip.png
--------------------------------------------------------------------------------
/img/25-chip.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/25-chip.png
--------------------------------------------------------------------------------
/img/50-chip.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/50-chip.png
--------------------------------------------------------------------------------
/img/Clubs-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/Clubs-2.png
--------------------------------------------------------------------------------
/img/Clubs-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/Clubs-3.png
--------------------------------------------------------------------------------
/img/Clubs-4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/Clubs-4.png
--------------------------------------------------------------------------------
/img/Clubs-5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/Clubs-5.png
--------------------------------------------------------------------------------
/img/Clubs-6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/Clubs-6.png
--------------------------------------------------------------------------------
/img/Clubs-7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/Clubs-7.png
--------------------------------------------------------------------------------
/img/Clubs-8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/Clubs-8.png
--------------------------------------------------------------------------------
/img/Clubs-9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/Clubs-9.png
--------------------------------------------------------------------------------
/img/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/favicon.ico
--------------------------------------------------------------------------------
/img/100-chip.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/100-chip.png
--------------------------------------------------------------------------------
/img/Clubs-10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/Clubs-10.png
--------------------------------------------------------------------------------
/img/Clubs-Ace.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/Clubs-Ace.png
--------------------------------------------------------------------------------
/img/Diamond-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/Diamond-2.png
--------------------------------------------------------------------------------
/img/Diamond-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/Diamond-3.png
--------------------------------------------------------------------------------
/img/Diamond-4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/Diamond-4.png
--------------------------------------------------------------------------------
/img/Diamond-5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/Diamond-5.png
--------------------------------------------------------------------------------
/img/Diamond-6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/Diamond-6.png
--------------------------------------------------------------------------------
/img/Diamond-7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/Diamond-7.png
--------------------------------------------------------------------------------
/img/Diamond-8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/Diamond-8.png
--------------------------------------------------------------------------------
/img/Diamond-9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/Diamond-9.png
--------------------------------------------------------------------------------
/img/Hearts-10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/Hearts-10.png
--------------------------------------------------------------------------------
/img/Hearts-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/Hearts-2.png
--------------------------------------------------------------------------------
/img/Hearts-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/Hearts-3.png
--------------------------------------------------------------------------------
/img/Hearts-4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/Hearts-4.png
--------------------------------------------------------------------------------
/img/Hearts-5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/Hearts-5.png
--------------------------------------------------------------------------------
/img/Hearts-6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/Hearts-6.png
--------------------------------------------------------------------------------
/img/Hearts-7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/Hearts-7.png
--------------------------------------------------------------------------------
/img/Hearts-8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/Hearts-8.png
--------------------------------------------------------------------------------
/img/Hearts-9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/Hearts-9.png
--------------------------------------------------------------------------------
/img/Spades-10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/Spades-10.png
--------------------------------------------------------------------------------
/img/Spades-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/Spades-2.png
--------------------------------------------------------------------------------
/img/Spades-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/Spades-3.png
--------------------------------------------------------------------------------
/img/Spades-4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/Spades-4.png
--------------------------------------------------------------------------------
/img/Spades-5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/Spades-5.png
--------------------------------------------------------------------------------
/img/Spades-6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/Spades-6.png
--------------------------------------------------------------------------------
/img/Spades-7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/Spades-7.png
--------------------------------------------------------------------------------
/img/Spades-8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/Spades-8.png
--------------------------------------------------------------------------------
/img/Spades-9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/Spades-9.png
--------------------------------------------------------------------------------
/img/card_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/card_back.png
--------------------------------------------------------------------------------
/img/pile-chip.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/pile-chip.png
--------------------------------------------------------------------------------
/img/Clubs-Jack.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/Clubs-Jack.png
--------------------------------------------------------------------------------
/img/Clubs-King.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/Clubs-King.png
--------------------------------------------------------------------------------
/img/Clubs-Queen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/Clubs-Queen.png
--------------------------------------------------------------------------------
/img/Diamond-10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/Diamond-10.png
--------------------------------------------------------------------------------
/img/Diamond-Ace.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/Diamond-Ace.png
--------------------------------------------------------------------------------
/img/Diamond-Jack.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/Diamond-Jack.png
--------------------------------------------------------------------------------
/img/Diamond-King.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/Diamond-King.png
--------------------------------------------------------------------------------
/img/Hearts-Ace.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/Hearts-Ace.png
--------------------------------------------------------------------------------
/img/Hearts-Jack.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/Hearts-Jack.png
--------------------------------------------------------------------------------
/img/Hearts-King.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/Hearts-King.png
--------------------------------------------------------------------------------
/img/Hearts-Queen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/Hearts-Queen.png
--------------------------------------------------------------------------------
/img/Spades-Ace.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/Spades-Ace.png
--------------------------------------------------------------------------------
/img/Spades-Jack.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/Spades-Jack.png
--------------------------------------------------------------------------------
/img/Spades-King.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/Spades-King.png
--------------------------------------------------------------------------------
/img/Spades-Queen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/Spades-Queen.png
--------------------------------------------------------------------------------
/img/blank-chip.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/blank-chip.png
--------------------------------------------------------------------------------
/img/chip_red_top.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/chip_red_top.png
--------------------------------------------------------------------------------
/img/Diamond-Queen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/Diamond-Queen.png
--------------------------------------------------------------------------------
/img/chip_yellow_top.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacquelynmarcella/blackjack/HEAD/img/chip_yellow_top.png
--------------------------------------------------------------------------------
/css/keyframes.css:
--------------------------------------------------------------------------------
1 | /* Animations for card dealing based on location */
2 | /* TO DO: Add webkit keyframes also */
3 |
4 | @keyframes deal-player {
5 | 0% {
6 | transform: translate(-90px, -150px);
7 | }
8 | 50% {
9 | transform: translate(-50px, -50px);
10 | }
11 | 100% {
12 | transform: translate(0, 0);
13 | }
14 | }
15 |
16 | @keyframes deal-player-split {
17 | 0% {
18 | transform: translate(-90px, -450px);
19 | }
20 | 50% {
21 | transform: translate(-50px, -150px);
22 | }
23 | 100% {
24 | transform: translate(0, 0);
25 | }
26 | }
27 |
28 | @keyframes deal-dealer {
29 | 0% {
30 | transform: translate(-100px, 0px);
31 | }
32 | 50% {
33 | transform: translate(-50px, 0px);
34 | }
35 | 100% {
36 | transform: translate(0, 0);
37 | }
38 | }
39 |
40 | @keyframes dealer-cardflip {
41 | 0% {
42 | transform: rotateY(25deg);
43 | }
44 | 50% {
45 | transform: rotateY(100deg);
46 | }
47 | 100% {
48 | transform: none;
49 | }
50 | }
51 |
52 |
53 | /* Card animations called using keyframes */
54 | /* Animation angle different for each */
55 | #dealer .card {
56 | animation: deal-dealer .25s linear;
57 | }
58 |
59 | #user-hand .card {
60 | animation: deal-player .5s linear;
61 | }
62 |
63 | #user-split-hand .card {
64 | animation: deal-player-split .5s linear;
65 | }
66 |
67 | #dealer .card.flipped {
68 | animation: dealer-cardflip .25s linear;
69 | }
--------------------------------------------------------------------------------
/js/game-win-logic.js:
--------------------------------------------------------------------------------
1 | // This file contains logic for what happens after the round is determined to be over
2 |
3 | function gameOver() {
4 | isGameOver = true;
5 | setTimeout(function(){
6 | flipHiddenCard();
7 | }, 750);
8 | disableButton(standButton);
9 | disableButton(hitButton);
10 | disableButton(splitButton);
11 | disableButton(doubleDownButton);
12 | if (dealerHandTotal === 21) {
13 | if (playerHandTotal === 21 || playerSplitHandTotal === 21) {
14 | gameWinner = "tie";
15 | } else {
16 | gameWinner = "dealer";
17 | }
18 | } else if (dealerHandTotal > 21) {
19 | if (playerHandTotal <= 21) {
20 | gameWinner = "player";
21 | } else if (splitGame === true && playerSplitHandTotal <= 21) {
22 | gameWinner = "player";
23 | } else {
24 | gameWinner = "tie";
25 | }
26 | } else if (dealerHandTotal < 21) {
27 | if (playerHandTotal === 21 || playerSplitHandTotal === 21) {
28 | gameWinner = "player";
29 | } else if (playerHandTotal < 21 && playerHandTotal > dealerHandTotal) {
30 | gameWinner = "player";
31 | } else if (playerSplitHandTotal < 21 && playerSplitHandTotal > dealerHandTotal) {
32 | gameWinner = "player";
33 | } else if (playerSplitHandTotal < 21 && playerSplitHandTotal === dealerHandTotal ||
34 | playerHandTotal < 21 && playerHandTotal === dealerHandTotal) {
35 | gameWinner = "tie";
36 | } else {
37 | gameWinner = "dealer";
38 | }
39 | }
40 | updateChipBalance();
41 | setTimeout(announceWinner, 2500); // Slight delay to give time to see the final cards play out
42 | }
43 |
44 | function updateChipBalance() {
45 | if (gameWinner === "player") {
46 | // Blackjack is 3:2 payout (and cannot occur on a split deck):
47 | if (splitGame === false && playerHasAce === true && playerHandTotal === 21 && playerHand.length === 2) {
48 | currentChipBalance += currentWager*(3/2) + currentWager;
49 | // Otherwise it's a 1:1 payout:
50 | } else {
51 | currentChipBalance += currentWager*2;
52 | }
53 | // If you tie, get just original wager back (no win or loss)
54 | } else if (gameWinner === "tie") {
55 | currentChipBalance += currentWager;
56 | }
57 | // Note: if dealer wins, nothing happens to player chip balance as their wager was already removed from it
58 | updateVisibleChipBalances();
59 | }
60 |
61 | function announceWinner() {
62 | updateVisibleHandTotals();
63 | currentWager = 0;
64 | updateVisibleChipBalances();
65 | $("#game-board").hide();
66 | enlargeDeck(playerSplitGameBoard, playerSplitHandTotalDisplay);
67 | enlargeDeck(playerGameBoard, playerHandTotalDisplay);
68 |
69 | // Move betting options from welcome screen to game over screen to play again
70 | $("#wager-options").appendTo($("#game-over"));
71 | $(playAgainButton).appendTo($("#wager-options")); // to move to bottom of container
72 | $(startButton).hide();
73 | $("#game-over").show("drop", 500);
74 |
75 | if (gameWinner === "player") {
76 | $("#game-outcome").text("You won");
77 | } else if (gameWinner === "dealer") {
78 | $("#game-outcome").text("Dealer won");
79 | } else if (gameWinner === "tie") {
80 | $("#game-outcome").text("You tied");
81 | }
82 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # :spades: blackjack
2 | https://jacquelynmarcella.github.io/blackjack/
3 |
4 | A JavaScript based Blackjack game. Beat the dealer by getting as close to 21 without going over.
5 |
6 | 
7 | 
8 |
9 | ## :diamonds: Requirements
10 | * Game is playable against dealer
11 | * Game is winnable and winner is displayed
12 | * Game has directions on how to play
13 | * Appropriate Use of GitHub and deployed on Github Pages
14 | * Long files appropriately split up
15 | * Appropriate use of functions
16 | * DRY Code
17 | * Draw detected (if applicable)
18 | * Good ease of triggering events
19 |
20 | ## :diamonds: Technologies Used
21 | * jQuery + jQuery UI
22 | * Materialize CSS Framework
23 |
24 | ## :diamonds: Process
25 | 1. Stubbed out overall game board structure and integrated initial card data.
26 | * Plotted out rules, dealer/player decks, hand totals, and key action buttons.
27 | * Installed Materialize framework and created grid system, which I utilized throughout the whole project to routinely check for how the integrated content was scaling smaller screen sizes.
28 | * Created cards.js file to store full deck of cards including images, value, and name.
29 | 1. Generated start game functionality to get the cards on the board.
30 | * Randomly sort the array to "shuffle" the deck.
31 | * Loop through the original deck and push/pop cards into both the dealer and player hands.
32 | * Display these card images on the appropriate sections of the screen.
33 | 1. Developed initial player interaction fuctionality ("hit" and "stand").
34 | 1. Built out dealer logic.
35 | * Dealer's actions are based on standard blackjack rules (hit if under 17, stand if 17 or above).
36 | 1. Created win logic and detection for aces.
37 | * Aces can hold values of either 11 or 1.
38 | * Default value for aces is 11, however, if the user goes over 21 the aces will reduce to 1.
39 | * Got initial working win logic up, which was adjusted several times.
40 | 1. Added in chip betting functionality and ongoing chip balance total tracking.
41 | * Added in double down functionality once the betting process was up and running.
42 | 1. Added split card functionality (required a lot of reworking of win logic and player interactions since there are now 2 decks).
43 | 1. Worked through automated turn switching functionality to keep the game moving if the player goes over 21 on their current deck (without them needing to press "stand").
44 | 1. Worked on an announce winner screen that shows who won, current chip balance, and final hand totals.
45 | * Implemented play again button to reset card deck values and start a new game.
46 | 1. Added ability to toggle in/out rules section using jQuery UI plugin.
47 | 1. Implemented CSS animations and transitions using keyframes to make the card game feel more interactive.
48 | * Dealer's second card appears to flip over when it is eventually displayed.
49 | * Cards move in on the screen and appear to be coming out of the deck.
50 | * Got cards to dynamically stack using offset properties as they are added in the JavaScript.
51 | * If the deck is split, the inactive deck scales down to both signify to the user what deck they are currently on, as well as make room on the page to fit both decks. When the user moves onto the second deck, the first deck scales down and the second deck scales up.
52 | * Set timeouts regularly to give a chance for these animations to complete before moving on to the next move.
53 | 1. Added modal for the rare chance that a player draws 2 aces - they need to be able to choose to split or not before the game automatically reduces their aces to value 1.
54 | 1. Further adjusted and tested layout for responsiveness using the Materialize framework.
55 | 1. Added local storage to chip balance.
56 |
57 | ## :diamonds: Next Steps
58 | * Further test the double ace drawing scenario to ensure it is working consistently.
59 |
60 | ## :diamonds: Resources Used
61 | * CSS Framework: http://materializecss.com/
62 | * Card Deck Graphics: https://opengameart.org/content/cards-set
63 | * Chip Icons:
64 | * https://thenounproject.com/dorxela/
65 | * https://thenounproject.com/meisandra0583/
66 |
--------------------------------------------------------------------------------
/js/button-actions.js:
--------------------------------------------------------------------------------
1 | // This file contains key interactions that will occur after the player has clicked a button
2 |
3 | var startGame = function() {
4 | getCards();
5 | if (currentWager === 0) {
6 | Materialize.toast("You must select a bet to play", 1000);
7 | } else if (currentChipBalance < 10) {
8 | Materialize.toast("You're out of chips! Reset the game to continue" , 2000);
9 | } else if (currentChipBalance < currentWager) {
10 | Materialize.toast("Insufficient chip balance, please select a lower bet" , 1500);
11 | } else {
12 | currentChipBalance -= currentWager;
13 | updateVisibleChipBalances();
14 | $("#welcome").hide();
15 | $("#game-over").hide();
16 | $(".brand-logo").text("blackjack");
17 | $("#game-board").show("fade", 1000);
18 | cardsInDeck = cards;
19 | cardsInDeck.sort(function() {return 0.5 - Math.random()});
20 | for (let i = 0; i <= 1; i++) {
21 | setTimeout(function(){
22 | currentTurn = "player";
23 | dealCard(playerHand, playerGameBoard);
24 | currentTurn = "dealer";
25 | dealCard(dealerHand, dealerGameBoard);
26 | }, i*1500);
27 | }
28 | setTimeout(function(){
29 | currentTurn = "player";
30 | if (playerHand.length === 2 && playerHand[0].name === playerHand[1].name) {
31 | enableButton(splitButton, split);
32 | }
33 | }, 2500);
34 |
35 | }
36 | }
37 |
38 | var hit = function() {
39 | if (currentTurn === "player") {
40 | playerStatus = "hit";
41 | dealCard(playerHand, playerGameBoard);
42 | } else if (currentTurn === "playerSplit") {
43 | playerSplitStatus = "hit";
44 | dealCard(playerSplitHand, playerSplitGameBoard);
45 | }
46 | }
47 |
48 | var stand = function() {
49 | if (currentTurn === "player") {
50 | changeHand(playerStatus);
51 | } else if (currentTurn === "playerSplit") {
52 | changeHand(playerSplitStatus);
53 | }
54 | }
55 |
56 | var split = function() {
57 | splitGame = true;
58 | playerHandTotal = playerHandTotal - playerHand[1].value;
59 | playerSplitHandTotal = playerHand[1].value;
60 | updateVisibleHandTotals();
61 | $(".split-hand-total").removeClass("inactive").show();
62 | $(playerSplitGameBoard).removeClass("inactive").show();
63 | var splitCard = playerHand.pop();
64 | playerSplitHand.push(splitCard);
65 | var cardImage = $("#player-card-1").attr("id", "playerSplit-card-0");
66 |
67 | cardImage.hide(); // Hide it at first to allow for the transition to occur
68 | // This is the first card in the deck, so want to cancel out the previous offset/stacking and have it go to the initial normal spot
69 | cardImage.appendTo($(playerSplitGameBoard)).offset({left: 60}).css("margin-right", "auto").show();
70 |
71 | currentChipBalance -= currentWager;
72 | currentWager = currentWager * 2;
73 | updateVisibleChipBalances();
74 |
75 | // Then, deal 1 new card for each newly split deck
76 | currentTurn = "player";
77 | dealCard(playerHand, playerGameBoard);
78 | currentTurn = "playerSplit";
79 | dealCard(playerSplitHand, playerSplitGameBoard);
80 |
81 | // Make split button no longer clickable as in this game you can only split once
82 | disableButton(splitButton);
83 |
84 | // Shrink the inactive deck to both signal what deck they are playing and to make room on the board
85 | setTimeout(function(){
86 | scaleDownDeck(playerSplitGameBoard, playerSplitHandTotalDisplay);
87 | currentTurn = "player";
88 | }, 1000);
89 |
90 | }
91 |
92 | function doubleDown() {
93 | if (currentChipBalance - currentWager <= 0) {
94 | Materialize.toast("Insufficient chip balance" , 1000);
95 | }
96 | else {
97 | currentChipBalance -= currentWager; //subtracts the same value again from current balance
98 | currentWager = currentWager * 2;
99 | updateVisibleChipBalances();
100 | disableButton(doubleDownButton);
101 | }
102 | }
103 |
104 | function newGame() {
105 | getCards();
106 | cardsInDeck = cards;
107 | gameWinner = "none";
108 | dealerHand = [];
109 | dealerHandTotal = 0;
110 | dealerStatus = "start";
111 | playerHand = [];
112 | playerHandTotal = 0;
113 | playerStatus = "start";
114 | playerHasAce = false;
115 | splitGame = false;
116 | isGameOver = false;
117 | playerSplitHand = [];
118 | playerSplitHandTotal = 0;
119 | playerSplitStatus = "start";
120 |
121 | if (currentWager === 0) {
122 | Materialize.toast("You must select a bet to play", 1000);
123 | } else {
124 | $(playerSplitGameBoard).hide();
125 | $(".split-hand-total").hide();
126 | enableButton(standButton, stand);
127 | enableButton(hitButton, hit);
128 | enableButton(doubleDownButton, doubleDown);
129 | dealerGameBoard.empty();
130 | playerGameBoard.empty();
131 | playerSplitGameBoard.empty();
132 | updateVisibleHandTotals();
133 | startGame();
134 | }
135 | }
136 |
137 | function resetGame() {
138 | currentWager = 0;
139 | currentChipBalance = 500;
140 | updateVisibleChipBalances();
141 | location.reload();
142 | }
--------------------------------------------------------------------------------
/js/main.js:
--------------------------------------------------------------------------------
1 | // Starting game board values
2 | var cardsInDeck;
3 |
4 | $( document ).ready(function() {
5 | getCards();
6 | cardsInDeck = cards;
7 | updateVisibleChipBalances();
8 | });
9 |
10 | var currentTurn = "player";
11 | var currentWager = 0;
12 | var currentChipBalance = localStorage.getItem('blackjackChips') || 500;
13 | var gameWinner = "none"; // To be declared at end of game
14 | var isGameOver = false;
15 |
16 | // Dealer hand and starting totals
17 | var dealerHand = [];
18 | var dealerHandTotal = 0;
19 | var dealerGameBoard = $("#dealer");
20 | var dealerStatus = "start"; // Possible statuses are start (initial gameplay), stand, hit
21 |
22 | // Player hand and starting totals
23 | var playerHand = [];
24 | var playerHandTotal = 0;
25 | var playerGameBoard = $("#user-hand");
26 | var playerHandTotalDisplay = $(".hand-total");
27 | var playerStatus = "start"; // Possible statuses are start (initial gameplay), stand, hit
28 |
29 | // Because aces can equal 1 or 11, need to quickly know if player has aces so we can
30 | // adjust value from 11 to 1 if they go over 21 (default value is 11)
31 | var playerHasAce = false;
32 |
33 | // Player split game variables only used if the player splits their hand
34 | var splitGame = false; // default value is false, must be turned true
35 | var playerSplitHand = [];
36 | var playerSplitHandTotal = 0;
37 | var playerSplitGameBoard = $("#user-split-hand");
38 | var playerSplitHandTotalDisplay = $(".split-hand-total");
39 | var playerSplitStatus;
40 |
41 | // Buttons pulled from DOM
42 | var startButton = $("#start-game-button");
43 | var doubleDownButton = $("#double-down-button");
44 | var hitButton = $("#hit-button");
45 | var standButton = $("#stand-button");
46 | var splitButton = $(".split-button");
47 | var playAgainButton = $(".new-game-button");
48 |
49 | // Deactivates a button (both event listener and appearance)
50 | function disableButton(buttonName) {
51 | $(buttonName).off();
52 | $(buttonName).addClass("disabled-button");
53 | }
54 |
55 | // Activates a button (both event listener and appearance)
56 | function enableButton(buttonName, event) {
57 | $(buttonName).click(event);
58 | $(buttonName).removeClass("disabled-button");
59 | }
60 |
61 | // Update chip totals displayed to user throughout the game
62 | function updateVisibleChipBalances() {
63 | $(".current-wager").text(currentWager);
64 | $(".current-chip-balance").text(currentChipBalance);
65 | localStorage.setItem('blackjackChips', currentChipBalance);
66 | }
67 |
68 | // Update card hand totals displayed to user throughout the game
69 | function updateVisibleHandTotals() {
70 | $(playerHandTotalDisplay).text(playerHandTotal);
71 | $(playerSplitHandTotalDisplay).text(playerSplitHandTotal);
72 |
73 | // If the dealer has not played yet or game is not over, only show value of 1st card
74 | // as the player is still making their initial moves
75 | if (dealerHand.length === 2 && isGameOver === false && dealerStatus === "start") {
76 | $(".dealer-hand-total").text(dealerHandTotal - dealerHand[1].value);
77 | } else {
78 | $(".dealer-hand-total").text(dealerHandTotal);
79 | }
80 |
81 | }
82 |
83 | // Called when player clicks on a chip
84 | function selectWager(amount){
85 | currentWager = amount;
86 | updateVisibleChipBalances();
87 | }
88 |
89 | // ANIMATIONS/INTERACTIVITY:
90 | function flipHiddenCard() {
91 | // If it's just the initial round, first we need to flip/reveal the hidden dealer card when this is called
92 | if (dealerHand.length === 2) {
93 | $("#dealer-card-1").addClass("flipped");
94 | setTimeout(function(){
95 | $("#dealer-card-1").attr("src", "img/" + dealerHand[1].src);
96 | updateVisibleHandTotals();
97 | }, 250);
98 | }
99 | }
100 |
101 | // Used in split game mode, shrinks the inactive deck and totals
102 | function scaleDownDeck(deck, totalDisplay) {
103 | $(totalDisplay).addClass("splithand-scaledown");
104 | $(deck).addClass("splithand-scaledown");
105 | }
106 |
107 | // Used in split game mode, enlarges the deck and totals when turn active or when
108 | // dome with gameplay
109 | function enlargeDeck(deck, totalDisplay) {
110 | $(totalDisplay).removeClass("splithand-scaledown");
111 | $(deck).removeClass("splithand-scaledown");
112 | }
113 |
114 | // Toggling rules from main nav gives an animation effect
115 | $(".rules-nav").click(function(){
116 | $("#rules").toggle("blind", 500);
117 | });
118 |
119 | // But clicking close does not provide an animation effect
120 | $("#rules-close").click(function(){
121 | $("#rules").hide();
122 | });
123 |
124 | // Materialize modal
125 | $(".modal").modal({
126 | dismissible: false,
127 | opacity: .40,
128 | inDuration: 300,
129 | outDuration: 200,
130 | startingTop: "10%", // Starting top style attribute
131 | endingTop: "10%", // Ending top style attribute
132 | }
133 | );
134 |
135 | // EVENT LISTENERS:
136 | $("#chip-10").click(function(){selectWager(10)});
137 | $("#chip-25").click(function(){selectWager(25)});
138 | $("#chip-50").click(function(){selectWager(50)});
139 | $("#chip-100").click(function(){selectWager(100)});
140 |
141 | // Button activation
142 | $(startButton).click(startGame);
143 | $(doubleDownButton).click(doubleDown);
144 | $(hitButton).click(hit);
145 | $(standButton).click(stand);
146 | $(playAgainButton).click(newGame);
147 | $("#reset-game").click(resetGame);
148 |
149 | $(".reduce-aces-button").click( // Can only see this if player draws 2 aces, would only be reducing in 1st deck
150 | function(){
151 | reduceAcesValue(playerHand);
152 | disableButton(splitButton, split);
153 | });
154 |
--------------------------------------------------------------------------------
/js/game-play-logic.js:
--------------------------------------------------------------------------------
1 | // This file contains the main logic utilized during active gameplay, before the game is declared over
2 |
3 | function dealCard(hand, location) {
4 | var cardDrawn = cardsInDeck.pop();
5 | hand.push(cardDrawn);
6 | var index = hand.length - 1;
7 |
8 | // Create card image for card, hide initially so it doesn't impact transition
9 | var cardImage = $("").attr("class", "card").attr("src", "img/" + hand[index].src).hide();
10 | cardImage.attr("id", currentTurn + "-card-" + index);
11 |
12 | // To create stacked card effect
13 | if (index === 0) {
14 | cardImage.appendTo($(location)).show();
15 | } else if (index > 0) {
16 | cardImage.appendTo($(location)).offset({left: -60}).css("margin-right", -60).show();
17 | }
18 | if (hand[index].name === "ace" && currentTurn != "dealer") {
19 | playerHasAce = true;
20 | }
21 | // Note: tried to dry this out by putting totals as a param but couldn't get it working yet
22 | if (currentTurn === "player") {
23 | playerHandTotal += hand[index].value;
24 | } else if (currentTurn === "playerSplit") {
25 | playerSplitHandTotal += hand[index].value;
26 | } else if (currentTurn === "dealer") {
27 | dealerHandTotal += hand[index].value;
28 | }
29 | // Second card only for dealer should show face down
30 | if (dealerHand.length === 2 && currentTurn === "dealer") {
31 | cardImage.attr("src", "img/card_back.png");
32 | }
33 | updateVisibleHandTotals();
34 | evaluateGameStatus();
35 | }
36 |
37 | function evaluateGameStatus() {
38 | // Player can only split or double down after first 2 cards drawn
39 | if (playerHand.length === 3 || dealerStatus === "hit") {
40 | disableButton(doubleDownButton);
41 | disableButton(splitButton);
42 | }
43 | if (currentTurn != "dealer") {
44 | if (playerHasAce === true) {
45 | if (currentTurn === "player") { // Dry out by having params in here
46 | reviewAcesValue(playerHand, playerHandTotal);
47 | } else if (currentTurn === "playerSplit") {
48 | reviewAcesValue(playerSplitHand, playerSplitHandTotal);
49 | }
50 | } else {
51 | isPlayerDone();
52 | }
53 | }
54 | if (currentTurn === "dealer" && dealerStatus === "hit") {
55 | dealerPlay();
56 | }
57 | }
58 |
59 |
60 | // The purpose of this function is to detect when a turn should be shifted without the player
61 | // needing to click "stand". This is also an important step for determining what the next move
62 | // is if there is a split deck.
63 | function isPlayerDone() {
64 | if (splitGame === false && playerHandTotal >= 21) {
65 | gameOver();
66 | } else if (splitGame === true) {
67 | if (currentTurn === "player") {
68 | if (playerHandTotal === 21) {
69 | gameOver();
70 | // If it's a split game, we can't just game over on the first hand if the player goes over
71 | } else if (playerHandTotal > 21)
72 | changeHand(playerStatus);
73 | } else if (currentTurn === "playerSplit") {
74 | if (playerSplitHandTotal === 21) {
75 | gameOver();
76 | } else if (playerSplitHandTotal > 21) {
77 | // If the player was under 21 in their first game, the dealer should play before gameover
78 | if (playerHandTotal < 21) {
79 | changeHand(playerSplitStatus);
80 | } else {
81 | gameOver();
82 | }
83 | }
84 | }
85 | }
86 | }
87 |
88 | function changeHand(currentDeckStatus) {
89 | currentDeckStatus = "stand";
90 | if (currentTurn === "player") {
91 | if (splitGame === true) {
92 | currentTurn = "playerSplit";
93 | // Scale down the player deck as we change turns, but only on split hand
94 | scaleDownDeck(playerGameBoard, playerHandTotalDisplay);
95 | enlargeDeck(playerSplitGameBoard, playerSplitHandTotalDisplay);
96 | } else if (splitGame === false) {
97 | currentTurn = "dealer";
98 | dealerStatus = "hit";
99 | }
100 | } else if (currentTurn === "playerSplit") {
101 | currentTurn = "dealer";
102 | dealerStatus = "hit";
103 | }
104 | evaluateGameStatus();
105 | }
106 |
107 | function reviewAcesValue(hand, total) {
108 | if (total > 21) {
109 | // If they have exactly 2 aces in the first draw, prompt them to choose to split or not
110 | if (hand.length === 2) {
111 | enableButton(splitButton, split);
112 | $("#two-aces-prompt").modal("open");
113 | // Otherwise, just reduce the aces value so they are no longer over 21
114 | } else if (hand.length > 2) {
115 | reduceAcesValue(hand);
116 | isPlayerDone();
117 | }
118 | } else {
119 | isPlayerDone();
120 | }
121 | }
122 |
123 | function reduceAcesValue(deck) {
124 | for (var i = 0; i < deck.length; i++) {
125 | if (deck[i].name === "ace" && deck[i].value === 11) { // Only focusing on aces that haven't been changed from 11 to 1 already
126 | deck[i].value = 1;
127 | if (currentTurn === "player") {
128 | playerHandTotal -= 10;
129 | } else if (currentTurn === "playerSplit") {
130 | playerSplitHandTotal -= 10;
131 | }
132 | updateVisibleHandTotals();
133 | Materialize.toast("Your ace value changed from 11 to 1", 1500);
134 | }
135 | }
136 | }
137 |
138 | function dealerPlay() {
139 | flipHiddenCard();
140 | disableButton(standButton);
141 | disableButton(hitButton);
142 | disableButton(splitButton);
143 | // The below logic is based on standard blackjack rules
144 | if (dealerHandTotal < 17) {
145 | setTimeout(function(){
146 | dealCard(dealerHand, dealerGameBoard);
147 | }, 1000);
148 | } else if (dealerHandTotal >= 21) {
149 | setTimeout(function(){
150 | gameOver();
151 | }, 1100);
152 | } else if (dealerHandTotal >= 17) {
153 | setTimeout(function(){
154 | dealerStatus = "stand";
155 | gameOver();
156 | }, 1100);
157 | }
158 | }
--------------------------------------------------------------------------------
/js/cards.js:
--------------------------------------------------------------------------------
1 | //Full array of possible cards
2 | var cards;
3 |
4 | function getCards(){
5 | cards = [
6 | {
7 | "suit": "clubs",
8 | "name": "2",
9 | "src": "Clubs-2.png",
10 | "value": 2
11 | },
12 | {
13 | "suit": "clubs",
14 | "name": "3",
15 | "src": "Clubs-3.png",
16 | "value": 3
17 | },
18 | {
19 | "suit": "clubs",
20 | "name": "4",
21 | "src": "Clubs-4.png",
22 | "value": 4
23 | },
24 | {
25 | "suit": "clubs",
26 | "name": "5",
27 | "src": "Clubs-5.png",
28 | "value": 5
29 | },
30 | {
31 | "suit": "clubs",
32 | "name": "6",
33 | "src": "Clubs-6.png",
34 | "value": 6
35 | },
36 | {
37 | "suit": "clubs",
38 | "name": "7",
39 | "src": "Clubs-7.png",
40 | "value": 7
41 | },
42 | {
43 | "suit": "clubs",
44 | "name": "8",
45 | "src": "Clubs-8.png",
46 | "value": 8
47 | },
48 | {
49 | "suit": "clubs",
50 | "name": "9",
51 | "src": "Clubs-9.png",
52 | "value": 9
53 | },
54 | {
55 | "suit": "clubs",
56 | "name": "10",
57 | "src": "Clubs-10.png",
58 | "value": 10
59 | },
60 | {
61 | "suit": "clubs",
62 | "name": "ace",
63 | "src": "Clubs-Ace.png",
64 | "value": 11
65 | },
66 | {
67 | "suit": "clubs",
68 | "name": "jack",
69 | "src": "Clubs-Jack.png",
70 | "value": 10
71 | },
72 | {
73 | "suit": "clubs",
74 | "name": "king",
75 | "src": "Clubs-King.png",
76 | "value": 10
77 | },
78 | {
79 | "suit": "clubs",
80 | "name": "queen",
81 | "src": "Clubs-Queen.png",
82 | "value": 10
83 | },
84 | {
85 | "suit": "diamonds",
86 | "name": "2",
87 | "src": "Diamond-2.png",
88 | "value": 2
89 | },
90 | {
91 | "suit": "diamonds",
92 | "name": "3",
93 | "src": "Diamond-3.png",
94 | "value": 3
95 | },
96 | {
97 | "suit": "diamonds",
98 | "name": "4",
99 | "src": "Diamond-4.png",
100 | "value": 4
101 | },
102 | {
103 | "suit": "diamonds",
104 | "name": "5",
105 | "src": "Diamond-5.png",
106 | "value": 5
107 | },
108 | {
109 | "suit": "diamonds",
110 | "name": "6",
111 | "src": "Diamond-6.png",
112 | "value": 6
113 | },
114 | {
115 | "suit": "diamonds",
116 | "name": "7",
117 | "src": "Diamond-7.png",
118 | "value": 7
119 | },
120 | {
121 | "suit": "diamonds",
122 | "name": "8",
123 | "src": "Diamond-8.png",
124 | "value": 8
125 | },
126 | {
127 | "suit": "diamonds",
128 | "name": "9",
129 | "src": "Diamond-9.png",
130 | "value": 9
131 | },
132 | {
133 | "suit": "diamonds",
134 | "name": "10",
135 | "src": "Diamond-10.png",
136 | "value": 10
137 | },
138 | {
139 | "suit": "diamonds",
140 | "name": "ace",
141 | "src": "Diamond-Ace.png",
142 | "value": 11
143 | },
144 | {
145 | "suit": "diamonds",
146 | "name": "jack",
147 | "src": "Diamond-Jack.png",
148 | "value": 10
149 | },
150 | {
151 | "suit": "diamonds",
152 | "name": "king",
153 | "src": "Diamond-King.png",
154 | "value": 10
155 | },
156 | {
157 | "suit": "diamonds",
158 | "name": "queen",
159 | "src": "Diamond-Queen.png",
160 | "value": 10
161 | },
162 | {
163 | "suit": "hearts",
164 | "name": "2",
165 | "src": "Hearts-2.png",
166 | "value": 2
167 | },
168 | {
169 | "suit": "hearts",
170 | "name": "3",
171 | "src": "Hearts-3.png",
172 | "value": 3
173 | },
174 | {
175 | "suit": "hearts",
176 | "name": "4",
177 | "src": "Hearts-4.png",
178 | "value": 4
179 | },
180 | {
181 | "suit": "hearts",
182 | "name": "5",
183 | "src": "Hearts-5.png",
184 | "value": 5
185 | },
186 | {
187 | "suit": "hearts",
188 | "name": "6",
189 | "src": "Hearts-6.png",
190 | "value": 6
191 | },
192 | {
193 | "suit": "hearts",
194 | "name": "7",
195 | "src": "Hearts-7.png",
196 | "value": 7
197 | },
198 | {
199 | "suit": "hearts",
200 | "name": "8",
201 | "src": "Hearts-8.png",
202 | "value": 8
203 | },
204 | {
205 | "suit": "hearts",
206 | "name": "9",
207 | "src": "Hearts-9.png",
208 | "value": 9
209 | },
210 | {
211 | "suit": "hearts",
212 | "name": "10",
213 | "src": "Hearts-10.png",
214 | "value": 10
215 | },
216 | {
217 | "suit": "hearts",
218 | "name": "ace",
219 | "src": "Hearts-Ace.png",
220 | "value": 11
221 | },
222 | {
223 | "suit": "hearts",
224 | "name": "jack",
225 | "src": "Hearts-Jack.png",
226 | "value": 10
227 | },
228 | {
229 | "suit": "hearts",
230 | "name": "king",
231 | "src": "Hearts-King.png",
232 | "value": 10
233 | },
234 | {
235 | "suit": "hearts",
236 | "name": "queen",
237 | "src": "Hearts-Queen.png",
238 | "value": 10
239 | },
240 | {
241 | "suit": "spades",
242 | "name": "2",
243 | "src": "Spades-2.png",
244 | "value": 2
245 | },
246 | {
247 | "suit": "spades",
248 | "name": "3",
249 | "src": "Spades-3.png",
250 | "value": 3
251 | },
252 | {
253 | "suit": "spades",
254 | "name": "4",
255 | "src": "Spades-4.png",
256 | "value": 4
257 | },
258 | {
259 | "suit": "spades",
260 | "name": "5",
261 | "src": "Spades-5.png",
262 | "value": 5
263 | },
264 | {
265 | "suit": "spades",
266 | "name": "6",
267 | "src": "Spades-6.png",
268 | "value": 6
269 | },
270 | {
271 | "suit": "spades",
272 | "name": "7",
273 | "src": "Spades-7.png",
274 | "value": 7
275 | },
276 | {
277 | "suit": "spades",
278 | "name": "8",
279 | "src": "Spades-8.png",
280 | "value": 8
281 | },
282 | {
283 | "suit": "spades",
284 | "name": "9",
285 | "src": "Spades-9.png",
286 | "value": 9
287 | },
288 | {
289 | "suit": "spades",
290 | "name": "10",
291 | "src": "Spades-10.png",
292 | "value": 10
293 | },
294 | {
295 | "suit": "spades",
296 | "name": "ace",
297 | "src": "Spades-Ace.png",
298 | "value": 11
299 | },
300 | {
301 | "suit": "spades",
302 | "name": "jack",
303 | "src": "Spades-Jack.png",
304 | "value": 10
305 | },
306 | {
307 | "suit": "spades",
308 | "name": "king",
309 | "src": "Spades-King.png",
310 | "value": 10
311 | },
312 | {
313 | "suit": "spades",
314 | "name": "queen",
315 | "src": "Spades-Queen.png",
316 | "value": 10
317 | }
318 | ]
319 | }
320 |
--------------------------------------------------------------------------------
/css/style.css:
--------------------------------------------------------------------------------
1 | /* Broad site-wide styles */
2 | body {
3 | background: #1f513b;
4 | background: linear-gradient(to top right, #1f513b, #0F2725) fixed;
5 | text-align: center;
6 | font-family: 'Lato', sans-serif;
7 | color: white;
8 | }
9 |
10 | h1, h2, h3, h4, h5, .brand-logo {
11 | font-family: 'Arvo', serif;
12 | }
13 |
14 | h1 {
15 | font-size: 4em;
16 | }
17 |
18 | h4 {
19 | font-size: 1.75em;
20 | }
21 |
22 | p {
23 | font-size: 1.25em;
24 | line-height: 1.75em;
25 | }
26 |
27 | strong {
28 | font-family: 'Arvo', serif;
29 | padding: 4px 0;
30 | display: block;
31 | font-size: 1.10em;
32 | }
33 |
34 |
35 | button, button:focus {
36 | margin: 5px;
37 | padding: 10px 20px;
38 | background: #d60438;
39 | color: white;
40 | font-size: 1.25em;
41 | font-weight: 400;
42 | letter-spacing: 1px;
43 | border: 0;
44 | }
45 |
46 | button.secondary {
47 | background: #1E6692;
48 | }
49 |
50 | button:active {
51 | background: black;
52 | }
53 |
54 | button.disabled-button, button.secondary.disabled-button {
55 | background: #0F2725;
56 | }
57 |
58 | /* Welcome screen */
59 | #welcome p {
60 | width: 50%;
61 | margin: 10px auto;
62 | }
63 |
64 | /* Rules section hidden at start and can toggle in from above */
65 | #rules {
66 | padding: 30px 20px 20px 20px;
67 | /* margin: 20px auto 30px auto;*/
68 | text-align: left;
69 | display: none;
70 | background: #0F2725;
71 | position: absolute;
72 | top: 55px;
73 | right: 0;
74 | width: 100%;
75 | z-index: 99;
76 | font-size: .75em;
77 | }
78 |
79 | #rules button {
80 | float: right;
81 | margin-right: 20px;
82 | }
83 |
84 | #rules h4 {
85 | text-align: center;
86 | }
87 |
88 | /* Card decks during gameplay */
89 |
90 | #deck-pile, #dealer, #user-hand, #user-split-hand {
91 | display: inline-block;
92 | position: relative;
93 | }
94 |
95 | .card {
96 | transition: all 3s;
97 | display: inline-block;
98 | background-color: none !important;
99 | border-radius: 12.5px;
100 | outline-offset: -6px;
101 | outline: 6px solid white;
102 | box-shadow: -3px 4px rgba(15, 39, 37, .25);
103 | }
104 |
105 | .card:hover {
106 | z-index: 100;
107 | }
108 |
109 | .pile {
110 | margin-right: 30px;
111 | }
112 |
113 | /* Chips and wagers */
114 |
115 | .wager {
116 | height: 60px;
117 | width: 60px;
118 | margin: 2px;
119 | display: inline-block;
120 | }
121 |
122 | .wager-clickable {
123 | margin: 15px 2px;
124 | }
125 |
126 | .wager-clickable:hover {
127 | transform: scale(1.10);
128 | }
129 |
130 | /* For bet screen where the supporting icons don't need to be full size */
131 | .wager-small {
132 | margin-left: 30px;
133 | margin-right: 10px;
134 | height: 40px;
135 | width: 40px;
136 | }
137 |
138 | /*For when user is choosing what their bet is */
139 | #wager-options {
140 | margin: 15px auto 5px auto;
141 | }
142 |
143 | #wager-options span {
144 | display: inline-block;
145 | margin: 20px auto;
146 | font-size: 2em;
147 | line-height: 1.5em;
148 | position: relative;
149 | bottom: 10px;
150 | }
151 |
152 | /* For displaying during the game */
153 | .wager-gameplay {
154 | font-size: 2.5em;
155 | position: relative;
156 | top: 50px;
157 | }
158 |
159 | .wager-gameplay span {
160 | display: block;
161 | }
162 |
163 | /* Gameover scoreboard table */
164 | table {
165 | width: 50%;
166 | margin: 0 auto;
167 | padding: 0;
168 | }
169 |
170 | .total-label {
171 | text-align: right;
172 | padding-right: 20px;
173 | }
174 |
175 | .total-output {
176 | text-align: left;
177 | }
178 |
179 | /* Card totals */
180 | .hand-total, .split-hand-total, .dealer-hand-total {
181 | background: black;
182 | padding: 10px 0;
183 | margin: 2px;
184 | display: inline-block;
185 | font-size: 1.25em;
186 | text-align: center;
187 | width: 50px;
188 | }
189 |
190 | /* On the gameboard, these totals get positioned differently over the decks */
191 | .game-board-totals {
192 | position: relative;
193 | left: -15px;
194 | bottom: 40px;
195 | margin-right: -15px;
196 | }
197 |
198 | #user-split-hand {
199 | margin-left: 20px;
200 | }
201 |
202 | /* For whenever split hand state is engaged, we will scale decks up and down */
203 | .splithand-scaledown {
204 | transition: all 1s;
205 | transform: scale(.75);
206 | left: -80px;
207 | margin-right: -40px;
208 | }
209 |
210 | #user-hand.splithand-scaledown, #user-split-hand.splithand-scaledown {
211 | transform: scale(.4);
212 | left: 0;
213 | margin-right: -30px;
214 | }
215 |
216 | /* Game button action items are styled bigger than the other buttons */
217 | #sidebar button {
218 | width: 100%;
219 | height: 70px;
220 | margin: 5px 0 10px 0;
221 | overflow: none;
222 | padding: 0;
223 | }
224 |
225 | /* For any items invisible at start that we will toggle/show later */
226 | .inactive {
227 | display: none;
228 | }
229 |
230 |
231 | /* Materialize framework style overrides*/
232 | .nav-wrapper {
233 | background-color: black !important;
234 | text-align: left !important;
235 | box-shadow: 0 !important;
236 | }
237 |
238 | .navbar-fixed {
239 | margin-bottom: 25px !important;
240 | }
241 |
242 | .brand-logo { /* Text in nav bar */
243 | padding-left: 20px !important;
244 | font-size: 1.5em !important;
245 | }
246 |
247 | .rules-nav { /* Icon to toggle rules */
248 | padding-right: 20px !important;
249 | }
250 |
251 | .modal {
252 | padding: 40px 0 !important;
253 | width: 75% !important;
254 | height: 75% !important;
255 | opacity: .90 !important;
256 | overflow: hidden !important;
257 | max-height: 100% !important;
258 | }
259 |
260 | .modal-content h4, .modal-content p {
261 | color: black;
262 | }
263 |
264 | .modal-body {
265 | max-height: 600px;
266 | }
267 |
268 | .row {
269 | margin: 0 auto;
270 | }
271 |
272 | /* Resposive mobile adjustments*/
273 | @media all and (max-width: 600px){
274 | .wager-gameplay {
275 | top: 0;
276 | }
277 | }
278 |
279 | @media only screen and (min-device-width : 320px) and (max-device-width : 480px) {
280 |
281 | .navbar-fixed {
282 | margin-bottom: 8px !important;
283 | }
284 |
285 | .game-board h4 {
286 | font-size: 1.25em;
287 | }
288 |
289 | .game-over h3 {
290 | font-size: 2.25em;
291 | }
292 |
293 | p {
294 | font-size: 1.4em;
295 | }
296 |
297 |
298 | table {
299 | width: 100%;
300 | }
301 |
302 | #welcome p {
303 | width: 100%;
304 | }
305 |
306 | .card {
307 | width: 77px;
308 | height: 103.5px;
309 | }
310 |
311 | #sidebar button {
312 | width: 70px;
313 | height: 40px;
314 | font-size: .75em;
315 | }
316 |
317 | .total-label {
318 | padding-right: 0;
319 | }
320 |
321 | .total-output {
322 | padding-left: 10px;
323 | }
324 |
325 | .wager-gameplay {
326 | font-size: 1.75em;
327 | position: relative;
328 | top: 0;
329 | margin: 0 auto;
330 | }
331 |
332 | .wager-gameplay .wager {
333 | height: 30px;
334 | width: 30px;
335 | }
336 |
337 | .wager-gameplay span {
338 | font-size: .75em;
339 | display: inline-block;
340 | margin-left: 20px;
341 | position: relative;
342 | bottom: 10px;
343 | }
344 |
345 | }
346 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Goal Beat the dealer by getting a hand as close to 21 as possible, without going over 21. A blackjack occurs when you get one ace and one 10 point card, without having split the deck first.
37 |Gameplay The dealer will give 2 cards to themself and 2 cards to you. The dealer's second card will be played face down. You can choose to either hit (receive more cards) or stand (move on to the next hand). You can hit as many times as you choose so long as your deck is under 21.
38 |Card Values Queens, Kings, and Jacks are worth 10, pip cards are worth their face value, but Aces can be worth either 11 or 1. In this game, Aces have a default value is 11 unless you go over 21 on your hand.
39 |Splitting Pairs If you receive 2 cards of the same face value, you may choose to split your pairs and play each hand separately. At this table, you can only split once. After you split, one new card will be dealt to each hand then you can choose to either hit or stand for each hand accordingly.
42 |Betting Bets must be placed prior to playing. After receiving your first 2 cards, you can choose to double down (double your original bet). After your next move, you can no longer choose to double down.
43 |Payout Payout is 1:1 unless you get a blackjack. For a blackjack, payout is 3:2.
44 | 45 |
82 | ___
83 |
86 | ___
87 | Dealer |
133 | 134 | |
Player |
137 | 138 | |