第6回函館大会の競技部門出身として、全国のプログラミング好き高専生へ、オープンソースのプレゼント。 中止になった競技部門のルールを読んでみると、今年のテーマは、1ターン最短3秒で最大14ユニット動かす、1on1の陣取りゲーム。戦況を見つつ人手で補正することや、3チーム以上の混戦も楽しそうなので、実装してみました。
「Kakomimasu - 競技システムコアモジュール for Deno/Node.js src on GitHub」
500行程度のJavaScriptで書いたクラスライブラリ kakomimasu.mjsと、15行の乱数ライブラリ util.mjsのみのシンプル設計。
IMIツール同様のESモジュールなので、DenoやNode.js、ブラウザ上に組み込むことも簡単です。
ざっくり書いたテストコードは通ってますが、まだまだ検証は足りないので、協力してくれる高専生、大募集。 我こそはという人、チャレンジしてみたい人、GitHub、Slack: Code for KOSEN、Twitter、Facbeookで連絡ください。 フォーク、他言語での移植、プルリク、Issue、何でも歓迎、お気軽にどうぞ!
目玉の塗りつぶしアルゴリズム、こんな感じで実装してみました。(full src on GitHub)
fillBase () { const w = this.board.w; const h = this.board.h; const field = this.field; for (let pid = 0; pid < this.board.nplayer; pid++) { const flg = new Array(w * h); for (let i = 1; i < w - 1; i++) { for (let j = 1; j < h - 1; j++) { if (flg[i + j * w] || this.field[i + j * w][0] === Field.WALL) { continue; } const fill = new Array(w * h); const chk = function (x, y) { if (x < 0 || x >= w || y < 0 || y >= h) { return false; } const n = x + y * w; if (fill[n]) { return true; } fill[n] = true; const f = field[n]; if (f[0] === Field.WALL) { if (f[1] === pid) { return true } } else { fill[n] = true; } if (!chk(x - 1, y )) { return false; } if (!chk(x + 1, y )) { return false; } if (!chk(x - 1, y - 1)) { return false; } if (!chk(x , y - 1)) { return false; } if (!chk(x + 1, y - 1)) { return false; } if (!chk(x - 1, y + 1)) { return false; } if (!chk(x , y + 1)) { return false; } if (!chk(x - 1, y + 1)) { return false; } return true; } if (chk(i, j)) { fill.forEach((f, idx) => { if (this.field[idx][0] === Field.BASE) { this.field[idx][1] = pid; flg[idx] = true; } }); } } } } }
効率よいアルゴリズムの追求もまたおもしろそう。
「高専プロコン」
楽しいは創れる!オンライン部門、やりましょう!
links
- 第31回高専プロコン 競技部門「雪降る大地 ミんなで クるっと 囲みマス」 9P〜
- taisukef/Kakomimasu: #procon31 競技部門 コアモジュール for Deno/Node.js