前章で作ったゲームを少し強くします。これは、
C言語編第75章の
「必勝法もどき」を使います。コンピュータの取る石の数を(m-1)%(n+1)とします。しかし、 これが0となる場合もあるので、この時は1だけ取って相手のミスを待ちます。
では、プログラムを見てみましょう。ほとんど変更はありません。
// ishi02.cpp
#include <iostream.h>
#include <string.h>
class Mountain
{
int m, n; //山の石の数、一度に取れる石の数
int turn; //0:人間の番、1:コンピュータの番
int comp_take(); //コンピュータが取る石の数を決定する
public:
Mountain();
int get_stone();
};
Mountain::Mountain()
{
char yesno[8];
cout << "交互に石を取り、最後の1個を取った人が負けです" << endl;
cout << "先手になりますか(Y/N): ";
cin >> yesno;
if (strcmp(yesno, "y") == 0 || strcmp(yesno, "Y") == 0)
turn = 0;
else
turn = 1;
while (1) {
cout << "石の山の数はいくつにしますか(5以上、100以下)";
cin >> m;
if (m < 5 || m > 100) {
cout << "石の数が不正です" << endl;
continue;
} else
break;
}
while (1) {
cout << "一度に取れる石の数はいくつにしますか(2以上)";
cin >> n;
if (n < 2 || n > m - 1) {
cout << "石の数が不正です" << endl;
continue;
} else
break;
}
}
int Mountain::get_stone()
{
int p; //取る石の数
if (turn == 1) {
if (m <= n + 1)
p = m - 1;
else
p = comp_take();
cout << "コンピュータは" << p << "個取りました" << endl;
} else {
while (1) {
cout << "取る石の数 ";
cin >> p;
if (p > 0 && p < m)
break;
else
cout << "取る石の数が不正です" << endl;
}
}
m = m - p;
cout << "石の山は" << m << "個です" << endl;
if (m == 1) {
if (turn == 1) {
cout << "コンピュータの勝ちです" << endl;
return 1;
} else {
cout << "あなたの勝ちです" << endl;
return 1;
}
}
if (turn == 1)
turn = 0;
else
turn = 1;
return 0;
}
int Mountain::comp_take()
{
int p;
p = (m - 1) % (n + 1);
if (p != 0)
return p;
else
return 1;
}
int main()
{
Mountain mt;
while (1) {
if (mt.get_stone() == 1)
break;
}
return 0;
}
乱数は使わなくなったので、stdlib.h, time.hは不要となりました。コンピュータの取る石の数を決めるcomp_takeメンバ関数が増えました。
石山の数を「○」で表すよう、改良してみてください。また、 繰り返してゲームが出来るように改良してみてください。
Update Feb/17/2002 By Y.Kumei