मुझे पता है कि आपने कहा है कि आप मेमोरी पदचिह्न को जितना संभव हो सके रखना चाहते हैं, लेकिन एक बहुत मेमोरी कुशल लुकअप टेबल ऑप्टिमाइज़ेशन है जिसे मैंने कुछ पोकर हैंड मूल्यांकनकर्ताओं में उपयोग किया है और मैंने इसे स्वयं इस्तेमाल किया है। यदि आप भारी पोकर सिमुलेशन कर रहे हैं और सर्वोत्तम संभव प्रदर्शन की आवश्यकता है, तो आप इसे विचार करना चाहेंगे। हालांकि मैं इस मामले में प्रवेश करता हूं, अंतर इतना बड़ा नहीं है क्योंकि सीधे ड्रॉ के लिए परीक्षण बहुत महंगा संचालन नहीं है, लेकिन उसी सिद्धांत का उपयोग पोकर प्रोग्रामिंग में हर प्रकार के हाथ मूल्यांकन के लिए किया जा सकता है।
विचार हम एक हैश समारोह निम्नलिखित गुण है कि एक तरह का बनाने के है जो:
1) की गणना करता है कार्ड के प्रत्येक अलग सेट के लिए एक अनूठा मूल्य रैंकों
2) अर्थ में सममित है कि यह नहीं करता है 'है टी
के आदेश पर निर्भर करता है इसका उद्देश्य लुकअप तालिका में आवश्यक तत्वों की संख्या को कम करना है।
ऐसा करने का एक साफ तरीका प्रत्येक रैंक (2-> 2, 3-> 3, 4-> 5, 5-> 7, 6-> 11, 7-> 13, 8-> 17, 9-> 1 9, टी-> 23, जे-> 2 9, क्यू-> 31, के-> 37, ए-> 41), और फिर प्राइम के उत्पाद की गणना करें। उदाहरण के लिए यदि कार्ड 39TJQQ हैं, तो हैश 3653625 9 है।
लुकअप टेबल बनाने के लिए आप रैंक के सभी संभावित संयोजनों के माध्यम से जाते हैं, और यह निर्धारित करने के लिए कुछ सरल एल्गोरिदम का उपयोग करते हैं कि वे सीधे ड्रॉ बनाते हैं या नहीं। प्रत्येक संयोजन के लिए आप हैश मान की भी गणना करते हैं और फिर परिणामों को उस मानचित्र में संग्रहीत करते हैं जहां कुंजी हैश और मान सीधे ड्रॉ चेक का परिणाम है। यदि कार्ड की अधिकतम संख्या छोटी है (4 या उससे कम) तो एक रैखिक सरणी भी संभव हो सकती है।
लुकअप टेबल का उपयोग करने के लिए आप पहले कार्ड के विशेष सेट के लिए हैश की गणना करते हैं और फिर मानचित्र से संबंधित मान पढ़ते हैं।
यहां सी ++ में एक उदाहरण है। मैं गारंटी नहीं देता कि यह सही तरीके से काम कर रहा है और इसे शायद हैश_मैप के बजाय क्रमबद्ध सरणी और बाइनरी खोज का उपयोग करके बहुत अनुकूलित किया जा सकता है। इस उद्देश्य के लिए हैश_मैप थोड़ी धीमी है।
#include <iostream>
#include <vector>
#include <hash_map>
#include <numeric>
using namespace std;
const int MAXCARDS = 9;
stdext::hash_map<long long, bool> lookup;
//"Hash function" that is unique for a each set of card ranks, and also
//symmetric so that the order of cards doesn't matter.
long long hash(const vector<int>& cards)
{
static const int primes[52] = {
2,3,5,7,11,13,17,19,23,29,31,37,41,
2,3,5,7,11,13,17,19,23,29,31,37,41,
2,3,5,7,11,13,17,19,23,29,31,37,41,
2,3,5,7,11,13,17,19,23,29,31,37,41
};
long long res=1;
for(vector<int>::const_iterator i=cards.begin();i!=cards.end();i++)
res *= primes[*i];
return res;
}
//Tests whether there is a straight draw (assuming there is no
//straight). Only used for filling the lookup table.
bool is_draw_slow(const vector<int>& cards)
{
int ranks[14];
memset(ranks,0,14*sizeof(int));
for(vector<int>::const_iterator i=cards.begin();i!=cards.end();i++)
ranks[ *i % 13 + 1 ] = 1;
ranks[0]=ranks[13]; //ace counts also as 1
int count = ranks[0]+ranks[1]+ranks[2]+ranks[3];
for(int i=0; i<=9; i++) {
count += ranks[i+4];
if(count==4)
return true;
count -= ranks[i];
}
return false;
};
void create_lookup_helper(vector<int>& cards, int idx)
{
for(;cards[idx]<13;cards[idx]++) {
if(idx==cards.size()-1)
lookup[hash(cards)] = is_draw_slow(cards);
else {
cards[idx+1] = cards[idx];
create_lookup_helper(cards,idx+1);
}
}
}
void create_lookup()
{
for(int i=1;i<=MAXCARDS;i++) {
vector<int> cards(i);
create_lookup_helper(cards,0);
}
}
//Test for a draw using the lookup table
bool is_draw(const vector<int>& cards)
{
return lookup[hash(cards)];
};
int main(int argc, char* argv[])
{
create_lookup();
cout<<lookup.size()<<endl; //497419
int cards1[] = {1,2,3,4};
int cards2[] = {0,1,2,7,12};
int cards3[] = {3,16,29,42,4,17,30,43};
cout << is_draw(vector<int>(cards1,cards1+4)) <<endl; //true
cout << is_draw(vector<int>(cards2,cards2+5)) <<endl; //true
cout << is_draw(vector<int>(cards3,cards3+8)) <<endl; //false
}
सिर्फ हमारे लिए जो पोकर नहीं खेलता है, ड्रॉ क्या होता है? – Gorgen
@ गोरगेन सीधे बाद के रैंक के 5 कार्ड हैं (उदाहरण के लिए, ए 2 3 4 5 या 9 10 जे क्यू के)। एक ड्रॉ सीधे 5 कार्डों में से चार में से एक है। एक 'ओपन एंडेड' ड्रॉ का मतलब है कि 4 कार्ड्स क्रमिक हैं और इसमें शामिल नहीं है - उदाहरण के लिए, 2 3 4 5 या 8 9 10 जे। 'अंदर' ड्रॉ का मतलब है कि कार्ड क्रमिक नहीं हैं या इनमें ए - उदाहरण शामिल हैं, 2 3 5 6 या ए 2 3 4. –