ジャンケンの結果を判定するプログラムを作りました。期待どおりに動作したのですが、悩みながら作ったせいか、どことなく読みづらいソースファイルになってしまいました。
どうすれば読みやすくなるか、分かりますか?
main.c
#include <stdio.h>
#include <stdlib.h>
typedef enum {
rock, /* グー */
Paper, /* パー */
Scissors /* チョキ */
} Hand;
enum result {
Won, /* 勝ち */
Lost, /* 負け */
draw /* 引き分け */
};
struct game {
Hand myHand; /* 自分の手 */
Hand your_hand; /* 相手の手 */
};
typedef struct {
Hand wins; /* 自分が勝つときの、相手の手 */
Hand loses; /* 自分が負けるときの、相手の手 */
} Rule;
enum result result_of(struct game game) {
Rule rules[] = {
[rock] = { .wins = Scissors, .loses = Paper },
[Paper] = { .wins = rock, .loses = Scissors },
[Scissors] = { .wins = Paper, .loses = rock }
};
Rule myRule = rules[game.myHand];
if (myRule.wins == game.your_hand) { return Won; }
if (myRule.loses == game.your_hand) { return Lost; }
return draw;
}
void Play(struct game game) {
switch (result_of(game)) {
case Won:
puts("The winner is me!");
break;
case Lost:
puts("The winner is you!");
break;
case draw:
puts("It's a draw.");
break;
}
}
int main(void) {
Play((struct game) { .myHand = rock, .your_hand = Scissors });
Play((struct game) { .myHand = Scissors, .your_hand = rock });
Play((struct game) { .myHand = Paper, .your_hand = Paper });
return EXIT_SUCCESS;
}
実行結果
The winner is me!
The winner is you!
It's a draw.
いつもより長めのソースファイルだけど、大丈夫かしら?
はい、たぶん……。
よしよし。まず、列挙型(
enum
)が2つあるわね。
列挙型は……あった!この2つか。
typedef enum {
rock, /* グー */
Paper, /* パー */
Scissors /* チョキ */
} Hand;
enum result {
Won, /* 勝ち */
Lost, /* 負け */
draw /* 引き分け */
};
1つ目はジャンケンの手が「グー」「チョキ」「パー」のどれかを、2つ目は結果が「勝ち」「負け」「引き分け」のどれかを表すものですね。
うんうん。じゃあ、構造体(
struct
)のほうはどう?
……これだな。
struct game {
Hand myHand; /* 自分の手 */
Hand your_hand; /* 相手の手 */
};
game
っていう名前で、自分と相手の手が格納されるみたいだから、ジャンケン1回分のデータを表してるんですかね。
そうね。あと、もう一つ構造体があるわね。
……うん、あるある。
typedef struct {
Hand wins; /* 自分が勝つときの、相手の手 */
Hand loses; /* 自分が負けるときの、相手の手 */
} Rule;
これですね。
Rule
ってことは、勝ち負けのルールみたいなものが入るとか……?
そうそう。
result_of()
の中で使われてるわね。
……あ、これか。
Rule rules[] = {
[rock] = { .wins = Scissors, .loses = Paper },
[Paper] = { .wins = rock, .loses = Scissors },
[Scissors] = { .wins = Paper, .loses = rock }
};
……
この配列ですね。……あ、なるほど。「グー」は「チョキ」に勝つ、でも「パー」には負けるとかのルールが入ってますね。
そういうこと!少し長いプログラムだけれど、だいたい理解できたかしらね。
はい。あと、なんだか書き方がバラバラになってるのも分かったかも!
そうよね。そこをキレイに直す練習をしてみようっていうのが今回の問題よ。
やってみます!
直せる場所は1カ所だけではありません!