Friction River Software

  • お問い合わせ

CakePHP5入門【WebAPI編⑮】ナンバーズ3を予想②

A子

前回作った「num3Prediction」メソッドだけど、もう少し改良していこう
(あれって各数字のスコアを返すだけだったしね)

B美

ふむ
どうするの?

C菜

引っ張り」の数字を軸として予想するのは当然ですけど~

問題はその組み合わせですね~

B美

私としては、そもそも前回のスコア計算アルゴリズムが「妥当かどうか」の検証をやりたいわね
例えば…

実施回当選番号
第6921回269
第6922回979
第6923回135
第6924回918

のとき、スコアはこうなる(曜日と六曜の加算は除く)んだけど、第6925回の当選番号は「843」だったわけ

0123456789
0603030035

もしも「1」と「9」を軸にして予想した場合、全然ダメだったという…(苦笑)
(ただ、スコア3点の「3」と「8」は出現してるんだけどね)

C菜

ということは~

例えば、第5回目から最新回までのスコアを全て算出して、それを一覧表示してみるってどうでしょう~?

A子

ふむ、だったら検証用のコントローラを作っちゃおうか…

VerificationController」って名前で良いかな?

C菜

OKです~
MATE端末」上でこう入力しましょう~

cd html/numapp[Enter]
bin/cake bake controller verification[Enter]

src/Controller/VerificationController.php」が生まれるので、中身を全て削除しておきますね~
あと、Numbersテーブルのフェッチについても書いておきました~


A子

それじゃ、「score01」メソッドの中身を書いていこう

基本的には「TopController」クラスの「pulling3」メソッドを参考にすれば良いよね
(「引っ張り」を検証したやつ)

スコア計算については「ApiController」クラスの「num3Prediction」メソッドの中身を使ったよ

//検証用01
public function score01()
{
    //numbersテーブルを検索(「実施回」の昇順)
    $numbers = $this->Numbers->find()->order(['lottery_time' => 'asc']);
    $numbers_array = $numbers->toArray();
    $result = [];

    //全件数分、ループを回す
    foreach ($numbers as $idx => $val) {
        //最初の4件はとばす
        if ($idx < 4) continue;

        //この回の結果を初期化
        $record = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, $val->lottery_time, $val->num3_str];

        //フラグ配列
        $pre1 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; //1回前に出現しているか(出現した場合「1」)
        $pre2 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; //2回前に出現しているか(出現した場合「1」)
        $pre3 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; //3回前に出現しているか(出現した場合「1」)

        //1回前
        $num3_place1 = $numbers_array[$idx - 1]->num3_place1;
        $num3_place10 = $numbers_array[$idx - 1]->num3_place10;
        $num3_place100 = $numbers_array[$idx - 1]->num3_place100;
        $num3_array = [$num3_place100, $num3_place10, $num3_place1];
        $num3_array = array_unique($num3_array); //重複排除
        foreach ($num3_array as $num) {
            $record[$num] += 3;
            $pre1[$num] = 1;
        }

        //2回前
        $num3_place1 = $numbers_array[$idx - 2]->num3_place1;
        $num3_place10 = $numbers_array[$idx - 2]->num3_place10;
        $num3_place100 = $numbers_array[$idx - 2]->num3_place100;
        $num3_array = [$num3_place100, $num3_place10, $num3_place1];
        $num3_array = array_unique($num3_array); //重複排除
        foreach ($num3_array as $num) {
            $record[$num] += 3;
            $pre2[$num] = 1;
        }

        //3回前
        $num3_place1 = $numbers_array[$idx - 3]->num3_place1;
        $num3_place10 = $numbers_array[$idx - 3]->num3_place10;
        $num3_place100 = $numbers_array[$idx - 3]->num3_place100;
        $num3_array = [$num3_place100, $num3_place10, $num3_place1];
        $num3_array = array_unique($num3_array); //重複排除
        foreach ($num3_array as $num) {
            if ($pre1[$num] == 1 && $pre2[$num] == 1) {
                //1回前と2回前の両方に出現している場合、何もしない
            } elseif ($pre1[$num] == 1 || $pre2[$num] == 1) {
                //1回前と2回前のどちらかに出現している場合、3回目にも出現していれば加点
                $record[$num] += 2;
                $pre3[$num] = 1;
            }
        }

        //4回前
        $num3_place1 = $numbers_array[$idx - 4]->num3_place1;
        $num3_place10 = $numbers_array[$idx - 4]->num3_place10;
        $num3_place100 = $numbers_array[$idx - 4]->num3_place100;
        $num3_array = [$num3_place100, $num3_place10, $num3_place1];
        $num3_array = array_unique($num3_array); //重複排除
        foreach ($num3_array as $num) {
            if ($pre1[$num] == 0 && $pre2[$num] == 1 && $pre3[$num] == 0) {
                //2回前だけに出現している場合、4回目を見る
                $record[$num] += 1;
            }
        }

        //結果配列に追加
        array_push($result, $record);
    }

    $this->set(compact('result'));
}

どうよ!




B美

ふむ
まぁ、良いんじゃない?

C菜

それに対応するビューですけど~

templatesの下に「Verification」ディレクトリを作って、そこに「score01.php」を作りましたよ~
(中身はほとんど「templates/Top/pulling3.php」からのコピーですけど~)



A子

んじゃ、実行してみよう
ブラウザのURL欄に直接以下の一文を入力してっと…

http://192.168.1.205/numapp/verification/score01

・・・

B美

見る限り、正しくスコア計算されてるみたいね

ただ、予想スコアと当選数字の関係が分かりにくいんじゃないかしら
(当たってんだか、当たってないんだか…よく分からん(苦笑))

C菜

スコアが0点ではなく、かつ当選番号数字である場合、背景を別の色で塗りつぶせばどうでしょうか~

A子

お、良いねぇ

あー、でもビューファイルだけの変更でいけるかな?

C菜

できなくはないですけど、多分メソッドのほうで情報を追加すべきじゃないでしょうか~?

B美

私もそう思うわよ

$record = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, $val->lottery_time, $val->num3_str];

の箇所を

$record = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, $val->lottery_time, $val->num3_str, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
$record[$val->num3_place1 + 12]++;
$record[$val->num3_place10 + 12]++;
$record[$val->num3_place100 + 12]++;

に変更しましょう

C菜

$record[12]から$record[21]までを「0」から「9」の当選番号数字に対応させるんですね~

良いと思います~

A子

それじゃ、それにあわせてビュー(score01.php)のほうも変更するよ

CSSの「td4」クラスで分かる通り、背景色は黄色にしてみた





C菜

それでは実行確認してみますね~

・・・

A子

おぉ!めっちゃ分かりやすい…

しっかし、得点が有って(1点以上で)当たってるパターンって、0個のケースから3個のケースまであるけどさ
だいたい、1個か2個しか当たってないね(苦笑)

C菜

しかも当たってる場合の得点って、割と3点が多いですよ~

これはスコア計算アルゴリズムに問題があるのでは~?

B美

うーん、たしかにね

ケーススコア備考
1回前に出現+6○◎
1回前に出現せず
かつ2回前に出現
+5○×◎
1回前に出現し
かつ2回前に出現
(3回前は出現せず)
-3×○○◎
1回前から3回前まで全て出現-4○○○◎
(1回前または2回前の
どちらかに出現していて、かつ)
3回前に出現
-2○×○◎,○○×◎
(2回前だけに出現していて、かつ)
4回前に出現
-3○×○×◎

これでどうかしら?

C菜

前回か前々回に出現していたら6点または5点で、連続して出現する回数が多くなるごとに減点していくってことですか~?

B美

そういうこと

3連続以上の「引っ張り」がそれほど出現しなくなるって傾向を考えると妥当じゃない?

A子

悩むよりも実際にやってみよう

結果を見ながら調整していけば良いじゃん

C菜

ですね~

それでは「score02」メソッドを作りましょう~

A子

基本的には「score01」メソッドと同じで、スコア計算の箇所だけが異なる感じだね

//検証用02
public function score02()
{
    //numbersテーブルを検索(「実施回」の昇順)
    $numbers = $this->Numbers->find()->order(['lottery_time' => 'asc']);
    $numbers_array = $numbers->toArray();
    $result = [];

    //全件数分、ループを回す
    foreach ($numbers as $idx => $val) {
        //最初の4件はとばす
        if ($idx < 4) continue;

        //この回の結果を初期化
        $record = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, $val->lottery_time, $val->num3_str, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        $record[$val->num3_place1 + 12]++;
        $record[$val->num3_place10 + 12]++;
        $record[$val->num3_place100 + 12]++;


        //フラグ配列
        $pre1 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; //1回前に出現しているか(出現した場合「1」)
        $pre2 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; //2回前に出現しているか(出現した場合「1」)
        $pre3 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; //3回前に出現しているか(出現した場合「1」)

        //1回前
        $num3_place1 = $numbers_array[$idx - 1]->num3_place1;
        $num3_place10 = $numbers_array[$idx - 1]->num3_place10;
        $num3_place100 = $numbers_array[$idx - 1]->num3_place100;
        $num3_array = [$num3_place100, $num3_place10, $num3_place1];
        $num3_array = array_unique($num3_array); //重複排除
        foreach ($num3_array as $num) {
            $record[$num] += 6;
            $pre1[$num] = 1;
        }

        //2回前
        $num3_place1 = $numbers_array[$idx - 2]->num3_place1;
        $num3_place10 = $numbers_array[$idx - 2]->num3_place10;
        $num3_place100 = $numbers_array[$idx - 2]->num3_place100;
        $num3_array = [$num3_place100, $num3_place10, $num3_place1];
        $num3_array = array_unique($num3_array); //重複排除
        foreach ($num3_array as $num) {
            if ($pre1[$num] == 0) {
                $record[$num] += 5;
                $pre2[$num] = 1;
            } else {
                $record[$num] -= 3;
            }

        }

        //3回前
        $num3_place1 = $numbers_array[$idx - 3]->num3_place1;
        $num3_place10 = $numbers_array[$idx - 3]->num3_place10;
        $num3_place100 = $numbers_array[$idx - 3]->num3_place100;
        $num3_array = [$num3_place100, $num3_place10, $num3_place1];
        $num3_array = array_unique($num3_array); //重複排除
        foreach ($num3_array as $num) {
            if ($pre1[$num] == 1 && $pre2[$num] == 1) {
                $record[$num] -= 1;
            } elseif ($pre1[$num] == 1 || $pre2[$num] == 1) {
                $record[$num] -= 2;
                $pre3[$num] = 1;
            }
        }

        //4回前
        $num3_place1 = $numbers_array[$idx - 4]->num3_place1;
        $num3_place10 = $numbers_array[$idx - 4]->num3_place10;
        $num3_place100 = $numbers_array[$idx - 4]->num3_place100;
        $num3_array = [$num3_place100, $num3_place10, $num3_place1];
        $num3_array = array_unique($num3_array); //重複排除
        foreach ($num3_array as $num) {
            if ($pre1[$num] == 0 && $pre2[$num] == 1 && $pre3[$num] == 0) {
                //2回前だけに出現している場合、4回目を見る
                $record[$num] -= 3;
            }
        }

        //結果配列に追加
        array_push($result, $record);
    }

    $this->set(compact('result'));
}

ビューファイルの「score02.php」については、「score01.php」の中身と全く同じになるね
(ファイル名を変更しただけ)



C菜

下記のURLを叩いた結果はこうなりました~

http://192.168.1.205/numapp/verification/score02

なんとなく、こっちのほうが良さそうです~

・・・

B美

ふむ
だったら、「num3Prediction」メソッドが返すJSONデータとして、こっちのスコアも追加したらどうかしら?

要するに、二種類のスコアを返すってわけ…
連続加点アルゴリズム(score01)連続減点アルゴリズム(score02)ってことになるかな

C菜

なるほどですねぇ~

下手に予想してクレームになるより、スコアだけを提示して、あとは各人の予想に任せると~(笑)

A子

私としては、ビシッと予想して「当たりました!」ってやりたいんだけどね(苦笑)
まぁ、良いか

「num3Prediction」メソッドの後半部分のみを表示するよ
赤色の部分が追加した箇所ね)






C菜

「apitest03.html」を改良して「apitest04.html」を作ってみました~

過去の実績はこちら」の部分は「verification/score01」や「verification/score02」へのリンクです~

B美

うん、なかなか良いんじゃない?

それじゃ、本番サーバにアップして誰でもアクセスできるようにしましょう

C菜

トップページのAPI説明文も追加しておきましたよ~
⑨のタブです~)

A子

これは結構良いものを作ったんじゃないかな?

当てになるかどうかは分からんけど…(苦笑)