<< 2019 年 11 月 >>
27
28
29
30
31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30


 トップ > プログラミング > Sudoku  ナンバープレイスを課題にしたプログラム作りです。

 1 2 3 4 5 6 7 8 9 10 11 12 13 
2010/08/10 17:39
4. マス目の状態の確認

手順2の記述に入る前に、81個のマス目の状態を確認するためのコードを書き加えてみます。

手順1の記述では、9×9 のマス目に入る数字の候補を'123456789'という文字列として、81個の要素を持つ配列に設定しました。81個の要素は、0 から 80 までの添字の値で識別されるのですが、9 行 9 列のマス目との対応をどうするのかについては、触れていませんでした。次図のように、対応させることにします。各マス目の中の数字は、添字になります。

012
91011
181920
345
121314
212223
678
151617
242526
272829
363738
454647
303132
394041
484950
333435
424344
515253
545556
636465
727374
575859
666768
757677
606162
697071
787980

任意の時点で何度でもこの確認作業を行えるように、関数としてコードを記述してみます。


Pocket詳解 PHP辞典
function PrintGridState()
{
    // 全てのマス目の状態を表示する。
    global $grid;
    $col = 0;
    $row = 0;
    $blk = 0;
    for($n = 0; $n < count($grid); $n++)
    {
        if($col == 0)
        {   // 行番号を表示
            $row++; // $row = $row + 1 のことです。
            echo "$row "; // $row . ' ' と書くこともできます。
        }

        if(strlen($grid[$n]) == 1)
            echo $grid[$n];     // 確定した一つの数字を表示
        else
            echo "($grid[$n])"; // 候補が複数の場合、括弧内に表示

        if(++$col == 9) // if()の評価の前に$col = $col + 1 を実行
        { // 9列で改行
            echo "\n"; // 改行します。
            $col = 0;
            $blk = 0;
        }
        elseif(++$blk == 3)
        { // 3列ごとに隙間を空ける
            echo ' ';
            $blk = 0;
        }
    }
}

関数は'function 関数名(){…}'と記述されます。{}の中には処理が記述されます。関数の特徴は、関数を呼び出さない限り、制御が{}内に移らないことです。ここでは、関数名をPrintGridStateとしました。

'global $grid;'という記述は、関数の外で定義されている変数 $grid を関数内でも使うことを宣言しています。手順1により、$gridには候補値が設定されています。この宣言なしで$gridを使った場合、$grid に値を設定しない限り、初期状態では何も設定されていません。

$col、$row は、行と列を表す変数です。$blk は3列ごとに空白を挿入し見やすくするために使っている変数です。候補が複数の場合は、括弧内に複数の候補を並べて表示するようにしました。表示には echo 文を使います。ダブルクォーテーション内には文字列だけでなく、変数や改行を表す特殊文字を書けます。変数は評価されて、変数の持つ値に置き換えられます。Perl も同様の記述ができます。PHP と Perl はともに、変数の先頭に'$'を付けるので、こういった記述が可能になるわけです。便利な機能です。文字列を連結させる演算子'.'を使った記述に比較して、読みやすいと思います。'\n'は改行文字です。

'$row++' は、'$row = $row + 1' 同じです。$row の値に 1 を加算し、$row に格納します。'if(++$col == 9)~'は、$col の値が9 かどうかを判定していますが、判定する前に $col に 1 を加算しています。'$col++; if($col == 9)~'と同義です。

手順1の記述と合わせたコードと、その実行結果を以下に記します。コードはsudoku.php というファイルに格納しましたので、コマンドプロンプトから php を呼び出すときに、引数として sudoku.php を指定して実行させています。

マス目の状態確認実行結果
数独パズルを解く。
<?php
// 数独パズルを解く。
// 9x9のマス目に候補値を設定する。
$grid = array();
for($n = 0; $n < 81; $n++)
{
    $grid[$n] = '123456789';
}

// 全てのマス目の状態を表示する。
PrintGridState();
exit;

function PrintGridState()
{
    // 全てのマス目の状態を表示する。
    global $grid;
    $col = 0;
    $row = 0;
    $blk = 0;
    for($n = 0; $n < count($grid); $n++)
    {
        if($col == 0)
        {
            $row++;
            echo "$row ";
        }

        if(strlen($grid[$n]) == 1)
            echo $grid[$n];
        else
            echo "($grid[$n])";

        if(++$col == 9)
        {
            echo "\n";
            $col = 0;
            $blk = 0;
        }
        elseif(++$blk == 3)
        {
            echo ' ';
            $blk = 0;
        }
    }
}
?>

'PrintGridState();'と関数を呼び出した後に、'exit;'でプログラムの実行を終了させています。'exit;'を書かなくても問題はありませんが、関数の下に実行可能なコードが書かれているかどうかを気にする必要がないように、明示的に終了させたまでです。


(Sudoku) 2010/08/10 17:39

名前:
コメント:
投稿キー: ※右の文字列を入力してください。