/* 教科書読解練習 p.196 * janken.c ; じゃんけんをするプログラム * * 結城浩 * Copyright (C) 1993 by Hiroshi Yuki. * * Modified by T. Watanabe, July 2, 2002. * * (Char Code; EUC-jp) */ #include #include #include #define GUU 0 #define CHO 1 #define PAA 2 #define HANDS 3 void learn(int lasthand, int curhand); int guess(int curhand); int winhand(int hand); void printhand(int hand); int judge(int hand, int hand2); void printbothhands(int chand, int mhand); int main(void); /* globalに通用する外部変数 */ int handlog[3] = {0,0,0}; /* 人間の手の頻度を記録する */ int maxhand = 0; /* もっとも頻度が多い, 人間の出した手 */ /* * learn(); 以前の手 lasthand と 現在の手 curhand を記憶する * 人間が出した手の頻度を記録して、もっとも頻度が高い手を探す */ void learn(int lasthand, int curhand) { extern int handlog[3], maxhand; /* 外部変数 */ handlog[curhand]++; if ( handlog[0] > handlog[1] ) maxhand = 0; else maxhand = 1; if ( handlog[maxhand] > handlog[2] ) ; else maxhand = 2; /* printf("DEBUG; learn/handlog[0,1,2]=%d %d %d, max=%d\n", handlog[0],handlog[1],handlog[2], maxhand); */ } /* * guess(); 以前の手 curhand から次の手を推測して戻り値として返す * */ int guess(int curhand) { return (rand() % HANDS); } /* * winhand(); 手 hand に勝つ手を返す */ int winhand(int hand) { if (hand == GUU) return PAA; else if (hand == CHO) return GUU; else if (hand == PAA) return CHO; else { printf("ERROR; 関数 winhand(%d) に異常な値が渡されました。\n", hand); exit(-1); /* その場でプログラムは終了する */ } } /* * printhand(); 手 hand を文字列で表示する。 */ void printhand(int hand) { if (hand == GUU) printf("グー"); else if (hand == CHO) printf("チョキ"); else if (hand == PAA) printf("パー"); else { printf("ERROR; 関数 printhand(%d) に異常な値が渡されました。\n", hand); exit(-1); /* その場でプログラムは終了する */ } } /* * judge(hand1, hand2); 2つの手 hand1 と hand2 のどちらが勝ったかを判断する * 前者が勝ったら 1, 後者が勝ったら 2, あいこなら 0 を返す */ int judge(int hand1, int hand2) { if (hand1 == hand2) return 0; else if ( hand1 == winhand(hand2) ) return 1; else if ( winhand(hand1) == hand2 ) return 2; else { printf("ERROR; 関数 judge(%d,%d) に異常な値が渡されました。\n", hand1, hand2); exit(-1); /* その場でプログラムは終了する */ } } /* * printbothhands(chand, mhand); コンピュータの手 chand と 人間の手 mhand を表示 */ void printbothhands(int chand, int mhand) { printf("コンピュータは "); printhand(chand); printf(" 、あなたは "); printhand(mhand); printf(" です。\n"); } /* * main関数 */ int main(void) { int wincom = 0; /* コンピュータの勝ち数 */ int winman = 0; /* 人間の勝ち数 */ int ndraw = 0; /* 引き分け回数 */ int manhand = 0; /* 人間の手 */ int lasthand = 0; /* 人間の以前の手 */ int comphand = 0; /* コンピュータの手 */ int i, winner; char buffer[256]; char c; extern int maxhand; printf("ジャンケンをしましょう。\n"); printf("グーなら 1、チョキなら 2、パーなら 3 を入力してください。\n"); printf("ジャンケンをやめるときは 0 を入力してください。\n"); for ( i = 0 ; i < 1000; i++) { comphand = winhand( maxhand ); /* 人間が最も良く出す手に勝てる手を出す */ printf("ジャンケン・・・(グー 1、チョキ 2、パー 3)\n"); gets(buffer); c = buffer[0]; /* 人間の手を取り込む */ /* 人間が入力した '0' '1' '2' '3' を -1 0 1 2 に変換 */ manhand = c - '0' -1; /* 'n' -> n-1 */ if ( c == '0') { printf("やめたっと\n"); break; /* forループを抜け出す */ } else if ( '1' <= c && c <= '3') { printf("ポン!\n"); winner = judge(comphand, manhand); /* どちらが勝ったか判定*/ printbothhands(comphand, manhand); if ( winner == 1) { wincom++; printf("コンピュータの勝ち!\n"); } else if ( winner == 2) { winman++; printf("あなたの勝ち!\n"); } else { ndraw++; printf("あいこ・・・\n"); } printf("コンピュータ %d勝, あなた %d勝, 引き分け %d\n", wincom, winman, ndraw); learn(lasthand, manhand); lasthand = manhand; /* 現在の手を記憶しておく */ } else { printf("? ? ?\n"); printf("0, 1, 2, 3 のどれかのキーを押してください。"); } printf("\n"); } /* forループの終り */ if ( wincom > winman * 2 ) printf("コンピュータは賢いでしょう?\n"); else if ( winman > wincom * 2 ) printf("コンピュータ, 完全敗北・・・\n"); else printf("また遊んでね。\n"); return 0; }