このページ
ビデオポーカーコードのプログラミング - パート2
概要
このビデオは、ビデオポーカーのプログラミングに関する全3部構成のシリーズの第2部です。第1部では、実行に13.7時間かかると思われる基本エンジンを構築しました。このビデオでは、ショートカットを追加して実行時間を約42分に短縮します。
以下はビデオで開発されたコードです。
#include <iostream>
#include <time.h>
構造体カード
{
整数 r;
整数 s;
};
void セットアップ(void);
無効取引(無効);
void 事前描画(int ランク1、int ランク2、int ランク3、int ランク4、int ランク5、int スーツ1、int スーツ2、int スーツ3、int スーツ4、int スーツ5、int ウェイト);
void 描画(int c1, int c2, int c3, int c4, int c5, int 重み);
int スコア(カード配布[]);
整数スコア配列[2598960];
カードデッキ[52]
int draw_combinations_array[] = { 1533939, 178365, 178365, 16215, 178365, 16215, 16215, 1081, 178365, 16215, 16215, 1081, 16215, 1081, 1081, 47, 178365, 16215, 16215, 1081, 16215, 1081, 1081, 47, 16215, 1081, 1081, 47, 1081, 47, 1 };
int weighting_array[] = { 5, 43, 43, 473, 43, 473, 473, 7095, 43, 473, 473, 7095, 473, 7095, 7095, 163185, 43, 473, 473, 7095, 473, 7095, 7095, 163185, 473, 7095, 7095, 163185, 7095, 163185, 163185, 7669695 };
__int64 合計組み合わせ[52];
整数tot_weight = 0;
const char* hand_name_array[] = {
「負け」、「ジャック以上」、「ツーペア」、「スリーカード」、「ストレート」、「フラッシュ」、「フルハウス」、「フォーカード」、「ストレートフラッシュ」、「ロイヤルフラッシュ」、「合計」 };
int win_array[] = { 0,1,2,3,4,6,9,25,50,800 };
int メイン()
{
time_t 開始時刻、終了時刻;
開始時間 = 時間(NULL);
設定();
取引();
終了時間 = 時間(NULL);
printf("合計秒数=\t%i\n", (int)endtime - (int)begtime);
}
void セットアップ(void)
{
int i, c1, c2, c3, c4, c5, カウント, score_deal_array[52], sc;
カードの配布[5]
(i = 0; i <= 51; i++) の場合
{
デッキ[i].r = (int)(i / 4);
デッキ[i]。s = i % 4;
スコア取引配列[i] = 0;
tot_combinations[i] = 0;
}
カウント = 0;
(c1 = 0; c1 <= 47; c1++) の場合
{
ディール[0] = デッキ[c1];
(c2 = c1 + 1; c2 <= 48; c2++) の場合
{
ディール[1] = デッキ[c2];
(c3 = c2 + 1; c3 <= 49; c3++) の場合
{
配る[2] = デッキ[c3];
(c4 = c3 + 1; c4 <= 50; c4++) の場合
{
配る[3] = デッキ[c4];
(c5 = c4 + 1; c5 <= 51; c5++) の場合
{
配る[4] = デッキ[c5];
sc = スコア(ディール);
スコア配列[カウント] = sc;
スコア計算配列[sc]++;
カウント++;
}
}
}
}
}
// std::cerr << "count =\t" << count << "\n";
// (i = 0; i <= 9; i++) の場合
// std::cerr << hand_name_array[i] << "\t" << score_deal_array[i] << "\n";
}
無効取引(無効)
{
/* int i, c1, c2, c3, c4, c5;
整数カウント = 0;
(c1 = 0; c1 <= 47; c1++) の場合
{
(c2 = c1 + 1; c2 <= 48; c2++) の場合
{
(c3 = c2 + 1; c3 <= 49; c3++) の場合
{
(c4 = c3 + 1; c4 <= 50; c4++) の場合
{
(c5 = c4 + 1; c5 <= 51; c5++) の場合
{
描画(c1、c2、c3、c4、c5);
カウント++;
if ((count % 1000) == 0)
std::cerr << count << "\n";
}
}
}
}
} */
整数 i,r1, r2,r3,r4,r5;
// フォー・オブ・ア・カインド
(r1 = 0; r1 <= 12; r1++) の場合
{
(r2 = 0; r2 <= 12; r2++) の場合
{
(r1 != r2) の場合
{
事前描画(r1, r1, r1, r1, r2, 0, 1, 2, 3, 0, 4);
}
}
}
// フルハウス
(r1 = 0; r1 <= 12; r1++) の場合
{
(r2 = 0; r2 <= 12; r2++) の場合
{
もし (r1 != r2)
{
事前描画(r1, r1, r1, r2, r2, 0, 1, 2, 0, 1, 12);
事前描画(r1, r1, r1, r2, r2, 0, 1, 2, 0, 3, 12);
}
}
}
// スリー・オブ・カインド
for (r1 = 0; r1 <= 12; r1++) // スリー・オブ・ア・カインド
{
for (r2 = 0; r2 <= 11; r2++) // 最初のシングルトン
{
for (r3 = r2 + 1; r3 <= 12; r3++) // 2番目のシングルトン
{
もし ((r1 != r2) && (r1!=r3))
{
事前描画(r1, r1, r1, r2, r3, 0, 1, 2, 0, 0, 12);
事前描画(r1, r1, r1, r2, r3, 0, 1, 2, 3, 3, 4);
事前描画(r1, r1, r1, r2, r3, 0, 1, 2, 0, 1, 24);
事前描画(r1, r1, r1, r2, r3, 0, 1, 2, 0, 3, 12);
事前描画(r1, r1, r1, r2, r3, 0, 1, 2, 3, 0, 12);
}
}
}
}
// ツーペア
for (r1 = 0; r1 <= 12; r1++) // シングルトン
{
for (r2 = 0; r2 <= 11; r2++) // ペア1
{
for (r3 = r2 + 1; r3 <= 12; r3++) // ペア2
{
もし ((r1 != r2) && (r1 != r3))
{
事前描画(r1, r2, r2, r3, r3, 0, 0, 1, 0, 1, 12);
事前描画(r1, r2, r2, r3, r3, 2, 0, 1, 0, 1, 12);
事前描画(r1, r2, r2, r3, r3, 0, 0, 1, 2, 3, 12);
事前描画(r1, r2, r2, r3, r3, 2, 0, 1, 2, 3, 12);
事前描画(r1, r2, r2, r3, r3, 0, 0, 1, 0, 2, 24);
事前描画(r1, r2, r2, r3, r3, 1, 0, 1, 0, 2, 24);
事前描画(r1, r2, r2, r3, r3, 2, 0, 1, 0, 2, 24);
事前描画(r1, r2, r2, r3, r3, 3, 0, 1, 0, 2, 24);
}
}
}
}
// 1組
for (r1 = 0; r1 <= 12; r1++) // ペア
{
std::cerr << "1つのペア\t" << r1 << "\n";
for (r2 = 0; r2 <= 10; r2++) // シングルトン 1
{
for (r3 = r2 + 1; r3 <= 11; r3++)// シングルトン 2
{
for (r4 = r3 + 1; r4 <= 12; r4++) // シングルトン 3
{
もし ((r1 != r2) && (r1 != r3) && (r1 != r4))
{
事前描画(r1, r1, r2, r3, r4, 0, 1, 0, 0, 0, 12);
事前描画(r1, r1, r2, r3, r4, 0, 1, 2, 2, 2, 12);
事前描画(r1, r1, r2, r3, r4, 0, 1, 0, 0, 1, 12);
事前描画(r1, r1, r2, r3, r4, 0, 1, 0, 1, 0, 12);
事前描画(r1, r1, r2, r3, r4, 0, 1, 1, 0, 0, 12);
事前描画(r1, r1, r2, r3, r4, 0, 1, 2, 2, 3, 12);
事前描画(r1, r1, r2, r3, r4, 0, 1, 2, 3, 2, 12);
事前描画(r1, r1, r2, r3, r4, 0, 1, 3, 2, 2, 12);
事前描画(r1, r1, r2, r3, r4, 0, 1, 0, 0, 2, 24);
事前描画(r1, r1, r2, r3, r4, 0, 1, 0, 2, 0, 24);
事前描画(r1, r1, r2, r3, r4, 0, 1, 2, 0, 0, 24);
事前描画(r1, r1, r2, r3, r4, 0, 1, 0, 2, 2, 24);
事前描画(r1, r1, r2, r3, r4, 0, 1, 2, 0, 2, 24);
事前描画(r1, r1, r2, r3, r4, 0, 1, 2, 2, 0, 24);
事前描画(r1, r1, r2, r3, r4, 0, 1, 0, 1, 2, 24);
事前描画(r1, r1, r2, r3, r4, 0, 1, 0, 2, 1, 24);
事前描画(r1, r1, r2, r3, r4, 0, 1, 2, 0, 1, 24);
事前描画(r1, r1, r2, r3, r4, 0, 1, 0, 2, 3, 24);
事前描画(r1, r1, r2, r3, r4, 0, 1, 2, 0, 3, 24);
事前描画(r1, r1, r2, r3, r4, 0, 1, 2, 3, 0, 24);
}
}
}
}
}
// 5つのシングルトン
(r1 = 0; r1 <= 8; r1++) の場合
{
std::cerr << "5 つのシングルトン\t" << r1 << "\n";
(r2 = r1+1; r2 <= 9; r2++) の場合
{
for (r3 = r2 + 1; r3 <= 10; r3++)
{
(r4 = r3 + 1; r4 <= 11; r4++) の場合
{
(r5 = r4 + 1; r5 <= 12; r5++) の場合
{
事前描画(r1, r2, r3, r4, r5, 0, 0, 0, 0, 0, 4);
事前描画(r1、r2、r3、r4、r5、1、0、0、0、0、12);
事前描画(r1、r2、r3、r4、r5、0、1、0、0、0、12);
事前描画(r1, r2, r3, r4, r5, 0, 0, 1, 0, 0, 12);
事前描画(r1, r2, r3, r4, r5, 0, 0, 0, 1, 0, 12);
事前描画(r1, r2, r3, r4, r5, 0, 0, 0, 0, 1, 12);
事前描画(r1, r2、r3、r4、r5、0、0、0、1、1、12);
事前描画(r1, r2, r3, r4, r5, 0, 0, 1, 0, 1, 12);
事前描画(r1, r2, r3, r4, r5, 0, 0, 1, 1, 0, 12);
事前描画(r1, r2, r3, r4, r5, 0, 1, 0, 0, 1, 12);
事前描画(r1, r2, r3, r4, r5, 0, 1, 0, 1, 0, 12);
事前描画(r1、r2、r3、r4、r5、0、1、1、0、0、12);
事前描画(r1、r2、r3、r4、r5、1、0、0、0、1、12);
事前描画(r1, r2, r3, r4, r5, 1, 0, 0, 1, 0, 12);
事前描画(r1、r2、r3、r4、r5、1、0、1、0、0、12);
事前描画(r1, r2, r3, r4, r5, 1, 1, 0, 0, 0, 12);
事前描画(r1、r2、r3、r4、r5、0、0、0、1、2、24);
事前描画(r1、r2、r3、r4、r5、0、0、1、0、2、24);
事前描画(r1、r2、r3、r4、r5、0、0、1、2、0、24);
事前描画(r1、r2、r3、r4、r5、0、1、0、0、2、24);
事前描画(r1、r2、r3、r4、r5、0、1、0、2、0、24);
事前描画(r1、r2、r3、r4、r5、0、1、2、0、0、24);
事前描画(r1、r2、r3、r4、r5、1、0、0、0、2、24);
事前描画(r1、r2、r3、r4、r5、1、0、0、2、0、24);
事前描画(r1、r2、r3、r4、r5、1、0、2、0、0、24);
事前描画(r1、r2、r3、r4、r5、1、2、0、0、0、24);
事前描画(r1、r2、r3、r4、r5、0、1、1、2、2、24);
事前描画(r1、r2、r3、r4、r5、0、1、2、1、2、24);
事前描画(r1、r2、r3、r4、r5、0、1、2、2、1、24);
事前描画(r1、r2、r3、r4、r5、1、0、1、2、2、24);
事前描画(r1、r2、r3、r4、r5、1、0、2、1、2、24);
事前描画(r1、r2、r3、r4、r5、1、0、2、2、1、24);
事前描画(r1、r2、r3、r4、r5、1、1、0、2、2、24);
事前描画(r1、r2、r3、r4、r5、1、2、0、1、2、24);
事前描画(r1、r2、r3、r4、r5、1、2、0、2、1、24);
事前描画(r1、r2、r3、r4、r5、1、1、2、0、2、24);
事前描画(r1、r2、r3、r4、r5、1、2、1、0、2、24);
事前描画(r1、r2、r3、r4、r5、1、2、2、0、1、24);
事前描画(r1、r2、r3、r4、r5、1、1、2、2、0、24);
事前描画(r1、r2、r3、r4、r5、1、2、1、2、0、24);
事前描画(r1、r2、r3、r4、r5、1、2、2、1、0、24);
事前描画(r1、r2、r3、r4、r5、0、0、1、2、3、 24);
事前描画(r1、r2、r3、r4、r5、0、1、0、2、3、24);
事前描画(r1、r2、r3、r4、r5、0、1、2、0、3、24);
事前描画(r1、r2、r3、r4、r5、0、1、2、3、0、24);
事前描画(r1、r2、r3、r4、r5、1、0、0、2、3、24);
事前描画(r1、r2、r3、r4、r5、1、0、2、0、3、24);
事前描画(r1、r2、r3、r4、r5、1、0、2、3、0、24);
事前描画(r1、r2、r3、r4、r5、1、2、0、0、3、24);
事前描画(r1、r2、r3、r4、r5、1、2、0、3、0、24);
事前描画(r1、r2、r3、r4、r5、1、2、3、0、0、24);
}
}
}
}
}
printf("総重量=\t%i\n", tot_weight);
(i = 9; i >= 0; i--) の場合
printf("%s\t%i\t%I64i\n", hand_name_array[i], win_array[i], tot_combinations[i]);
}
void 事前描画(int ランク1、int ランク2、int ランク3、int ランク4、int ランク5、int スーツ1、int スーツ2、int スーツ3、int スーツ4、int スーツ5、int ウェイト)
{
整数 c1、c2、c3、c4、c5;
c1 = ランク1 * 4 + スーツ1;
c2 = ランク2 * 4 + スーツ2;
c3 = ランク 3 * 4 + スーツ 3;
c4 = ランク4 * 4 + スーツ4;
c5 = ランク5 * 4 + スーツ5;
合計重量 += 重量;
描画(c1, c2, c3, c4, c5, 重み);
}
void 描画(int c1, int c2, int c3, int c4, int c5, int 重み)
{
int i, j, d1, d2, d3, d4, d5, インデックス, sc, draw_score_array[32][10];
整数カウント = 0;
(i = 0; i <= 31; i++) の場合
{
(j = 0; j <= 9; j++) の場合
draw_score_array[i][j] = 0;
}
(d1 = 0; d1 <= 47; d1++) の場合
{
(d2 = d1 + 1; d2 <= 48; d2++) の場合
{
for (d3 = d2 + 1; d3 <= 49; d3++)
{
(d4 = d3 + 1; d4 <= 50; d4++) の場合
{
(d5 = d4 + 1; d5 <= 51; d5++) の場合
{
sc = スコア配列[カウント];
インデックス = 0;
if ((d1 == c1) || (d2 == c1) || (d3 == c1) || (d4 == c1) || (d5 == c1))
インデックス += 16;
((d1 == c2) || (d2 == c2) || (d3 == c2) || (d4 == c2) || (d5 == c2)) の場合
インデックス += 8;
もし ((d1 == c3) || (d2 == c3) || (d3 == c3) || (d4 == c3) || (d5 == c3))
インデックス += 4;
((d1 == c4) || (d2 == c4) || (d3 == c4) || (d4 == c4) || (d5 == c4)) の場合
インデックス += 2;
もし ((d1 == c5) || (d2 == c5) || (d3 == c5) || (d4 == c5) || (d5 == c5))
インデックス += 1;
draw_score_array[インデックス][sc]++;
カウント++;
}
}
}
}
}
ダブルev;
ダブルmax_ev = 0;
int best_play = 0;
(i = 0; i <= 31; i++) の場合
{
ev = 0.0;
(j = 0; j <= 9; j++) の場合
ev += draw_score_array[i][j] * win_array[j];
ev /= 組み合わせ配列[i]を描画します。
もし (ev > max_ev)
{
max_ev = ev;
ベストプレイ = i;
}
}
(j = 0; j <= 9; j++) の場合
{
tot_combinations[j] += weight*draw_score_array[best_play][j] * weighting_array[best_play];
}
}
int スコア(カード配布[])
{
int ストレート、フラッシュ;
もし ((deal[0].s == deal[1].s) && (deal[0].s == deal[2].s) && (deal[0].s == deal[3].s) && (deal[0].s == deal[4].s))
フラッシュ = 1;
それ以外
フラッシュ = 0;
もし ((deal[0].r != deal[1].r) && (deal[1].r != deal[2].r) && (deal[2].r != deal[3].r) && (deal[3].r != deal[4].r))
{
もし ((deal[0].r + 4) == deal[4].r)
ストレート = 1;
else if ((deal[4].r == 12) && (deal[3].r == 3)) // ホイール
ストレート = 1;
それ以外
ストレート = 0;
}
それ以外
ストレート = 0;
if ((ストレート == 1) && (フラッシュ == 1))
{
もし (deal[0].r == 8)
9 を返します。
それ以外
8を返します。
}
そうでない場合 (フラッシュ == 1)
5 を返します。
そうでない場合 (ストレート == 1)
4 を返します。
そうでない場合 ((deal[0].r == deal[3].r) || (deal[1].r == deal[4].r))
7 を返します。
そうでない場合 ((deal[0].r == deal[2].r) && (deal[3].r == deal[4].r))
6を返します。
そうでない場合 ((deal[0].r == deal[1].r) && (deal[2].r == deal[4].r))
6を返します。
そうでない場合 ((deal[0].r == deal[2].r) || (deal[1].r == deal[3].r) || (deal[2].r == deal[4].r))
3 を返します。
そうでない場合 ((deal[0].r == deal[1].r) && (deal[2].r == deal[3].r))
2を返します。
そうでない場合 ((deal[0].r == deal[1].r) && (deal[3].r == deal[4].r))
2を返します。
そうでない場合、((deal[1].r == deal[2].r) && (deal[3].r == deal[4].r))
2を返します。
そうでない場合 ((deal[0].r == deal[1].r) && (deal[0].r >= 9))
1 を返します。
そうでない場合 ((deal[1].r == deal[2].r) && (deal[1].r >= 9))
1 を返します。
そうでない場合 ((deal[2].r == deal[3].r) && (deal[2].r >= 9))
1 を返します。
そうでない場合 ((deal[3].r == deal[4].r) && (deal[3].r >= 9))
1 を返します。
それ以外
0を返します。
}