Deck of Cards

by onejdc

HTML

<fieldset>
  <legend>Welcome</legend>
  <h1>
  Homegrown Poker
  </h1>
  <button id="btnAddPlayer">
  Add a Player
  </button>
</fieldset>
<fieldset>
  <legend>Board</legend>
  <div id="deck" class="deck background"></div>
  <div id="board"></div>
  
</fieldset> 
  
<fieldset id='player-hands'>
  <legend>Player Hands</legend>
<!--   <div id="player1" class='player-hand'>
  </div>
  <div id="player2" class='player-hand'>
  </div> -->
</fieldset>

CSS

#deck { cursor: pointer;}
.card {
  width: 60px;
  border: 1px solid #000;
  border-radius: 10px 10px;
  height: 86px;
  float:left;
  margin: 5px;
}
.card.card-color-RED {
  color: red;
}
.card.card-color-BLACK {
  color: black;
}

.suit {
  width: 20px;
  height: 20px;
  font-size: 40px;
  
}
.suit::before {
  position:relative;
  top:-10px;
}
.suit-CLUBS::before {
  content: '♣';
  
}
.suit-HEARTS::before {
  content: '♥';
}
.suit-DIAMONDS::before {
  content: '♦';
}
.suit-SPADES::before {
  content: '♠';
}



div.suit:last-child {
  float:right;
  bottom: 20px;
  position: relative;
  right: 0px;
  transform: rotate(-180deg);
}
.rank { 
  width: 80%;
  height: 80%;
 /*  background-color: blue; */
  margin: auto;
  font-size: 2.5em;
  text-align: center;
}

.deck.background {
  background-color: #e5e5f7;
  opacity: 0.8;
  background-image:  linear-gradient(135deg, #444cf7 25%, transparent 25%), linear-gradient(225deg, #444cf7 25%, transparent 25%), linear-gradient(45deg, #444cf7 25%, transparent 25%), linear-gradient(315deg, #444cf7 25%, #e5e5f7 25%);
  background-position:  10px 0, 10px 0, 0 0, 0 0;
  background-size: 10px 10px;
  background-repeat: repeat;
  width: 120px;
  height: 175px;
  position:relative;
  float:left;
  
    border: 1px solid #000;
  border-radius: 10px 10px;
  margin: 5px;

}

#player-hands {
  
  display:flex;align-items:stretch;
}
.player-hand { position: relative; flex:1;}
.player-name {

  text-align:center;
}

JavaScript

// https://stackoverflow.com/questions/47194034/shuffling-a-poker-deck-in-javascript-with-window-crypto-getrandomvalues
// Add Fisher-Yates shuffle method to Javascript's Array type, using
// window.crypto.getRandomValues as a source of randomness.

if (Uint8Array && window.crypto && window.crypto.getRandomValues) {
    Array.prototype.shuffle = function() {
        var n = this.length;
    
        // If array has <2 items, there is nothing to do
        if (n < 2) return this;
        // Reject arrays with >= 2**31 items
        if (n > 0x7fffffff) throw "ArrayTooLong";
    
        var i, j, r=n*2, tmp, mask;
        // Fetch (2*length) random values
        var rnd_words = new Uint32Array(r);
        // Create a mask to filter these values
        for (i=n, mask=0; i; i>>=1) mask = (mask << 1) | 1;
    
        // Perform Fisher-Yates shuffle
        for (i=n-1; i>0; i--) {
            if ((i & (i+1)) == 0) mask >>= 1;
            do {
                if (r == n*2) {
                    // Refresh random values if all used up
                    window.crypto.getRandomValues(rnd_words);
                    r = 0;
                }
                j = rnd_words[r++] & mask;
            } while (j > i);
            tmp = this[i];
            this[i] = this[j];
            this[j] = tmp;
        }
        return this;
    }
} else throw "Unsupported";


const ranks = ["A",2,3,4,5,6,7,8,9,10,"J","Q","K"];
const suits = ["CLUBS","DIAMONDS","HEARTS","SPADES"];

class Deck {

	constructor(name) {
  	this.name = name;
    this.cards = [];
    self = this;
  }
  
  build() {
  	ranks.forEach(function (r,rank_index) {
    	suits.forEach(function (s, suit_index) {
        self.cards.push(new Card(r,s));
      })
    })
  }
  
  shuffle(type='random',times=1) {
  
  	if (type === 'random') {
      // Durstenfeld shuffle, optimized for es6
      for (let i = this.cards.length - 1; i > 0; i--) {
          const j = Math.floor(Math.random() * (i + 1));
         ...