コマンドプロンプトで遊ぶポーカー

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

コマンドプロンプトで遊ぶポーカー

#1

投稿記事 by trans6243 » 12年前

1人用のポーカーゲームは作れましたが、相手にCOMをつくってやるとエラーがでます。下にソースを貼るので、アドバイスもらえませんか?COMの実装が全然わかっていません。

コード:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "porker.h"

/* 手札をバブルソート */
int sort( int tehuda[5] )
{
	int i,j,c;
	
	for( i = 0; i<5; i++){
		for( j = 4; j > i; j--){
			if( tehuda[j] < tehuda[j-1] ){
				c = tehuda[j];
				tehuda[j] = tehuda[j-1];
				tehuda[j-1] = c;
			}
		}
	}
	
	return 0;
}

int get_card( int player, int tranp[4][13], int num, int tehuda[5], int exchange)
{
	int i,j,k,l,count;

	for(count = 0; count<5; count++ ){ /* num枚数交換の場合 */
		if( num == 0 ){ break; }
		if( !( exchange & (1 << count)) ){
			continue; 
		}

		i = (int)((rand() / (double)RAND_MAX) * 4);
		j = (int)((rand() / (double)RAND_MAX) * 13);
		if (tranp[i][j] > 0){ 
			count--;
			continue; 
		}

		if( tehuda[count] != -1 ){
			k = tehuda[count] / 13;
			l = tehuda[count] % 13;
			tranp[k][l] = 1;
		}
		
		tranp[i][j] = player;
		tehuda[count] = i*13+j;
	}

	return 0;
}

/* 手札の交換、プロンプト表示関数 */
int exchange( int player, int tranp[4][13], int tehuda[5]){
	int c = 0,i,j,suit,num,count=0;
	int exchange = 0;
	char *suit_name[4] = {"ハート","ダイヤ","スペード","クラブ"};

	while( 1 ){
		j = 1;

		puts("手札");
		for( i=0; i<5; i++){
			suit = tehuda[i]/13;
			num  = tehuda[i]%13;
		
			printf("%d: %sの%d",i+1,suit_name[suit],num+1);
			if( exchange & j ){
				printf( ASTA );
			}
			printf("\n");
			j *= 2;
		}

		puts("交換するカードの番号を入力してください(1-5)。終了は*印です。: ");
/*		puts("終了は*印です");*/
		c = getchar();
		getchar();
		
		while( c<0x31 || 0x35<c ){
			if( c == '*' ){ break; }
			puts("間違っています。番号を入力してください(1-5): ");
			c = getchar();
			getchar();
		}

		if( c == '*' ) { break; }
		c -= 0x31;
		
		if( !(exchange & (1 << c)) ){
			exchange = exchange + (1 << c);
			count++;
		}
	}
	
	if( get_card( player, tranp, count, tehuda, exchange ) ){
		puts("error in exchange_card");
		return 1;
	}
	
	return 0;
}


int waza(int tehuda[5])
{
	int i,max=0,max2=0;
	int strait_flg=0,flash_flg=0,royal_flg=0;
	int num[5],suit[5],pair[13];
	
/*	memset( pair, 0, 13 ); */
	for( i = 0; i<13; i++){ pair[i] = 0; }
	
	for( i = 0; i<5; i++){
		suit[i] = tehuda[i]/13;
		num[i]  = tehuda[i]%13;
		pair[num[i]]++;
	}
	
	if( (suit[0]==suit[1]) && (suit[1]==suit[2]) && (suit[2]==suit[3]) && 
		(suit[3]==suit[4]) ){
		flash_flg = 1;
	}
	if( num[4] - num[0] == 4 ){ strait_flg = 1; }
	if( flash_flg == 1 ){
		if( (num[0]==0) && (num[1]==10) && (num[2]==11) && (num[3]==12) && 
		(num[4]==13) ){ 
			royal_flg = 1;
		} 
	}
	
	for( i = 0; i<13; i++){
		if( pair[i] >= max ){
			max2 = max;
			max  = pair[i];
		}
	}
	
	if( royal_flg ){
		return ROYAL;
	}else if( strait_flg && flash_flg ){
		return STRAITFLASH;
	}else if( max == 4 ){
		return FOUR_CARD;
	}else if( max == 3 && max2 == 2 ){
		return FULLHOUSE;
	}else if( flash_flg ){
		return FLASH;
	}else if( strait_flg ){
		return STRAIT;
	}else if( max == 3 ){
		return THREE;
	}else if( max == 2 && max2 == 2 ){
		return TWO;
	}else if( max == 2 ){
		return ONE;
	}else{
		return BUTA;
	}
}


int main(char *argv[], int argc)
{
/* tranp[][]の数字:0なら山、1なら場、2ならPlayer1の手札、3ならPlayer2の手札 */
	int tranp[4][13],i,j,num,play1,play2,suit,finish;
	int tehuda1[5],tehuda2[5];
	char *suit_name[4] = {"ハート","ダイヤ","スペード","クラブ"};
	char *finish_name[11] = {"ブタ","ワンペア","ツーペア","スリーオブアカインド","ストレート",
	"フラッシュ","フルハウス","フォーカード","ストレートフラッシュ","ロイヤルストレートフラッシュ",
	"ファイブカード"};
	/* 手は11種、ジョーカーは未実装なのでファイブカードはでない */
	
/* 初期化 */	
	play1 = 0; play2 = 0;
	for( i=0; i<4; i++){
		for( j=0; j<13; j++){
			tranp[i][j]=0;
		}
	}
	for( i = 0; i<5; i++ ){
		tehuda1[i] = -1;
	}
	
	srand((unsigned int)time(0));

/* カード取得 */	
/* player1 */
	if( get_card( PLAYER1, tranp, 5, tehuda1, ALL_CARD ) ){
		printf("get card error:001\n");
		return 1;
	}

/* player2 */

	if( get_card( PLAYER2, tranp, 5, tehuda2, ALL_CARD ) != 0 ){
		printf("get card error:002\n");
		return 1;
	}


/* 交換する手札の選択 */
	if( exchange(PLAYER1, tranp, tehuda1) ){
		puts("error in exchange");
	}

	sort( tehuda1 );
	puts("新しい手札");
	for( i=0; i<5; i++){
		suit = tehuda1[i]/13;
		num  = tehuda1[i]%13;
		
		printf("%d: %sの%d",i+1,suit_name[suit],num+1);
		printf("\n");
	}

/* 交換する手札の選択 */
	if( exchange(PLAYER2, tranp, tehuda2) ){
		puts("error in exchange");
	}

	sort( tehuda2 );
	puts("新しい手札");
	for( i=0; i<5; i++){
		suit = tehuda1[i]/13;
		num  = tehuda1[i]%13;
		
		printf("%d: %sの%d",i+1,suit_name[suit],num+1);
		printf("\n");
	}

/* 手の判定 */
	finish = waza(tehuda1);
	printf("%sをあがりました\n",finish_name[finish]);
	finish = waza(tehuda2);
	printf("%sをあがりました\n",finish_name[finish]);

#ifdef DEBUG
	printf("\n");
	puts("場の状態:");
	for( i=0; i<4; i++){
		printf("%d: ",i);
		for( j=0; j<13; j++){
			printf("%d ",tranp[i][j]);
		}
		printf("\n");
	}
#endif

	return 0;
}

Priest
記事: 123
登録日時: 12年前
住所: 愛知

Re: コマンドプロンプトで遊ぶポーカー

#2

投稿記事 by Priest » 12年前

具体的にはどのようなエラーが出ますか?

ヘッダファイルも貼ってくださるとこちらも検証できます。

とりあえず、226行目とかおかしくはないですか?

コード:

#include <Priest.h>
int MyPolicy ( void ) { printf( "何事も楽しくね!" ); return 0; }

trans6243

Re: コマンドプロンプトで遊ぶポーカー

#3

投稿記事 by trans6243 » 12年前

デバックなしでビルドすると動作が停止されました。ってでます。
ヘッダーファイルです
[code]
#define PLAYER1 2
#define PLAYER2 3
#define ALL_CARD 0x1f
#define ASTA " *"

#define BUTA 0
#define ONE 1
#define TWO 2
#define THREE 3
#define STRAIT 4
#define FLASH 5
#define FULLHOUSE 6
#define FOUR_CARD 7
#define STRAITFLASH 8
#define ROYAL 9
[/code]

Priest
記事: 123
登録日時: 12年前
住所: 愛知

Re: コマンドプロンプトで遊ぶポーカー

#4

投稿記事 by Priest » 12年前

とりあえず、エラーで動かないのは、
tehuda2の初期化し忘れです。

コード:

    for( i = 0; i<5; i++ ){
        tehuda1[i] = -1;
        tehuda2[i] = -1;
    }
とすれば動作します。

しかし、CPUの思考等は入ってないですね。
そちらを実装しましょう。CPUの実装の流れはどうですか?分からないところがあれば具体的にお願いします。

コード:

#include <Priest.h>
int MyPolicy ( void ) { printf( "何事も楽しくね!" ); return 0; }

trans6243

Re: コマンドプロンプトで遊ぶポーカー

#5

投稿記事 by trans6243 » 12年前

CPUの実装は正直やったことなくて、わからないのです。
ペアがあったら残すという条件のプログラムを作っていただけないでしょうか?
ストレートとかのプログラムの見本にしたいので。。。よろしくおねがいします

Priest
記事: 123
登録日時: 12年前
住所: 愛知

Re: コマンドプロンプトで遊ぶポーカー

#6

投稿記事 by Priest » 12年前

もし何も分からないのであれば、
いっそのこと、全部ランダムに行動するCPUをまず作ってみませんか?

初期段階として、配られたカード1枚1枚に対して残すか残さないかの2択をランダムに選択するCPUをば!
賢くするのはそれからでも良いと思います。

コード:

#include <Priest.h>
int MyPolicy ( void ) { printf( "何事も楽しくね!" ); return 0; }

trans6243

Re: コマンドプロンプトで遊ぶポーカー

#7

投稿記事 by trans6243 » 12年前

ランダムで捨てるやついいっすね^^
参考になるURLとかあれば教えてもらえませんか?

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

Re: コマンドプロンプトで遊ぶポーカー

#8

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

trans6243 さんが書きました:ランダムで捨てるやついいっすね^^
参考になるURLとかあれば教えてもらえませんか?
ここまで作れたのならランダムで捨てるぐらいは自力で作れると思います。
それとも、このコードは何処かのサンプルなのでしょうか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

Priest
記事: 123
登録日時: 12年前
住所: 愛知

Re: コマンドプロンプトで遊ぶポーカー

#9

投稿記事 by Priest » 12年前

例えば、上記のコードだと、どのカードを交換するか入力させるところありますよね?
そのあたりに、もしPLAYER1だったら今まで通り入力を促し、PLAYER2だったらランダムにcの値を決めるようなif文を追加する方法があります。

コード:

#include <Priest.h>
int MyPolicy ( void ) { printf( "何事も楽しくね!" ); return 0; }

trans6243

Re: コマンドプロンプトで遊ぶポーカー

#10

投稿記事 by trans6243 » 12年前

やってみます^^ありがとうございますた

閉鎖

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