第56章 石取りゲームを強くする


前章で作ったゲームを少し強くします。これは、 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メンバ関数が増えました。

石山の数を「○」で表すよう、改良してみてください。また、 繰り返してゲームが出来るように改良してみてください。


[C++Index] [総合Index] [Previous Chapter] [Next Chapter]

Update Feb/17/2002 By Y.Kumei
当ホーム・ページの一部または全部を無断で複写、複製、 転載あるいはコンピュータ等のファイルに保存することを禁じます。