コンピュータの取る石の数を(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