じゃんけん

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
yuui

じゃんけん

#1

投稿記事 by yuui » 8年前

3、4、5人の時に(各1回勝負で)100回勝負を行ったときの勝敗表を作りたいです。ABCの3人のそれぞれの勝敗引き分け数。ABCDの4人のそれぞれの勝敗引き分け数。5人の時の引き分け数を記録することが条件です。使う言語はC言語です。提出期限が迫っているので出来ればソースコードがほしいです。そして授業でプログラミングを習っているのですが全然わかりません。C言語から始めたいのですがおすすめの教材、勉強方法などあれば合わせて教えていただきたいです。よろしくお願いします。

アバター
Dixq (管理人)
管理人
記事: 1662
登録日時: 14年前
住所: 北海道札幌市
連絡を取る:

Re: じゃんけん

#2

投稿記事 by Dixq (管理人) » 8年前

いきなり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やコンパイラを入れて開発環境を用意し、ドンドン自分でプログラムを書いてみてください。
私がいつもお勧めしている本はこれです。

読んだら次は

あんどーなつ
記事: 171
登録日時: 8年前
連絡を取る:

Re: じゃんけん

#3

投稿記事 by あんどーなつ » 8年前

プログラムのフォーマットは、指定されていますか?
例えば、このような感じのものですけど

入力

コード:

g g c p
p p p c
c g c g
...
g c c c
出力

コード:

DRAW
PLAYER 3 WIN
PLAYER 1, 3 WIN
...
PLAYER 0 WIN

[結果]
PLAYER0 は 10 回勝ちました。
PLAYER1 は 14 回勝ちました。
PLAYER2 は 7 回勝ちました。
PLAYER3 は 24 回勝ちました。
引き分けは 9 回ありました。

yuui

Re: じゃんけん

#4

投稿記事 by yuui » 8年前

Dixqさん、あんどーなつさん回答ありがとう御座います。
提出期限の関係とプログラミングができる環境下にいないということから解答を作成して頂くことは可能でしょうか。お手数おかけいたしますが何卒よろしくお願いいたします。

プログラミングが出来る環境下にいないので出来る時に試させていただきたいと思います。 勉強方法の記載もとても為になります。

yuui

Re: じゃんけん

#5

投稿記事 by yuui » 8年前

先ほどの追記です。
あんどーなつさん、フォーマットはC言語を使うときには指定しなければならないのでしょうか。

アバター
Dixq (管理人)
管理人
記事: 1662
登録日時: 14年前
住所: 北海道札幌市
連絡を取る:

Re: じゃんけん

#6

投稿記事 by Dixq (管理人) » 8年前

今スマホしか無いんでコーディング出来ませんがプログラミング出来る環境無しにどうやって課題を行うつもりだったのですか?
学校にも環境ないんですか?

yuui

Re: じゃんけん

#7

投稿記事 by yuui » 8年前

Dixqさん

言葉不足でした。 学校にはあるのですがパソコンを使う部屋が他の授業で使用されていて入れない状況です。

あんどーなつ
記事: 171
登録日時: 8年前
連絡を取る:

Re: じゃんけん

#8

投稿記事 by あんどーなつ » 8年前

yuui さんが書きました: あんどーなつさん、フォーマットはC言語を使うときには指定しなければならないのでしょうか。
C言語に限らず、入出力の例がないと先生ではなく回答する方が苦労すると思います。なので、通常は提示されているはずだと思って聞きました。

あんどーなつ
記事: 171
登録日時: 8年前
連絡を取る:

Re: じゃんけん

#9

投稿記事 by あんどーなつ » 8年前

yuui さんが書きました: 言葉不足でした。 学校にはあるのですがパソコンを使う部屋が他の授業で使用されていて入れない状況です。
ぷ、よっしゃ。やっちゃるか

あんどーなつ
記事: 171
登録日時: 8年前
連絡を取る:

Re: じゃんけん

#10

投稿記事 by あんどーなつ » 8年前

できました。

コード:

#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;
}

yuui

Re: じゃんけん

#11

投稿記事 by yuui » 8年前

ありがとうございます。 また後日実行できるかなどやってみます!

閉鎖

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