Aランクレベルアップメニュー 陣取りゲーム「STEP: 22 陣取りのターン数 PHP編」

(追記)コードを眺めていたら、初期処理部分はばっさり消せることに気づきました。
新しいコードを置いておきます。

<?php
    // 自分の得意な言語で
    // Let's チャレンジ!!


    $s = explode(" ",trim(fgets(STDIN)));
    $h = $s[0];
    $w = $s[1];
    $l_num = $s[2];
    
    $con = 0;//reset カウント
    $hatena_flag = false;// ?にしたかどうか
    
    //map取得
    for ($i = 0; $i < $h; $i++) {
        $hoge = trim(fgets(STDIN));
        for ($j = 0; $j < $w; $j++) {
            $map[$i][$j] = mb_substr($hoge, $j, 1); 
            if($map[$i][$j]=="*"){
                $y = $i;
                $x = $j;
            }
        }
    }
    
    
    //l取得
    for ($i = 0; $i < $l_num; $i++) {
        $hatena[] = trim(fgets(STDIN));
    }
    //print_r($hatena);
    
    
    //初期位置に関して
    if($hatena[0] == $con){
        $map[$y][$x] = "?";
        array_shift($hatena);
    }else{
        $map[$y][$x] = "*";
    }
    $newstar[]=array($y,$x, $con);
    
    $con++;
    //print_r($map);
    
    while(count($newstar)>=1){//移動可能な配列がある限り続ける
        
        $y = $newstar[0][0];
        $x = $newstar[0][1];
        $con = ($newstar[0][2])+1;

        
        //?にするところかどうか
        for($i=0; $i<count($hatena); $i++){
            if($con == $hatena[$i]){
                $hatena_flag = true;
            }
        }
        if($hatena_flag == true){
            $put_text="?";
        }else{
            $put_text="*";
        }
        
        
        //共通操作
        if($y>=1 && $map[$y-1][$x]=="."){
            $map[$y-1][$x] =$put_text;
            $newstar[]=array($y-1,$x, $con);
        }
        if($y<$h-1 && $map[$y+1][$x]=="."){
            $map[$y+1][$x] = $put_text;
            $newstar[]=array($y+1,$x, $con);
        }
        if($x>=1 && $map[$y][$x-1]=="."){
            $map[$y][$x-1] = $put_text;
            $newstar[]=array($y,$x-1, $con);
        }
        if($x<$w-1 && $map[$y][$x+1]=="."){
            $map[$y][$x+1] = $put_text;
            $newstar[]=array($y,$x+1, $con);
        }
        
        array_shift($newstar);//いまつかった配列を消す
        //print_r($newstar);
        
        $hatena_flag = false;
    }

    
    //出力
    for ($i = 0; $i < $h; $i++) {
        for ($j = 0; $j < $w; $j++) {
            echo($map[$i][$j]);
        }
        echo("\n");
    }


?>

すっきりしました。


(以下は修正前のコードです。参考にはなりません。あしからず)

くたくたなのでコードだけ置いておきます。

ご参考になるかどうか。

ここまでくると、コードが正しいかどうか見当がつかず、「通ったから合ってるんだろう、たぶん」の境地です。

<?php
    // 自分の得意な言語で
    // Let's チャレンジ!!


    $s = explode(" ",trim(fgets(STDIN)));
    $h = $s[0];
    $w = $s[1];
    $l_num = $s[2];
    
    $con = 0;//reset カウント
    $hatena_flag = false;// ?にしたかどうか
    
    //map取得
    for ($i = 0; $i < $h; $i++) {
        $hoge = trim(fgets(STDIN));
        for ($j = 0; $j < $w; $j++) {
            $map[$i][$j] = mb_substr($hoge, $j, 1); 
            if($map[$i][$j]=="*"){
                $y = $i;
                $x = $j;
            }
        }
    }
    
    
    //l取得
    for ($i = 0; $i < $l_num; $i++) {
        $hatena[] = trim(fgets(STDIN));
    }
    //print_r($hatena);
    
    
    //初期位置に対して
    if($hatena[0] == $con){
        $map[$y][$x] = "?";
        array_shift($hatena);
    }else{
        $map[$y][$x] = "*";
    }
    
    
    
    $con++;
    //print_r($map);
    
    
    
    //初期処理
    //新たに*にした場所を$newstarに格納する
    
    if($con == $hatena[0]){
        $put_text = "?";
        if(count($hatena)>=1){
            array_shift($hatena);//使用済みにつきひとつ消去
        }
    }else{
        $put_text = "*";
    }
    
    if($y>=1 && $map[$y-1][$x]=="."){
        $map[$y-1][$x] =$put_text;
        $newstar[]=array($y-1,$x, $con);
    }
    if($y<$h-1 && $map[$y+1][$x]=="."){
        $map[$y+1][$x] = $put_text;
        $newstar[]=array($y+1,$x, $con);
    }
    if($x>=1 && $map[$y][$x-1]=="."){
        $map[$y][$x-1] = $put_text;
        $newstar[]=array($y,$x-1, $con);
    }
    if($x<$w-1 && $map[$y][$x+1]=="."){
        $map[$y][$x+1] = $put_text;
        $newstar[]=array($y,$x+1, $con);
    }
    
    //print_r($newstar);
    //echo($newstar[0][2]."\n");
    
    
    while(count($newstar)>=1){//移動可能な配列がある限り続ける
        
        $y = $newstar[0][0];
        $x = $newstar[0][1];
        $con = ($newstar[0][2])+1;

        
        //?にするところかどうか
        for($i=0; $i<count($hatena); $i++){
            if($con == $hatena[$i]){
                $hatena_flag = true;
            }
        }
        if($hatena_flag == true){
            $put_text="?";
        }else{
            $put_text="*";
        }
        
        
        //共通操作
        if($y>=1 && $map[$y-1][$x]=="."){
            $map[$y-1][$x] =$put_text;
            $newstar[]=array($y-1,$x, $con);
        }
        if($y<$h-1 && $map[$y+1][$x]=="."){
            $map[$y+1][$x] = $put_text;
            $newstar[]=array($y+1,$x, $con);
        }
        if($x>=1 && $map[$y][$x-1]=="."){
            $map[$y][$x-1] = $put_text;
            $newstar[]=array($y,$x-1, $con);
        }
        if($x<$w-1 && $map[$y][$x+1]=="."){
            $map[$y][$x+1] = $put_text;
            $newstar[]=array($y,$x+1, $con);
        }
        
        array_shift($newstar);//いまつかった配列を消す
        //print_r($newstar);
        
        $hatena_flag = false;
    }

    
    //出力
    for ($i = 0; $i < $h; $i++) {
        for ($j = 0; $j < $w; $j++) {
            echo($map[$i][$j]);
        }
        echo("\n");
    }


?>

追加になった$l(ハテナマークの位置)の処理位置をちょっと間違えて、
かなり意地悪なcase4で引っかかりました。
それがくるとは!!

https://paiza.jp/works/mondai/a_rank_level_up_problems

paizaAランクレベルアップメニュー(各言語あり)
2+