Skip to content

Instantly share code, notes, and snippets.

@dapperAuteur
Last active November 4, 2016 03:25
Show Gist options
  • Save dapperAuteur/aa67953ed210df30ed4faed01ff0a144 to your computer and use it in GitHub Desktop.
Save dapperAuteur/aa67953ed210df30ed4faed01ff0a144 to your computer and use it in GitHub Desktop.
import { fromJS, List } from 'immutable';
import seedrandom from 'seedrandom';
export const shuffle = (array, seed) => {
let j, x, i;
for (i = array.length; i; i -= 1) {
j = Math.floor(seedrandom(seed + i)() * i);
x = array[i - 1];
array[i - 1] = array[j];
array[j] = x;
}
};
export const newDeck = (seed) => {
const ranks = ['A', 2, 3, 4, 5, 6, 7, 8, 9, 10, 'J', 'Q', 'K'];
const suits = ['S', 'C', 'H', 'D'];
const deck = [];
ranks.forEach( (r) => {
suits.forEach( (s) => {
deck.push({ "rank": r, "suit": s});
});
});
shuffle(deck, seed);
return fromJS(deck);
};
// deal n cards from arbitrary position in deck
export const deal = (deck, n, seed) => {
if(n == 1) {
const r = Math.floor(seedrandom(seed)() * deck.size);
let dealtCards = new List([deck.get(r)]);
let newDeck = deck.remove(r);
return [newDeck, dealtCards]
}
let dealtCards = new List();
let newDeck = deck;
for(let i = 0; i < n; i += 1) {
let [d, c] = deal(newDeck, 1, seed + i);
dealtCards = dealtCards.push(c.first());
newDeck = d;
}
return [newDeck, dealtCards];
};
export const rankAsNum = (rank) => {
if(rank == 'K' || rank == 'Q' || rank == 'J') {
return 10;
} else {
return rank;
}
};
export const score = (cards) => {
const aces = cards.filter((card) => card.get('rank') == 'A');
const nonAces = cards.filter((card) => card.get('rank') != 'A');
if(nonAces.size == 0 && aces.size == 0) {
return 0;
} else if(aces.size == 0) {
return cards.reduce( (sum, card) => {
return sum + rankAsNum(card.get('rank'));
}, 0);
} else {
let acesAllOneScore = score(nonAces) + aces.size;
if(acesAllOneScore <= 11) {
acesAllOneScore += 10;
}
return acesAllOneScore;
}
};
import { Map } from 'immutable';
import { newDeck, deal, score } from './lib/cards';
const setupGame = (currentState, seed) => {
let deck = newDeck(seed);
let playerHand, dealerHand;
let playerCash, playerBet;
[deck, playerHand] = deal(deck, 2, seed);
[deck, dealerHand] = deal(deck, 1, seed + 1);
dealerHand = dealerHand.push(new Map());
const hasStood = false;
let gameOver = false;
let playerWon = undefined;
let winCount = currentState.get('winCount') || 0;
let lossCount = currentState.get('lossCount') || 0;
if(score(playerHand) == 21) {
gameOver = true;
playerWon = true;
winCount += 1;
}
const newState = new Map({
deck, playerHand, dealerHand, hasStood, gameOver, playerWon, winCount, lossCount });
return currentState.merge(newState);
};
const stand = (currentState, seed) => {
let newState = new Map({"hasStood": true});
let dealerHand = currentState.get('dealerHand');
let deck = currentState.get('deck');
dealerHand = dealerHand.filter((element) => element != new Map());
//getting error: "Cannot read property 'filter' of undefined at stand (/home/ubuntu/workspace/app/reducer.js:40:18)"
while(score(dealerHand) < 17) {
let newCards;
[deck, newCards] = deal(deck, 1, 1);
dealerHand = dealerHand.push(newCards.get(0));
}
let winCount = currentState.get('winCount');
let lossCount = currentState.get('lossCount');
let tieCount = currentState.get('tieCount');
const playerHand = currentState.get('playerHand');
const playerScore = score(playerHand);
const dealerScore = score(dealerHand);
let playerWon = undefined;
if(playerScore > dealerScore || dealerScore > 21) {
//winCount = (currentState.get('winCount') + 1);
winCount++;
playerWon = true;
} else if(dealerScore > playerScore) {
//lossCount = (currentState.get('lossCount') + 1);
lossCount++;
playerWon = false;
} else if ( dealerScore == playerScore) {
//tieCount = (currentState.get('tieCount') + 1);
tieCount++;
playerWon = undefined;
}
const gameOver = true;
newState = newState.merge({dealerHand, deck, winCount, lossCount, tieCount, gameOver, playerWon});
return currentState.merge(newState);
};
const setRecord = (currentState, wins, losses, ties, cash, bet) => {
return currentState.merge(new Map({ "winCount": wins, "lossCount": losses, "tieCount": ties, "playerCash": cash, "playerBet": bet }));
};
const dealToPlayer = (currentState, seed) => {
const [deck, newCard] = deal(currentState.get('deck'), 1, seed);
const playerHand = currentState.get('playerHand').push(newCard.get(0));
let newState = new Map({ deck, playerHand });
const newScore = score(playerHand);
if(newScore > 21) {
const lossCount = currentState.get('lossCount') + 1;
const gameOver = true;
const playerWon = false;
newState = newState.merge({lossCount, gameOver, playerWon});
}
if(newScore == 21) {
const winCount = currentState.get('winCount') + 1;
const gameOver = true;
const playerWon = true;
newState = newState.merge({winCount, gameOver, playerWon});
}
return currentState.merge(newState);
};
// player cash & bet is set when record is set for player
export default function(currentState=new Map(), action) {
switch(action.type) {
case 'SETUP_GAME':
return setupGame(currentState, action.seed);
case 'SET_RECORD':
return setRecord(currentState, action.wins, action.losses, action.ties, action.cash, action.bet);
case 'DEAL_TO_PLAYER':
return dealToPlayer(currentState, action.seed);
case 'STAND':
return stand(currentState, action.seed);
}
return currentState;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment