Index |
||
DOSポーカー(3)
ゲームの実行部分である"Poker"クラスの実装コードです。最後に"main"関数を記述していますが、Pokerクラスのインスタンスをつくって、Start関数を呼び出すだけで済みます。
sasaraan programming ![]() Exposition [6] Player クラスの実装
/**************************************************
Poker クラス : 実装
**************************************************/
// コンストラクタ
Poker::Poker()
{
// map の初期化
g_HandMap[NoPair] = &g_Hand[0];
g_HandMap[Pair] = &g_Hand[1];
g_HandMap[TwoPair] = &g_Hand[2];
g_HandMap[ThreeOfKind] = &g_Hand[3];
g_HandMap[Straight] = &g_Hand[4];
g_HandMap[Flush] = &g_Hand[5];
g_HandMap[FullHouse] = &g_Hand[6];
g_HandMap[FourOfKind] = &g_Hand[7];
g_HandMap[StraightFlush] = &g_Hand[8];
g_HandMap[Royal] = &g_Hand[9];
}
// デストラクタ
Poker::~Poker()
{
}
// リセット
void Poker::Reset()
{
// タイトル表示
m_util.MoveCursor(0, 0);
m_util.InitScreen();
printf("*********************************\n");
printf(" DOSポーカー\n");
printf("*********************************\n\n");
// カードの初期化(-1:配列の終端、99:使用済みカード)
int i;
for (i=0; i<52; i++) m_card[i] = i; // トランプ一組を0から順に初期化
m_card[52] = -1; // 配列の終端に-1を置く
for (i=0; i<5; i++) m_mycard[i] = 99; // 手札5枚を使用済みに設定
m_mycard[5] = -1; // 配列の終端に-1を置く
}
// シャッフル
// ... 引数 *card : トランプ(組)
void Poker::Shuffle(int *card)
{
srand((unsigned)time(NULL)); // 乱数の初期化
int i, j, len, temp;
len = 0;
while (*(card+len) != -1) len++; /* 枚数 */
/* 添え字0のカードから順にランダムに取得した添え字の位置のカードと入れ替え */
for (i=0; i<len; i++) {
j = rand() % len;
temp = card[i];
card[i] = card[j];
card[j] = temp;
}
}
// 交換
// ... 引数 *card : トランプ(組) / ... 引数 *mycard : トランプ(手札)
void Poker::Exchange(int *card, int *mycard)
{
// 交換した位置には99(交換済みを表す数字)を入れる
while (*mycard != -1) {
if (*mycard == 99) {
if (*card == -1) break;
while (*card == 99) card++;
*mycard = *card;
*card = 99;
}
mycard++;
}
}
// 並べ替え
// ... 引数 *card : トランプ(組)
void Poker::Sort(int *card)
{
int len = 0;
int i, j;
int temp;
while (*(card+len)!=-1) len++; // 枚数
// 札の数字の小さい順に並べ替え
for (i=0; i<len-1; i++) {
for (j=i+1; j<len; j++) {
if ((card[i]%13)>(card[j]%13)) {
temp = card[i];
card[i] = card[j];
card[j] = temp;
}
}
}
}
// 手役の評価
// ... 引数 *card : トランプ(手札) / .... 戻り値 : 手役データ(Hand構造体)へのポインタ
Hand* Poker::Grading(int *card)
{
int mark[4]; // マークごとの手札の枚数
int fig[13]; // 数字ごとの手札の枚数
int i;
int temp;
int fPair = 0; // ワンペアフラグ
int fThree = 0; // スリーカードフラグ
for (i=0; i<4; i++) mark[i] = 0; // 各マークを0枚に初期化
for (i=0; i<13; i++) fig[i] = 0; // 各数字を0枚に初期化
// 持ち札のマークと数字を調べて集計
for (i=0; i<5; i++) {
temp = (int)(*(card+i) / 13);
mark[temp]++; // マークごとの手札の枚数を集計
temp = *(card+i) % 13;
fig[temp]++; // 数字ごとの手札の枚数を集計
}
// 集計の結果から同じ数字の組み合わせをチェック
for (i=0; i<13; i++) {
if (fig[i]==4) return g_HandMap[FourOfKind]; /* フォーカード */
if (fig[i]==3) {
if (fPair==1) return g_HandMap[FullHouse]; /* フルハウス */
else fThree = 1;
}
if (fig[i]==2){
if (fThree==1) return g_HandMap[FullHouse]; /* フルハウス */
else if (fPair==1) return g_HandMap[TwoPair]; /* ツーペア */
else fPair = 1;
}
}
if (fThree) return g_HandMap[ThreeOfKind]; /* スリーカード */
if (fPair) return g_HandMap[Pair]; /* ワンペア */
int fStraight = 0; /* ストレートフラグ */
int fFlush = 0; /* フラッシュフラグ */
// フラッシュのチェック
for (i=0; i<4; i++) {
if (mark[i]==5) fFlush = 1;
}
// ストレートのチェック
if (fig[0] && fig[9] && fig[10] && fig[11] && fig[12]) { /* エースハイの場合 */
if (fFlush) return g_HandMap[Royal]; /* ロイヤルストレートフラッシュ */
fStraight = 1;
} else {
for (i=0; i<9; i++) {
if (fig[i] && fig[i+1] && fig[i+2] && fig[i+3] && fig[i+4]) fStraight = 1;
}
}
if (fFlush && fStraight) return g_HandMap[StraightFlush]; /* ストレートフラッシュ */
if (fFlush) return g_HandMap[Flush]; /* フラッシュ */
if (fStraight) return g_HandMap[Straight]; /* ストレート */
return g_HandMap[NoPair]; /* ノーペア */
}
// 表示
// ... 引数 line : 行番号 / ... 引数 *card : トランプ(組)
void Poker::Show(int line, int *card)
{
m_util.MoveCursor(0, line);
printf(" 番号:\n");
printf(" 手札:\n");
char mark[5] = "SHDC"; // S:スペード,H:ハート,D:ダイヤ,C:クローバー
int m; // 札のマーク
int n; // 札の数字
int i = 0;
while (*card != -1) {
m_util.MoveCursor(i*6+7, line);
m_util.SetColor();
printf(" -%d- ", i+1);
m_util.MoveCursor(i*6+7, line+1);
if (*card==99) { /* 選択済みカードは"*"を表示 */
m_util.SetColor();
printf("[ * ] ");
} else {
m = (int)(*card / 13); // 札のマーク
n = *card % 13 + 1; // 札の数字
if (m==0 || m==3) m_util.SetColor(BLUE); // スペードとクラブは青
else m_util.SetColor(RED); // ハートとダイヤは赤
printf("[%c%-2d] ", mark[m], n);
}
i++;
card++;
}
printf("\n");
m_util.SetColor();
}
// スタート
int Poker::Start()
{
string ans; // ユーザーが入力した文字列
char req[64]; // ユーザーへの要求を表す文字列
int res; // ユーザー入力から取り出した値
int paid; // 配当金
int count = 0; // ゲーム回数
Hand* hand; // 手役
m_money = 10000; // 持ち金
// ゲームループ
while(1) {
count++;
Reset(); // 初期化
do { /* 掛け金の入力待ち */
m_util.MoveCursor(0, 4);
strcpy(req, " 掛け金(持ち金: %d) > ");
printf(req, m_money);
getline(cin, ans, '\n'); // 入力文字列の格納
res = atoi(ans.c_str()); // 値の取り出し
} while (!(res>0 || res<=m_money));
m_bet = res; // 掛け金
m_money -= m_bet; // 持ち金から掛け金を引く
Shuffle(m_card); // シャッフル
Exchange(m_card, m_mycard); // カードの配布
Sort(m_mycard); // 並べ替え
Show(6, m_mycard); // 描画
hand = Grading(m_mycard); // 手の評価
printf("\n 手役: %s\n\n",hand->Name);
while (1) {
do { /* カード交換の入力待ち */
m_util.MoveCursor(0, 10);
strcpy(req, " 交換するカード(1〜5、9:選択終了) > ");
printf(req);
getline(cin, ans, '\n'); // 入力文字列の格納
res = atoi(ans.c_str()); // 値の取り出し
} while (!(res>=1 && res<=5 || res==9));
if (res==9) break;
m_mycard[res-1] = 99; // 選ばれたカードを選択済みにする
printf("\b"); // 次の入力に備え一文字戻す
Show(6, m_mycard); // 対象カードを再描画
}
Exchange(m_card, m_mycard); // カードの交換
Sort(m_mycard); // 並べ替え
Show(12, m_mycard); // 描画
hand = Grading(m_mycard); // 手札の評価
paid = m_bet * hand->Odds; // 配当金の算出
m_money += paid; // 持ち金の計算
printf("\n 手役: %s(%d回/全%d回)\n\n",hand->Name, ++hand->Times, count);
printf(" 配 当: %d×%d=%d\n", m_bet, hand->Odds, paid);
printf(" 持ち金: %d", m_money);
if (m_money<=0) break; // 破産のときはループを抜けてゲーム終了
do { /* 続けるかどうかの入力待ち */
m_util.MoveCursor(0, 20);
printf(" 1:続ける、2:やめる > ");
getline(cin, ans, '\n');
res = atoi(ans.c_str());
} while (res != 1 && res != 2);
if (res == 2) break;
}
if (m_money<=0){ /* 破産のチェック */
m_util.SetCursor(0,false); // カーソルを非表示に
printf(" 破産です\n");
::Sleep(2500); // 2.5秒待機してから終了
m_util.SetCursor(); // カーソルを復帰
}
return 0;
}
[7] main 関数
/**************************************************
メイン関数
**************************************************/
int main()
{
Poker m_poker; // Pokerクラスのインスタンス作成
::SetConsoleTitle("DOSポーカー"); // タイトルバー
m_poker.Start(); // ゲーム開始
return 0;
}
|
||
www.sasaraan.net |
(c) morijoh |