2014-02-24 14 views
9

Ich habe eine Untersuchung über Poker Aktien durchgeführt. Was ich getan habe ist pokerstove Programm mit einigen ausgewählten. Und mit diesem Programm berechnet die Aktien unter Verwendung aller Methoden. So Pokerstove Ergebnisse:PHP Poker generierte zufällige Ergebnisse stimmen nicht mit dem, was erwartet wird

enter image description here

Ich habe auch eine Tabelle, wo ich die zufällige Ergebnisse speichern:

CREATE TABLE poker_results 
(
id int NOT NULL AUTO_INCREMENT, 
matches_id int NOT NULL, -- just for filtering in case I will want another starting hands. 
result varchar(255) NOT NULL, 
winner_hands varchar(255) NOT NULL, 
PRIMARY KEY (id) 
) 

Die Ergebnisspalte Daten wie folgt aussieht: Jd, 9d, Qh, 5c, Kc - Das sind die Karten an Bord.

Winner_hands Spalte Daten sehen so aus: Ks-Ac, 6c-Ad, 3c-Ah (kann 1 Hand gewonnen werden, kann alle 8 Hände gewonnen werden).

Hier ist der Code, der die Ergebnisse zur Datenbank generiert. Sein auf codeigniter Rahmen. Und auch nicht die ganze poker.php zu kopieren, ich kopiere nur einige Funktionen, die von ihm verwendet werden:

protected function get_probabilities($hands, $board_cards = array()) { 
     $players = count($hands); 

     $board = implode('', $board_cards); 
     $board = trim($board); 
     if (empty($board)) { 
      $board = '-'; 
     } 
     $hx = ''; 
     $hand_counter = 1; 

     foreach ($hands as $hand) { 
      $hx .= '&h' . $hand_counter++ . '=' . $hand[0] . $hand[1]; 
     } 

     $url = 'http://' . $this->poker_server . '/?board=' . $board . $hx . '&auth=' . $this->auth; 



     //Output exm. string '0.1342, 0.2042, 0.13525, 0.52635' 
     //WAR!! check if alive 
     $result = $this->parse_url_link($url); 

     if (substr($result, 0, 3) == 'Err') { 
      $this->utils->logging('ERROR', 'Poker server authorization failed!'); 
     } 

     //echo $result; 

     return array(
      'hands' => $hands, 
      'prob' => explode(', ', $result), 
      'board' => $board_cards 
     ); 
    } 


// protected because in child class needed 
    protected function get_poker_winner($table_winners) { 
     $to_return = array(); 
     foreach($table_winners['prob'] as $key => $val) { 
      if ($val > 0) { 
       $to_return[] = $table_winners['hands'][$key][0] . '-' . $table_winners['hands'][$key][1]; 
      } 
     } 

     return $to_return; 
    } 

poker_tests.php

<?php if (! defined('BASEPATH')) exit('No direct script access allowed'); 


include_once(APPPATH . 'controllers/poker.php');  
require_once APPPATH . "libraries/downloaded/Mersenne_twister.php"; 
use mersenne_twister\twister; 

class Poker_tests extends Poker { 

    public function __construct() { 
     parent::__construct(); 
    } 

    /** 
    * Generates data in database with such structure: 
    * CREATE TABLE matches 
    * (
    * id int NOT NULL AUTO_INCREMENT, 
    * player_cards varchar(255) NOT NULL, 
    * 
    * PRIMARY KEY (ID) 
    *) 
    * 
    * CREATE TABLE poker_results 
    * (
    * id int NOT NULL AUTO_INCREMENT, 
    * result varchar(255) NOT NULL, 
    * PRIMARY KEY (id) 
    *) 
    * 
    * 
    * Here 1 match will have many results, because we use same preflop cards. 
    * 
    * Text results appended to pokerstove.txt 
    * 
    * 376,992 games  0.013 secs 28,999,384 games/sec 
    * 
    * Board: 
    * Dead: 
    * 
    *   equity  win  tie    pots won pots tied 
    * Hand 0: 20.925%  20.53% 00.40%   77382  1504.50 { KhQs } 
    * Hand 1: 06.215%  03.50% 02.72%   13190  10239.00 { 9c4d } 
    * Hand 2: 06.396%  04.08% 02.32%   15379  8734.00 { 8d4c } 
    * Hand 3: 18.906%  18.15% 00.76%   68426  2847.50 { AcKs } 
    * Hand 4: 08.767%  06.91% 01.86%   26032  7019.50 { 9h2c } 
    * Hand 5: 10.204%  09.83% 00.38%   37044  1424.00 { Ad6c } 
    * Hand 6: 09.046%  08.67% 00.38%   32678  1424.00 { Ah3c } 
    * Hand 7: 19.541%  18.08% 01.46%   68154  5514.50 { 8c7c } 
    * 
    * 
    * --- 
    * 
    * 
    */ 
    public function run() { 

     $this->benchmark->mark('start'); 

     $this->output->enable_profiler(TRUE); 

     //close the current connection, because its not needed 
     $this->db->close(); 

     $db_poker = $this->load->database('poker_test', TRUE); 

     $sql = "INSERT INTO poker_results (result, winner_hands, matches_id) VALUES (?, ?, ?)"; 

     // matches_id = 1. Insert new match 
     $table8_hands = 'Kh,Qs,4d,9c,4c,8d,Ks,Ac,2c,9h,6c,Ad,3c,Ah,7c,8c'; // do test with this. Do those win the right amount of time? 

     for ($i=0; $i < 400000; $i++) { // pradejus id 100194 

      $flop = $this->poker_flop($table8_hands); 
      $turn = $this->poker_turn($flop, $table8_hands); 
      $river = $this->poker_stop($turn, $table8_hands); 
      //echo json_encode($river) . '<br>'; 

      $db_poker->query($sql, array($river['river_board'], implode(',', $river['winner_hands8']), 2)); 
     } 

     $db_poker->close(); 

     $this->benchmark->mark('end'); 
     echo $this->benchmark->elapsed_time('start', 'end') . '<br>'; 
    } 





    /** 
    * 
    * Override - remove unneeded things for test from that function in poker.php 
    * Generates 3 flop cards 
    */ 
    public function poker_flop($table8_hands) { 


     $table8_cards = explode(',', $table8_hands); 

     $table8_results = $this->random_result($table8_cards, 3); 

     return $table8_results; 

    } 

    /** 
    * Generates 1 turn card 
    * @param $table8_hands - same as match score in database. But here we have hardcoded in run function 
    * 
    */ 
    public function poker_turn($table8_flop, $table8_hands) { 

      $table8_cards = explode(',', $table8_hands); 

      //Join players cards and opened board cards   
      $table8_reserved_cards = array_merge($table8_cards, $table8_flop); 

      //Pass all opened cards and get one new board card   
      $table8_results = $this->random_result($table8_reserved_cards, 1); 

      //Merge all opened board cards 
      $table8_results = array_merge($table8_flop, $table8_results); 

      // this is flop and turn both   
      return $table8_results; 

    } 

    /** 
    * 
    * Generates 1 river card 
    */ 
    public function poker_stop($table8_flop_turn, $table8_hands) { 

     $table8_cards = explode(',', $table8_hands); 

     $table8_reserved_cards = array_merge($table8_cards, $table8_flop_turn); 

     $table8_results = $this->random_result($table8_reserved_cards, 1); 

     $table8_results = array_merge($table8_flop_turn, $table8_results); 


     $table8_hands = $this->array_to_hands_array($table8_cards); 

     $flop_turn_results = implode(',', $table8_results); 

     // $this->benchmark->mark('code_start'); 
     //Get new probabilities - they will be needed to determine if hand has won or not. When prob. > 0 - then won 
     $table8_prob = $this->get_probabilities($table8_hands, $table8_results); 

     // $this->benchmark->mark('code_end'); 
     // echo $this->benchmark->elapsed_time('code_start', 'code_end'); 

     return array(
      'winner_hands8' => $this->get_poker_winner($table8_prob), 
      'river_board' => $flop_turn_results 
     ); 

    } 


    /** 
    * for second generation - new random function 
    * @param array $reserved_cards 
    * @param integer $cards_amount 
    * @return array 
    */ 
    protected function random_result($reserved_cards, $cards_amount = 5) { 

     $card_types = array('s', 'c', 'h', 'd'); 
     $card_values = array('A', 2, 3, 4, 5, 6, 7, 8, 9, 'T', 'J', 'Q', 'K'); 

     $deck = array(); 
     foreach ($card_values as $value) { 
      foreach ($card_types as $type) { 
       $deck[] = $value . $type; 
      } 
     } 

     $remaining_deck = array_diff($deck, $reserved_cards); 
     // make keys sequence: 
     $remaining_deck = array_values($remaining_deck); 

     $results = array(); 

     while (count($results) != $cards_amount) {   

      $rand_card_key = $this->random(0, (count($remaining_deck) - 1)); 

      $results[] = $remaining_deck[$rand_card_key]; 

      // remove from deck   
      unset($remaining_deck[$rand_card_key]); 
      // make keys sequence: 
      $remaining_deck = array_values($remaining_deck); 
     } 

     return $results; 
    } 


    /** 
    * Picks random element from range 
    * @param integer $from   
    * @param integer $to   
    * @return integer    
    */ 
    private function random($from, $to) { 

     if (file_exists('/dev/urandom')) { 
      $twister4 = new twister; 
      $twister4->init_with_file("/dev/urandom", twister::N); 

      return $twister4->rangeint($from, $to); 
     } 
     else { 
      return mt_rand($from, $to); 
     } 



    } 


} 

Wie wir in der Zufallsfunktion sehen - ich benutze twister library mit linux dev/urnadom wenn ich auf linux und nativ mt_rand teste, wenn ich auf Windows bin. Unterschiede nicht bemerken.

So Ergebnisse auszuwählen ich Abfragen wie folgt verwendet werden:

Zum Gesamtgewinn Gesamtzahl der Ergebnisse

select count(*) from poker_results where matches_id = 2 and id < 296351 

Um wie viel ist zu bekommen (+ tie gewinnen) von Hand:

select count(*) from poker_results where matches_id = 2 and id < 296351 and winner_hands like '%Kh-Qs%' 

Um wie viele Töpfe von Hand gebunden:

select count(*) from poker_results where matches_id = 2 and id < 296351 and winner_hands like '%Kh-Qs%' and winner_hands != 'Kh-Qs' 

Der Poker-Server dient dazu, die Hand Equity zu bekommen. Bei Hand-Equity am River ermittle ich, ob die Hand gewonnen wurde oder nicht - wenn das Hand-Equity> 0 ist, dann hat es gewonnen.

Dieses Tool wird auf einem anderen Server verwendet - es gibt PHP-Code, der das Python-Programm ausführt, aber das spielt hier keine Rolle.

http://pokersleuth.com/programmable-poker-calculator.shtml

Das Werkzeug ist wie Pokerstove, aber es hat Version Befehlszeile. Btw nicht kaufen dieses Tool, wir kauften und sie nicht den Lizenzschlüssel senden, irgendwie mögen sie nicht.

Und nun die Ergebnisse: Jetzt

https://docs.google.com/spreadsheet/pub?key=0ArMZCQvNc-oQdEs0a1UyMkFGazVoN09KZmU1Q0FCU0E&output=html&richtext=true

wenn wir vergleichen, die Hände gewinnen + binden häufiger als Pokerstove oder pokersleuth zeigt Eigenkapital. Und wenn ich ant bin% - es ist viel größer als Poker-Herd zeigt. Die Probe ist nicht so klein. Pokerstove verwendet fast 400K Spiele, da ist es etwas weniger, aber die Tendenz bleibt die gleiche. Zuerst probierte ich viel kleinere Proben wie 10K-Spiele - gleiche Tendenz. Wenn ich 100K mehr erzeugen werde, bin ich nicht überrascht, wenn das Ergebnis ungefähr gleich bleibt. Auch dieses Beispiel wird unter Linux generiert.Aber ungefähr dasselbe Beispiel wird auch auf Fenstern erzeugt, und noch sind die Gewinne mehr als pokerstove Shows, und die Summe des Gewinns% ist 110-112% auch.

Also verstehen wir nicht - erzeuge ich etwas Schlechtes oder zeigen diese Programme falsch? Programme mit falschen Aktien sind nicht wahrscheinlich, da sie weit verbreitet sind und wahrscheinlich schon viel getestet werden sollten.

Update:

Ich glaube, ich endlich verstanden :) Pokersleuth berechnet die Chancen einer Hand (zwei Karten) zu gewinnen, die 5 Karten auf dem Board zu kennen. Sie sind und vergleichen dann diese Chancen mit dem realen Ergebnis (die Hände von alle anderen Spieler kennen). Recht?

Richtig. Ich musste hier schreiben, weil es in den Kommentaren keine längeren Diskussionen gab.

Update:

generiert mehr Reihen - derzeit 515.989 auf Linux-Server, bleiben die% noch aproximately die gleiche wie zuvor. Also nicht in Bewegung

+0

Sie generieren also Hände und dann Aktien berechnen mit pokerstove, die korrekte Daten und ein anderes Werkzeug produziert, das Sie nicht denken? 'get_probabilities' ist die Methode, die mit pokerstove Daten erzeugt? –

+0

Ich erzeuge Karten an Bord basierend auf den Händen der Spieler. Ich meine für alle Sample-Spieler haben die gleichen Hände. Nur Boards sind anders. Und Pokerstove mit anderen Tools bekommen fast die gleichen Aktien. Ich erinnere mich nicht, aber wahrscheinlich bei der Verwendung von Enumerate - es sollte die gleichen Äquivalenzen genau bekommen. Die Sache ist, dass meine zufällig generierten Daten nicht mit diesen Aktien übereinstimmen. Es ist nah dran, aber nicht nahe genug. Wenn es wegen der Varianz sein würde, sollte ich Höhen und Tiefen sehen, aber Resultate auf verschiedenen Proben haben Tendenz, zu sein, wie ich zeige. –

+0

get_probabilities() -Methode erzeugt Equity auf dem Fluss - wenn alle Board-Karten mit anderen Worten geöffnet sind. Und es verwendet Poker-Detektiv-Tool auf dem Server. Dieses Tool gibt 100% Equity, wenn 1 Hand gewonnen hat, 50% Equities für jedes, wenn 2 Hände gewonnen haben (Gleichstand) und so weiter. –

Antwort

4

Sie haben 296350 generierte Ergebnisse, aber 332911 gewinnt & Bindungen.

Gibt es einen Teil dieses Prozesses, der die Tatsache in Einklang bringt, dass wenn es eine Krawatte gibt, sie zwischen zwei oder mehr Händen liegt? Es sieht so aus, als ob Krawatten überzählt werden.

Nehmen Sie Ihren gesamten Gewinn und binden%, 112.3371014%. Multiplizieren (erzeugte Ergebnisse geteilt durch Gewinne & Bindungen). Sie erhalten genau 100%. Was schlägt das vor?

Siehe auch Ad6c und Ah3c. Die Anzahl der Unentschieden ist genau die gleiche und sehr wahrscheinlich die gleichen Hände (wo der Sieg ein Paar Asse war).

Aber für die Hände, wo sie binden, wird diese Hand zweimal gezählt/gewichtet (einmal für Ad6c und einmal für Ah3c). Das ist der Grund, warum deine Krawatte% mindestens das Doppelte ist, was sie sein sollten. Sie müssen die Anzahl der Unentschieden durch die Anzahl der Hände, die binden, normalisieren

+0

Willkommen bei Stack Overflow. Das sind gute Einsichten, aber Sie sollten Ihre Antwort bearbeiten, anstatt sie zu kommentieren. –

+0

Ich denke du hast Recht. Versucht, jetzt durch Gruppierung von Gewinnen auszuwählen, und wenn es 2 Gewinner gibt - dann dividiere durch 2 die Anzahl der Bindungen, wenn es 8 Gewinner gibt - dividiere durch 8, dann summiere es und die Prozentsätze sehen jetzt viel schöner aus und insgesamt ist 100% statt 110 -112 :) danke. Also die Kopfgeldpunkte werden automatisch hinzugefügt, denke ich. Dann könnte ich warten und sehen, ob jemand anderes einen Bug bemerkt –