新規記事の投稿を行うことで、非表示にすることが可能です。
2017年12月28日
《その210》 問題演習 p.235演習6-3
今回も、演習問題です。
新版明解C++中級編 p.235 演習6-3
ジャンケンの《プレーヤ》を表す抽象クラスを定義せよ。そのクラスから、以下のクラスを派生すること。
・人間プレーヤクラス(出す手をキーボードから読み込む)
・コンピュータプレーヤクラス(出す手を乱数で生成する)
以下の解答では、クラス名が次のようになっています。
・JankenPlayer → ジャンケンの《プレーヤ》を表す抽象クラス
・JankenPlayer_A → 人間プレーヤクラス
・JankenPlayer_B → コンピュータプレーヤクラス
// Janken.h ---------------------------
#ifndef ___Janken___
#define ___Janken___
#include<string>
#include<ctime>
#include <cstdlib>
#include <iostream>
int opponent();
class JankenPlayer {
protected:
virtual ~JankenPlayer() { };
int win; // 勝ち回数
int lose; // 負け回数
int draw; // 引分け回数
int te0; // 自分の手
int te1; // 相手の手
public:
// 出す手 te0 を決定 … グー(0), チョキ(1), パー(2)
virtual void set_te0() = 0;
// 判定結果を返却 … 勝ち(0), 負け(1), あいこ(2)
virtual int judge() {
switch (te0) {
case 0 : if (te1 == 0) return 2;
if (te1 == 1) return 0;
if (te1 == 2) return 1;
break;
case 1 : if (te1 == 0) return 1;
if (te1 == 1) return 2;
if (te1 == 2) return 0;
break;
case 2 : if (te1 == 0) return 0;
if (te1 == 1) return 1;
if (te1 == 2) return 2;
break;
}
}
// じゃんけん結果の累積記録
virtual void accumulation(int x){
if (x == 0) win++; // 勝ち → win++
if (x == 1) lose++; // 負け → lose++
if (x == 2) draw++; // あいこ→ draw++
}
// じゃんけんの一連動作
virtual void go() {
// 自分の手を決定
set_te0();
// 相手の手を受け取る
te1 = opponent();
// 勝ち負けの判定
int val = judge();
// 勝負結果の表示
accumulation(val);
if (val == 0) std::cout << "〇勝ち ";
if (val == 1) std::cout << "×負け ";
if (val == 2) std::cout << "△あいこ";
// "グー", "チョキ", "パー" の文字列作成
std::string s0, s1;
switch (te0) {
case 0: s0 = "グー "; break;
case 1: s0 = "チョキ"; break;
case 2: s0 = "パー "; break;
}
switch (te1) {
case 0: s1 = "グー "; break;
case 1: s1 = "チョキ"; break;
case 2: s1 = "パー "; break;
}
// 自分と相手の手を表示
std::cout << "(自分:" << s0 << ", 相手:" << s1 << ")\n";
// 累積結果の表示
std::cout << " 勝ち回数 …" << win << '\n';
std::cout << " 負け回数 …" << lose << '\n';
std::cout << " あいこ回数…" << draw << '\n';
}
};
// 人間プレーヤ
class JankenPlayer_A : public JankenPlayer {
public:
JankenPlayer_A() {
win = 0; lose = 0; draw = 0;
}
// 手の決定 … 勝ち(0), 負け(1), あいこ(2)
virtual void set_te0() {
std::cout << "自分の手を入力"
"《グー(0), チョキ(1), パー(2)》: ";
std::cin >> te0;
}
};
// コンピュータプレーヤ
class JankenPlayer_B : public JankenPlayer {
public:
JankenPlayer_B() {
win = 0; lose = 0; draw = 0;
srand((unsigned)time(NULL));
}
// 手の決定 … 勝ち(0), 負け(1), あいこ(2)
virtual void set_te0() {
te0 = rand() % 3;
}
};
// 対戦相手
int opponent() {
return rand() % 3;
}
#endif
// ------------------------------------
// Janken.cpp -------------------------
#include <iostream>
#include "Janken.h"
using namespace std;
int main() {
int x;
cout << "あなたは、人間プレーヤ(0)ですか?\n"
" コンピュータプレーヤ(1)ですか?"
" (\"0\" or \"1\" を入力) : ";
cin >> x;
JankenPlayer_A playerA;
JankenPlayer_B playerB;
char q;
do {
cout << "\n◆開始!\n";
if (!x) playerA.go();
else playerB.go();
cout << "続けますか(\"Y\" or \"N\") : "; cin >> q;
} while (q != 'N' && q != 'n');
}
// ------------------------------------