Full Code of chenosaurus/poker-evaluator for AI

master 73217b5857e3 cached
8 files
9.7 KB
3.7k tokens
1 symbols
1 requests
Download .txt
Repository: chenosaurus/poker-evaluator
Branch: master
Commit: 73217b5857e3
Files: 8
Total size: 9.7 KB

Directory structure:
gitextract_jq9kxenc/

├── .gitignore
├── .travis.yml
├── lib/
│   ├── 3CardConverter.js
│   └── PokerEvaluator.js
├── package.json
├── readme.md
└── test/
    ├── poker-evaluator.spec.js
    └── speedtest.js

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
node_modules
npm-debug.log

================================================
FILE: .travis.yml
================================================
language: node_js
node_js:
  - 0.8
env: NODE_ENV=travis
before_install:
  - npm config set loglevel warn


================================================
FILE: lib/3CardConverter.js
================================================
//converts 3 card to lowest equivalent 5 card hand
module.exports = {
  CARDVALS: ['2', '3', '4', '5', '6', '7', '8', '9', 't', 'j', 'q', 'k', 'a'],
  CARDS: {
    "2c": 1,
    "2d": 2,
    "2h": 3,
    "2s": 4,
    "3c": 5,
    "3d": 6,
    "3h": 7,
    "3s": 8,
    "4c": 9,
    "4d": 10,
    "4h": 11,
    "4s": 12,
    "5c": 13,
    "5d": 14,
    "5h": 15,
    "5s": 16,
    "6c": 17,
    "6d": 18,
    "6h": 19,
    "6s": 20,
    "7c": 21,
    "7d": 22,
    "7h": 23,
    "7s": 24,
    "8c": 25,
    "8d": 26,
    "8h": 27,
    "8s": 28,
    "9c": 29,
    "9d": 30,
    "9h": 31,
    "9s": 32,
    "tc": 33,
    "td": 34,
    "th": 35,
    "ts": 36,
    "jc": 37,
    "jd": 38,
    "jh": 39,
    "js": 40,
    "qc": 41,
    "qd": 42,
    "qh": 43,
    "qs": 44,
    "kc": 45,
    "kd": 46,
    "kh": 47,
    "ks": 48,
    "ac": 49,
    "ad": 50,
    "ah": 51,
    "as": 52
  },
  makesStraight: function(cardsUsed, rank) {
    //add ace to bottom as well
    var newCards = [cardsUsed[12]].concat(cardsUsed);
    //add in new card (pushed up one by ace)
    newCards[rank+1] = 2;
    //determine if there are 5 cards in a row
    return 5 === newCards.reduce(function(prev, next) {
      if (prev === 5) {
        return 5;
      } else {
        return next ? prev + 1 : 0;
      }
    });
  },

  fillHand: function(cards) {

  	var cardsUsed = [0,0,0,0,0,0,0,0,0,0,0,0,0];

  	//convert each card to vals 0-12, strip suit
  	cards.forEach(function(card) {
  		var i = Math.floor((this.CARDS[card.toLowerCase()]-1)/4);
  		cardsUsed[i] = 1;
  	}, this);

  	var toFill = 2; //need to fill 2 cards

    //fill in <toFill> cards to complete 5 card hand
  	for (var i = 0; i < 13; i++) {
  	  if (toFill == 0) break; //done filling
      //prevent adding a card to finish a straight
      if (cardsUsed[i] == 0 && !this.makesStraight(cardsUsed,i)) {
        cardsUsed[i] = 2;
        toFill--;
      }
  	}

    //fill dummy cards for lowest possible hand
    var suit = ['s', 'd'];
    for (var i = 0; i <= 13; i++) {
      if (cardsUsed[i] == 2) {
        var card = this.CARDVALS[i] + suit[0];
        suit.splice(0, 1);
        cards.push(card);
      }
    }
    return cards;
  }
};

================================================
FILE: lib/PokerEvaluator.js
================================================
var fs = require("fs");
var path = require("path");
var ThreeCardConverter = require("./3CardConverter");

module.exports = {
  HANDTYPES: [
    "invalid hand",
    "high card",
    "one pair",
    "two pairs",
    "three of a kind",
    "straight",
    "flush",
    "full house",
    "four of a kind",
    "straight flush"
  ],

  CARDS: {
    "2c": 1,
    "2d": 2,
    "2h": 3,
    "2s": 4,
    "3c": 5,
    "3d": 6,
    "3h": 7,
    "3s": 8,
    "4c": 9,
    "4d": 10,
    "4h": 11,
    "4s": 12,
    "5c": 13,
    "5d": 14,
    "5h": 15,
    "5s": 16,
    "6c": 17,
    "6d": 18,
    "6h": 19,
    "6s": 20,
    "7c": 21,
    "7d": 22,
    "7h": 23,
    "7s": 24,
    "8c": 25,
    "8d": 26,
    "8h": 27,
    "8s": 28,
    "9c": 29,
    "9d": 30,
    "9h": 31,
    "9s": 32,
    "tc": 33,
    "td": 34,
    "th": 35,
    "ts": 36,
    "jc": 37,
    "jd": 38,
    "jh": 39,
    "js": 40,
    "qc": 41,
    "qd": 42,
    "qh": 43,
    "qs": 44,
    "kc": 45,
    "kd": 46,
    "kh": 47,
    "ks": 48,
    "ac": 49,
    "ad": 50,
    "ah": 51,
    "as": 52
  },

  evalHand: function(cards) {
    if (!this.ranks) {
      throw new Error("HandRanks.dat not loaded");
    }

    if (cards.length != 7 && cards.length != 6 && cards.length != 5 && cards.length != 3) {
      throw new Error("Hand must be 3, 5, 6, or 7 cards, but got " + cards.length);
    }

    //if 3 card hand, fill in to make 5 card
    if (cards.length == 3) {
      cards = ThreeCardConverter.fillHand(cards);
    }

    //if passing in string formatted hand, convert first
    if (typeof cards[0] == "string") {
      cards = cards.map(function(card) {
        return this.CARDS[card.toLowerCase()];
      }.bind(this));
    }

    return this.eval(cards);
  },

  eval: function(cards) {
    var p = 53;
    for (var i = 0; i < cards.length; i++) {
      p = this.evalCard(p + cards[i]);
    }

    if (cards.length == 5 || cards.length == 6) {
      p = this.evalCard(p)
    }

    return {
      handType: p >> 12,
      handRank: p & 0x00000fff,
      value: p,
      handName: this.HANDTYPES[p >> 12]
    }
  },

  evalCard: function(card) {
    return this.ranks.readUInt32LE(card * 4);
  }
}

var ranksFile = path.join(__dirname, '../data/HandRanks.dat');
module.exports.ranks = fs.readFileSync(ranksFile);


================================================
FILE: package.json
================================================
{
  "name": "poker-evaluator",
  "version": "0.3.2",
  "description": "A library to evaluate 3, 5 or 7 card poker hands",
  "homepage": "http://github.com/chenosaurus/poker-evaluator",
  "keywords": ["poker", "games"],
  "author": "David Chen <chenosaurus@gmail.com>",
  "contributors": [
    {
      "name": "Andreas Brekken",
      "email": "a@abrkn.com"
    }
  ],
  "repository": {
    "type": "git",
    "url": "https://github.com/chenosaurus/poker-evaluator.git"
  },
  "dependencies": {},
  "scripts": {
    "test": "jest && node test/speedtest.js"
  },
  "devDependencies": {
    "jest": "^20.0.4"
  },
  "main": "./lib/PokerEvaluator.js",
  "engines": {
    "node": ">= 0.6.0"
  }
}


================================================
FILE: readme.md
================================================
# Poker Hand Evaluator

Poker hand evaluator using the Two Plus Two alogorithm and lookup table.
The lookup table HandRanks.dat is included in the module.

It is capable of evaluating 7, 6, 5, and 3 card hands.  The highest hand possible in a 3 card hand is 3 of a kind, straights & flushes do not apply to 3 cards.

Hands can be evaluated by comparing the handType then the handRank to determine the better hand.

This can evaluate about 22MM hands per second on a quad-core 2.7GHz Macbook Pro.  Run the speedtest.js file under /test to try it.

## to install:

npm install poker-evaluator

## Usage:

```js
var PokerEvaluator = require("poker-evaluator");

PokerEvaluator.evalHand(["As", "Ks", "Qs", "Js", "Ts", "3c", "5h"]);

//{ handType: 9,
//  handRank: 10,
//  value: 36874,
//  handName: 'straight flush' }

PokerEvaluator.evalHand(["As", "Ac", "Ad", "5d", "5s"]);

//{ handType: 7,
//  handRank: 148,
//  value: 28820,
//  handName: 'full house' }

PokerEvaluator.evalHand(["As", "Ac", "Qs"]);

//{ handType: 2,
//  handRank: 2761,
//  value: 10953,
//  handName: 'one pair' }

```


================================================
FILE: test/poker-evaluator.spec.js
================================================
const PokerEvaluator = require('../lib/PokerEvaluator');

describe('evalHand', function() {
  describe('should throw', function() {
    it('if 4 cards', function() {
      expect(function() {
        PokerEvaluator.evalHand(['As', 'Ac', 'Ad', '5s']);
      }).toThrow();
    });
    it('if 8 cards', function() {
      expect(function() {
        PokerEvaluator.evalHand([
          'As',
          'Ac',
          'Ad',
          '5s',
          'Ad',
          'Ah',
          '5c',
          '5s'
        ]);
      }).toThrow();
    });
  });
  it('5 cards, full house', function() {
    expect(PokerEvaluator.evalHand(['As', 'Ac', 'Ad', '5d', '5s'])).toEqual({
      handType: 7,
      handRank: 148,
      value: 28820,
      handName: 'full house'
    });
  });
  it('3 cards, one pair', function() {
    expect(PokerEvaluator.evalHand(['As', 'Ac', 'Qs'])).toEqual({
      handType: 2,
      handRank: 2761,
      value: 10953,
      handName: 'one pair'
    });
  });
  it('7 cards, straight flush', function() {
    expect(
      PokerEvaluator.evalHand(['As', 'Ks', 'Qs', 'Js', 'Ts', '3c', '5h'])
    ).toEqual({
      handType: 9,
      handRank: 10,
      value: 36874,
      handName: 'straight flush'
    });
  });
});


================================================
FILE: test/speedtest.js
================================================
var evaluator = require("..");
var path = require("path");
var assert = require("assert");

function enumerateAllHands() {
  var u0, u1, u2, u3, u4, u5;
  var c0, c1, c2, c3, c4, c5, c6;
  var handTypeSum = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
  var count = 0;

  console.log("Enumerating and evaluating all 133,784,560 possible 7-card poker hands...\n");

  var startTime = Date.now();

  for (c0 = 1; c0 < 47; c0++) {
    u0 = evaluator.evalCard(53+c0);
    for (c1 = c0+1; c1 < 48; c1++) {
      u1 = evaluator.evalCard(u0+c1);
      for (c2 = c1+1; c2 < 49; c2++) {
        u2 = evaluator.evalCard(u1+c2);
        for (c3 = c2+1; c3 < 50; c3++) {
          u3 = evaluator.evalCard(u2+c3);
          for (c4 = c3+1; c4 < 51; c4++) {
            u4 = evaluator.evalCard(u3+c4);
            for (c5 = c4+1; c5 < 52; c5++) {
              u5 = evaluator.evalCard(u4+c5);
              for (c6 = c5+1; c6 < 53; c6++) {

                handTypeSum[evaluator.evalCard(u5+c6) >> 12]++;
                count++;
              }
            }
          }
        }
      }
    }
  }

  var endTime = Date.now();

  console.log("BAD:              %d\n", handTypeSum[0]);
  console.log("High Card:        %d\n", handTypeSum[1]);
  console.log("One Pair:         %d\n", handTypeSum[2]);
  console.log("Two Pair:         %d\n", handTypeSum[3]);
  console.log("Trips:            %d\n", handTypeSum[4]);
  console.log("Straight:         %d\n", handTypeSum[5]);
  console.log("Flush:            %d\n", handTypeSum[6]);
  console.log("Full House:       %d\n", handTypeSum[7]);
  console.log("Quads:            %d\n", handTypeSum[8]);
  console.log("Straight Flush:   %d\n", handTypeSum[9]);

  // Perform sanity checks.. make sure numbers are where they should be
  var testCount = 0;
  for (var index = 0; index < 10; index++)
    testCount += handTypeSum[index];
  assert(testCount === count);
  assert(count === 133784560);
  assert(handTypeSum[0] === 0);

  console.log("\nEnumerated " + count + " hands in " + (endTime - startTime) + " milliseconds!\n");
}

assert.equal(evaluator.CARDS['as'], 52);
assert.equal(evaluator.HANDTYPES.length, 10);
assert.deepEqual(evaluator.eval([1, 2, 3, 4, 5]), {
  handType: 8,
  handName: 'four of a kind',
  value: 32769,
  handRank: 1
});

enumerateAllHands();
Download .txt
gitextract_jq9kxenc/

├── .gitignore
├── .travis.yml
├── lib/
│   ├── 3CardConverter.js
│   └── PokerEvaluator.js
├── package.json
├── readme.md
└── test/
    ├── poker-evaluator.spec.js
    └── speedtest.js
Download .txt
SYMBOL INDEX (1 symbols across 1 files)

FILE: test/speedtest.js
  function enumerateAllHands (line 5) | function enumerateAllHands() {
Condensed preview — 8 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (11K chars).
[
  {
    "path": ".gitignore",
    "chars": 26,
    "preview": "node_modules\nnpm-debug.log"
  },
  {
    "path": ".travis.yml",
    "chars": 105,
    "preview": "language: node_js\nnode_js:\n  - 0.8\nenv: NODE_ENV=travis\nbefore_install:\n  - npm config set loglevel warn\n"
  },
  {
    "path": "lib/3CardConverter.js",
    "chars": 2192,
    "preview": "//converts 3 card to lowest equivalent 5 card hand\nmodule.exports = {\n  CARDVALS: ['2', '3', '4', '5', '6', '7', '8', '9"
  },
  {
    "path": "lib/PokerEvaluator.js",
    "chars": 2288,
    "preview": "var fs = require(\"fs\");\nvar path = require(\"path\");\nvar ThreeCardConverter = require(\"./3CardConverter\");\n\nmodule.export"
  },
  {
    "path": "package.json",
    "chars": 692,
    "preview": "{\n  \"name\": \"poker-evaluator\",\n  \"version\": \"0.3.2\",\n  \"description\": \"A library to evaluate 3, 5 or 7 card poker hands\""
  },
  {
    "path": "readme.md",
    "chars": 1091,
    "preview": "# Poker Hand Evaluator\n\nPoker hand evaluator using the Two Plus Two alogorithm and lookup table.\nThe lookup table HandRa"
  },
  {
    "path": "test/poker-evaluator.spec.js",
    "chars": 1232,
    "preview": "const PokerEvaluator = require('../lib/PokerEvaluator');\n\ndescribe('evalHand', function() {\n  describe('should throw', f"
  },
  {
    "path": "test/speedtest.js",
    "chars": 2285,
    "preview": "var evaluator = require(\"..\");\nvar path = require(\"path\");\nvar assert = require(\"assert\");\n\nfunction enumerateAllHands()"
  }
]

About this extraction

This page contains the full source code of the chenosaurus/poker-evaluator GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 8 files (9.7 KB), approximately 3.7k tokens, and a symbol index with 1 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!