明解C言語 中級の3章末問題解いてみた

3章はじゃんけんプログラムでした。じゃんけんゲームのアルゴリズムはすごくおもしろかったけど、章末の課題についてはあんまりだったかな。と言っても、自分もいい課題が思いつくってこともないのだけど。

※コードが長くなってきたのでSyntaxHighlighterを導入しました。

最初はWordpressでJqueryを使う方法で考えていたのですが、Wordpress編集画面のビジュアル⇔テキストと切り替えると、なんと自動整形しやがるので、ドジでのろまなカメなたけけんはそのうちうっかり失敗しそうだから、静的なページをポップアップすることにしたのでした。
※mod_pagespeedがやってるんだけど、ソースコードの一番下でincludeしたヘッダを閉じてる記述が足されている・・・。
まぁおいおい何かやりますわ。

最終更新日:「うっかり失敗しそうだから、静的なページをポップアップすることにした」ことで消してしまったコードをちびちび修正ちう

1問目 これは例題を編集する問題です。

void update_score_and_disp_result(int result)
{
    switch (result)
    {
    case 0:
        draw_no++;
        puts("引き分けです。");
        break; /* 引き分け */
    case 1:
        lose_no++;
        puts("あなたの負けです。");
        break; /* 負け */
    case 2:
        win_no++;
        puts("あなたの勝ちです。");
        break; /* 勝ち */
    }
}

2問目 これも例題を編集する問題です。

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

int human;		
int comp;		
int win_no;		
int lose_no;	
int draw_no;	
int game_rounds; 

char *hd[] = {"グー", "チョキ", "パー"};

void initialize(void)
{
	win_no	= 0;
	lose_no	= 0;
	draw_no	= 0;

	srand(time(NULL));

	printf("じゃんけんゲーム開始!!\n");

    char buffer[256];
    char *end;
    do {
        printf("何回勝負しますか?(数値を入力してください) : ");
        fgets(buffer, 256, stdin);
        game_rounds = strtol(buffer, &end, 10);
        if (end == buffer || *end != '\n' || game_rounds <= 0){
            printf("エラー:数値以外が入力されました。再度入力してください。\n");
        }
    } while(end == buffer || *end != '\n' || game_rounds <= 0);
}

void jyanken(void)
{
	int i;
	comp = rand() % 3;

    char buffer[256];
    char *end;
	do {
		printf("\n\aじゃんけんポン …");
		for (i = 0; i < 3; i++)
			printf(" (%d)%s", i, hd[i]);
		printf(" : ");
        fgets(buffer, 256, stdin);
        human = strtol(buffer, &end, 10);
		if(end == buffer || *end != '\n' || human < 0 || human > 2){
			printf("エラー:数値以外が入力されました。再度入力してください。\n");
		}
	} while (end == buffer || *end != '\n' || human < 0 || human > 2);
}

void update_score_and_disp_result(int result)
{
    switch (result)
    {
    case 0:
        draw_no++;
        puts("引き分けです。");
        break;
    case 1:
        lose_no++;
        puts("あなたの負けです。");
        break;
    case 2:
        win_no++;
        puts("あなたの勝ちです。");
        break;
    }
}

int main(void)
{
	int judge;

	initialize();

	do {
		jyanken();
		printf("私は%sで、あなたは%sです。\n", hd[comp], hd[human]);
		judge = (human - comp + 3) % 3;	
        update_score_and_disp_result(judge);
	} while (win_no < game_rounds && lose_no < game_rounds);

	if (win_no == game_rounds)
		printf("\nあなたの勝ちです。\n");
	else
		printf("\n私の勝ちです。\n");

	return (0);
}

3問目 これは例題を利用して作ったりする問題

そーす:ごめんなさい。データなくなっちゃいました。

4問目 最初はグーってやつなのだが、もっといい答えはある。

そーす:ごめんなさい。データなくなっちゃいました。

5問目 5回ごとに後出しさせるものですが、後出しってまるわかりなようにした。

そーす:ごめんなさい。データなくなっちゃいました。

6問目 第5章を参考にするらしいので、5章が終わってからやろうと思います。

7問目 3人じゃんけん VS COM方式にしたのでじゃんけんアルゴリズムではありません。
ほんとはなにかアルゴリズムを考えるのがよい気はするけど、いまはこれでいいと思ってます。

そーす:ごめんなさい。データなくなっちゃいました。

8問目 4人じゃんけん 7問目の条件を増やしただけです。
これもVSCOM式として考えたもので、複数人じゃんけんのアルゴリズムを考えたわけではないのはちょっと気になるけど、いまはこれでいいと思っています。

デバッグをそこそこやったので間違いないとは思うが・・・。

そーす:ごめんなさい。データなくなっちゃいました。

 

ちゃんと納得のいくアルゴリズムを考えてはいないのだけど、とりあえず先にすすもうと思います。

 

Related Posts


投稿者: Takeken

インターネット利用者のITリテラシーを向上したいという設定の2次元キャラです。 サーバー弄りからプログラミングまで手を付けた自称エッセイストなたけけんの物語。

「明解C言語 中級の3章末問題解いてみた」への7件のフィードバック

    1. 山田将之さん

      こんばんわー。
      ファイルがないのでリダイレクトされてトップページに飛んでるようです。
      WordPress配下にファイルを置いてたものの、WordPressからは独立したHTMLファイルだったので
      サーバーを移動する時のバックアップ対象から漏れてしまっていて、データ消失していました。。orz
      せっかく見に来ていただいたのにごめんなさい。

      1. 返信ありがとうございます。
        修正して、見れるようにしてもらえるととても嬉しいです。3-5まで自力で
        解けたのですが、3-6からの3題は苦戦中です。
        よろしくお願いします。

  1. 6問目は、履歴を保存しなくても、じゃんけんでだした結果はすでに表示されているので問題としてふさわしくないと思います。7問目は、h、c1、c2として、じゃんけんの出し方は27通り、そのうち1人だけ勝つ、2人が勝つ、あいこになるのがそれぞれ9通りです。
    グーを0、チョキを1、パーを2とすると3人の出した結果を全部足して3でわるとその余りによって3パターンに分類できます。あいこの場合は、余り0でいっきに片付きます。
    問題は、他の2パターンです。誰が勝のかを判定する式を考えても思いつかず、if文で全部列挙してしまいました。
    おそらくもっと別のいい方法があるのではないかと思うのですが、どうでしょうか。
    アドヴァイスよろしくお願いします。

  2. ##include
    #include
    #include

    int main(void)
    {
    int i;
    int human; /* 人間の手 */
    int comp1; /* コンピュータの手 */
    int comp2;
    int sum;
    int retry; /* もう一度? */
    char *hd[] = {“グー”, “チョキ”, “パー”}; /* 手 */

    srand(time(NULL)); /* 乱数の種を初期化 */

    printf(“じゃんけんゲーム開始!!\n”);

    do {
    comp1 = rand() % 3; /* コンピュータの手(0~2)を乱数で生成 */
    comp2 = rand() % 3;
    do {
    printf(“\n\aじゃんけんポン …”);
    for (i = 0; i < 3; i++)
    printf(" (%d)%s", i, hd[i]);
    printf(":");
    scanf("%d", &human); /* 人間の手を読み込む */
    } while (human 2);

    printf(“C1は%sでC2は%sで、あなたは%sです。\n”, hd[comp1],hd[comp2], hd[human]);

    sum = human + comp1 + comp2;

    if (sum % 3 ==0)
    puts(“引き分けです。”);
    if (sum % 3 ==1 && hd[comp1]==hd[comp2])
    puts(“C1とC2が勝ちです。”);
    if (sum % 3 ==1&& hd[human]==hd[comp2])
    puts(“あなたとC2が勝ちです。”);
    if (sum % 3 ==1&& hd[human]==hd[comp1])
    puts(“あなたとC1が勝ちです。”);
    if (sum % 3 ==2 && hd[comp1]==hd[comp2])
    puts(“あなたが勝ちです。”);
    if (sum % 3==2 && hd[human]==hd[comp2])
    puts(“C1が勝ちです。”);
    if (sum % 3==2 && hd[human]==hd[comp1])
    puts(“C2が勝ちです。”);

    printf(“もう一度しますか…(0)いいえ (1)はい:”);
    scanf(“%d”, &retry);
    } while (retry == 1);

    return (0);
    }
    [EOF]
    これで動きました。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です