黄昏より暗きもの、血の流れより赤きもの

黄昏より暗きもの、血の流れより赤きもの

自分の好きな事を好きなように書いて行きます。

○×ゲームをC言語で作成する

問題


Nを自然数とする。N*Nの升目に、2人のプレイヤーが順々に○か×を書き込み(入力)、縦、横、斜めの何れかの方向に○か×を先に揃えたプレイヤーを勝ちとするゲームを考える。例えばN=3のとき以下の図のように縦、横、斜めに○または×がN個先に揃えたプレイヤーが勝ちとなる。このようなゲームのプログラムを作成せよ。可能ならばNの値が変わっても、動作するように実装せよ。



[ヒント]:升目の状態を表示する部分、升目に○×を置く部分、升目がそろっているかを判定する部分の3つの関数などに分けて作成していく。

解説


仕様


プレイヤーは先手を1、後手を2とする。さらに問題の升目boardは長さN*Nの一次元配列とし、例えばN=5,N=kの場合、各升目は配列の以下の部分に対応している。



ここでN=5のとき、各プレイヤーが0〜24の部分の値を入力すると、上図の位置に○または×が置かれるような仕様となっている。


手順


まず升目の状態を表示する部分、升目に○×を置く部分、升目がそろっているかを判定する部分の3つの関数などに分けて作成していく。


print関数(表示):升目を表示する部分。for文ループを使って升目の中身を表示する。
putoff関数(○を置く部分):升目に○か×かを置く部分。特定の升目にプレイヤーの番号を入力していく。
check関数(判定):○か×かが縦、横、斜めにN個きちんと並んでいるかを調べ、並んでいればプレイヤーの番号を返す

1.升目に○×を置く:putoff関数について


C言語の場合、○か×かを書き込みたい番号の升目(board)に、プレイヤーの番号を格納すれば良い。書き込みたい番号はscanf関数を使ってやれば良い。

2.升目が揃っているか判定:check関数について


まず縦、横、斜めの各列における、プレイヤーの番号(1または2)の個数を格納する配列row,col,squareという配列を用意する。そして1,2の個数をカウントしていき、各配列の値がNとなったら、そのプレイヤーの値を返り値として持たせる。何も揃ってない時は0を返すようにすれば良い。

3.升目の状態を表示する:board_print関数について


単に配列の個数分だかループし、配列の中身を表示すればよい。プレイヤーの番号が1なら○、2なら×、0ならばNとして表示をしていく。

ソースコード


検証(テスト)


テストの経験談


筆者はソーシャルゲームのテスト(デバッグ)をしたことがあった。テストにおいてはまずテスト項目をExcelや紙で表にまとめ、実際に検証して行く事が多かった。例えばストーリーが追加された場合は、ストーリーに応じた新しいカードがExcelの表通りに表示されるか?キャラクターに応じて、バトルに勝った時/負けた時の台詞が変わるか?など分岐をはらむ場合も少なくない。

勝ち負けに応じて台詞が変わるときは、まず負けた方から先に検証し次に勝った場合を検証して行った。勝った場合だと後に戻れない場合が多いので、まずは負けた方からやらねばならない事もある。

テストにかかる時間を見積もる


問題

キャラA,B,C,Dの4人がボスEに戦いを挑む。AvsE,BvsE,CvsE,DvsEで戦いを行いそれぞれの場合で勝った時、負けた時、引き分けの場合でボスが全く違う台詞がそれぞれ1種類ずつ用意されている。このとき、
(1):考えられる台詞の組み合わせは何通りか?
(2):台詞1通りがきちんと表示されるのに2分かかるとき、全部調べるのに何分かかるか?

答え

(1):4*3=12通り(答)
(2):2(分)*12(通り) = 24(分) (答)

上記の問題を見ての通り、テストは地味に時間がかかるという事だ。大体何時間で全作業が終了するか?と言う見積もりは働いて行く上で結構必要だ。

プレイヤーが1人の場合の検証(ホワイトボックステスト)


ここからは自分で作ったプログラムの検証を行って行く。プログラム等と見比べて、テスト項目を作成して行こう。特にputoff関数の分岐の部分や、3つ揃った時にcheck関数がきちんと動作しているのかを調べて行く。

テスト項目(テストケース)の作成


テストするとき、どのようにテストするのかを定めた物をテストケースという。まず縦横斜めに1がN個揃ったときに正常に終了するか調べ、check関数の判定法が正しく行われているのかを調べる。又Nの値を変えても正常に動作するのかを調べるため、const int Nの値をN=3,N=5のそれぞれの場合において検証していく。又、putoff関数の値に0以下、25以上、今まで置いた場所に○を置こうとすると再度入力されるかどうかを調べていく。これを表にしてまとめていくと、








N=3N=5
縦(↓)
横(→)
上斜め(↓→)
下斜め(↑←)

次は入力エラーが起こっていないかどうかを表にすると、






0以下
25以上
同じ場合

プレイヤーが2人の場合の検証(N=3)


ところでcheck関数では、プレイヤーに応じて違う配列のインデックスを使って判定を行っていた。そこで先手と後手とは分けて調べるようにした。







先手縦後手縦
先手横後手横
先手上斜め(↓→)後手上斜め(↓→)
先手下斜め(↑←)後手下斜め(↑←)

全部をここに書く訳には行かないので、プレイヤー2人の場合の実行結果の一部をここに表示する。下を見ると斜めに揃ったときゲームは無事に終了したので、プログラムは無事に動作している。他の場合も検証してみたのだが、無事動作している。