プログ

’14修了無内定理系院卒の活動雑記||プー太郎ログ||プログラミング雑記

中括弧の開始とインデント

昨日載せたプログラムでもそうだったように,僕は今まで中括弧の開始位置を次の行にしています.多分世の中では行末に書くのが圧倒的多数なので,他の人と一緒にプログラミングをする仕事に就きたいならいつか直さなきゃなと思っており,良い機会なので公開予定のサイトでは極力行末にしていきたいと思います.その分インデントはきっちりしないとね.

今日は昨日に続きプログラミング.ホントはFEの勉強しなきゃいけないんだけど,PHPいじるのが楽しくてついつい手を伸ばしてしまいます.FEはブログのネタ的にもあまり書くこと無いしね.

今日実装したのは

  • プレイヤー側も一度選んだ数は選択できないように.
  • コンピュータの思考強化.

プレイヤー側の入力補助
プレイヤー側の回答は入力が必要なためコンピュータ側のものをそのまま流用することはできない.ただやってることはそれほど変わらないので似通ったものになる.現在はコンボボックスからの選択にしており,結果から書くと以下のようになった.

<form action="result.php" method="post">
  <input type="hidden" name="myNum" value='<?php echo $myNum ?>'>
  <input type="hidden" name="enNum" value='<?php echo $enNum ?>'>
  <input type="hidden" name="turn" value=0>
  <select name="answer">
<?php
    $answer=$myNum+1;
    while($answer<=$myNum+10)
    {
      if(strpos($record,num2char($answer))===false)
        echo    "<option selected>$answer</option>";
      $answer = $answer+1;
    }
?>
  </select>
  <input type="hidden" name="record" value='<?php echo $record?>'>
  <input type="submit">
</form>

$myNum+1~10のうち,回答済みでないものを除いてechoするだけ.昨日とは逆に===を使うことに注意.selectedは元々最小値についていたけど,別に気にしないし細かい設定も面倒いので,毎回呼んで結果として最大値が選択済みになる.
<form>タグ内の<select>タグ以外は同時に送信するデータなので今回の実装のメイン部分ではない.ただ気になることがあって,recordを送信する部分で$record.num2char($answer)とするとうまくいかなかった.form関連で余計な情報がつくせいなのかもしれないけど,原因がわからないため,result.phpの方で追加することで現在は解決している.

思考強化
「一度選んだ数を相手は選択しない」を昨日の時点で実装済みでしたが,今日は新たにプレイヤーの回答から正答を絞り込む機能を実装.
プレイヤーの回答から絞り込むためには,$recordの内どれがプレイヤーのものかを理解する必要があるので,プレイヤーの回答だけ抜き取る関数を,

<?php
function readPRec($input){
  $i = 0;
  $temp = "";
  while($i < strlen($input)/2 ){
    $temp = $input[strlen($input)-1-$i*2] . $temp ;
    $i = $i+1;
  }
  return $temp;
}
?>

このように実装.つまり,$recordの末尾から1個おきに読み取って,空文字列の頭に加えていく.先頭でなく末尾から読むことで,どちらが先攻でも関係なく動作する.んでプレイヤーの回答履歴を手に入れたら,その中から最大のものと最小のものを入手し(それぞれ関数maxStr(),minStr()で入手.関数名変かも,内容は割愛),

<?php
$min = ((maxStr(readPRec($record))>11)?maxStr(readPRec($record))-10:0);
$max = ((minStr(readPRec($record))<11)?minStr(readPRec($record))-1:10);
?>

とすることでプレイヤーの番号の範囲を$min~$maxに絞り込める.そして昨日のwhile文で$enNum+1~10だった条件範囲を$enNum+$min~$maxにすることでプレイヤーの数を絞り込める.あとはrand(1,10)+rand(1,10)にしてた部分を適切にすれば人間と同じ強さのコンピュータができるはず.これ以上強くするなら,正答を知ってる(=ルール違反)動きになるんじゃないかな.

ここまでやった時点でココらへんの関数の引数に空行列""を入力すると無限ループ(?)に突入することが発覚した.とりあえず上記の$min及び$maxへの代入をif($record!="")で条件付けることで解決させたけど,スマートな方法ではないので理解を深めて修正したい.昨日のreadRec()はリジェクトしなくても大丈夫そうな辺りにヒントがあるかも知れない.