?
So nachdem mir heute Nacht einige Lichter aufgegangen sind bezüglich C++ hab ich es jetzt geschafft. Herzlichen Dank dafür an alle insbesondere der Tipp (und der Beispielcode) mit dem struct war zielführend. Und nebenbei noch ein bisschen was über Ruby gelernt. Ich hab jetzt 1 Millionen durchläufe für 3 Spieler in gefühlt einer Sekunde. Das sollte erstmal ausreichen. Bei Bedarf werd ich es noch mit OpenCL erweitern.
Rein interessehalber hät ich allerdings noch zwei Fragen:
1. Was bedeutet dieser gcc output(g++ Evaluator.cpp -o eval.exe):
Info: resolving std::nothrow by linking to __imp___ZSt7nothrow (auto-importc:/mingw/bin/../lib/gcc/mingw32/4.5.0/../../../../mingw32/bin/ld.exe: warning: auto-importing has been activated without --enable-auto-import specified on the command line.
This should work unless it involves constant data structures referencing symbols from auto-imported DLLs.)
2. Warum funktioniert HandLookup als C Version hier nicht:
require 'inline'
class HandLookup
def initialize
file = File.new(Dir.pwd + "/HandRanks.dat", "rb")
file.binmode()
rank_table_string = file.read()
file.close()
@rank_table = rank_table_string.unpack("l*")
end
def eval_hand_7(ary_cards)
p = 53
ary_cards.each do |pc|
p = pc + p
p = @rank_table[p]
end
return p
end
end
class HandLookupC
inline(:C) do |code|
code.include '<stdio.h>'
code.c '
int HR[32487834];
int InitTheEvaluator()
{
memset(HR, 0, sizeof(HR));
FILE * fin = fopen("HandRanks.dat", "rb");
size_t bytesread = fread(HR, sizeof(HR), 1, fin);
fclose(fin);
}
int GetHandValue(int* pCards)
{
int p = HR[53 + *pCards++];
p = HR[p + *pCards++];
p = HR[p + *pCards++];
p = HR[p + *pCards++];
p = HR[p + *pCards++];
p = HR[p + *pCards++];
return HR[p + *pCards++];
}'
end
end
Hier noch der Code wenns jemanden interessiert:
#include <stdlib.h>
#include <windows.h>
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <time.h>
using namespace std;
struct Tuple
{
int first;
int second;
};
int HR[32487834];
int randCards[52];
int hand_categories[] = {0, 1277, 4137, 4995, 5853, 5863, 7140, 7296, 7452, 7462};
int InitTheEvaluator()
{
memset(HR, 0, sizeof(HR));
FILE * fin = fopen("HandRanks.dat", "rb");
size_t bytesread = fread(HR, sizeof(HR), 1, fin);
fclose(fin);
}
int GetHandValue(int* pCards)
{
int p = HR[53 + *pCards++];
p = HR[p + *pCards++];
p = HR[p + *pCards++];
p = HR[p + *pCards++];
p = HR[p + *pCards++];
p = HR[p + *pCards++];
return HR[p + *pCards++];
}
int PickRandomCard()
{
int random_card = 0;
while (random_card == 0) {
char rand_nbr = rand() % 52;
random_card = randCards[rand_nbr];
randCards[rand_nbr] = 0;
}
return random_card;
}
bool pred(const Tuple& lhs, const Tuple& rhs)
{
return lhs.second > rhs.second;
}
void MonteCarlo(int rounds, char players, int player_cards[][2], int* com_cards, int* odds)
{
srand(time(NULL));
int i;
int ii;
int loop;
int com_cards_t[5];
int player_cards_t[players][2];
Tuple ranks[players];
for (loop = 0; loop < rounds; loop++) {
for (i = 0; i < 52; i++) {
randCards[i] = i+1;
}
for (i = 0; i < 5; i++) {
if (com_cards[i] != 0) {
com_cards_t[i] = com_cards[i];
randCards[com_cards[i]-1] = 0;
}
}
for (i = 0; i < players; i++) {
for (ii = 0; ii < 2; ii++) {
if (player_cards[i][ii] != 0) {
player_cards_t[i][ii] = player_cards[i][ii];
randCards[player_cards[i][ii]-1] = 0;
}
}
}
for (i = 0; i < 5; i++) {
if (com_cards[i] == 0) {
com_cards_t[i] = PickRandomCard();
}
}
for (i = 0; i < players; i++) {
for (ii = 0; ii < 2; ii++) {
if (player_cards[i][ii] == 0) {
player_cards_t[i][ii] = PickRandomCard();
}
}
}
for (i = 0; i < players; i++) {
int eval_array[] = { player_cards_t[i][0], player_cards_t[i][1], com_cards_t[0], com_cards_t[1], com_cards_t[2], com_cards_t[3], com_cards_t[4] };
int value_t = GetHandValue(eval_array);
ranks[i].first = i;
ranks[i].second = hand_categories[(value_t >> 12)-1] + (value_t & 0x00000FFF);
}
stable_sort(ranks, ranks+players, pred);
odds[ranks[0].first] = odds[ranks[0].first] + 1;
for (i = 1; i < players; i++) {
if (ranks[i].second == ranks[i-1].second) {
odds[ranks[i].first] = odds[ranks[i].first] + 1;
}
}
}
}
int main() {
InitTheEvaluator();
int player_cards[][2] = {{2, 35}, {22, 13}, {26, 7}};
int com_cards[] = {1, 5, 24, 0, 0};
int odds[] = {0, 0, 0};
MonteCarlo(1000000, 3, player_cards, com_cards, odds);
printf("%d %d %d", odds[0], odds[1], odds[2]);
}