Created
December 5, 2011 14:07
-
-
Save zachmayer/1433677 to your computer and use it in GitHub Desktop.
pokeR
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
#!/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 | |
#///////// |
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
#!/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) |
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
#!/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) | |
} |
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
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