0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

DjangoとDocker自由課題OAAA1001o1o0ga13o__10o0 ライフゲームのGUIを作ろう!

Last updated at Posted at 2022-08-19

サンプルを見る

📚 この連載のゴール
📖 この記事のゴール - 同上

目標

What is This is
この連載の目的 ライフゲームを作る
この記事の目標 GUIを作る

情報

この記事はレッスン編と前回の記事を読み終えた人を対象とする

What is This is
レッスン編 📖 DjangoとDockerでゲーム対局サーバーを作ろう!
前回の記事 📖 DjangoとDocker自由課題OAAA1001o1o0ga12o_1o0 ライフゲームの思考エンジンを作ろう!

Step OAAA1001o1o0ga13o__10o0 画面作成 - gui/cell_id_helper/v1o0.js ファイル

👇 以下の既存ファイルを編集してほしい

    └── 📂 src1
        ├── 📂 apps1
        │   └── 📂 lifegame_vol1o0                  # アプリケーション
        │       ├── 📂 migrations
        │       │   └── 📄 __init__.py
        │       ├── 📂 static
        │       │   └── 📂 lifegame_vol1o0          # アプリケーションと同名
        │       │       ├── 📂 gui
        │       │       │   └── 📂 cell_id_helper
👉      │       │       │       └── 📄 ver1o0.js
        │       │       └── 📂 think
        │       │           ├── 📂 engine
        │       │           │   ├── 📂 parser
        │       │           │   │   └── 📄 ver1o0.js
        │       │           │   └── 📄 ver1o0.js
        │       │           ├── 📂 position
        │       │           │   └── 📄 ver1o0.js
        │       │           ├── 📂 things
        │       │           │   └── 📄 ver1o0.js
        │       │           └── 📂 user_ctrl
        │       │               └── 📄 ver1o0.js
        │       ├── 📂 templates
        │       │   └── 📂 lifegame_vol1o0
        │       │       └── 📂 board
        │       │           ├── 📄 ver0o1o0.html
        │       │           └── 📄 ver0o2o0.html.txt
        │       ├── 📂 views
        │       │   └── 📂 board
        │       │       ├── 📂 ver0o1o0
        │       │       │   └── 📄 __init__.py
        │       │       └── 📂 ver0o2o0
        │       │           └── 📄 __init__.py
        │       ├── 📄 __init__.py
        │       ├── 📄 admin.py
        │       ├── 📄 apps.py
        │       └── 📄 tests.py
        └── 📂 project1
            ├── 📄 settings.py
👉          ├── 📄 urls_lifegame.py
            └── 📄 urls.py
// OAAA1001o1o0ga13o__10o0

class CellIdHelper {
    /**
     * IDを作成します
     * @param {*} boardIndex - 盤番号
     * @param {*} sq - セル番号
     */
    static createId(boardIndex, sq) {
        return `b${boardIndex}_sq${sq}`;
    }

    static destructuringId(id) {
        const re = /b(\d+)_sq(\d+)/;
        const result = id.match(re);

        return [parseInt(result[1]), parseInt(result[2])];
    }
}

Step OAAA1001o1o0ga13o_1o0 画面作成 - gui/dynamic_html_board/v1o0.js ファイル

👇 以下のファイルを新規作成してほしい

    └── 📂 src1
        ├── 📂 apps1
        │   └── 📂 lifegame_vol1o0                  # アプリケーション
        │       ├── 📂 migrations
        │       │   └── 📄 __init__.py
        │       ├── 📂 static
        │       │   └── 📂 lifegame_vol1o0          # アプリケーションと同名
        │       │       ├── 📂 gui
        │       │       │   └── 📂 dynamic_html_board
👉      │       │       │       └── 📄 ver1o0.js
        │       │       └── 📂 think
        │       │           ├── 📂 engine
        │       │           │   ├── 📂 parser
        │       │           │   │   └── 📄 ver1o0.js
        │       │           │   └── 📄 ver1o0.js
        │       │           ├── 📂 position
        │       │           │   └── 📄 ver1o0.js
        │       │           ├── 📂 things
        │       │           │   └── 📄 ver1o0.js
        │       │           └── 📂 user_ctrl
        │       │               └── 📄 ver1o0.js
        │       ├── 📂 templates
        │       │   └── 📂 lifegame_vol1o0
        │       │       └── 📂 board
        │       │           ├── 📄 ver0o1o0.html
        │       │           └── 📄 ver0o2o0.html.txt
        │       ├── 📂 views
        │       │   └── 📂 board
        │       │       ├── 📂 ver0o1o0
        │       │       │   └── 📄 __init__.py
        │       │       └── 📂 ver0o2o0
        │       │           └── 📄 __init__.py
        │       ├── 📄 __init__.py
        │       ├── 📄 admin.py
        │       ├── 📄 apps.py
        │       └── 📄 tests.py
        └── 📂 project1
            ├── 📄 settings.py
            ├── 📄 urls_lifegame.py
            └── 📄 urls.py
// OAAA1001o1o0ga13o_1o0

/**
 * 盤を動的生成
 */
class DynamicHtmlBoard {
    /**
     *
     * @param {number} boardIndex - 盤の番号
     */
    constructor(boardIndex) {
        this._boardIndex = boardIndex;
    }

    /**
     * テーブルを動的生成
     */
    installTable() {
        let lifeGameCanvas = document.getElementById(`life_game_canvas${this._boardIndex}`);
        let sq = 0;

        // 盤について
        // 縦に並べる
        for (let y = 0; y < vue1.engine.position.boards[this._boardIndex].height; y++) {
            // 横に並べる
            for (let x = 0; x < vue1.engine.position.boards[this._boardIndex].width; x++) {
                let span = document.createElement("span");
                let cellId = CellIdHelper.createId(this._boardIndex, sq);
                span.setAttribute("id", cellId);
                sq++;
                span.setAttribute("class", "dead");
                // 正方形に近い文字
                span.textContent = "";

                span.setAttribute("onClick", `vue1.onCellClicked("${cellId}"); return false;`);
                // span.setAttribute("onClick", "alert('test'); return false;");

                lifeGameCanvas.appendChild(span);
            }

            // 改行
            let br = document.createElement("br");
            lifeGameCanvas.appendChild(br);
        }
    }

    /**
     * テーブルを削除
     */
    uninstallTable() {
        let lifeGameCanvas = document.getElementById(`life_game_canvas${this._boardIndex}`);

        // 子要素を全て削除
        var child = lifeGameCanvas.lastElementChild;
        while (child) {
            lifeGameCanvas.removeChild(child);
            child = lifeGameCanvas.lastElementChild;
        }
    }
}

Step OAAA1001o1o0ga13o0 画面作成 - board/ver0o3o0.html.txt ファイル

👇 以下のファイルを新規作成してほしい

    └── 📂 src1
        ├── 📂 apps1
        │   └── 📂 lifegame_vol1o0                  # アプリケーション
        │       ├── 📂 migrations
        │       │   └── 📄 __init__.py
        │       ├── 📂 static
        │       │   └── 📂 lifegame_vol1o0          # アプリケーションと同名
        │       │       ├── 📂 gui
        │       │       │   └── 📂 dynamic_html_board
        │       │       │       └── 📄 ver1o0.js
        │       │       └── 📂 think
        │       │           ├── 📂 engine
        │       │           │   ├── 📂 parser
        │       │           │   │   └── 📄 ver1o0.js
        │       │           │   └── 📄 ver1o0.js
        │       │           ├── 📂 position
        │       │           │   └── 📄 ver1o0.js
        │       │           ├── 📂 things
        │       │           │   └── 📄 ver1o0.js
        │       │           └── 📂 user_ctrl
        │       │               └── 📄 ver1o0.js
        │       ├── 📂 templates
        │       │   └── 📂 lifegame_vol1o0
        │       │       └── 📂 board
        │       │           ├── 📄 ver0o1o0.html
        │       │           ├── 📄 ver0o2o0.html.txt
👉      │       │           └── 📄 ver0o3o0.html.txt
        │       ├── 📂 views
        │       │   └── 📂 board
        │       │       ├── 📂 ver0o1o0
        │       │       │   └── 📄 __init__.py
        │       │       └── 📂 ver0o2o0
        │       │           └── 📄 __init__.py
        │       ├── 📄 __init__.py
        │       ├── 📄 admin.py
        │       ├── 📄 apps.py
        │       └── 📄 tests.py
        └── 📂 project1
            ├── 📄 settings.py
            ├── 📄 urls_lifegame.py
            └── 📄 urls.py
<!-- BOF OAAA1001o1o0ga13o0 -->
{% load static %} {# 👈あとで static "URL" を使うので load static します #}
<!DOCTYPE html>
<html>
    <head>
        <link rel="shortcut icon" type="image/png" href="{% static 'favicon.ico' %}" />
        <link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet" />
        <link href="https://cdn.jsdelivr.net/npm/@mdi/font@6.x/css/materialdesignicons.min.css" rel="stylesheet" />
        <link href="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.min.css" rel="stylesheet" />
        <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui" />
        <title>Life game</title>
        <style>
            /* 等幅 */
            .v-textarea textarea {
                font-family: monospace, monospace;
            }
            /* 生きているセル */
            .live {
                font-family: monospace, monospace;
                color:#FFC107; /* amber */
                background-color:#FFC107; /* amber */
                border:solid 1px black;
            }
            /* 死んでいるセル */
            .dead {
                font-family: monospace, monospace;
                color:#607D8B; /* blue-gray */
                background-color:#607D8B; /* blue-gray */
                border:solid 1px black;
            }
            /* エラーのセル */
            .error {
                font-family: monospace, monospace;
                color:red;
                background-color:red;
                border:solid 1px black;
            }
        </style>
    </head>
    <body>
        <div id="app">
            <v-app>
                <v-main>
                    <v-container fluid>
                        <h1>Life game</h1>
                        <div>
                            Original: 📖 <a href="https://conwaylife.com/">https://conwaylife.com/</a><br/>
                            Tutorial Video: 📺 <a href="https://www.youtube.com/playlist?list=PLZC7Zqdh0Qb3wOpit5dewit3q2-Mqg9vC">THE RECURSIVE COSMOS: Conway's Game of Life ライフゲームの世界</a>
                        </div>
                    </v-container>
                    <!--
                        ディスプレイ部
                        横幅いっぱい広げるために fluid を指定
                    -->
                    <v-container fluid>
                        <!-- 盤0 -->
                        <v-card
                            elevation="2"
                        >
                            <v-card-title>board 0</v-card-title>
                            <v-card-text>
                                <!-- Example: <span id="b0_sq0" class="live">■</span><span id="b0_sq1" class="dead">■</span> -->
                                <div id="life_game_canvas0" style="line-height:1;"></div>
                                <!-- 再生ボタン -->
                                <v-btn block elevation="2" v-on:click="playVu()" v-show="playButton.isShow" :disabled="!playButton.enabled"> ▶ Play </v-btn>
                                <!-- 一時停止ボタン -->
                                <v-btn block elevation="2" v-on:click="pauseVu()" v-show="pauseButton.isShow" :disabled="!pauseButton.enabled"> ▮▮ Pause </v-btn>
                                <div>Pause, then click a cell.</div>
                            </v-card-text>
                        </v-card>

                        <!-- 盤1 -->
                        <v-card
                            elevation="2"
                        >
                            <v-card-title>board 1</v-card-title>
                            <v-card-text>
                                <div id="life_game_canvas1" style="line-height:1;"></div>
                            </v-card-text>
                        </v-card>

                        <!-- 盤2 -->
                        <v-card
                            elevation="2"
                        >
                            <v-card-title>board 2</v-card-title>
                            <v-card-text>
                                <div id="life_game_canvas2" style="line-height:1;"></div>
                            </v-card-text>
                        </v-card>
                    </v-container>
                    <!-- テキストエディター部 -->
                    <v-container fluid>
                        <v-form method="POST">
                            {% csrf_token %}

                            <!-- `po_` は POST送信するパラメーター名の目印 -->
                            <!-- 入力 -->
                            <v-textarea name="po_input" required rows="6" v-model="inputText.value" label="Input" :disabled="!inputText.enabled" background-color="#263238" dark></v-textarea>

                            <!-- 入力ボタン -->
                            <v-btn block elevation="2" v-on:click="enterVu()" :disabled="!enterButton.enabled"> Enter </v-btn>

                            <!-- 出力 -->
                            <v-textarea name="po_output" rows="1" disabled v-model="outputText.value" label="Output"></v-textarea>
                        </v-form>
                    </v-container>
                </v-main>
            </v-app>
        </div>

        <script src="{% static 'lifegame_vol1o0/gui/cell_id_helper/v1o0.js' %}"></script>
        <script src="{% static 'lifegame_vol1o0/gui/dynamic_html_board/v1o0.js' %}"></script>
        <script src="{% static 'lifegame_vol1o0/think/engine/parser/v1o0.js' %}"></script>
        <script src="{% static 'lifegame_vol1o0/think/engine/v1o0.js' %}"></script>
        <script src="{% static 'lifegame_vol1o0/think/position/v1o0.js' %}"></script>
        <script src="{% static 'lifegame_vol1o0/think/things/v1o0.js' %}"></script>
        <script src="{% static 'lifegame_vol1o0/think/things/board/v1o0.js' %}"></script>
        <script src="{% static 'lifegame_vol1o0/think/user_ctrl/v1o0.js' %}"></script>
        <!--            ===============================================
                        1
        1. src1/apps1/lifegame_vol1o0/static/lifegame_vol1o0/think/user_ctrl/v1o0.js
                                      ==============================================
        -->

        <script src="https://cdn.jsdelivr.net/npm/vue@2.x/dist/vue.js"></script>
        <script src="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.js"></script>
        <script>
            /**
             * 盤の数
             */
            let BOARDS_COUNT = 3;

            // 盤を動的生成
            let dynamicHtmlBoards = Array(BOARDS_COUNT);

            // 全要素の初期化(.fill()は参照渡しなので使いません)
            for (let i = 0; i < BOARDS_COUNT; i++) {
                dynamicHtmlBoards[i] = new DynamicHtmlBoard(i);
            }

            const vue1 = new Vue({
                el: "#app",
                vuetify: new Vuetify(),
                data: {
                    // 入力
                    inputText: {
                        enabled: true,
                        value: `# 盤[0] ムービー
# サイズ
board 0 width 64
board 0 height 32
# 点描
board 0 """
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
"""

# 盤[1] 停止
# サイズ
board 1 width 64
board 1 height 6
# 点描
#    5     11   16   21    27 30    36    42    48
board 1 """
................................................................
.xx...xx...xx....xx...xx...x...xx...xx.....x.....x..............
.xx..x..x..x.x..x.x..x..x..x..x.....x......x.x....x.............
......xx....x...xx...x..x..x.....x.....x..x.x...xxx.............
......................xx.......xx.....xx....x...................
................................................................
"""

# 盤[2] 停止
# サイズ
board 2 width 64
board 2 height 7
# 点描
board 2 """
................................................................
.xxx...xxx...xxx..xxx..xxx...x...x..xxx.........................
.x..x..x....x.....x....x..x..x...x..x...........................
.xxx...xxx...xx...xxx..xxx...x...x..xxx.........................
.x..x..x.......x..x....x..x...x.x...x...........................
.x..x..xxx..xxx...xxx..x..x....x....xxx.........................
................................................................
"""

# コピー
# グライダー
board 0 xy 1 1 copy_from board 1 rect 48 1 3 3
# ブロック
board 0 xy 10 3 copy_from board 1 rect 1 1 2 2
# 蜂の巣
board 0 xy 17 5 copy_from board 1 rect 5 1 4 3
# ボート
board 0 xy 24 3 copy_from board 1 rect 11 1 3 3
# 船
board 0 xy 31 6 copy_from board 1 rect 16 1 3 3
# 池
board 0 xy 38 2 copy_from board 1 rect 21 1 4 4
# ブリンカー
board 0 xy 45 5 copy_from board 1 rect 27 1 1 3
# ヒキガエル
board 0 xy 52 8 copy_from board 1 rect 30 1 4 4
# ビーコン
board 0 xy 57 3 copy_from board 1 rect 36 1 4 4
# 時計
board 0 xy 46 15 copy_from board 1 rect 42 1 4 4
`,
                    },
                    // 出力
                    outputText: {
                        value: 'Please push "Enter" button.',
                    },
                    // 思考エンジン
                    engine: new Engine(
                        // ユーザーコントロール
                        new UserCtrl(),
                        // 盤の数
                        BOARDS_COUNT
                    ),
                    // 入力ボタン
                    enterButton: {
                        enabled: true,
                    },
                    // 再生ボタン
                    playButton: {
                        enabled: false,
                        isShow: true,
                    },
                    // 一時停止ボタン
                    pauseButton: {
                        enabled: true,
                        isShow: false,
                    },
                    // 入力されたテキスト
                    enteredText : null,
                    // タイマー
                    timer: {
                        // 停止するのに使う
                        id: null,
                        // 再生間隔(ミリ秒)
                        intervalMilliseconds: 100,
                    },
                },
                mounted() {
                    window.onload = ()=>{
                        console.log('ページが読み込まれました!');

                        // 初期状態を設定
                        let boardIndex = 0;
                        vue1.engine.position.boards[boardIndex].width = 24;
                        vue1.engine.position.boards[boardIndex].height = 24;
                        vue1.engine.position.boards[boardIndex].parse(`........................
........................
........................
........................
........................
........................
........................
........................
........................
........................
........................
.........x....x.........
.......xx.xxxx.xx.......
.........x....x.........
........................
........................
........................
........................
........................
........................
........................
........................
........................
........................`.replace(/\r?\n/g, ''));

                        // GUIに反映
                        dynamicHtmlBoards[boardIndex].uninstallTable();
                        dynamicHtmlBoards[boardIndex].installTable();

                        // 初期状態を描画
                        this.repaintVu();

                        // 自動再生する
                        this.playVu();
                    }
                },
                methods: {
                    // 関数名の末尾の Vu は vue1 のメソッドであることを表す目印
                    /**
                     * po_input 欄のコマンドを入力します
                     */
                    enterVu() {
                        console.log("入力ボタンをクリックした");

                        // this.inputText.enabled = false;
                        // this.enterButton.enabled = false;

                        this.enteredText = vue1.inputText.value;
                        vue1.inputText.value = "";

                        // 入力テキストを処理
                        // * タイマーの処理が走っているときに、この処理がどう割り込むのか分からない
                        this.processingTextVu();
                    },
                    /**
                     * 画面更新
                     */
                    updateVu() {
                        if (this.enteredText !== null) {
                            // 入力テキストを処理
                            this.processingTextVu();
                        } else {
                            // 盤[0]を動かす。それ以外の盤は動かさない
                            let boardIndex = 0;
                            vue1.engine.userCtrl.doMove(vue1.engine.position, boardIndex);
                        }

                        this.repaintVu();
                    },
                    /**
                     * 入力テキストを処理
                     */
                    processingTextVu(){
                        // 盤のサイズを一時記憶
                        let widthOfBoards = new Array(BOARDS_COUNT);
                        widthOfBoards.fill(0);
                        let heightOfBoards = new Array(BOARDS_COUNT);
                        heightOfBoards.fill(0);
                        for(let boardIndex=0; boardIndex<BOARDS_COUNT; boardIndex++){
                            widthOfBoards[boardIndex] = vue1.engine.position.boards[boardIndex].width;
                            heightOfBoards[boardIndex] = vue1.engine.position.boards[boardIndex].height;
                        }

                        // コマンドを実行
                        let log = vue1.engine.execute(this.enteredText);
                        this.enteredText = null;

                        this.outputText.value = log;

                        // 盤のサイズが変わっていれば作り直し
                        for(let boardIndex=0; boardIndex<BOARDS_COUNT; boardIndex++){
                            if (widthOfBoards[boardIndex] !== vue1.engine.position.boards[boardIndex].width ||
                                heightOfBoards[boardIndex] !== vue1.engine.position.boards[boardIndex].height) {
                                dynamicHtmlBoards[boardIndex].uninstallTable();
                                dynamicHtmlBoards[boardIndex].installTable();
                            }
                        }
                    },
                    /**
                     * 再描画
                     */
                    repaintVu(){
                        // 盤表示
                        for(let boardIndex=0; boardIndex<BOARDS_COUNT; boardIndex++){
                            vue1.engine.position.boards[boardIndex].eachSq((sq, cellValue) => {
                                const cellId = CellIdHelper.createId(boardIndex, sq);
                                let cell = document.getElementById(cellId);
                                switch(cellValue) {
                                    case PC_X:
                                        cell.setAttribute("class", "live");
                                        break;

                                    case PC_EMPTY:
                                        cell.setAttribute("class", "dead");
                                        break;

                                    default:
                                        cell.setAttribute("class", "error");
                                        break;
                                }
                            })
                        }
                    },
                    /**
                     * 再生ボタンをクリックした
                     */
                    playVu(){
                        // console.log("再生ボタンをクリックした");

                        this.playButton.enabled = false;
                        this.playButton.isShow = false;

                        // タイマー開始
                        this.timer.id = setInterval(() => {
                            this.updateVu();
                        }, this.timer.intervalMilliseconds);

                        this.pauseButton.enabled = true;
                        this.pauseButton.isShow = true;
                    },
                    /**
                     * 停止ボタンをクリックした
                     */
                    pauseVu(){
                        // console.log("停止ボタンをクリックした");

                        this.pauseButton.enabled = false;
                        this.pauseButton.isShow = false;

                        // タイマー停止
                        clearInterval(this.timer.id);

                        this.playButton.enabled = true;
                        this.playButton.isShow = true;
                    },
                    /**
                     * セルクリック時
                     */
                    onCellClicked(cellId){
                        const [boardIndex, sq] = CellIdHelper.destructuringId(cellId);

                        // Reverse piece
                        const revPc = flip_pc(vue1.engine.position.boards[boardIndex].getPieceBySq(sq));
                        // alert(`cell clicked id:${cellId} board:${boardIndex} sq:${sq} revPc:${revPc}`);

                        vue1.engine.position.boards[boardIndex].setPiece(sq, revPc);

                        // 再生中に1セル塗っても、すぐ消える。
                        // 一時停止中に塗る。
                        // 一時停止中は描画されないので、明示的に再描画する
                        this.repaintVu();
                    },
                },
            });
        </script>
    </body>
</html>
<!-- EOF OAAA1001o1o0ga13o0 -->

Step OAAA1001o1o0ga14o0 ビュー作成 - board/ver0o3o0 フォルダー

👇 以下のファイルを新規作成してほしい

    └── 📂 src1
        ├── 📂 apps1
        │   └── 📂 lifegame_vol1o0                  # アプリケーション
        │       ├── 📂 migrations
        │       │   └── 📄 __init__.py
        │       ├── 📂 static
        │       │   └── 📂 lifegame_vol1o0          # アプリケーションと同名
        │       │       ├── 📂 gui
        │       │       │   └── 📂 dynamic_html_board
        │       │       │       └── 📄 ver1o0.js
        │       │       └── 📂 think
        │       │           ├── 📂 engine
        │       │           │   ├── 📂 parser
        │       │           │   │   └── 📄 ver1o0.js
        │       │           │   └── 📄 ver1o0.js
        │       │           ├── 📂 position
        │       │           │   └── 📄 ver1o0.js
        │       │           ├── 📂 things
        │       │           │   └── 📄 ver1o0.js
        │       │           └── 📂 user_ctrl
        │       │               └── 📄 ver1o0.js
        │       ├── 📂 templates
        │       │   └── 📂 lifegame_vol1o0
        │       │       └── 📂 board
        │       │           ├── 📄 ver0o1o0.html
        │       │           ├── 📄 ver0o2o0.html.txt
        │       │           └── 📄 ver0o3o0.html.txt
        │       ├── 📂 views
        │       │   └── 📂 board
        │       │       ├── 📂 ver0o1o0
        │       │       │   └── 📄 __init__.py
        │       │       ├── 📂 ver0o2o0
        │       │       │   └── 📄 __init__.py
        │       │       └── 📂 ver0o3o0
👉      │       │           └── 📄 __init__.py
        │       ├── 📄 __init__.py
        │       ├── 📄 admin.py
        │       ├── 📄 apps.py
        │       └── 📄 tests.py
        └── 📂 project1
            ├── 📄 settings.py
            ├── 📄 urls_lifegame.py
            └── 📄 urls.py
# BOF OAAA1001o1o0ga14o0

from django.shortcuts import render


class BoardView():
    """OAAA1001o1o0ga14o0 盤"""

    @staticmethod
    def render(request):
        """描画"""

        template_path = 'lifegame_vol1o0/board/ver0o3o0.html.txt'
        #                ---------------------------------------
        #                1
        # 1. `src1/apps1/lifegame_vol1o0/templates/lifegame_vol1o0/board/ver0o3o0.html.txt` を取得
        #                                          ---------------------------------------

        context = {}
        return render(request, template_path, context)

# EOF OAAA1001o1o0ga14o0

Step OAAA1001o1o0ga15o0

Merged to OAAA1001o1o0ga15o1o0

Step OAAA1001o1o0ga15o1o0 ルート編集 - urls.csv ファイル

👇 以下の既存ファイルの末尾に追記してほしい

    ├── 📂 src1
    │   ├── 📂 apps1
    │   │   └── 📂 lifegame_vol1o0                  # アプリケーション
    │   │       ├── 📂 migrations
    │   │       │   └── 📄 __init__.py
    │   │       ├── 📂 static
    │   │       │   └── 📂 lifegame_vol1o0          # アプリケーションと同名
    │   │       │       ├── 📂 gui
    │   │       │       │   └── 📂 dynamic_html_board
    │   │       │       │       └── 📄 ver1o0.js
    │   │       │       └── 📂 think
    │   │       │           ├── 📂 engine
    │   │       │           │   ├── 📂 parser
    │   │       │           │   │   └── 📄 ver1o0.js
    │   │       │           │   └── 📄 ver1o0.js
    │   │       │           ├── 📂 position
    │   │       │           │   └── 📄 ver1o0.js
    │   │       │           ├── 📂 things
    │   │       │           │   └── 📄 ver1o0.js
    │   │       │           └── 📂 user_ctrl
    │   │       │               └── 📄 ver1o0.js
    │   │       ├── 📂 templates
    │   │       │   └── 📂 lifegame_vol1o0
    │   │       │       └── 📂 board
    │   │       │           ├── 📄 ver0o1o0.html
    │   │       │           ├── 📄 ver0o2o0.html.txt
    │   │       │           └── 📄 ver0o3o0.html.txt
    │   │       ├── 📂 views
    │   │       │   └── 📂 board
    │   │       │       ├── 📂 ver0o1o0
    │   │       │       │   └── 📄 __init__.py
    │   │       │       ├── 📂 ver0o2o0
    │   │       │       │   └── 📄 __init__.py
    │   │       │       └── 📂 ver0o3o0
    │   │       │           └── 📄 __init__.py
    │   │       ├── 📄 __init__.py
    │   │       ├── 📄 admin.py
    │   │       ├── 📄 apps.py
    │   │       └── 📄 tests.py
    │   └── 📂 project1
    │       ├── 📄 settings.py
    │       └── 📄 urls.py
    └── 📂 src1_meta
        └── 📂 data
👉          └── 📄 urls.csv
...略... file,path,name,comment,module,class,alias,method
...略...


../src1/project1/urls_lifegame_vol1o0_autogen.py,lifegame/vol1.0/board/ver0.3,,"OAAA1001o1o0ga15o1o0 ライフゲーム1.0巻 盤0.3版",apps1.lifegame_vol1o0.views.board.ver0o3o0,BoardView,Lifegame1o0BoardView0o3o0,render

Step OAAA1001o1o0ga10o2o0 ルート編集 - コマンド打鍵

👇 以下のコマンドを打鍵してほしい

cd ../src1_meta
python -m scripts.auto_generators.urls
cd ../src1
docker-compose restart
  • ディレクトリーは、がんばって移動してほしい
  • スクリプトについて See also: O3o2o_1o0g2o0
  • 設定ファイルを変更したら、サーバーの再起動が必要

Step OAAA1001o1o0ga16o0 Webページにアクセスする

📖 http://localhost:8000/lifegame/vol1.0/board/ver0.3

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?