プログラムの実行結果は以下の通り。☆のあるところが解。次郎は「いぬ」と答えるべき。今年は「戌年(いぬどし)」だからか。
太郎 次郎 => 勝ち 負け あい あい => 0 0 あい いか => 0 1 あい いし => 0 1 あい いぬ => 1 0 ☆ あい いま => 0 1 あい えと => 0 0 あい かき => 0 0 あい きく => 0 0 あい くち => 0 0 あい しか => 0 0 あい ちえ => 0 0 あい とし => 0 0 あい ぬか => 0 0 あい まめ => 0 0 あい めし => 0 0
プログラムのソースは以下の通り。
#include "puzutl.h"
cstring word[] = { "あい", // 太郎と次郎が知っている全ての単語
"いか",
"いし",
"いぬ",
"いま",
"えと",
"かき",
"きく",
"くち",
"しか",
"ちえ",
"とし",
"ぬか",
"まめ",
"めし"};
const int num_word = sizeof(word) / sizeof(word[0]); // 単語数
int nextword[num_word][num_word]; // しりとり出来る単語の並び
int num_nextword[num_word]; // しりとり出来る単語の数
int num_win[num_word]; // 次郎の2番目の単語での勝ち数
int num_loss[num_word]; // 次郎の2番目の単語での負け数
YesNo word_used[num_word]; // 単語は既に使われたか?
int find_word[num_word]; // 太郎・次郎が言った単語
void find_next( int lvl, int ab, int preword) // 次の単語を言う
{
// lvl :次の単語
// ab :==0:次は太郎
// !=0:次は次郎
// preword :前の人が言った単語
if( lvl > num_word) { // 最後までしりとりできた,次の言葉はもう無いので次の人が負け
if( ab) { // 次郎の負け
num_loss[find_word[1]]++; // 次郎が二番目に言った単語の勝ち負けを記録する
}
else { // 次郎の勝ち
num_win[find_word[1]]++; // 次郎が二番目に言った単語の勝ち数を増やす
}
return;
}
// 次の単語を考える。
int num_nw = 0;
for( int i=0; i< num_nextword[preword]; i++) {// 自分が次に言える単語を調べる
int nw = nextword[preword][i]; // 次に言える単語の候補
if( word_used[nw]) continue; // 残念この単語は既に使っていた
num_nw++;
word_used[nw] = YES; // この単語は私が言いました
find_word[lvl] = nw; // この単語は太郎・次郎が既に言った
find_next( lvl+1/*次の単語を言ってください*/, !ab, nw);
word_used[nw] = NO; // この単語はまた使っても良いです
}
if( num_nw == 0) { // 次の単語を言えなかったので負け
if( ab) { // 次郎の負け
num_loss[find_word[1]]++; // 次郎が二番目に言った単語の勝ち負けを記録する
}
else { // 次郎の勝ち
num_win[find_word[1]]++; // 次郎が二番目に言った単語の勝ち数を増やす
}
}
}
int main( int argc, cstring argv[])
{
// しりとりできる単語の繋がりを求める
for( int i=0; i< num_word; i++) {
jap chr_last = lastjap(word[i]); // 前の単語の最後の文字
int n = 0;
for( int j=0; j< num_word; j++) { // 次の単語全てを調べる
if( chr_last == firstjap( word[j])) { // 前の単語と後ろの単語が繋がる
nextword[i][n++] = j; // 次の単語を記録しておく
}
}
num_nextword[i] = n; // word[i]に繋がる単語の数
word_used[i] = NO; // 単語はまだ使われていない
}
int lvl = 0;
find_word[lvl] = 0; // 「あい」から始める
find_next( lvl+1, 1/*次は次郎の番*/, 0/*最初は「あい」と言った*/);
// 単語と勝ち負けの数を出力してみる
ps( "太郎 次郎 => 勝ち 負け\n");
for( i=0; i< num_word; i++) {
ps( "%s %s => %4d %4d", word[0], word[i], num_win[i], num_loss[i]);
if( num_win[i] > 0 && num_loss[i] == 0) ps( " ☆\n");
else ps( "\n");
}
return 0;
}