UNPKG

blackjack-strategy

Version:

provides a suggested action for a player based on Basic Strategy

201 lines (165 loc) 6.06 kB
/* * MIT License * Copyright (c) 2016 Garrett Vargas * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ const lib = require('../src/suggestion'); function OptionsToText(options) { var text = ""; text += (options.numberOfDecks + " deck(s), "); text += (options.hitSoft17) ? "Dealer Hits ": "Dealer Stands "; text += "on soft 17 - " + options.strategyComplexity + " complexity"; return text; } function ResultToLetter(result) { var letter = "N"; switch (result) { case "surrender": letter = "R"; break; case "split": letter = "P"; break; case "stand": letter = "S"; break; case "hit": letter = "H"; break; case "double": letter = "D"; break; } return letter; } function GetOneRow(playerCards, options) { var dealerCard; var line = ""; var result; // Go thru every combination with this set of options and spit out to a CSV file // Start with the most liberal double and surrender rules, and then augment with a qualifier if you // aren't able to double or surrender options.doubleRange = [1,21]; options.surrender = "late"; options.doubleAfterSplit = true; for (dealerCard = 2; dealerCard <= 11; dealerCard++) { result = lib.GetRecommendedPlayerAction(playerCards, (dealerCard == 11) ? 1 : dealerCard, 1, true, options); line += ResultToLetter(result); if ((result == "double") || (result == "surrender")) { // Do it again with no double or surrender options.doubleRange = [0,0]; options.surrender = "none"; result = lib.GetRecommendedPlayerAction(playerCards, dealerCard, 1, true, options); line += ResultToLetter(result); // Reset to initial liberal options options.doubleRange = [1,21]; options.surrender = "late"; } else if (result == "split") { // Try it again if you can't double after split options.doubleAfterSplit = false; result = lib.GetRecommendedPlayerAction(playerCards, dealerCard, 1, true, options); if (result != "split") { line += ResultToLetter(result); } // Reset to initial liberal options options.doubleAfterSplit = true; } if (dealerCard < 11) { line += "," } } return line; } // Creates a chart for the given playing options - for double and surrender, it creates an entry that tells // you what the alternate action should be if you cannot double or surrender function CreateChart(options) { var playerTotal; var line = ""; var playerCards = []; // First the hard totals (8-17) console.log(OptionsToText(options)); console.log(" ,2,3,4,5,6,7,8,9,10,A"); for (playerTotal = 8; playerTotal <= 17; playerTotal++) { // Turn this into a hard hand - make it 10+ (or 2+), as this avoids splits // Note this assumes that we are not looking at exactComposition if (playerTotal < 12) { playerCards[0] = 2; playerCards[1] = playerTotal - 2; } else { playerCards[0] = 10; playerCards[1] = playerTotal - 10; } line = playerTotal + "," + GetOneRow(playerCards, options); // Write out this line console.log(line); } // Then the soft totals (13-20) console.log(" ,2,3,4,5,6,7,8,9,10,A"); playerCards[0] = 1; for (playerTotal = 13; playerTotal <= 20; playerTotal++) { playerCards[1] = playerTotal - 11; line = playerTotal + "," + GetOneRow(playerCards, options); // Write out this line console.log(line); } // And last the pairs console.log(" ,2,3,4,5,6,7,8,9,10,A"); for (playerTotal = 4; playerTotal <= 18; playerTotal += 2) { playerCards[0] = playerTotal / 2; playerCards[1] = playerCards[0]; line = playerCards[0] + " pair," + GetOneRow(playerCards, options); // Write out this line console.log(line); } // Aces last playerCards[0] = 1; playerCards[1] = 1; line = "A pair," + GetOneRow(playerCards, options); console.log(line); } // We will spit out basic single/double/4+ options for both hit and stand on soft 17 const playerOptions = { hitSoft17: true, numberOfDecks: 1, strategyComplexity: "advanced"}; CreateChart(playerOptions); playerOptions.hitSoft17 = false; CreateChart(playerOptions); playerOptions.numberOfDecks = 2; playerOptions.hitSoft17 = true; CreateChart(playerOptions); playerOptions.hitSoft17 = false; CreateChart(playerOptions); playerOptions.numberOfDecks = 4; playerOptions.hitSoft17 = true; CreateChart(playerOptions); playerOptions.hitSoft17 = false; CreateChart(playerOptions);