Last active
November 4, 2016 03:25
-
-
Save dapperAuteur/aa67953ed210df30ed4faed01ff0a144 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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