ページ 11

ボウリングのスコア計算について

Posted: 2011年6月13日(月) 14:25
by C言語入門者
ボウリングのスコアを計算するプログラムを作ったんですが、これをボウリング場にある得点掲示板のように点数が確定した時点での得点結果を表示させたいのですが、以下のプログラムですと10フレーム目まで入力してから途中結果を出しています。これを途中の結果を出すようにしたいのですがイメージが湧きません。ご指導お願いします。

1フレーム目1回目は= 10
2フレーム目1回目は= 10
3フレーム目1回目は= 2
1フレーム目終了時点でのスコアは22点
3フレーム目2回目は= 3
2フレーム目終了時点でのスコアは37点

コード:

#include <stdio.h>
int main()
{
	while(1)
	{
    	int score[10][2] = {0,0};
    	int strike = 0;
    	int total_score = 0;
    	int i;
		/*一投で終わるか二投で終わるかの処理*/
		for (i = 0; i < 9; i++) {
        	printf(" %dフレーム目1回目= ",i+1);												/*一投目*/
			scanf("%d", &score[i][0]);					
        	if (score[i][0] != 10) {														/*ストライクでなければ二投目*/
            	printf(" %dフレーム目2回目= ",i+1);
				scanf("%d", &score[i][1]);
			}
    	}
    	/*最終フレームのスコア計算*/
		printf("10フレーム目1回目= ");			
		scanf("%d", &score[9][0]);		/*一投目*/
    	printf("10フレーム目2回目= ");
		scanf("%d", &score[9][1]);		/*二投目*/
		if (score[9][0] == 10 || score[9][0] + score[9][1] == 10) {							/*最終フレームで一投目がストライクか二投目までスペアだったら*/
			printf("10フレーム目3回目= ");													/*三投目を投げる*/
			scanf("%d", &strike);
    	}
		/*1フレーム目から9フレーム目までのスコア計算*/
		for (i = 0; i < 9; i++) {
        	if (score[i][0] == 10) {														/*一投目がストライクだったら*/
				if (i != 8 && score[i + 1][0] == 10) {										/*1~8フレームまでで次のフレームがストライクだったら*/
                	total_score = total_score + 10 + score[i + 1][0] + score[i + 2][0];		/*次の2フレームまでの結果を足す*/
            		printf("%dフレーム目終了時点のスコアは%d点\n",i+1, total_score);
				} else {
                	total_score = total_score + 10 + score[i + 1][0] + score[i + 1][1];		/*次のフレームの一投目と二投目を足す*/
            		printf("%フレーム目終了時点のスコアは%d点\n",i+1, total_score);
				}
        	} else if ((score[i][0] + score[i][1]) == 10) {									/*スペアだったら*/
            	total_score = total_score + 10 + score[i + 1][0];							/*次の1フレームの結果を足す*/
        		printf("%dフレーム目終了時点のスコアは%d点\n",i+1, total_score);
			} else {																		
            	total_score = total_score + score[i][0] + score[i][1];						/*次のフレームの一投目と二投目を足す*/
        		printf("%dフレーム目終了時点のスコアは%d点\n",i+1, total_score);
			}
    	}
    	total_score = total_score + score[i][0] + score[i][1] + strike;
    	printf("********合計スコアは%d点********\n", total_score);
	}
}

Re: ボウリングのスコア計算について

Posted: 2011年6月13日(月) 15:36
by softya(ソフト屋)
こちらの続きですね? 毎回新しいトピックを立てないようにお願いします。
「ボウリングのスコア手入れ計算プログラム • C言語交流フォーラム ~ mixC++ ~」
http://dixq.net/forum/viewtopic.php?f=3&t=8633
とりあえず別プログラムと言って良いほど変わってますが続きは続きです。
とりあえず今回は、前のを解決にしておいてください。

でプログラムですが、少なくとも、どのフレームまで確定して表示したかの位置を覚える変数と確定をチェックする処理は必要ですね。
そこは作れますか?

Re: ボウリングのスコア計算について

Posted: 2011年6月13日(月) 15:40
by C言語入門者
早い返答ありがとうございます。
確定をチェックする処理のイメージが湧きません。
誠に申し訳ありませんが教えていただけますか?

Re: ボウリングのスコア計算について

Posted: 2011年6月13日(月) 15:55
by softya(ソフト屋)
30から44行目がスコア確定処理だと思いますが、これを応用するだけです。
調べたいフレームから、今現在のフレームと投目の番号で確定できるか確認することになります。

イメージで書くとこのように場合分けをして考えていけば良いことになります。

コード:

int kakutei_flag = 0;
int score = 0;
if(調べたいフレームの一投目はストライク )  {
 score += 10;
 if( 次のフレームの一投目は既に値がある ) {
  if( その一投目はストライク ) {
   score += 10;
   (1)自分で考えてみましょう。
  } else {
   if( 2投目は既に値がある ) {
    score += 倒したピン数;
  (2)自分で考えてみましょう。
   } else {
    kakutei_flag = 0;  //未確定
   }
  }
 } else {
  kakutei_flag = 0;  //未確定
 ]
} else {
  (3)自分で考えてみましょう。
}
// 確定していたら
if( kakutei_flag ) {
 printf( スコアを表示 );
 kakutei_frame++;
}
あと、8フレーム目のガードを入れ忘れましたね。それも入れてみてください。
こんなふうにまず日本語で書いてみると分かりやすかも知れませんよ。

あとこれ、関数化したほうがソースの見通しが楽に気はしますね。

【追記】
EXCELなどでこんな形に整理してみるのもよいでしょう。
ボウリング_01.png

Re: ボウリングのスコア計算について

Posted: 2011年6月14日(火) 06:30
by c言語入門者
返答ありがとうございます。
昨日、しばらく考えていたんですが、教えて頂いてる方には私が作成したソースでは途中経過を表示する事が出来ないと言われました。フォーラムルールには沿っていませんが誰か教えて頂けますか?
正直、作り直すとなると頭が固いのか新しいのを作り直すイメージが湧きません。本当に宜しくお願いします。

Re: ボウリングのスコア計算について

Posted: 2011年6月14日(火) 10:47
by softya(ソフト屋)
c言語入門者 さんが書きました:返答ありがとうございます。
昨日、しばらく考えていたんですが、教えて頂いてる方には私が作成したソースでは途中経過を表示する事が出来ないと言われました。フォーラムルールには沿っていませんが誰か教えて頂けますか?
正直、作り直すとなると頭が固いのか新しいのを作り直すイメージが湧きません。本当に宜しくお願いします。
それを考えることが重要ですよ。
プログラムの作業の大半は、そういう事(作り直し・拡張・修正)で成り立っていますので作ったプログラムを手直しできることが何よりも重要なスキルなんです。
答えを貰うことは楽ですが、ご自分のためには絶対なりません。
私のヒントで何が分からないか具体的に質問しつもんはありませんか?

「私が作成したソースでは途中経過を表示する事が出来ないと言われました」
それはなぜだと思いますか?問題点のポイントは?

[補足]
もしかしたら、今のプログラム自体が「教えて頂いてる方」の言われている通り作ったもので、プログラムを一旦消してしまうと同じプログラムを作れないのではないですか?
だとしたら、このプログラムの理解からやり直したほうが良いですよ。

Re: ボウリングのスコア計算について

Posted: 2011年6月14日(火) 11:02
by C言語入門者
配列を使用すると出来ないと言われました。
配列を使用しないで今作成中です。
以下のプログラムでも途中経過は出るんですが確定した時点での出力方法の条件分岐のイメージがつかめません。
softyaさんからのアドバイスを基に修正をしましたが、上手くいきません。

コード:

 
#include <stdio.h>

int main(void)
{

    int th1,th2,th3;				/*一投目、二投目、三投目*/
    int score1=0, score2=0;			
    int total=0;
    int i;
	
	for(i=1 ; i<=9 ; i++){
        printf("%dフレーム1投目:",i);
        scanf("%d",&th1);						//一投目
		if(th1 != 10){							//ストライクでなければ二投目
            printf("%dフレーム2投目:",i);
            scanf("%d",&th2);
        }
		
		if(score1 != 0){							
            total = total + th1;				//一投目
            score1--;
            if(th1!=10 && score1 != 0){			//一投目がストライクでなく、score1=0でなければ
                total =total + th2;				
                score1--;
        	}
        }
        if(score2 != 0){
            total = total + th1;
            score2--;
            if(th1!=10 && score2 != 0){
                total = total + th2;
                score2--;
            }
        }
		    total =total + th1;
			printf("スコア=%d\n",i,total);
		if(th1 != 10){
            total = total + th2;
			printf("スコア=%d\n",i,total);
		}

        if(th1!=10 && (th1+th2 == 10)){			//スペアだったら
            score1 = 1;
        }else if(th1 == 10 || score1 == 1){		//ストライクだったら
            if(score1 == 1){
                score2 = 2;
            }
            if(score2 != 2){
                score1 =2;
            }
        }
    }
    /*最終フレーム*/
    while(1){
        printf("10フレーム1投目:");
        scanf("%d",&th1);

        printf("10フレーム2投目:");
        scanf("%d",&th2);

        if(th1+th2>=10){					//一投目と二投目で10ピン倒していれば三投目
            printf("10フレーム3投目:");
            scanf("%d",&th3);
        }

        if(score1 != 0){
            total =total + th1;
            score1--;
            if(score1 != 0){
                total =total + th2;
            }
        }
        if(score2 != 0){
            total =total + th1;
            score2--;
            if(score2 != 0){
                total =total + th2;
            }
        }

        total = total + (th1+th2);
        if(th1+th2>=10){
            total =total + th3;
        }
		break;
    }
    printf("スコア:%d\n",total);
}

Re: ボウリングのスコア計算について

Posted: 2011年6月14日(火) 11:18
by softya(ソフト屋)
配列を使っても出来ますし、私は配列を使ったほうが好きですけどね。最後に成績表を出し直せるし。
まぁ、私が「教えて頂いてる方」と喧嘩しても意味が無いので「教えて頂いてる方」の意向に沿って考えてみましょう。

ソースを見てみますので、またしばらく後で。

Re: ボウリングのスコア計算について

Posted: 2011年6月14日(火) 11:49
by softya(ソフト屋)
score1とscore2が何を意味するつもりか言葉で書いてもらって良いですか?

Re: ボウリングのスコア計算について

Posted: 2011年6月14日(火) 12:02
by C言語入門者
返答ありがとうございます。
th1,th2,th3だけを使った条件分岐だと上手くいかなかったため無理やり作って結果がでるようにしたため
自分でも正直分かりません。
本当に申し訳ありません。
ただ、それを使わないと上手く表示できないため使用しています。

Re: ボウリングのスコア計算について

Posted: 2011年6月14日(火) 12:10
by softya(ソフト屋)
C言語入門者 さんが書きました:返答ありがとうございます。
th1,th2,th3だけを使った条件分岐だと上手くいかなかったため無理やり作って結果がでるようにしたため
自分でも正直分かりません。
本当に申し訳ありません。
ただ、それを使わないと上手く表示できないため使用しています。
私としては表を書いて条件をまとめることをお勧めします。
参考で上げたEXCEL表みたいなやつですね。
あれとは変えて
2つ前のフレーム 1つ前のフレーム 今のフレーム
といった感じで条件を書きだしてみましょう。
その表の横に
確定するフレーム スコアの計算
を書き出します。
ボウリングのルールが分かっているなら書き出せるはずです。

Re: ボウリングのスコア計算について

Posted: 2011年6月14日(火) 15:28
by C言語入門者
前回、投稿したソースをわかりやすく書いてみました。
このプログラムだと目的のプログラムにならないと言われました。
フラグを立てて分岐させて、確定したら表示というようにしないと駄目だといわれましたが、フラグの意味が分かりません。
教えていただけますか?あと、どのあたりにフラグを使った分岐処理を入れたら良いかも教えていただけますか?
よろしくお願いします。

コード:

 
#include <stdio.h>

int main(void)
{

    int th1,th2,th3;				/*一投目、二投目、三投目*/
    int spare=0,strike=0;			/*スペア時、ストライク時の分岐に使用*/
    int total=0;
    int i;
	
	for(i=1 ; i<=9 ; i++){
        printf("%dフレーム1投目:",i);
        scanf("%d",&th1);						/*一投目*/
		if(th1 != 10){							/*ストライクでなければ二投目*/
            printf("%dフレーム2投目:",i);
            scanf("%d",&th2);
        }

		/********スペア********/
		if(spare != 0){
            total = total + th1;
            spare--;
		}
		/******ストライク******/
        if(strike != 0){
            total = total + th1;
            strike--;
            if(th1!=10 && strike != 0){
                total = total + th2;
                strike--;
            }
        }
		    total =total + th1;
			printf("%dフレーム目1投目までのスコア=%d\n",i,total);
		if(th1 != 10){
            total = total + th2;
			printf("%dフレーム目2投目までのスコア=%d\n",i,total);
		}
		/*****ストライクかスペアを判断*****/
        if(th1!=10 && (th1+th2 == 10)){			/*スペアだったら*/
            spare = 1;							/*次の1投目まで足す*/
        }else if(th1 == 10 || spare == 1){		/*ストライクだったら*/
            if(spare == 1){
                strike = 2;
            }
            if(strike != 2){
                spare =2;
            }
        }

    }
    /*最終フレーム*/
	while(1){
        printf("10フレーム1投目:");
        scanf("%d",&th1);
        printf("10フレーム2投目:");
        scanf("%d",&th2);

        if(th1+th2>=10){					/*一投目と二投目で10ピン倒していれば三投目*/
            printf("10フレーム3投目:");
            scanf("%d",&th3);
        }
		/*10フレーム目は変則で2投、あるいは3投した合計を加算する*/
        if(spare != 0){
            total =total + th1;
            spare--;
            if(spare != 0){
                total =total + th2;
            }
        }
        if(strike != 0){
            total =total + th1;
            strike--;
            if(strike != 0){
                total =total + th2;
            }
        }
        total = total + (th1+th2);
        if(th1+th2>=10){
            total =total + th3;
        }
		break;
    }
    printf("スコア:%d\n",total);
}

Re: ボウリングのスコア計算について

Posted: 2011年6月14日(火) 15:31
by softya(ソフト屋)
フラグというかストライクの連続数をカウントするだけで良いんですけどね。
私の提案はどうなったのでしょう?

Re: ボウリングのスコア計算について

Posted: 2011年6月14日(火) 15:36
by C言語入門者
素早い返答ありがとうございます。
softyaさんの提案した通り、表を作ってみましたがボウリングのスコア計算の複雑さからどう書いたら良いかわかりません。

Re: ボウリングのスコア計算について

Posted: 2011年6月14日(火) 15:46
by softya(ソフト屋)
C言語入門者 さんが書きました:素早い返答ありがとうございます。
softyaさんの提案した通り、表を作ってみましたがボウリングのスコア計算の複雑さからどう書いたら良いかわかりません。
その表をcsvでかまいませんのでテキストとして、ここに貼ってみてください。
頭が整理できているか、それだけでも分かります。

Re: ボウリングのスコア計算について

Posted: 2011年6月14日(火) 17:07
by C言語入門者
http://park1.wakwak.com/~shiraki/bowling/score.html
上記のサイトを使って実際に手入れをして見ましたが、机上の上では確認できたのですが
パソコンを前にするとどうしたらいいか分かりません。
今はstrikeとspareのフラグしか使っていませんがもっと必要だといわれました。
もう、どうしたらいいか分からなくなってきました。

Re: ボウリングのスコア計算について

Posted: 2011年6月14日(火) 17:15
by softya(ソフト屋)
C言語入門者 さんが書きました:http://park1.wakwak.com/~shiraki/bowling/score.html
上記のサイトを使って実際に手入れをして見ましたが、机上の上では確認できたのですが
パソコンを前にするとどうしたらいいか分かりません。
今はstrikeとspareのフラグしか使っていませんがもっと必要だといわれました。
もう、どうしたらいいか分からなくなってきました。
人によりプログラム構造の設計方針が違うので人により言う事が違うのは当たりまえで、その「教えて頂いてる方」の考えが私には分からないので、そちらに合わせることも難しいです。数学みたいに答えは一つではないです。
私からすれば、strikeとspareの2つも不要でストライクの連続数をカウントするだけで確定できます。
両方の意見を取り入れようとすると混乱するでしょうね。やはり。
softya(ソフト屋) さんが書きました:その表をcsvでかまいませんのでテキストとして、ここに貼ってみてください。
頭が整理できているか、それだけでも分かります。
結局これは頂けないのでしょうか?

Re: ボウリングのスコア計算について

Posted: 2011年6月14日(火) 21:09
by non
教えてくれる人がいるのなら、その人にしっかり教えてもらうほうがいいですね。その人が一度に教えようとしないのは、あなたに
勉強してもらおうという意図があると思えます。私もソフト屋さんと同じように、配列を使ったほうが考えやすいと思いますし、
また、絵などを書きながら説明しないとわかってもらうのは難しいです。いろんな考え方で、混乱するより、教えてもらっている
人の考えで解くべきでしょう。