Portal:siro

ダイレクトマーケティングブログ

ちっサイラスBOT制作:reply反応(その1)

ちっサイ実装のまた続き

今回の目標

前回は「なでなで」したら好感度が上がるようになりました

今回は「なでなで」以外の反応を増強し、反応を返すようにします。
\reply返すよ!やったねたえちゃん!/

の前に覚書

デバッグするには、

	echo "line:" . __line__ . "<br>";

を差し入れるのが多分早い

スキンシップ以外の反応の追加

前回作った「chi_silas_skinshipWord」と同じ要領で「chi_silas_angerWord」「chi_silas_terrorWord」を作ります。
playとfeedに関しては実装がまた別になるので、今は作りません。
ついでにできたと思った部分にバグがあったのでさらっと直しておきます。continueそこに入れちゃだめだろ俺ェ……。

基本的にコピペと若干のバグ修正のため、解説することも特になかったり。

$skinshipWord;	// スキンシップ反応ワード格納配列
$angerWord;	// 怒り反応ワード格納配列
$terrorWord;	// 怯え反応ワード格納配列

if($conn !== false){
	// スキンシップ反応ワード読み込み
	$query = mysql_query("select * from chi_silas_skinshipWord");
	while(($tempWord = mysql_fetch_object($query))){
		// ↑のwhile文おかしいので後で直す
		// fetch_arrayでもfetch_objでもどちらでもいい気がするけど、今回はobjで。
		// 最終的に$skinshipWord["なでなで"] = 1みたいな感じになります
		$skinshipWord[$tempWord->string] = $tempWord->quantity;
	}
	// 怒り反応ワード読み込み
	$query = mysql_query("select * from chi_silas_angerWord");
	while(($tempWord = mysql_fetch_object($query))){
		// ↑のwhile文おかしいので後で直す
		// fetch_arrayでもfetch_objでもどちらでもいい気がするけど、今回はobjで。
		// 最終的に$skinshipWord["なでなで"] = 1みたいな感じになります
		$angerWord[$tempWord->string] = $tempWord->quantity;
	}
	// 怯え反応ワード読み込み
	$query = mysql_query("select * from chi_silas_terrorWord");
	while(($tempWord = mysql_fetch_object($query))){
		// ↑のwhile文おかしいので後で直す
		// fetch_arrayでもfetch_objでもどちらでもいい気がするけど、今回はobjで。
		// 最終的に$skinshipWord["なでなで"] = 1みたいな感じになります
		$terrorWord[$tempWord->string] = $tempWord->quantity;
	}
	mysql_close($conn);
}
$nextReply = false;

// 未処理のreplyに対して[古いほうから]繰り返す
$nextReply = false;
for ($i = 19; $i >= 0 ;$i--){
	if ( floatval($rep[$i]["id_str"]) > floatval($lastReply)/* && strcmp("Chi_Silas",$rep[$i]["user"]["screen_name"]) != 0*/){
		// 自分(chi_silas)からのreplyには反応しない(将来的に必要になるので現時点で実装)	
		if(!$nextReply){
			// スキンシップ反応ワード
			foreach($skinshipWord as $string => $quantity){
				if(strpos( $rep[$i]["text"], $string ) !== false){
					// 返事
					reaction_reply("skinship",$i);
					// 好感度の更新
					update_likability($rep[$i]["user"]["screen_name"],$quantity,"skinship");
					$nextReply = true;
					break;
				}
			}
		}
		if(!$nextReply){
			// 怒り反応ワード
			foreach($angerWord as $string => $quantity){
				if(strpos( $rep[$i]["text"], $string ) !== false){
					// 返事
					reaction_reply("anger",$i);
					// 好感度の更新
					update_likability($rep[$i]["user"]["screen_name"],$quantity,"anger");
					$nextReply = true;
					break;
				}
			}
		}
			// 怯え反応ワード
		if(!$nextReply){
			foreach($terrorWord as $string => $quantity){
				if(strpos( $rep[$i]["text"], $string ) !== false){
					// 返事
					reaction_reply("terror",$i);
					// 好感度の更新
					update_likability($rep[$i]["user"]["screen_name"],$quantity,"terror");
					$nextReply = true;
					break;
				}
			}
		}
		$nextReply = false;
		$lastReply = $rep[$i]["id_str"];
	}
}

反応ワードの追加

こっちはもう手動登録していきます。
誰か考えてー……。

reply反応

実装方法は2つあります。
1.撫でられたら無条件で喜び、叩かれたら無条件で怯える
2.撫でられても現在値が不機嫌だったら不機嫌な反応をし、叩かれても機嫌がよければ許容する

1.は非常に単純な実装になります。
撫でられたら、撫でられた場合の反応リストから返信を引っ張ってきて返事をします
2.はもっと単純な実装になります。
何されてもとりあえず現在の気分を読みに行き、現在の気分に対応する返事をします

さてどうしようかと考えましたが、1と2の複合技でお返事したいと思います。
最終的にねむいときに撫でられたら「ぴー……。[あったかくてもっとねむくなっちゃった]」とか、
かなしいときに撫でられたら「……ぴぃぴぃ。[ぐすんぐすん、あまえていーい?]」とか、
そういう返事をするようになったらいいなあ(願望

Let's実装

まずは台詞パターンを考えます。chi_silas_replyListというテーブルを作り、
id(PK),string,res,emotionというカラムを作ります。

そんでもって
・うれしい
・おこった
・かなしい
・たのしい
・ねむたい
・はらぺこ
・さみしい
・すやすや
これに対応する反応をばーっと登録していきます。

例えばskinshipに対する反応で
1,ぴっぴっ! [にこにこっ!],skinship,うれしい
2,……ぴぃー。 [むすっ],skinship,おこった
3,……ぴぃぴぃ。[ぐすんぐすん、あまえていーい?],skinship,かなしい
4,ぴぃ! [わーいっ],skinship,たのしい

……以下略。
こんな風に設定していきます。


ソースは単純。これを引っ張ってきて返答するだけです。関数作っちゃったほうが早いので作りますと、

function reaction_reply($res,$i){
	global $st,$rep;
	$conn = db_conn();
	if($conn !== false){
		// 現在の感情を取得
		$query = mysql_query("select emotion from chi_silas_status where id = (select max(id) from chi_silas_status)");
		$obj = mysql_fetch_object($query);
		$emotion = $obj->emotion;
		// 今の感情と合致する台詞を喋る
		$query = mysql_query("select string from chi_silas_replyList where emotion = '" . $emotion . "' and res = '" . $res . "' order by RAND() limit 1");
		$obj = mysql_fetch_object($query);
		$reply_status = "@" . $rep[$i]["user"]["screen_name"] . " " . $obj->string;
		echo $reply_status;
		$st->setUpdate(array('status'=>$reply_status,'in_reply_to_status_id_str'=>$rep[$i]["id_str"]));
		mysql_close($conn);
	}
}

解る人むけ:
Q.なんでSQL2文書いてるんだよ……副問い合わせで1文にまとめろよ……
A.だって僕バカだからそんなに1文を複雑にしたらわからないんですよう!!

許せ。ほんと許してくれ。
いやマジメに3行とか4行にもわたるSQL書くくらいなら素直に分けたほうが見た目わかりやすいじゃないっすか……てへぺろ


これを呼び出してやれば喋ります(理論上は)


というわけでこれである程度の返事はするようになりました。
ソースコードは長いので貼らなくてもいいですk

そろそろplayとfeed(こっちが優先)を実装したいのですが、実装アイディアがないのと、
最近まじめに仕事したり遊んだりしてるのでちょいとちっサイに関しては停滞中です。しょぼぼ。ごめんなあ。