では、早速プログラムを見てみましょう。
// game35702.cpp #include <iostream.h> #include <stdlib.h> #include <string.h> #include <time.h> class Mountain { int mt[3]; int sente, order; int judge(); int show_stone(); int init(); int take_stone(); int comp_take(); int no_of_0(); public: int play(); };Mountainクラスにno_of_0メンバ関数が増えました。これは、石の数が0である 山の数を返します。
int Mountain::show_stone() { cout << "[A]---" << mt[0] << ", [B]---" << mt[1] << ", [C]---" << mt[2] << endl; return 0; } int Mountain::judge() { if (mt[0] + mt[1] + mt[2] == 1) return 0; else return 1; } int Mountain::take_stone() { char ans[8]; int stone, mtorder; if (sente != order) { comp_take(); if (judge() == 0) { cout << "コンピュータの勝ちです" << endl; return 1; } if (order == 1) order = 0; else order = 1; return 0; } while (1) { cout << "どの山からとりますか(A,B,C)---"; cin >> ans; if (strcmp(ans, "A") != 0 && strcmp(ans, "B") != 0 && strcmp(ans, "C") != 0 && strcmp(ans, "a") != 0 && strcmp(ans, "b") != 0 && strcmp(ans, "c") != 0) { cout << "山の指定が正しくありません" << endl; continue; } else { ans[0] = toupper(ans[0]); mtorder = ans[0] - 'A'; if (mt[mtorder] == 0) { cout << "その山にはもう石はありません" << endl; continue; } break; } } while (1) { cout << "いくつとりますか---"; cin >> ans; stone = atoi(ans); mt[mtorder] -= stone; if (mt[0] + mt[1] + mt[2] == 0) { cout << "その取り方では山の石が全部0になります" << endl; mt[mtorder] += stone; continue; } mt[mtorder] += stone; if (mt[mtorder] - stone < 0 || stone <= 0) { cout << "取る石の数が不正です" << endl; continue; } else { break; } } mt[mtorder] -= stone; show_stone(); if (judge() == 0) { cout << "あなたの勝ちです" << endl; return 1; } if (order == 1) order = 0; else order = 1; return 0; } int Mountain::init() { char ans[8]; mt[0] = 3; mt[1] = 5; mt[2] = 7; cout << "あなたが先手になりますか(Y/N)---"; cin >> ans; if (ans[0] == 'y' || ans[0] == 'Y') { sente = 1; } else { sente = 0; } order = 1; return 0; }これらのメンバ関数に変更はありません。
int Mountain::comp_take() { int mtorder, stone; char mtname; int jump = 0, i; srand((unsigned)time(NULL)); if (no_of_0() == 0) { //どの山も0ではない //2-4-6パターンにする if (mt[0] == 3 && mt[1] == 4 && mt[2] == 6) { mtorder = 0; stone = 1; mt[0] = 2; goto end; } if (mt[1] == 5 && mt[0] == 2 && mt[2] == 6) { mtorder = 1; stone = 1; mt[1] = 4; goto end; } if (mt[2] == 7 && mt[0] == 2 && mt[1] == 4) { mtorder = 2; stone = 1; mt[2] = 6; goto end; } //1-4-5パターンにする if (mt[0] > 1 && mt[1] + mt[2] == 9 && mt[1] * mt[2] == 20) { mtorder = 0; stone = mt[0] - 1; mt[0] = 1; goto end; } if (mt[1] > 4 && mt[0] == 1 && mt[2] == 5) { mtorder = 1; stone = mt[1] - 4; mt[1] = 4; goto end; } if (mt[2] > 4 && mt[0] == 1 && mt[1] == 5) { mtorder = 2; stone = mt[2] - 4; mt[2] = 4; goto end; } if (mt[2] > 5 && mt[0] == 1 && mt[1] == 4) { mtorder = 2; stone = mt[2] - 4; mt[2] = 4; goto end; } //1-2-3パターンにする if (mt[0] > 1 && mt[1] + mt[2] == 5 && mt[1] * mt[2] == 6) { mtorder = 0; stone = mt[0] - 1; mt[0] = 1; goto end; } if (mt[0] > 2 && mt[1] + mt[2] == 4 && mt[1] * mt[2] == 3) { mtorder = 0; stone = mt[0] - 2; mt[0] = 2; goto end; } if (mt[0] == 3 && mt[1] + mt[2] == 3 && mt[1] * mt[2] == 2) { mtorder = 0; stone = mt[0] - 3; mt[0] = 3; goto end; } if (mt[1] > 1 && mt[0] + mt[2] == 5 && mt[0] * mt[2] == 6) { mtorder = 1; stone = mt[1] - 1; mt[1] = 1; goto end; } if (mt[1] > 2 && mt[0] + mt[2] == 4 && mt[0] * mt[2] == 3) { mtorder = 1; stone = mt[1] - 2; mt[1] = 2; goto end; } if (mt[1] > 3 && mt[0] + mt[2] == 3 && mt[0] * mt[2] == 2) { mtorder = 1; stone = mt[1] - 3; mt[1] = 3; goto end; } if (mt[2] > 1 && mt[0] + mt[1] == 5 && mt[0] * mt[1] == 6) { mtorder = 2; stone = mt[2] - 1; mt[2] = 1; goto end; } if (mt[2] > 2 && mt[0] + mt[1] == 4 && mt[0] * mt[1] == 3) { mtorder = 2; stone = mt[2] - 2; mt[2] = 2; goto end; } if (mt[2] > 3 && mt[0] + mt[1] == 3 && mt[0] * mt[1] == 2) { mtorder = 2; stone = mt[2] - 3; mt[2] = 3; goto end; } //1-1-1パターンにする if (mt[0] == mt[1] && mt[0] == 1 && mt[2] > 1) { mtorder = 2; stone = mt[2] - 1; mt[2] = 1; goto end; } if (mt[1] == mt[2] && mt[1] == 1 && mt[0] > 1) { mtorder = 0; stone = mt[0] - 1; mt[0] = 1; goto end; } if (mt[0] == mt[2] && mt[0] == 1 && mt[1] > 1) { mtorder = 1; stone = mt[1] - 1; mt[1] = 1; goto end; } if (mt[0] == mt[1]) { mtorder = 2; stone = mt[2]; mt[mtorder] = 0; goto end;; } if (mt[1] == mt[2]) { mtorder = 0; stone = mt[0]; mt[mtorder] = 0; goto end;; } if (mt[2] == mt[0]) { mtorder = 1; stone = mt[1]; mt[mtorder] = 0; goto end;; } } //0の山が1つだけである if (no_of_0() == 1) { if (mt[0] == 0) { if (mt[1] == 1) { mtorder = 2; stone = mt[2]; mt[2] = 0; goto end; } if (mt[2] == 1) { mtorder = 1; stone = mt[1]; mt[1] = 0; goto end; } if (mt[1] > mt[2]) { mtorder = 1; stone = mt[1] - mt[2]; mt[mtorder] -= stone; goto end; } if (mt[2] > mt[1]) { mtorder = 2; stone = mt[2] - mt[1]; mt[mtorder] -= stone; goto end; } if (mt[2] == mt[1]){ mtorder = 1; stone = 1; mt[mtorder] -= stone; goto end; } } if (mt[1] == 0) { if (mt[0] == 1) { mtorder = 2; stone = mt[2]; mt[2] = 0; goto end; } if (mt[2] == 1) { mtorder = 0; stone = mt[0]; mt[0] = 0; goto end; } if (mt[0] > mt[2]) { mtorder = 0; stone = mt[0] - mt[2]; mt[mtorder] -= stone; goto end; } if (mt[2] > mt[0]) { mtorder = 2; stone = mt[2] - mt[0]; mt[mtorder] -= stone; goto end; } if (mt[0] == mt[2]) { mtorder = 2; stone = 1; mt[mtorder] -= stone; goto end; } } if (mt[2] == 0) { if (mt[1] == 1) { mtorder = 0; stone = mt[0]; mt[0] = 0; goto end; } if (mt[0] == 1) { mtorder = 1; stone = mt[1]; mt[1] = 0; goto end; } if (mt[0] > mt[1]) { mtorder = 0; stone = mt[0] - mt[1]; mt[mtorder] -= stone; goto end; } if (mt[1] > mt[0]) { mtorder = 1; stone = mt[1] - mt[0]; mt[mtorder] -= stone; goto end; } if (mt[1] == mt[0]) { mtorder = 0; stone = 1; mt[mtorder] -= 1; goto end; } } } if (no_of_0() == 2) { for (i = 0; i < 3; i++) { if (mt[i] != 0) { stone = mt[i] - 1; mtorder = i; mt[i] = 1; goto end; } } } while (1) { mtorder = rand() % 3; if (mt[mtorder] == 0) continue; else break; } while (1) { stone = 1; mt[mtorder] -= stone; if (mt[0] + mt[1] + mt[2] == 0) { mt[mtorder] += stone; continue; } else { break; } } end: mtname = mtorder + 'A'; cout << "コンピュータは" << mtname << "から" << stone << "個取りました" << endl; show_stone(); return 0; }コンピュータが取る石を決定するメンバ関数です。具体的考え方は C言語編第77章を参照してください。
int Mountain::play() { int ret; char ans[8]; while (1) { init(); show_stone(); while (1) { ret = take_stone(); if (ret == 1) break; } cout << endl << "もう一度やりますか(Y/N)"; cin >> ans; if (ans[0] == 'y' || ans[0] == 'Y') continue; else break; } return 0; }このメンバ関数に変更はありません。
int Mountain::no_of_0() { int no, i; no = 0; for (i = 0; i < 3; i++) { if (mt[i] == 0) no++; } return no; }石の数が0である山の数を返す関数です。特に説明は不要ですね。
int main() { Mountain m; m.play(); return 0; }main関数はいつもと同じです。
今回のプログラムでは、コンピュータは相当強くなったはずです。 必勝法もどきを知らない人と対戦するとまず100%コンピュータが勝つはずです。
対戦中、石の数を「○」で表示するなど、視覚に訴えられるように改良してみてください。
Update Apr/29/2002 By Y.Kumei