じゃんけん
- Dixq (管理人)
- 管理人
- 記事: 1662
- 登録日時: 14年前
- 住所: 北海道札幌市
- 連絡を取る:
Re: じゃんけん
いきなり5人で考えると難しいのでまず2人で考えてみましょう。
こういうのはまず簡単な数字に置き換えてみると分かりやすいです。
グー:2
チョキ:1
パー:0
これで色んな結果を考えてみてください。
グー:パー=2:0
チョキ:グー=1:2
チョキ:パー=1:0
・・・
沢山書き出して法則性を考えてみましょう。
======一旦ここで画面から目を話して自分で考えてみてください。======
さて、法則性が見つけられたでしょうか。
Aさん=パー0:Bさん=チョキ1
の時Bさんの勝ちです。
Aさん=チョキ1:Bさん=グー2
の時Bさんの勝ちです。
⇒なるほど、Aさんより結果の数字が+1ならBさんの勝ちなんだなと分かります。
つまりif文は
if(A+1==B){
となります。しかしその要領だと
Aさん=グー2:Bさん=パー0
の時困ります。
これは「割ったあまり」というプログラミング界隈では非常によく使う考え方を導入すると解決します。
メニューの選択項目なんかにも使ったりします。
ゲームプログラミングの館にその考え方の紹介がありますのでどうぞ
http://dixq.net/g/03_02.html
(下に次章へのリンクがあります)
つまりじゃんけんは3通りあるので、「3で割ったあまり」を用いればいいのです。
Aさんの数+1←これの3で割ったあまりという表現はプログラムで
(A+1)%3
と書きます。すなわち
if((A+1)%3 == B){
と書くことになります。
あいこはif(A==B)の時で判定は簡単なのでいいとして次は負けの判定です。
これは結構プログラムに慣れている人でも最初は頭を捻る計算の仕方なんですけど、
Aさんの数+1←これの3で割ったあまり
の逆を計算する必要があります。これは
Aさんの数-1←これの3で割ったあまり
ではありません。なぜかは計算結果を表示してみれば分かります。
これをうまく解決する方法もうちのサイトで紹介しているのでご覧ください。
http://dixq.net/g/03_04.html
マイナス方向へのループ計算を実現する時は「じゃんけんのパターンである3通り-1の数ほど足したものを3で割ったあまり」として計算すればいいのです。
なんだか頭が混乱しそうな時は紙に書いて計算してみてください。
Aさん=チョキ1:Bさん=パー0
の時Bさんは負けですよね。これはA+2を3でわったあまりがBと等しいにほかなりません。
つまり
(A+2)%3 が Bであれば「負け」なので。すなわち
if((A+2)%3 == B){
と書きます。
これで「勝ち」「あいこ」「負け」が判定可能です。
これで何とかプログラムかけそうですか?
まずは2人からやってみて、順番に数を増やしてみてください。
5人とかになったとき、
0も1も2もあれば勝敗があいこ
5人とも全て同じ数ならそれもあいこ
0か1か2、どれかが誰も出していなければ勝敗が決まります。
これを基準にするといいでしょう。
C言語は正直学校で習っていることを講義の時間だけ聞いてたんじゃ分かりません。
自分のPCにVisualStudioなり、IDEやコンパイラを入れて開発環境を用意し、ドンドン自分でプログラムを書いてみてください。
私がいつもお勧めしている本はこれです。
読んだら次は
こういうのはまず簡単な数字に置き換えてみると分かりやすいです。
グー:2
チョキ:1
パー:0
これで色んな結果を考えてみてください。
グー:パー=2:0
チョキ:グー=1:2
チョキ:パー=1:0
・・・
沢山書き出して法則性を考えてみましょう。
======一旦ここで画面から目を話して自分で考えてみてください。======
さて、法則性が見つけられたでしょうか。
Aさん=パー0:Bさん=チョキ1
の時Bさんの勝ちです。
Aさん=チョキ1:Bさん=グー2
の時Bさんの勝ちです。
⇒なるほど、Aさんより結果の数字が+1ならBさんの勝ちなんだなと分かります。
つまりif文は
if(A+1==B){
となります。しかしその要領だと
Aさん=グー2:Bさん=パー0
の時困ります。
これは「割ったあまり」というプログラミング界隈では非常によく使う考え方を導入すると解決します。
メニューの選択項目なんかにも使ったりします。
ゲームプログラミングの館にその考え方の紹介がありますのでどうぞ
http://dixq.net/g/03_02.html
(下に次章へのリンクがあります)
つまりじゃんけんは3通りあるので、「3で割ったあまり」を用いればいいのです。
Aさんの数+1←これの3で割ったあまりという表現はプログラムで
(A+1)%3
と書きます。すなわち
if((A+1)%3 == B){
と書くことになります。
あいこはif(A==B)の時で判定は簡単なのでいいとして次は負けの判定です。
これは結構プログラムに慣れている人でも最初は頭を捻る計算の仕方なんですけど、
Aさんの数+1←これの3で割ったあまり
の逆を計算する必要があります。これは
Aさんの数-1←これの3で割ったあまり
ではありません。なぜかは計算結果を表示してみれば分かります。
これをうまく解決する方法もうちのサイトで紹介しているのでご覧ください。
http://dixq.net/g/03_04.html
マイナス方向へのループ計算を実現する時は「じゃんけんのパターンである3通り-1の数ほど足したものを3で割ったあまり」として計算すればいいのです。
なんだか頭が混乱しそうな時は紙に書いて計算してみてください。
Aさん=チョキ1:Bさん=パー0
の時Bさんは負けですよね。これはA+2を3でわったあまりがBと等しいにほかなりません。
つまり
(A+2)%3 が Bであれば「負け」なので。すなわち
if((A+2)%3 == B){
と書きます。
これで「勝ち」「あいこ」「負け」が判定可能です。
これで何とかプログラムかけそうですか?
まずは2人からやってみて、順番に数を増やしてみてください。
5人とかになったとき、
0も1も2もあれば勝敗があいこ
5人とも全て同じ数ならそれもあいこ
0か1か2、どれかが誰も出していなければ勝敗が決まります。
これを基準にするといいでしょう。
C言語は正直学校で習っていることを講義の時間だけ聞いてたんじゃ分かりません。
自分のPCにVisualStudioなり、IDEやコンパイラを入れて開発環境を用意し、ドンドン自分でプログラムを書いてみてください。
私がいつもお勧めしている本はこれです。
読んだら次は
- Dixq (管理人)
- 管理人
- 記事: 1662
- 登録日時: 14年前
- 住所: 北海道札幌市
- 連絡を取る:
Re: じゃんけん
今スマホしか無いんでコーディング出来ませんがプログラミング出来る環境無しにどうやって課題を行うつもりだったのですか?
学校にも環境ないんですか?
学校にも環境ないんですか?
Re: じゃんけん
C言語に限らず、入出力の例がないと先生ではなく回答する方が苦労すると思います。なので、通常は提示されているはずだと思って聞きました。yuui さんが書きました: あんどーなつさん、フォーマットはC言語を使うときには指定しなければならないのでしょうか。
Re: じゃんけん
ぷ、よっしゃ。やっちゃるかyuui さんが書きました: 言葉不足でした。 学校にはあるのですがパソコンを使う部屋が他の授業で使用されていて入れない状況です。
Re: じゃんけん
できました。
#include <stdio.h>
#include <string.h>
#define PLAYMAX 100
#define PLAYERMAX 5
#define LINEMAX 128
int player; /* プレイヤーの数 */
int plays; /* プレイ回数 */
int play[PLAYMAX][PLAYERMAX]; /* 試合結果 */
int win[PLAYERMAX];
int draw;
int te_flag[3]; /* グーチョキパーが出ていれば1, 出ていなければ0 */
const int GU = 0;
const int CYOKI = 1;
const int PA = 2;
int main() {
char line[LINEMAX+1];
int i, j, k;
int first;
// 入力の読み込み
fgets(line, LINEMAX, stdin);
if (strlen(line) > 0 && line[strlen(line)-1] == '\n')
line[strlen(line)-1] = '\0'; // 改行文字を削除
player = strlen(line) / 2 + 1; // 3人なら5文字、5人なら9文字なので
plays = 0;
do {
if (strlen(line) / 2 + 1 < player) break; // 空行対策
for (i = 0; i < player; i++) {
char te = line[2*i];
if (te == 'g') play[plays][i] = GU;
else if (te == 'c') play[plays][i] = CYOKI;
else if (te == 'p') play[plays][i] = PA;
else {
printf("ERROR!\n");
return 1;
}
}
plays++;
} while (fgets(line, LINEMAX, stdin) != NULL);
// 各行の判定、出力
for (i = 0; i < player; i++)
win[i] = 0;
draw = 0;
for (i = 0; i < plays; i++) {
for (j = 0; j < 3; j++)
te_flag[j] = 0;
for (j = 0; j < player; j++)
te_flag[play[i][j]] = 1;
if (te_flag[0] && te_flag[1] && !te_flag[2]) {
first = 1;
printf("PLAYER ");
for (j = 0; j < player; j++) {
if (play[i][j] == GU) {
win[j]++;
if (!first) printf(", ");
printf("%d", j);
first = 0;
}
}
printf(" WIN");
} else if (!te_flag[0] && te_flag[1] && te_flag[2]) {
first = 1;
printf("PLAYER ");
for (j = 0; j < player; j++) {
if (play[i][j] == CYOKI) {
win[j]++;
if (!first) printf(", ");
printf("%d", j);
first = 0;
}
}
printf(" WIN");
} else if (te_flag[0] && !te_flag[1] && te_flag[2]) {
first = 1;
printf("PLAYER ");
for (j = 0; j < player; j++) {
if (play[i][j] == PA) {
win[j]++;
if (!first) printf(", ");
printf("%d", j);
first = 0;
}
}
printf(" WIN");
} else {
printf("DRAW");
draw++;
}
printf("\n");
}
printf("\n");
printf("[結果]\n");
for (i = 0; i < player; i++)
printf("PLAYER%d は %d 回勝ちました。\n", i, win[i]);
printf("引き分けは %d 回ありました。\n", draw);
return 0;
}