Skip to content

Instantly share code, notes, and snippets.

@zachmayer
Created December 5, 2011 14:07
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save zachmayer/1433677 to your computer and use it in GitHub Desktop.
Save zachmayer/1433677 to your computer and use it in GitHub Desktop.
pokeR
#!/usr/bin/env python
# encoding: utf-8
#Constants.R
#Created by Kenneth J. Shackleton on 14 June 2011.
#Copyright (c) 2011 Ringo Limited.
#All rights reserved.
#R Port by Zach Mayer on 4 December 2011
DECK_SIZE = 52
INDEX_OF_SEVEN_OF_SPADES = 32
INDEX_OF_EIGHT_OF_CLUBS = 31
NUMBER_OF_SUITS = 4
NUMBER_OF_FACES = 13
SPADE = 0
HEART = 1
DIAMOND = 8
CLUB = 57
TWO_FIVE = 0
THREE_FIVE = 1
FOUR_FIVE = 5
FIVE_FIVE = 22
SIX_FIVE = 94
SEVEN_FIVE = 312
EIGHT_FIVE = 992
NINE_FIVE = 2422
TEN_FIVE = 5624
JACK_FIVE = 12522
QUEEN_FIVE = 19998
KING_FIVE = 43258
ACE_FIVE = 79415
TWO_FLUSH = 1
THREE_FLUSH = 2
FOUR_FLUSH = 4
FIVE_FLUSH = 8
SIX_FLUSH = 16
SEVEN_FLUSH = 32
EIGHT_FLUSH = 64
NINE_FLUSH = (EIGHT_FLUSH+SEVEN_FLUSH+SIX_FLUSH+FIVE_FLUSH+FOUR_FLUSH+THREE_FLUSH+TWO_FLUSH+1) #128
TEN_FLUSH = (NINE_FLUSH+EIGHT_FLUSH+SEVEN_FLUSH+SIX_FLUSH+FIVE_FLUSH+FOUR_FLUSH+THREE_FLUSH+1) #255
JACK_FLUSH = (TEN_FLUSH+NINE_FLUSH+EIGHT_FLUSH+SEVEN_FLUSH+SIX_FLUSH+FIVE_FLUSH+FOUR_FLUSH+1) #508
QUEEN_FLUSH = (JACK_FLUSH+TEN_FLUSH+NINE_FLUSH+EIGHT_FLUSH+SEVEN_FLUSH+SIX_FLUSH+FIVE_FLUSH+1) #1012
KING_FLUSH = (QUEEN_FLUSH+JACK_FLUSH+TEN_FLUSH+NINE_FLUSH+EIGHT_FLUSH+SEVEN_FLUSH+SIX_FLUSH+1) #2016
ACE_FLUSH = (KING_FLUSH+QUEEN_FLUSH+JACK_FLUSH+TEN_FLUSH+NINE_FLUSH+EIGHT_FLUSH+SEVEN_FLUSH+1) #4016
#_SEVEN tag suppressed
TWO = 0
THREE = 1
FOUR = 5
FIVE = 22
SIX = 98
SEVEN = 453
EIGHT = 2031
NINE = 8698
TEN = 22854
JACK = 83661
QUEEN = 262349
KING = 636345
ACE = 1479181
#end of _SEVEN tag suppressed
MAX_FIVE_NONFLUSH_KEY_INT = ((4*ACE_FIVE)+KING_FIVE)
MAX_FIVE_FLUSH_KEY_INT = (ACE_FLUSH+KING_FLUSH+QUEEN_FLUSH+JACK_FLUSH+TEN_FLUSH)
MAX_SEVEN_FLUSH_KEY_INT = (ACE_FLUSH+KING_FLUSH+QUEEN_FLUSH+JACK_FLUSH+TEN_FLUSH+NINE_FLUSH+EIGHT_FLUSH)
MAX_NONFLUSH_KEY_INT = ((4*ACE)+(3*KING))
MAX_FLUSH_CHECK_SUM = (7*CLUB)
L_WON = -1
R_WON = 1
DRAW = 0
CIRCUMFERENCE_FIVE = 187853
CIRCUMFERENCE_SEVEN = 4565145
#/////////
#//The following are used with NSAssert for
#//debugging, ignored by release mode
RANK_OF_A_WORST_HAND = 0
RANK_OF_A_BEST_HAND = 7462
RANK_OF_WORST_FLUSH = 5864
RANK_OF_BEST_NON_STRAIGHT_FLUSH = 7140
RANK_OF_WORST_STRAIGHT = 5854
RANK_OF_BEST_STRAIGHT = 5863
RANK_OF_WORST_STRAIGHT_FLUSH = 7453
RANK_OF_BEST_STRAIGHT_FLUSH = RANK_OF_A_BEST_HAND
KEY_COUNT = 53924
NON_FLUSH_KEY_COUNT = 49205
FLUSH_KEY_COUNT = 4719
#/////////
#Used in flush checking. These must be distinct from each of the suits.
UNVERIFIED = -2
NOT_A_FLUSH = -1
#/////////
#Bit masks
SUIT_BIT_MASK = 511
NON_FLUSH_BIT_SHIFT = 9
#/////////
#!/usr/bin/littler
# encoding: utf-8
#FiveEval.R
#Created by Kenneth J. Shackleton on 14 June 2011.
#Copyright (c) 2011 Ringo Limited.
#All rights reserved.
#R Port by Zach Mayer on 4 December 2011
FiveEval <- list(
rankArray = rep(0,MAX_FIVE_NONFLUSH_KEY_INT + 1),
flushRankArray = rep(0,MAX_FIVE_FLUSH_KEY_INT + 1),
deckcardsFace = rep(0,DECK_SIZE),
deckcardsFlush = rep(0,DECK_SIZE),
deckcardsSuit = rep(0,DECK_SIZE),
face = c(TWO_FIVE, THREE_FIVE, FOUR_FIVE,
FIVE_FIVE, SIX_FIVE, SEVEN_FIVE,
EIGHT_FIVE, NINE_FIVE, TEN_FIVE,
JACK_FIVE, QUEEN_FIVE, KING_FIVE,
ACE_FIVE),
faceFlush = c(TWO_FLUSH, THREE_FLUSH,
FOUR_FLUSH, FIVE_FLUSH,
SIX_FLUSH, SEVEN_FLUSH,
EIGHT_FLUSH, NINE_FLUSH,
TEN_FLUSH, JACK_FLUSH,
QUEEN_FLUSH, KING_FLUSH,
ACE_FLUSH)
)
for (n in seq(0,NUMBER_OF_FACES-1)) {
FiveEval$deckcardsSuit[4*n + 1] = SPADE
FiveEval$deckcardsSuit[4*n + 2] = HEART
FiveEval$deckcardsSuit[4*n + 3] = DIAMOND
FiveEval$deckcardsSuit[4*n + 4] = CLUB
FiveEval$deckcardsFace[4*n + 1] = FiveEval$face[12 - n + 1]
FiveEval$deckcardsFace[4*n + 2] = FiveEval$face[12 - n + 1]
FiveEval$deckcardsFace[4*n + 3] = FiveEval$face[12 - n + 1]
FiveEval$deckcardsFace[4*n + 4] = FiveEval$face[12 - n + 1]
FiveEval$deckcardsFlush[4*n + 1] = FiveEval$faceFlush[12 - n + 1]
FiveEval$deckcardsFlush[4*n + 2] = FiveEval$faceFlush[12 - n + 1]
FiveEval$deckcardsFlush[4*n + 3] = FiveEval$faceFlush[12 - n + 1]
FiveEval$deckcardsFlush[4*n + 4] = FiveEval$faceFlush[12 - n + 1]
}
# n increments as rank.
n = 0
# High card.
for (i in seq(5, NUMBER_OF_FACES-1)) {
for (j in seq(3, i-1)) {
for (k in seq(2, j-1)) {
for (l in seq(1, k-1)) {
# No straights
for (m in seq(0, l-1)) {
if (! (i - m == 4 | (i == 12 & j == 3 & k == 2 & l == 1 & m == 0))) {
n <- n+1
FiveEval$rankArray[FiveEval$face[i + 1] + FiveEval$face[j + 1] + FiveEval$face[k + 1] + FiveEval$face[l + 1] + FiveEval$face[m + 1] + 1] = n
}
}
}
}
}
}
# Pair.
for (i in seq(0, NUMBER_OF_FACES-1)) {
for (j in seq(2, NUMBER_OF_FACES-1)) {
for (k in seq(1, j-1)) {
for (l in seq(0, k-1)) {
if ((i != j & i != k & i != l)) {
n <- n+1
FiveEval$rankArray[(2*FiveEval$face[i + 1]) + FiveEval$face[j + 1] + FiveEval$face[k + 1] + FiveEval$face[l + 1] + 1] = n
}
}
}
}
}
# Two pair.
for (i in seq(1, NUMBER_OF_FACES-1)) {
for (j in seq(0, i-1)) {
for (k in seq(0, NUMBER_OF_FACES-1)) {
# No fullhouse
if (k != i & k != j) {
n <- n+1
FiveEval$rankArray[(2*FiveEval$face[i + 1]) + (2*FiveEval$face[j + 1]) + FiveEval$face[k + 1] + 1] = n
}
}
}
}
# Triple.
for (i in seq(0, NUMBER_OF_FACES-1)) {
for (j in seq(1, NUMBER_OF_FACES-1)) {
for (k in seq(0, j-1)) {
# No quad
if (i != j & i != k) {
n <- n+1
FiveEval$rankArray[(3*FiveEval$face[i + 1]) + FiveEval$face[j + 1] + FiveEval$face[k + 1] + 1] = n
}
}
}
}
# Low straight non-flush.
n <- n+1
FiveEval$rankArray[FiveEval$face[12 + 1] + FiveEval$face[0 + 1] + FiveEval$face[1 + 1] + FiveEval$face[2 + 1] + FiveEval$face[3 + 1] + 1] = n
# Usual straight non-flush.
for (i in seq(0, 9-1)) {
n <- n+1
FiveEval$rankArray[FiveEval$face[i + 1] + FiveEval$face[i+2] + FiveEval$face[i+3] + FiveEval$face[i+4] + FiveEval$face[i+5] + 1] = n
}
# Flush not a straight.
for (i in seq(5, NUMBER_OF_FACES-1)) {
for (j in seq(3, i-1)) {
for (k in seq(2, j-1)) {
for (l in seq(1, k-1)) {
for (m in seq(0, l-1)) {
if (! (i - m == 4 | (i == 12 & j == 3 & k == 2 & l == 1 & m == 0))) {
n <- n+1
FiveEval$flushRankArray[FiveEval$faceFlush[i + 1] + FiveEval$faceFlush[j + 1] + FiveEval$faceFlush[k + 1] + FiveEval$faceFlush[l + 1] + FiveEval$faceFlush[m + 1] + 1] = n
}
}
}
}
}
}
# Full house.
for (i in seq(0, NUMBER_OF_FACES-1)) {
for (j in seq(0, NUMBER_OF_FACES-1)) {
if (i != j) {
n <- n+1
FiveEval$rankArray[(3*FiveEval$face[i + 1]) + (2*FiveEval$face[j + 1]) + 1] = n
}
}
}
# Quad.
for (i in seq(0, NUMBER_OF_FACES-1)) {
for (j in seq(0, NUMBER_OF_FACES-1)) {
if (i != j) {
n <- n+1
FiveEval$rankArray[(4*FiveEval$face[i + 1]) + FiveEval$face[j + 1] + 1] = n
}
}
}
# Low straight flush.
n <- n+1
FiveEval$flushRankArray[FiveEval$faceFlush[0 + 1] + FiveEval$faceFlush[1 + 1] + FiveEval$faceFlush[2 + 1] + FiveEval$faceFlush[3 + 1] + FiveEval$faceFlush[12 + 1] + 1] = n;
# Usual straight flush.
for (i in seq(0, 9-1)) {
n <- n+1
FiveEval$flushRankArray[FiveEval$faceFlush[i+1] + FiveEval$faceFlush[i+2] + FiveEval$faceFlush[i+3] + FiveEval$faceFlush[i+4] + FiveEval$faceFlush[i+5] + 1] = n
}
FiveEval$getRankOfFive <- function(card_1, card_2, card_3, card_4, card_5) {
if (FiveEval$deckcardsSuit[card_1+1] == FiveEval$deckcardsSuit[card_2+1] &
FiveEval$deckcardsSuit[card_1+1] == FiveEval$deckcardsSuit[card_3+1] &
FiveEval$deckcardsSuit[card_1+1] == FiveEval$deckcardsSuit[card_4+1] &
FiveEval$deckcardsSuit[card_1+1] == FiveEval$deckcardsSuit[card_5+1]) {
return(FiveEval$flushRankArray[FiveEval$deckcardsFlush[card_1+1] +
FiveEval$deckcardsFlush[card_2+1] +
FiveEval$deckcardsFlush[card_3+1] +
FiveEval$deckcardsFlush[card_4+1] +
FiveEval$deckcardsFlush[card_5+1]+1])
} else {
return(FiveEval$rankArray[FiveEval$deckcardsFace[card_1+1] +
FiveEval$deckcardsFace[card_2+1] +
FiveEval$deckcardsFace[card_3+1] +
FiveEval$deckcardsFace[card_4+1] +
FiveEval$deckcardsFace[card_5+1]+1])
}
return(-1)
}
FiveEval$getRankOfSeven <- function(CARD1, CARD2, CARD3, CARD4, CARD5, CARD6, CARD7) {
seven_cards = c(CARD1, CARD2, CARD3, CARD4, CARD5, CARD6, CARD7)
five_temp = rep(0,5)
BEST_RANK_SO_FAR = 0
CURRENT_RANK = 0
m = 0
for (i in seq(1, 7-1)) {
for (j in seq(0, i-1)) {
m = 0
for (k in seq(0, 7-1)) {
if (k != i & k != j) {
five_temp[m+1] = seven_cards[k+1]
m <- m+1
}
}
CURRENT_RANK = FiveEval$getRankOfFive(five_temp[0+1], five_temp[1+1], five_temp[2+1], five_temp[3+1], five_temp[4+1])
if (BEST_RANK_SO_FAR < CURRENT_RANK) {
BEST_RANK_SO_FAR = CURRENT_RANK
}
}
}
return(BEST_RANK_SO_FAR)
}
library(compiler)
FiveEval$getRankOfFive <- cmpfun(FiveEval$getRankOfFive)
FiveEval$getRankOfSeven <- cmpfun(FiveEval$getRankOfSeven)
#!/usr/bin/littler
# encoding{ utf-8
#SevenEval.R
#Created by Kenneth J. Shackleton on 15 June 2011.
#Copyright (c) 2011 Ringo Limited.
#All rights reserved.
#R Port by Zach Mayer on 4 December 2011
require(bitops)
SevenEval <- list()
SevenEval$rankArray = rep(0,CIRCUMFERENCE_SEVEN)
SevenEval$flushRankArray = rep(0,MAX_SEVEN_FLUSH_KEY_INT + 1)
SevenEval$deckcardsKey = rep(0,DECK_SIZE)
SevenEval$deckcardsFlush = rep(0,DECK_SIZE)
SevenEval$deckcardsSuit = rep(0,DECK_SIZE)
SevenEval$flushCheck = rep(0,MAX_FLUSH_CHECK_SUM + 1)
SevenEval$face = c(ACE, KING, QUEEN, JACK, TEN,
NINE, EIGHT, SEVEN, SIX, FIVE,
FOUR, THREE, TWO)
SevenEval$faceFlush = c(ACE_FLUSH, KING_FLUSH, QUEEN_FLUSH,
JACK_FLUSH, TEN_FLUSH, NINE_FLUSH,
EIGHT_FLUSH, SEVEN_FLUSH, SIX_FLUSH,
FIVE_FLUSH, FOUR_FLUSH, THREE_FLUSH,
TWO_FLUSH)
for (n in seq(0, NUMBER_OF_FACES-1)) {
SevenEval$deckcardsKey[4*n + 1] = bitShiftL(SevenEval$face[n + 1], NON_FLUSH_BIT_SHIFT) + SPADE
SevenEval$deckcardsKey[4*n + 2] = bitShiftL(SevenEval$face[n + 1], NON_FLUSH_BIT_SHIFT) + HEART
SevenEval$deckcardsKey[4*n + 3] = bitShiftL(SevenEval$face[n + 1], NON_FLUSH_BIT_SHIFT) + DIAMOND
SevenEval$deckcardsKey[4*n + 4] = bitShiftL(SevenEval$face[n + 1], NON_FLUSH_BIT_SHIFT) + CLUB
SevenEval$deckcardsFlush[4*n + 1] = SevenEval$faceFlush[n + 1]
SevenEval$deckcardsFlush[4*n + 2] = SevenEval$faceFlush[n + 1]
SevenEval$deckcardsFlush[4*n + 3] = SevenEval$faceFlush[n + 1]
SevenEval$deckcardsFlush[4*n + 4] = SevenEval$faceFlush[n + 1]
SevenEval$deckcardsSuit[4*n + 1] = SPADE
SevenEval$deckcardsSuit[4*n + 2] = HEART
SevenEval$deckcardsSuit[4*n + 3] = DIAMOND
SevenEval$deckcardsSuit[4*n + 4] = CLUB
}
# Track increments.
count = 0
# High card.
for (i in seq(1, NUMBER_OF_FACES-1)) {
for (j in seq(1, i+1-1)) {
for (k in seq(1, j+1-1)) {
for (l in seq(0, k+1-1)) {
for (m in seq(0, l+1-1)) {
for (n in seq(0, m+1-1)) {
for (p in seq(0, n+1-1)) {
if (i != m & j != n & k != p) {
count <- count+1
key = SevenEval$face[i + 1] + SevenEval$face[j + 1] + SevenEval$face[k + 1] + SevenEval$face[l + 1] + SevenEval$face[m + 1] + SevenEval$face[n + 1] + SevenEval$face[p + 1]
# The 4*i+0 and 4*m+1 trick prevents flushes.
rank = FiveEval$getRankOfSeven(4*i, 4*j, 4*k, 4*l, 4*m+1, 4*n+1, 4*p+1)
SevenEval$rankArray[(key %% CIRCUMFERENCE_SEVEN) + 1] = rank
}
}
}
}
}
}
}
}
# Flush ranks.
# All 7 same suit.
for (i in seq(6, NUMBER_OF_FACES-1)) {
for (j in seq(5, i-1)) {
for (k in seq(4, j-1)) {
for (l in seq(3, k-1)) {
for (m in seq(2, l-1)) {
for (n in seq(1, m-1)) {
for (p in seq(0, n-1)) {
count <- count + 1
key = SevenEval$faceFlush[i + 1] + SevenEval$faceFlush[j + 1] + SevenEval$faceFlush[k + 1] + SevenEval$faceFlush[l + 1] + SevenEval$faceFlush[m + 1] + SevenEval$faceFlush[n + 1] + SevenEval$faceFlush[p + 1]
rank = FiveEval$getRankOfSeven(4*i, 4*j, 4*k, 4*l, 4*m, 4*n, 4*p)
SevenEval$flushRankArray[key + 1] = rank
}
}
}
}
}
}
}
# Only 6 same suit.
for (i in seq(5, NUMBER_OF_FACES-1)) {
for (j in seq(4, i-1)) {
for (k in seq(3, j-1)) {
for (l in seq(2, k-1)) {
for (m in seq(1, l-1)) {
for (n in seq(0, m-1)) {
count <- count + 1
key = SevenEval$faceFlush[i + 1] + SevenEval$faceFlush[j + 1] + SevenEval$faceFlush[k + 1] + SevenEval$faceFlush[l + 1] + SevenEval$faceFlush[m + 1] + SevenEval$faceFlush[n + 1]
# The Two of clubs is the card at index 51; the other six
# cards all have the spade suit.
rank = FiveEval$getRankOfSeven(4*i, 4*j, 4*k, 4*l, 4*m, 4*n, 51)
SevenEval$flushRankArray[key + 1] = rank
}
}
}
}
}
}
# Only 5 same suit.
for (i in seq(4, NUMBER_OF_FACES-1)) {
for (j in seq(3, i-1)) {
for (k in seq(2, j-1)) {
for (l in seq(1, k-1)) {
for (m in seq(0, l-1)) {
count <- count + 1
key = SevenEval$faceFlush[i + 1] + SevenEval$faceFlush[j + 1] + SevenEval$faceFlush[k + 1] + SevenEval$faceFlush[l + 1] + SevenEval$faceFlush[m + 1]
rank = FiveEval$getRankOfFive(4*i, 4*j, 4*k, 4*l, 4*m);
SevenEval$flushRankArray[key + 1] = rank
}
}
}
}
}
# Initialise flush checks.
SUIT_COUNT = 0
FLUSH_SUIT_INDEX = -1
card_S_MATCHED_SO_FAR = 0
SUIT_KEY = SPADE
suits = c(SPADE, HEART, DIAMOND, CLUB)
# Initialise all entries of flushCheck[] to UNVERIFIED, as yet unchecked.
SevenEval$flushCheck = rep(UNVERIFIED,MAX_FLUSH_CHECK_SUM + 1)
# 7-card flush.
for (card_1 in seq(0, NUMBER_OF_SUITS-1)) {
for (card_2 in seq(0, card_1 + 1-1)) {
for (card_3 in seq(0, card_2 + 1-1)) {
for (card_4 in seq(0, card_3 + 1-1)) {
for (card_5 in seq(0, card_4 + 1-1)) {
for (card_6 in seq(0, card_5 + 1-1)) {
for (card_7 in seq(0, card_6 + 1-1)) {
SUIT_COUNT = 0
FLUSH_SUIT_INDEX = -1
CARDS_MATCHED_SO_FAR = 0
SUIT_KEY = suits[card_1 + 1] + suits[card_2 + 1] + suits[card_3 + 1] +
suits[card_4 + 1] + suits[card_5 + 1] + suits[card_6 + 1] +
suits[card_7 + 1]
if (SevenEval$flushCheck[SUIT_KEY + 1] == UNVERIFIED) {
while (CARDS_MATCHED_SO_FAR < 3 & FLUSH_SUIT_INDEX < 4) {
FLUSH_SUIT_INDEX = FLUSH_SUIT_INDEX+1
SUIT_COUNT = (suits[card_1 + 1] == suits[FLUSH_SUIT_INDEX + 1]) +
(suits[card_2 + 1] == suits[FLUSH_SUIT_INDEX + 1]) +
(suits[card_3 + 1] == suits[FLUSH_SUIT_INDEX + 1]) +
(suits[card_4 + 1] == suits[FLUSH_SUIT_INDEX + 1]) +
(suits[card_5 + 1] == suits[FLUSH_SUIT_INDEX + 1]) +
(suits[card_6 + 1] == suits[FLUSH_SUIT_INDEX + 1]) +
(suits[card_7 + 1] == suits[FLUSH_SUIT_INDEX + 1])
CARDS_MATCHED_SO_FAR = CARDS_MATCHED_SO_FAR+SUIT_COUNT
}
}
# A count of 5 or more means we have a flush. We place
# the value of the flush suit here.
if (SUIT_COUNT > 4) {
SevenEval$flushCheck[SUIT_KEY + 1] = suits[FLUSH_SUIT_INDEX + 1]
} else { # Otherwise this is a non-flush hand.
SevenEval$flushCheck[SUIT_KEY + 1] = NOT_A_FLUSH
}
}
}
}
}
}
}
}
SevenEval$getRankOfSeven <- function(card_1, card_2, card_3, card_4, card_5, card_6, card_7) {
# Create a 7-card hand key by adding up each of the card keys.
KEY = SevenEval$deckcardsKey[card_1 + 1] +
SevenEval$deckcardsKey[card_2 + 1] +
SevenEval$deckcardsKey[card_3 + 1] +
SevenEval$deckcardsKey[card_4 + 1] +
SevenEval$deckcardsKey[card_5 + 1] +
SevenEval$deckcardsKey[card_6 + 1] +
SevenEval$deckcardsKey[card_7 + 1]
# Tear off the flush check strip.
FLUSH_CHECK_KEY = bitAnd(KEY, SUIT_BIT_MASK )
FLUSH_SUIT = SevenEval$flushCheck[FLUSH_CHECK_KEY + 1]
if (FLUSH_SUIT == NOT_A_FLUSH) {
# Tear off the non-flush key strip, and look up the rank.
KEY = bitShiftR(KEY, NON_FLUSH_BIT_SHIFT)
# Take key modulo the circumference. A dichotomy is faster than using
# the usual modulus operation. This is fine for us because the circumference
# is more than half the largest SevenEval$face key we come across.
rank = ifelse(KEY < CIRCUMFERENCE_SEVEN, SevenEval$rankArray[KEY + 1], SevenEval$rankArray[KEY - CIRCUMFERENCE_SEVEN + 1])
return(rank)
} else {
# print "flush"
# Generate a flush key, and look up the rank.
FLUSH_KEY = ifelse(SevenEval$deckcardsSuit[card_1 + 1] == FLUSH_SUIT, SevenEval$deckcardsFlush[card_1 + 1], 0) +
ifelse(SevenEval$deckcardsSuit[card_2 + 1] == FLUSH_SUIT, SevenEval$deckcardsFlush[card_2 + 1], 0) +
ifelse(SevenEval$deckcardsSuit[card_3 + 1] == FLUSH_SUIT, SevenEval$deckcardsFlush[card_3 + 1], 0) +
ifelse(SevenEval$deckcardsSuit[card_4 + 1] == FLUSH_SUIT, SevenEval$deckcardsFlush[card_4 + 1], 0) +
ifelse(SevenEval$deckcardsSuit[card_5 + 1] == FLUSH_SUIT, SevenEval$deckcardsFlush[card_5 + 1], 0) +
ifelse(SevenEval$deckcardsSuit[card_6 + 1] == FLUSH_SUIT, SevenEval$deckcardsFlush[card_6 + 1], 0) +
ifelse(SevenEval$deckcardsSuit[card_7 + 1] == FLUSH_SUIT, SevenEval$deckcardsFlush[card_7 + 1], 0)
#print(FLUSH_KEY)
return(SevenEval$flushRankArray[FLUSH_KEY + 1])
}
return(-1)
}
library(compiler)
SevenEval$getRankOfSeven <- cmpfun(SevenEval$getRankOfSeven)
#RCPP version
SevenEval$getRankOfSeven <- function(card_1, card_2, card_3, card_4, card_5, card_6, card_7) {
# Create a 7-card hand key by adding up each of the card keys.
KEY = SevenEval$deckcardsKey[card_1 + 1] +
SevenEval$deckcardsKey[card_2 + 1] +
SevenEval$deckcardsKey[card_3 + 1] +
SevenEval$deckcardsKey[card_4 + 1] +
SevenEval$deckcardsKey[card_5 + 1] +
SevenEval$deckcardsKey[card_6 + 1] +
SevenEval$deckcardsKey[card_7 + 1]
# Tear off the flush check strip.
FLUSH_CHECK_KEY = bitAnd(KEY, SUIT_BIT_MASK )
FLUSH_SUIT = SevenEval$flushCheck[FLUSH_CHECK_KEY + 1]
if (FLUSH_SUIT == NOT_A_FLUSH) {
# Tear off the non-flush key strip, and look up the rank.
KEY = bitShiftR(KEY, NON_FLUSH_BIT_SHIFT)
# Take key modulo the circumference. A dichotomy is faster than using
# the usual modulus operation. This is fine for us because the circumference
# is more than half the largest SevenEval$face key we come across.
rank = ifelse(KEY < CIRCUMFERENCE_SEVEN, SevenEval$rankArray[KEY + 1], SevenEval$rankArray[KEY - CIRCUMFERENCE_SEVEN + 1])
return(rank)
} else {
# print "flush"
# Generate a flush key, and look up the rank.
FLUSH_KEY = ifelse(SevenEval$deckcardsSuit[card_1 + 1] == FLUSH_SUIT, SevenEval$deckcardsFlush[card_1 + 1], 0) +
ifelse(SevenEval$deckcardsSuit[card_2 + 1] == FLUSH_SUIT, SevenEval$deckcardsFlush[card_2 + 1], 0) +
ifelse(SevenEval$deckcardsSuit[card_3 + 1] == FLUSH_SUIT, SevenEval$deckcardsFlush[card_3 + 1], 0) +
ifelse(SevenEval$deckcardsSuit[card_4 + 1] == FLUSH_SUIT, SevenEval$deckcardsFlush[card_4 + 1], 0) +
ifelse(SevenEval$deckcardsSuit[card_5 + 1] == FLUSH_SUIT, SevenEval$deckcardsFlush[card_5 + 1], 0) +
ifelse(SevenEval$deckcardsSuit[card_6 + 1] == FLUSH_SUIT, SevenEval$deckcardsFlush[card_6 + 1], 0) +
ifelse(SevenEval$deckcardsSuit[card_7 + 1] == FLUSH_SUIT, SevenEval$deckcardsFlush[card_7 + 1], 0)
#print(FLUSH_KEY)
return(SevenEval$flushRankArray[FLUSH_KEY + 1])
}
return(-1)
}
rm(list = ls(all = TRUE))
setwd('~/SpecialK/R')
source('Evaluator/Constants.R')
source('Evaluator/FiveEval.R')
source('Evaluator/SevenEval.R')
#Convert human-readable cards to integers
card <- function(x) {
allCards <- paste(
do.call(c,lapply(c('A','K','Q','J','T',9:2),function(x) rep(x,4))),
c('s','h','d','c'), sep='')
which(allCards==x)-1
}
card('As')
card('2d')
#Wrapper for the evaluator
evaluate <- function(hand) {
hand <- do.call(c,lapply(hand,card))
SevenEval$getRankOfSeven(hand[1], hand[2], hand[3], hand[4], hand[5], hand[6], hand[7])
}
evaluate(c('As','Ks','Qs','Js','Ts','8d','7d'))
evaluate(c('As','Ks','Qs','Td','9d','8d','7d'))
evaluate(c('7s','6s','5s','4s','2d','9d','Td'))
#Generate 10,000 random hands
randomHand <- function(...) {
sample(0:51,7)
}
n <- 10000
hands <- lapply(1:n,randomHand)
#Evaluate them!
evaluate <- function(hand) {
SevenEval$getRankOfSeven(hand[1], hand[2], hand[3], hand[4], hand[5], hand[6], hand[7])
}
T <- system.time(lapply(hands,evaluate))
c('Hands Per Second'=as.numeric(round(n/T['elapsed'],0)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment