Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- const fs = require('fs');
- const ACCOUNTS = require('./ACCOUNTS.json');
- const CONFIG = require('./CONFIG.json');
- const STRATEGY = require('./STRATEGY.json');
- const POKER_CONTRACT = 'eospokerwins';
- const verboseLog = false;
- /* ==== Record and regularly print out total earning of all accounts ==== */
- let totalWagered = 0;
- let totalEarning = 0;
- let totalHandPlayed = 0;
- setInterval(() => {
- console.log(`------ Earnings / House Edge (${totalHandPlayed} Hands) ------`);
- const printTxt = `${totalEarning.toFixed(4)} EOS / ${-(totalEarning / totalWagered * 100).toFixed(4)}%`;
- console.log(printTxt);
- fs.appendFileSync('poker-log.txt', `${printTxt}\n`, 'utf8');
- }, 600000);
- /* ==== Start all accounts, will continue unfinished games automatically ==== */
- Object.keys(ACCOUNTS).forEach((name, index) => {
- setTimeout(() => playPoker(name), index * 2000);
- });
- /* ==== Transfer all POKER to collectorAccount regularly ==== */
- setInterval(() => {
- Object.keys(ACCOUNTS).forEach(name => {
- getCurrencyBalance('eospokercoin', name, 'POKER').then(balance => {
- transfer(name, CONFIG.collectorAccount, balance, '', 'eospokercoin').catch(() => {});
- });
- });
- }, 300000);
- function playPoker(account) {
- getLastGame(account).then(game => {
- if (!game || game.ended) {
- bet(account).then(() => nextStep(account)).catch(error => {
- if (error.message.startsWith('billed CPU time')) {
- console.error(account, error.message);
- } else if (!error.message.startsWith('Could not find block') && error.message !== 'Transaction\'s reference block did not match. Is this transaction from a different fork?') {
- console.error(account, error.message, JSON.stringify(game, null, 2));
- }
- setTimeout(() => playPoker(account), 10000);
- });
- } else {
- if (game.player_hands.length === 2 && game.player_hands[0].ended) {
- nextStep(account, 2, game.player_hands[1].player_cards.length);
- } else {
- nextStep(account, 1, game.player_hands[0].player_cards.length);
- }
- }
- });
- }
- function nextStep(account, hand = 1, step = 2, justSplit = false) {
- waitForCards(account, hand, step, justSplit).then(game => {
- if (game == null) {
- setTimeout(() => playPoker(account), CONFIG.gameDelay);
- return;
- }
- const isSplit = game.player_hands.length >= 2;
- const isSurrendered = game.player_hands[hand - 1].surrendered;
- const playerCards = game.player_hands[hand - 1].player_cards;
- let betAmount = +game.bet_amount.quantity.split(' ')[0];
- if (game.player_hands[hand - 1].doubled_bet) betAmount *= 2;
- const dealerHandValue = getSoftHandValue(game.dealer_cards);
- const playerHandValue = getSoftHandValue(playerCards);
- let dealerBlackjack = game.dealer_cards.length === 2 && dealerHandValue === 21;
- let playerBlackjack = playerCards.length === 2 && playerHandValue === 21;
- if (verboseLog) {
- console.log(`---- ${account} (${betAmount})${game.ended ? ' (ended)' : ''} ----`);
- console.log(`Game ${game.game_id} (hand ${hand})${game.player_hands[hand - 1].ended ? ' (ended)' : ''}`);
- if (dealerBlackjack) {
- console.log(`Dealer: ${getCards(game.dealer_cards)} (Blackjack)`);
- } else {
- console.log(`Dealer: ${getCards(game.dealer_cards)} (${isSoft(game.dealer_cards) ? 'Soft ' : ''}${dealerHandValue})`);
- }
- if (playerBlackjack) {
- console.log(`Player: ${getCards(playerCards)} (Blackjack)`);
- } else {
- console.log(`Player: ${getCards(playerCards)} (${isSoft(playerCards) ? 'Soft ' : ''}${playerHandValue})`);
- }
- }
- if (game.ended || (isSplit && hand === 1 && game.player_hands[0].ended)) {
- totalWagered += betAmount;
- if (isSurrendered) {
- totalEarning -= betAmount * 0.5;
- } else if (playerBlackjack && !dealerBlackjack) {
- totalEarning += betAmount * 1.5;
- } else if (dealerBlackjack && !playerBlackjack) {
- totalEarning -= betAmount;
- } else if (playerHandValue > 21) {
- totalEarning -= betAmount;
- } else if (dealerHandValue > 21) {
- totalEarning += betAmount;
- } else if (playerHandValue > dealerHandValue) {
- totalEarning += betAmount;
- } else if (dealerHandValue > playerHandValue) {
- totalEarning -= betAmount;
- }
- totalHandPlayed++;
- setTimeout(() => playPoker(account), CONFIG.gameDelay);
- return;
- }
- const strategy = getStrategy(game, hand);
- if (verboseLog) {
- console.log(`Strategy: ${strategy}`);
- }
- let actionFunc;
- switch (strategy) {
- case 'P':
- actionFunc = split;
- break;
- case 'S':
- actionFunc = stand;
- break;
- case 'H':
- actionFunc = hit;
- break;
- case 'D':
- actionFunc = isSplit ? hit : doubleup;
- break;
- case 'R':
- actionFunc = isSplit ? hit : surrender;
- break;
- default:
- console.error(account, `Error: Invalid Strategy "${strategy}"`);
- setTimeout(() => nextStep(account, hand, step, justSplit), 10000);
- return;
- }
- actionFunc(account, hand, step).then(() => {
- setTimeout(() => nextStep(account, hand, strategy === 'P' ? 2 : step + 1, strategy === 'P'), 3000);
- }).catch(error => {
- if (error.message.startsWith('billed CPU time')) {
- console.error(account, error.message);
- } else if (!error.message.startsWith('Could not find block') && error.message !== 'Transaction\'s reference block did not match. Is this transaction from a different fork?') {
- console.error(account, error.message, JSON.stringify({ hand, step, justSplit, isSplit, strategy }), JSON.stringify(game, null, 2));
- }
- setTimeout(() => nextStep(account, hand, step, justSplit), 10000);
- });
- }).catch(error => {
- console.error(account, error.message);
- setTimeout(() => nextStep(account, hand, step, justSplit), 10000);
- });
- }
- function waitForCards(account, hand, cardCount, justSplit) {
- return new Promise((resolve, reject) => {
- const waitInterval = setInterval(() => {
- getLastGame(account).then(game => {
- const isSplit = game.player_hands.length >= 2;
- if (!game) {
- console.error(account, 'The seed has been used in a previous game.');
- clearInterval(waitInterval);
- resolve(null);
- } else if (justSplit) {
- if (game.player_hands.length >= 2 && game.player_hands[0].player_cards.length === 2) {
- clearInterval(waitInterval);
- resolve(game);
- }
- } else if (game.ended || (isSplit && hand === 1 && game.player_hands[0].ended) || game.player_hands[hand - 1].player_cards.length === cardCount) {
- clearInterval(waitInterval);
- resolve(game);
- }
- }).catch(error => reject(error));
- }, 3000);
- });
- }
- function getStrategy(game, hand) {
- let strategy;
- const playerCards = game.player_hands[hand - 1].player_cards;
- const pair = getPair(playerCards);
- if (game.player_hands.length === 1 && pair !== -1) {
- strategy = STRATEGY.split[pair - 1][getSoftHandValue(game.dealer_cards) - 2];
- } else if (isSoft(playerCards)) {
- strategy = STRATEGY.soft[getSoftHandValue(playerCards) - 4][getSoftHandValue(game.dealer_cards) - 2];
- } else {
- strategy = STRATEGY.hard[getSoftHandValue(playerCards) - 4][getSoftHandValue(game.dealer_cards) - 2];
- }
- if (playerCards.length > 2 && (strategy === 'D' || strategy === 'R')) {
- strategy = 'H';
- }
- return strategy;
- }
- function getHardHandValue(cards) {
- return getCards(cards).reduce((prev, curr) => {
- return prev + curr;
- }, 0);
- }
- function getSoftHandValue(cards) {
- const sum = getHardHandValue(cards);
- if (getCards(cards).indexOf(1) !== -1 && sum <= 11) {
- return sum + 10;
- } else {
- return sum;
- }
- }
- function isSoft(cards) {
- return getSoftHandValue(cards) > getHardHandValue(cards);
- }
- function getPair(cards) {
- if (cards.length !== 2) {
- return -1;
- }
- const cardValues = getCards(cards);
- return cardValues[0] === cardValues[1] ? cardValues[0] : -1;
- }
- function getCards(cards) {
- return cards.filter(card => card !== 255).map(card => Math.min(card % 13 + 1, 10));
- }
- function getLastGame(account) {
- return getTableRows(POKER_CONTRACT, 'games', account).then(rows => {
- return rows[0];
- });
- }
- function bet(account) {
- return getBalance(account).then(balance => {
- const betAmount = Math.min(+(+balance.split(' ')[0] / CONFIG.betRatio).toFixed(1), 25);
- if (betAmount === 0) { return Promise.reject(new Error('Error: insufficient funds')); }
- const randomSeed = `${Math.random().toString(32).substring(2)}${Math.random().toString(32).substring(2)}`;
- return transfer(account, POKER_CONTRACT, betAmount, `newgame-${CONFIG.collectorAccount}-${randomSeed}`);
- });
- }
- function split(account) {
- return getLastGame(account).then(game => {
- return transfer(account, POKER_CONTRACT, game.bet_amount.quantity, 'split-1');
- });
- }
- function hit(account, hand, step) {
- return transact(account, POKER_CONTRACT, 'hit', { player: account, hand, slot: step + 1 });
- }
- function stand(account, hand) {
- return transact(account, POKER_CONTRACT, 'stand', { player: account, hand });
- }
- function doubleup(account, hand) {
- return getLastGame(account).then(game => {
- return transfer(account, POKER_CONTRACT, game.bet_amount.quantity, `doubledown-${hand}`);
- });
- }
- function surrender(account, hand) {
- return transact(account, POKER_CONTRACT, 'surrender', { player: account, hand });
- }
- /* ==== Blockchain helper functions ==== */
- const eosjs = require('eosjs');
- const fetch = require('node-fetch');
- const { TextDecoder, TextEncoder } = require('text-encoding');
- const API_ENDPOINT = 'https://eos.greymass.com:443';
- const defaultRpc = new eosjs.JsonRpc(API_ENDPOINT, { fetch });
- function getTableRows(code, table, scope, limit = 10000) {
- scope = scope || code;
- return defaultRpc.get_table_rows({
- json: true,
- code,
- scope,
- table,
- table_key: '',
- lower_bound: 0,
- upper_bound: -1,
- limit,
- }).then(result => result.rows);
- }
- function getBalance(account) {
- return defaultRpc.get_currency_balance('eosio.token', account, 'EOS').then(result => result[0]);
- }
- function getCurrencyBalance(code, account, symbol) {
- return defaultRpc.get_currency_balance(code, account, symbol).then(result => result[0]);
- }
- function transact(accountName, contractName, funcName, data = {}, permission = 'active') {
- const signatureProvider = new eosjs.JsSignatureProvider([ACCOUNTS[accountName]]);
- const api = new eosjs.Api({ rpc: defaultRpc, signatureProvider, textDecoder: new TextDecoder, textEncoder: new TextEncoder });
- return api.transact({
- actions: [{
- account: contractName,
- name: funcName,
- authorization: [{
- actor: accountName,
- permission,
- }],
- data,
- }]
- }, {
- blocksBehind: 3,
- expireSeconds: 600,
- });
- }
- function transfer(from, to, quantity, memo = '', code = 'eosio.token') {
- return transact(from, code, 'transfer', { from, to, quantity: typeof quantity === 'number' ? `${quantity.toFixed(4)} EOS` : quantity, memo });
- }
Add Comment
Please, Sign In to add comment