ブラックジャックのC++プログラミングなんですけど

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
takotakon

ブラックジャックのC++プログラミングなんですけど

#1

投稿記事 by takotakon » 14年前

[1] 質問文
 [1.1] 自分が今行いたい事は何か
 簡単なブラックジャックのプログラミングの作成
 最初にいくらかけるかを決める。。。プレイヤーが勝てばプラス、負ければ0←ここはたぶんできます
 プレイヤーに2枚カードが来る ハートの11、ダイヤの2など。←この部分がわかりません
 プレイヤーがカードを引くか決める。←こちらもたぶんできると思います
 ディーラー側は16以下なら自動的に21に近づくまで引く←これはWhile loopを使えばOKですか??16以下なら自動的にカードを引くというので。
 スコアの大小で勝者決定。。。同点ならディーラー勝利←同点の場合ディーラー勝利にする方法??
 最初のもちきん100円が0円になるか1000円こえると終了←こちらもたぶん大丈夫です。


 [1.2] どのように取り組んだか(プログラムコードがある場合記載)
 いまのところ、Aを1または11と数えるコードと10以上のカードを全部10にするというコードしかできていません。

 [1.3] どのようなエラーやトラブルで困っているか(エラーメッセージが解る場合は記載)
 困っている部分はランダムナンバーで最初のカード2枚、重複しないようにする方法がわかりません


[3] その他
 ・どの程度C言語を理解しているか
 初心者です、前回OXゲームやループの方法を習いました。
 今回はランダムナンバーのところの課題としてこのプログラム作成があります
 
ステップ別にアシスタントが示してくれたメールも添付しときます

コード:

#include <iostream>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
using namespace std;

void draw_card(string& card, int& total);// this is your function declaration.

int main()
{
    srand ( time(NULL) );	// this is just initialize the random seed. 

    /***************step one, declaration **************************/

    /* within the main, you first declare the variables player_total,
            dealer_total, player_amount, bet and so on...    */

    while ((player_amount>0)&&(player_amount<1000)) //
    {
    /* This is where you write the whole game. We do it in 3 steps */
	
    /**************** step one, player's turn *****************/
	 
	/* call the function draw_card twice, that will generate the first 2 cards for the player.
	 * in the mean time, you need to cout the cards. It will be as the following:
     cout<<"Your cards are: \n";
     draw_card(card, player_total);
     cout<<card<<"\n";
     draw_card(card, player_total);
	 * where card and player_total should be declared before. 
	 * then you should define a boolean variable ans, and ask the player "Do you want to draw another card?"
	 * then you can cin>>ans. 
	 * while ( ans==y), you can keep drawing cards, until player bursts or ans=="n". 
	 */ 
	
   /**************** step two, dealer's turn *****************/
   
	/* you can use the same draw_card function and the same variable card for dealer as well. 
	 * The dealer's condition on stop drawing cards is dealer_total>16. 
	 * so you can write a while loop to check that condition, and if dealer_total<16, you can 
	 * keep drawing the cards. 
	 */
	
  /***************** step three, determine who wins the round ***********/

	/* Here you have the sudo code for different cases. 
	 * if (player_total>21){
	 * 	player loses;} 		// if player busts, dealer automatically wins. 
	 * else if (dealer_total>21){	
	 * 	dealer wins;}		// if player hasn't bust, but dealer bust, player wins. 
	 * else if (player_total>dealer_total){
	 * 	player wins;}		// if both not burst, and player has higher total, player wins. 
	 * else if (player_total<dealer_total){
	 * 	dealer wins;}		// otherwise the dealer wins. 
	 * else{
	 * 	tie;}			// or else, you get a tie. 
	 * in each of the cases above, you need to type the message indicating whoever wins, 
	 * and increase or decrease the corresponding amount of money. 
	 */
    }
    cout<<"You have "<<player_amount<<" left. Game over. "
    return 0;
}


void draw_card(string& card, int& total) // here starts your function defition.
{

    /**************step one, randomly draw cards*************************/

    /* declear int variables n1, n2, rank and suit.
        and then randomly generate a number between 1 and 13, store it as n1;
        also randomly generate a number between 1 and 4, store it as n2;
        by the way, the way to generate a random integer from 1 to n is the following:
        rand()%n+1;
        */

    /**************step two, change the int n1 and n2 to strings and store them as card ***********/

    /* you can either use switch or if statements.
    Here is the syntax for switch:
  switch ( n1 ) {

  case 1 :		// case 1 means n1=1. 
    // Process for n1 = 1
    ...
    break;

  case 5 :
    // Process for n2 = 5
    ...
    break;

  default :
    // Process for all other cases.
    ...

}

    And for the syntax of if statement, I think you guys should already know that.

    In each case listed above, you want to set the rank to be the corresponding string.
    For example, if n1=2, you want to set the rank to be "2", and if n1=1, you want to set
    the rank to be "Ace".
    Besides, you also want to update the total in each case.
    For example, if n1=2, you should have: total+=2; if n1=5, you should have: total+=5;
    if n1=13, that's the case you draw a king, and king is regarded as 10, so you should
    have total+=10; if n1=1, you need to check if total+11>21, if so, total+=1, otherwise, total+=11.
   
    ***** important: after the statements in each case,
                    you need to put the command break; to break from the statement*******

    You need to have two switches, or two if statements. One for n1, the other for n2.
    The first switch sets rank to the corresponding n1, and the second switch sets suite to
    the corresponding n2.
    */

}
codeタグを使われていなかったので、codeタグを追加。 by softya(ソフト屋)

よろしくお願いします

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: ブラックジャックのC++プログラミングなんですけど

#2

投稿記事 by softya(ソフト屋) » 14年前

とりあえず、今できているコードを貼ってもらって良いですか?
codeタグをお忘れなく。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
はんなり
記事: 48
登録日時: 14年前

Re: ブラックジャックのC++プログラミングなんですけど

#3

投稿記事 by はんなり » 14年前

説明がグダグダになったので初期化と全体の簡単な流れだけでも・・・


※ コードが無いので要求と合わないかもしれませんが、
悪しからず

※ 僕はブラックジャックを知らないので
ちょっと間違ってるかもしれません



初期化:

コード:

int cards[52];//カード
int mochi_cards[10];//持ってるカード

int i=0,ii=0;//for文用に適当な名前で変数を作ってください


for(i=0;i<52;i++){//1~13まで、4つずつ。計52
 if(i!=0 && i%4==0) ii++;
 cards[i]=ii;
}

for(i=0;i<10;i++){//持ってるカード。最初は何もないので-1としておきます
 mochi_cards[i]=-1;
}


全体の流れ:
1.乱数を 0~51-x変数 でとります。

2.cards[取得した乱数] でカードのナンバーを取得。
(↓:取得したナンバーを配列に格納すると良いかと)

コード:

for(i=0;i<10;i++){
 if(mochi_cards[i]==-1) {
  mochi_cards[i]=cards[取得した乱数];
  break;//ブレイクを入れてループ脱出しないと全部cards[取得した乱数]の内容で埋まります^^;
 }
}

3.cards[取得した乱数] の値を14以上にする。ここではわかりやすく100としておきます。

4.バブルソートをかける(昇順です)。でも、ぶっちゃけソートであればなんでもいいです。

5.x変数を1増やす

6.グラフィックやゲーム内の処理を経て、1へ


以上です。
分かりづらい説明ですが、何かの役に立てば幸いですm(_ _)m
最後に編集したユーザー はんなり on 2011年5月06日(金) 23:13 [ 編集 2 回目 ]

takotakon

Re: ブラックジャックのC++プログラミングなんですけど

#4

投稿記事 by takotakon » 14年前

コメントありがとうございます。
大学のPCルームでしかできず、日本語が打てないのでデータが持ち出せるかわかりませんができたらアップしたいと考えています。
流れだけでも教えていただきありがとうございます!!

三郎

Re: ブラックジャックのC++プログラミングなんですけど

#5

投稿記事 by 三郎 » 14年前

余談雑談ですが、芸無しの私は船の中で毎日ブラックジャックをやっていた事があります。
今はルールも忘れましたが。どのようなアルゴリズムでソフトを造られるか興味があります(コードを見ても理解できませんが)。

これは確立のゲーム、子(プレーヤ)が確立を計算して、どんな場合どうすれば良いかという早見表があった(コッソリ見せてもらった)。
ソフトを造る場合問題は親のカードの切り方です。

この場合、場にでているカードを全て読む必要があるはず(確立計算のため)。
アルゴリズムを発表して欲しいものです(苦笑)。


アバター
はんなり
記事: 48
登録日時: 14年前

Re: ブラックジャックのC++プログラミングなんですけど

#7

投稿記事 by はんなり » 14年前

三郎 さんが書きました: この場合、場にでているカードを全て読む必要があるはず(確率計算のため)。
アルゴリズムを発表して欲しいものです(苦笑)。
場にでているカードを全て読むなんて面倒なことはしません。
ちゃんとしっかり理にかなってると思いますが・・・。

なんなら検証してもいいですよ?

アバター
ゆーずぃ
記事: 62
登録日時: 14年前
住所: 埼玉県

Re: ブラックジャックのC++プログラミングなんですけど

#8

投稿記事 by ゆーずぃ » 14年前

三郎さん
三郎 さんが書きました: これは確立のゲーム、子(プレーヤ)が確立を計算して、どんな場合どうすれば良いかという早見表があった(コッソリ見せてもらった)。
ソフトを造る場合問題は親のカードの切り方です。

この場合、場にでているカードを全て読む必要があるはず(確立計算のため)。
場に出ているカードを全て読む、というのはアルゴリズムで使うといった意味合いに取れたのですが、
その解釈で合っていれば、その必要は無いはずです。
ご自分で仰られているように、早見表はプレーヤー側で用意するものです。
このゲームに立派なAIは必要ありません。

ディーラー側の仕様は既に提示されています。
takotakon さんが書きました: ディーラー側は16以下なら自動的に21に近づくまで引く
これ以上の動作もこれ以下の動作も望まれてはいません。
というか、確率を計算しようがしまいがディーラー側は山の上から適当にカードを引くしかないわけで、
これが確率という名の元に好きな数字を出されたらイカサマになってしまいます。

又、プレーヤー側はAIではなく、自分で次のカードを引くかどうかを選べるようになっています。
ということで早見表は画面の前に用意しておけばいいです。

ですが、この後のtakotakonさんへの質問の回答によっては、三郎さんの仰る場のカードを保持しておく仕組み(計算には使いませんが)
は必要となってくるでしょう。

私の勘違いであれば失礼いたしました。

takotakonさん
takotakon さんが書きました:  スコアの大小で勝者決定。。。同点ならディーラー勝利←同点の場合ディーラー勝利にする方法??
 最初のもちきん100円が0円になるか1000円こえると終了←こちらもたぶん大丈夫です。
持ち金が最終的な終了条件のようですが、その前提を少し詰めた方がいいです。

このゲームは何回勝負ですか?
カードが無くなるまでですか?それとも規定数(一発勝負等)でしょうか?
その場合、ゲーム開始から通してカードの重複が無いようにしなければならないのでしょうか?カード(一山)が無くなった場合は?
それともその回のカードだけが重複しなければいいのでしょうか?
(一山使いきるまでゲームをするのか、それとも1ゲームごとにカードを回収して切りなおすのか)
それによっては三郎さんの仰ったように場にあるカードを保持しておく仕組みが必要となってきます。

三郎

Re: ブラックジャックのC++プログラミングなんですけど

#9

投稿記事 by 三郎 » 14年前

はんなりさん、ゆーずいさん、私のの言葉がたらなくて失礼しました言葉を付け加えます。
もう数年前ですので当時ルールを完全に覚えていたのですが今は、あやふやで忘れています。
確か、日本ではカジノは禁止(現金を賭ける)のはず。
海の上で、客船にカジノが存在する。外国の客船は現金を賭けて勝てば現金をもらえる。
日本の客船は全ての船でチップを現金に換えれず、売店に売っている商品に換えてもらえる。
この場合でも国内航路でなく外国へ行く航路の場合のみだったと思う。

そんな中で私がゼロからルールを習って毎日挑戦していた。

結論は如何に正確な確率計算をしても絶対お客は勝てなく親、カジノ側が勝つ(当たり前)。
今思えば確かに親は判断のする余地のないルールだった(うろ覚え)。
我々お客は早見表によって判断しても少し負けるようになる(確率計算)。
早見表は大負けしないための道具に過ぎないのも承知。

そんな中で当時ルールを覚え外国の港で下船に颯爽と本場のカジノに向う。
そして、当然負けました、でも楽しかった。

下船して当時考えていた。
親の立場でなく、子(我々)が如何に負けを少なくするかを考えていた。
そのような時に問題は、親の、めくる(くばる)カードが何か分らないからである。
それが分れば(インチキ)子は勝って儲かる。

その時に場に出ている、めくってあるカードは二度と出ないから、
それを計算するのと、計算しないのでは負け方が確率的に小さくなる。
これは、カードゲーム全てに言える当然のことです。
この事を言いたかったのに混同していました(ボケの症状?)
早トチリで皆さんには幼稚な意見を述べて申し訳なかった(恥)。
しかし親は何パーセンと確率で勝つのかなあ。
しかし、少しでも今後カジノを楽しめるようにブラックジャックのソフト製作も期待しますね。

三郎

Re: ブラックジャックのC++プログラミングなんですけど

#10

投稿記事 by 三郎 » 14年前

それから、これも余計な事ですが、船の中ではカードゲームの定番として、
コントラクトブリッジが、よく行なわれています。

船に限らず、インテリジェンスの高い方々がよく楽しんでおられます。
私は頭が悪くルールを覚える事が難しい。

これのパソコンソフトもあるようですが難しいらしいです。

閉鎖

“C言語何でも質問掲示板” へ戻る