質問です。c言語でじゃんけんゲームを作っています

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
梅こんぶ
記事: 3
登録日時: 8年前

質問です。c言語でじゃんけんゲームを作っています

#1

投稿記事 by 梅こんぶ » 8年前

現在、c言語でじゃんけんゲームを作っています。
まだc言語を習って半年くらいです。
じゃんけんゲームを色々参考にしながら作ってみました。
コンピューターが相手のじゃんけんです。自分が出した手とコンピューターの出した手を比べて、相手の出した手と、勝ち負けを表示します。
2回勝つか負けるかすると、○勝○負○分と表示されプログラムは終了します。
以下がソースです。このソースで一応、目標としていた動作を行うことができるものは作れました。
しかし、疑問点があるためここで質問させていただきました。

コード:

#include <stdio.h> #include<string.h>

main() 
{

int i=0,com,k=0,player,m=0;
 char moji[7][10]={"グー","チョキ","パー","あいこ ","勝ち","負け","負け"};
 srand((unsigned)time()); 
while((k<2)&&(m<2))
 {
 printf("じゃんけん勝負。2戦先勝方式。\n%d回 戦!最初はグー、じゃんけん・・・\n
                              1. グー 2 . チョキ 3. パー >",++i);
 scanf("%d",&player);
 com=rand()%3;
 printf("%d",com);
 printf("あいては%sで、%s。%d勝%d敗\n\n\n\n", moji[com],moji[(com-(player-1)+3)%3+3],
                     k= k+(player%3==com),m=m+((com-(player-3))% 3==1));
 }
 printf("%d勝%d敗%d分で,あなたの%s",k,m,i-( m+k),moji[6-k]); 
}
上記のソースで作ったのですが、勝った回数を計算している、k=k+(player%3==com)と負けた計算をしているm=m+((com-(player-3))%3= =1))で、なぜ勝った回数と負けた回数が計算できているのかわかりません。(player%3==com),は自分が勝ったとき、((com-(player-3))%3==1))は自分が負けた時です。
この部分は参考にしたソースが存在するのですが、そのソースにも説明が書いておらず、なぜこの文で実行できるのか、凄く疑問です。
だれかわかる人がいらっしゃいましたら、お答えいただけると幸いです。
新参もので、何か不手際があるかもしれませんが宜しくお願いします。

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 質問です。c言語でじゃんけんゲームを作っています

#2

投稿記事 by みけCAT » 8年前

まず、自分の手は1 = グー、2 = チョキ、 3 = パーで、相手の手は0 = グー、1 = チョキ、 2 = パーです。

player%3はplayer(自分の手)を3で割った余りなので、playerが3のとき0、それ以外の時playerになります。
これがcom(相手の手)と同じ時、自分と相手の手がそれぞれグーとチョキ、チョキとパー、パーとグーなので、自分が勝っていることがわかります。
また、じゃんけんの他の手の組み合わせでは自分が負けるかあいこなので、player%3==comが自分が勝っていることの必要十分条件になっています。
C言語の==演算子は両辺が等しい時1、等しくない時0になるので、自分が勝った場合はkに1が足され、勝てなかった場合はkに0が足されるので、
k=k+(player%3==com)で自分が勝った回数を数えることができます。

com-(player-3))%3==1は、変形すると(com-player+3)%3==1となるので、相手の数値が自分の数値を3で割った余りより「1個次」のときです。
この条件を満たすのは、自分と相手の手がそれぞれグーとパー(1と2)、チョキとグー(2と0)、パーとチョキ(3と1)なので、自分が負けていることがわかります。
また、じゃんけんの他の手の組み合わせでは自分が勝つかあいこなので、player%3==comが自分が勝っていることの必要十分条件になっています。
C言語の==演算子は両辺が等しい時1、等しくない時0になるので、自分が勝った場合はmに1が足され、勝てなかった場合mに0が足されるので、
m=m+((com-(player-3))% 3==1))で自分が負けた回数を数えることができます。
ただし、m=m+((com-(player-3))%3= =1))は==演算子ではなく2個の=演算子が連続したものが使われているため、コンパイルエラーになり、負けた計算はできません。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

梅こんぶ
記事: 3
登録日時: 8年前

Re: 質問です。c言語でじゃんけんゲームを作っています

#3

投稿記事 by 梅こんぶ » 8年前

みけCATさん、解答ありがとうございます。
player%3==comとかの意味は分かってたのですが、k=k+(player%3==com)でなぜ答えが出るのかわからず...
でも、みけCATさんの答えで意味が分かり、納得できましたありがとうございます。==演算子は両辺が等しい時1、等しくない時0を返すというのを知らなかったので、この式(k=)の意味が分かってませんでした。
==演算子はただ左辺の値と右辺の値が等しいとき、という意味でif文などにしか使ったことがなかったので...こんな初歩的なことも分かっておらず恥ずかしい限りですが、とても勉強になりました。ありがとうございます。
これからも、c言語の勉強を頑張っていきたいと思います。ありがとうございました。
それと、m=m+((com-(player-3))%3= =1))はの==演算子の部分ですが、携帯から投稿したので変なところにスペースが入ってたみたいで、直すのを見落としていた部分でした。実際のソースはきちんと==になっております。ご指摘ありがとうございました。

かずま

Re: 質問です。c言語でじゃんけんゲームを作っています

#4

投稿記事 by かずま » 8年前

梅こんぶ さんが書きました:

コード:

#include <stdio.h> #include<string.h>
#include は、1行に 2つは書けません。
<string.h> は不要です。
梅こんぶ さんが書きました:

コード:

 srand((unsigned)time()); 
time() には引数が必要です。
#include <stdlib.h> と #include <time.h> もあったほうがいいでしょう。

printf の中で、計算するのは分かりにくいので、書き直してみました。

コード:

#include <stdio.h>   // printf, scanf
#include <stdlib.h>  // srand, rand
#include <time.h>    // time
 
const char *hand[3] = { "グー", "チョキ", "パー" };
const char *judge[3] = { "あいこ", "あなたの負け", "あなたの勝ち" };

int main(void) 
{
    int i = 0, j, win = 0, lose = 0, player, com;
 
    srand(time(0));
    printf("じゃんけん勝負。2戦先勝方式。\n\n");
    do {
        printf("%d回戦! 最初はグー、じゃんけん・・・\n"
               "  1:グー, 2:チョキ, 3:パー > ", ++i);
        if (scanf("%d", &player) != 1 || --player >= 3u) return 1;
        com = rand() % 3;
        j = (3 + player - com) % 3;
        if (j == 2) win++;
        else if (j == 1) lose++;
        printf("あなたは%s、相手は%sで、%s。%d勝%d敗\n\n",
            hand[player], hand[com], judge[j], win, lose);
    } while (win < 2 && lose < 2);
    printf("%d勝%d敗%d分で,%s\n",
        win ,lose , i - lose - win, judge[j]);
    return 0;
}

返信

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