第31回の高専プロコン競技部門を勝手に創るオンライン会。APIサーバー、Javaのクライアント、C言語のクライアント、JavaScriptのクライアントとそれぞれ役割分担して開発中。(src on GitHub競技ルールの後半)


対戦している様子!・・・ただ、コアにバグがあるようで、途中青忍者が消失する現象あり。

JavaScriptのクライアント、クラスを作って整理。デタラメに置いてデタラメに動くAIプログラムはこんな感じに書けます。(src on GitHub)

import { KakomimasuClient, Action, DIR } from "./KakomimasuClient.js" import util from "../util.js"; const kc = new KakomimasuClient("a3", "デタラメ", "サンプル", "a3-pw" ); let info = await kc.waitMatching(); const pno = kc.getPlayerNumber(); const nagents = kc.getAgentCount(); const points = kc.getPoints(); // ポイントの高い順ソート const pntall = []; for (let i = 0; i < points.length; i++) { for (let j = 0; j < points[i].length; j++) { pntall.push({ x: j, y: i, point: points[i][j] }); } } const pntsorted = pntall.sort((a, b) => b.point - a.point); info = await kc.waitStart(); // スタート時間待ち while (info) { // ランダムにずらしつつ置けるだけおく // 置いたものはランダムに8方向動かす const actions = []; const offset = util.rnd(nagents); for (let i = 0; i < nagents; i++) { const agent = info.players[pno].agents[i]; console.log(pno, agent); if (agent.x === -1) { // 置く前? const p = pntsorted[i + offset]; actions.push(new Action(i, "PUT", p.x, p.y)); } else { const [dx, dy] = DIR[util.rnd(8)]; actions.push(new Action(i, "MOVE", agent.x + dx, agent.y + dy)); } } kc.setActions(actions); info = await kc.waitNextTurn(); }

一歩進めて、周りの点数の高いところから狙っていき、壁破壊も行うAIにしたものがこちら。(src on GitHub)

const dirall = []; for (const [dx, dy] of DIR) { const x = agent.x + dx; const y = agent.y + dy; if (x >= 0 && x < w && y >= 0 && y < h && checkFree(x, y)) { const f = field[y][x]; if (f.type === 0 && f.pid !== -1 && f.pid !== pno) { // 敵土地、おいしい! dirall.push({ x, y, type: f.type, pid: f.pid, point: f.point + 10 }); } else if (f.type === 0 && f.pid === -1) { // 空き土地優先 dirall.push({ x, y, type: f.type, pid: f.pid, point: f.point + 5 }); } else if (f.type === 1 && f.pid !== pno) { // 敵壁 dirall.push({ x, y, type: f.type, pid: f.pid, point: f.point }); } } } if (dirall.length > 0) { sortByPoint(dirall); const p = dirall[0]; if (p.type === 0 || p.pid === -1) { actions.push(new Action(i, "MOVE", p.x, p.y)); poschk.push({ x: p.x, y: p.y }); poschk.push({ x: agent.x, y: agent.y }); // 動けなかった時用 } else { actions.push(new Action(i, "REMOVE", p.x, p.y)); poschk.push({ x: agent.x, y: agent.y }); } } else { // 周りが全部埋まっていたらランダムに動く


圧勝!・・・おや、フィールドに忍者がいる!?コアのバグ修正が必要です。
何か気づいたことがあれば、Issuesまで、お寄せください。

C言語版クライアントのサンプル、Windowsで動かなかったのを修正。Windowsでは標準のスタック領域が1Mbyteしかないようで、メモリ確保できずに落ちてしまうことが判明。ヒープ領域を使う malloc/free を使うよう、変更(src on GitHub)。 ただ、JSONのパースなど、もうひと手間必要なので、手っ取り早くAIプログラミングにチャレンジしたい人は、JavaScript版かJava版がオススメです。

次回、8/20(木)20:00〜に、練習試合します!
Code for KOSENSlackまでどうぞ!

福井高専未来戦略アドバイザー、「創造」を軸にものづくり人材を育成する高専。日本で唯一「アントレプレナーサポートセンター」を持つ、福井高専の新しい取り組み、創業を目指すビジネスプランコンテスト。 その一環、今日は福井高専にてアイデアソン!1年生から4年生まで、集まってくれた、やる気あふれる高専生!

課題、アイデア、データを使ってアプリづくりを繰り返そう。良いアプリができて、横展開できれば、それがイノベーション。


チーム毎に発表!聞く方は、投資家のつもりになって聞こう。

身近な課題からのアプリデザインまでやった後、発想を切り替えるヒントとして、世界中の課題が詰まったSDGsを紹介。 15分、新たな視点で、課題、アイデアを出してみて、新たな発見を感じてもらう体験。


今日をKPT(ケプト)で、ふりかえり。
最強の振り返りメソッド「KPT法」で、失敗を反省するどころか、長所も希望も見つかった話 - STUDY HACKER|これからの学びを考える、勉強法のハッキングメディア

視野が広がったところで、福井高専がある鯖江市。今年は鯖江の未来を占う重要な市長選挙。


鯖江市長選2020 / Twitter
鯖江市長選2020、候補者Twitter、リストを作ってみました。それぞれ候補者のつぶやき、見てみましょう!


鯖江市長選挙 立候補予定者 公開討論会
主催は、OCサミット実行委員会と有志の会。鯖江市の女性の投票率が低いことを問題視した女性による企画とのこと!

早速データで見てみましょう!

Code for Sabae で相談し、オープンデータ化してもらった「投票所ごとの投票者数、投票率オープンデータ」を、高校の情報I教材の延長として実装、公開。

鯖江市 女性投票率」ほか


鯖江市 女性投票率 - 男性投票率


鯖江市 合計有権者数

 みんなでつくろう、世界一持続可能なまち!

Code for Kosen、Kakomimasu project、オンラインハックデー。
コア、APIサーバーが揃ったので、サーバーを仮に立ててAIプログラムをテスト実行!


同時に手が進行する陣取りゲーム「囲みマス
2018年のボードを元に、デタラメな手を打つAI同士を対戦させた結果。

AIづくりは、何を見て、どう打つかの手順(=アルゴリズム)をプログラムにすること。

デタラメAIの戦略
1. 点数の高いマスに優先して配置する
2. 置いたエージェントは、ランダムに動く

ただ、このAI同士を対戦させると、点数の高いマスにお互い同時に置こうとしてしまって、何もエージェントを置けず引き分けになってしまうので、1の置く場所決定をランダムでゆらぎを入れました。

JavaScriptのプログラムにしたものがこちら(src on GitHub)

// デタラメに置き、デタラメに動くアルゴリズム // 8方向、上から時計回り const DIR = [[0, -1], [1, -1], [1, 0], [1, 1], [0, 1], [-1, 1], [-1, 0], [-1, -1]]; // ポイントの高い順ソート const pntall = points.map((p, idx) => { return { x: idx % w, y: Math.floor(idx / w), p: p }}); const pntsorted = pntall.sort((a, b) => b.p - a.p); // スタート時間待ち await sleep(diffTime(gameInfo.startedAtUnixTime)); for (let i = 1; i <= totalTurn; i++) { console.log("turn", i); // ランダムにずらしつつ置けるだけおく // 置いたものはランダムに8方向動かす const actions = []; const offset = util.rnd(nplayers); for (let i = 0; i < nplayers; i++) { const agent = gameInfo.players[pno].agents[i]; console.log(pno, agent); if (agent.x === -1) { const p = pntsorted[i + offset]; actions.push(new Action(i, "PUT", p.x, p.y)); } else { const [dx, dy] = DIR[util.rnd(8)]; actions.push(new Action(i, "MOVE", agent.x + dx, agent.y + dy)); } } setAction(roomid, playerid, actions); const bknext = gameInfo.nextTurnUnixTime; await sleep(diffTime(gameInfo.nextTurnUnixTime)); for (;;) { gameInfo = await getGameInfo(roomid); if (gameInfo.nextTurnUnixTime !== bknext) break; await sleep(100); } }

動く先を画面外を排除したり、高い点数を狙ったり、相手の手を見て狙い所を変えたり、戦略を練って、プログラムにしていきましょう!

手元のサーバーで試す際は、host を client_util.js の host を localhost:8880 に変更して実行してください。 apiserver、client_ai1.js x2、合計3つのコンソールで動かします。

次回も来週金曜日20時、オンラインで開催!
ご興味ある高専生は「Code for KOSEN」へどうぞ。

総務省主催の「WiCON / 高専ワイヤレスIoTコンテスト2020」の二次審査会がありました。 ハードもソフトも強い高専生ならでは。そんな高専生におなじみ電子パーツ専門店「秋月電子通商」のwebサイト。 コピペ時に、伝統の全角英数が気になります。


思いつく解決方法は3つ
1. プロキシーで変換する(HTTPなので変換可能)→ 全通信が通って重い
2. ブラウザ上で変換する(Chrome拡張)→ 特定サイトのみ適応できて軽い
3. コピーする際に変換する(Chrome拡張で可能?)→ 調査に時間かかるかも

ということで、スピード優先、2でいきます。FAXっぽいwebに続く、Chrome拡張第二弾。(src on GitHub)

Chrome拡張の設定ファイル manifest.json を用意します。

{ "name": "zen2han", "version": "1.0.0", "manifest_version": 2, "description": "zenkaku alphabets and numbers to hankaku", "content_scripts": [{ "matches": ["*://akizukidenshi.com/*"], "js": ["content.js"] }] }

matchesで適応するサイトを指定、jsで今から作成するプログラムのファイル名 content.js を指定しておきます。

const toHalf = s => { if (s === null || s === undefined) return s const ZEN = "0123456789()/−!&: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" const HAN = "0123456789()/-!&: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" let s2 = "" for (const c of s) { const n = ZEN.indexOf(c) if (n >= 0) { s2 += HAN.charAt(n) } else { s2 += c } } return s2 } const toHalfText = parent => { if (parent.children.length === 0) { parent.textContent = toHalf(parent.textContent); } else { for (const c of parent.children) { toHalfText(c); } } } toHalfText(document.body); document.title = toHalf(document.title);

HTMLのドキュメント構造(DOM)を再帰的に辿り、子を持たない textContent の全角英数を半角英数に変更するJavaScriptのプログラムです。 ついでに、タイトルも変換しておきましょう。

あとは chrome://extensions/ を開き、「Load unpacked」で読み込むだけ!
適応したい他のサイトがあれば、matchesをいじり、リロードしましょう。快適電子パーツブラウジングが完成です!

経産省のオープンソース、IMIコンポーネントツール全角半角統一コンポーネントなど外部ライブラリを使った変換もありですが、強力すぎるChrome拡張、セキュリティ確保のために極力依存なしでの実装がオススメです。 (Hana道場では中学生がサイバーセキュリティ入門スタート!


今年から審査委員として参加中。日本中にある高専、その地域性も審査項目の一つ。それぞれ特色あるバラエティー豊かな作品達。 採択されたテーマの仕上がりが楽しみです。残念ながら採択されなかったものも、チャンスはたくさんあります。ぜひ独自に実現する道、探りましょう。応援します!


高専ワイヤレスIoTコンテスト(WiCON) (@Kosen_WiCON) / Twitter
高専ワイヤレスIoTコンテスト、通称WiCONのタイトルロゴも決定!Twitterの運用も始まりました。 きっと来年度も開催されるので、身近な課題5GやIoTなど、ワイヤレスで解決できそうなネタ、普段から意識してみるといいですよ。

イノベーションのタネは様々な日常にあり。
視界広げていきましょう!

Code for KOSEN チーム開発で進む高専プロコン競技部門予定だった「囲みマス」のシステムづくり、APIサーバーの第一弾が動き出し、AIプログラムづくりに取り組む準備ができました!

Deno TypeScript APIサーバー、JavaScriptで作ったKakomimasuコアを使っています。

GitHubのKakomimasuリポジトリをcloneまたはダウンロードして、APIサーバーの使い方記載の手順で動かすと、PC上でAPIサーバーが起動し、テストのAIプレイヤー2人の試合をブラウザで見ることができます。

JavaScriptで、AIを作ってみましょう。(src on GitHub

import { Action, sleep, match, getGameInfo, setAction, diffTime } from "./client_util.js"; const [ playerid, roomid] = await match(`高専太郎`, "ポンコツ"); let gameInfo; do { gameInfo = await getGameInfo(roomid); await sleep(100); } while (gameInfo.startedAtUnixTime === null); console.log(gameInfo); console.log( "ゲーム開始時間:", new Date(gameInfo.startedAtUnixTime / 1000).toLocaleString("ja-JP"), ); await sleep((diffTime(gameInfo.startedAtUnixTime) + 1) * 1000); // ターン1 setAction( roomid, playerid, [new Action(0, "PUT", 1, 1), new Action(1, "PUT", 3, 3)], ); await sleep((diffTime(gameInfo.nextTurnUnixTime) + 3 + 1) * 1000);

APIサーバーへのアクセス用の関数群(client_util.js)をimportして、プレイヤー登録し、ゲーム開始を待って、ターン毎にアクションを送ります。

getGameInfo で、フィールドの状態、自分や相手の状態、点数を把握できます。 まずはシンプルに高得点から順に押さえるだけのAIから作ってみることから始めてみましょう!

TypeScript版もあるので、お好きな言語でどうぞ!(client_test1.ts on GitHub

週1でオンラインで集まってます。
次回は、7/16(木)20:00-22:00内、ご興味ある方、ぜひどうぞ!
Code for KOSEN Slack

links
- 中止になった高専プロコン競技部門はオンラインで遊ぼう! 競技システムのDeno/Node.js用コアモジュールのオープンソース公開

プログラミングの必修化、2020年から小学校、2021年から中学校、2022年から高校でスタート。 高校では「情報I」という必修と、選択の「情報II」にてプログラミングが登場します。 教員研修用教材が公開されたので貢献できるところを探してみました。


高等学校情報科「情報Ⅰ」「情報II」教員研修用教材
一番気になるのは「高等学校情報科「情報Ⅰ」教員研修用教材(本編)」の「第3章コンピュータとプログラミング」。 Python版を基本に、他のプログラミング言語版として、 JavaScript版VBA版ドリトル版 Swift版の5つのプログラミング言語を教員が選ぶスタイルになっている。

まず一番気になったのは、他言語版として用意されたものに、API・グラフ描画・ハードウェア制御の実習が省略されていること。

さらにこの数式モデルの計算結果をわかりやすく評価するため,グラフで表示することが可能なプログラミング 言語もある。
※ JavaScript では実行が難しいため,本書においては割愛する。
高等学校情報科「情報I」教員研修用教材 JavaScript版 (第3章のみ) P43
世界中にある多種多様なライブラリがあり、ブラウザのみで動作するJavaScript、グラフ表示も簡単です。オープンソースな実装と共に実習例を紹介する。

学習16で登場する福利計算。まずは下記は10年分の預金残高を表示するプログラム。model1.html というファイル名で、テキスト形式(utf-8)で保存し、ブラウザで開くだけで動く。

<script type="module"> let yokin = 100000; const riritsu = 0.05; for (let i = 0; i < 10; i++) { const risoku = yokin * riritsu; yokin += risoku; alert(`${i + 1} 年目 : ${yokin}`); } </script>


document.write や、type="module" ではない古いJavaScript(クラシックスクリプト)は2022年に教える内容としてはふさわしくないので要修正(*)。


学習16 預金複利計算のグラフ」(src on GitHub)

<body style="margin:0"> <canvas id="chart"></canvas> <script type="module"> import Chart from "https://code4sabae.github.io/kafumon/lib/Chart.mjs"; const riritsu = 0.05; const yokin = [100000]; const labels = []; for (let i = 0; i < 10; i++) { const risoku = Math.floor(yokin[i] * riritsu); yokin.push(yokin[i] + risoku); labels[i] = i + 1; } const config = { type: "line", data: { labels: labels, datasets: [{ data: yokin, borderColor: 'rgb(255, 99, 132)', fill: false, lineTension: 0 }] }, options: { title: { display: true, text: "FUKURI KEISAN" }, scales: { xAxes: [{ scaleLabel: { display: true, labelString: "Year" } }], yAxes: [{ scaleLabel: { display: true, labelString: "Yokin[YEN]" }, ticks: { beginAtZero: true } }], }, legend: { display: false } } }; new Chart.Chart(chart, config); </script>

グラフ化するライブラリとして、東京都の新型コロナウイルス対策サイトでも使われた「Chart.js」のモジュールスクリプト版「Chart.mjs」を使用。 こちらも graph1.html として保存して、ブラウザで開くだけで動作する。


5%10年では複利の効きが分かりづらいので、50年に変更した図がこちら。for文、繰り返しの回数をいろいろ変更してみるとおもしろい。

続いて、サイコロの確率のグラフ化。

学習16 サイコロの出目確率のグラフ」(src on GitHub)
type: "bar" で棒グラフにできます。 試行回数がたかだか100回だと期待値から大きく外れることがわかります。ブラウザを何度かリロードしてみましょう。

<body style="margin:0"> <canvas id="chart"></canvas> <script type="module"> import Chart from "https://code4sabae.github.io/kafumon/lib/Chart.mjs"; const deme = [0, 0, 0, 0, 0, 0] // 出目の数を数える配列 for (let i = 0; i < 100; i++) { const saikoro = Math.floor(Math.random() * 6 + 1); deme[saikoro - 1]++; } const left = [1, 2, 3, 4, 5, 6] // グラフの左方向の値指定用 const config = { type: "bar", data: { labels: left, datasets: [{ data: deme, backgroundColor: 'rgb(255, 99, 132)' }] }, options: { title: { display: true, text: "SAIKORO SIMULATION" }, scales: { xAxes: [{ scaleLabel: { display: true, labelString: "ME" } }], yAxes: [{ scaleLabel: { display: true, labelString: "KAISUU" }, ticks: { beginAtZero: true } }], }, legend: { display: false } } }; new Chart.Chart(chart, config); </script>

グラフの細かい設定は、Chart.jsのドキュメントを案内するといいでしょう。 まずは色を変えてみるとか、簡単なところ試行錯誤するのが楽しく学習するポイントです。


こちらもfor文内の繰り返し回数を増やすと確率のばらつきが収まっていく様子がわかります。 600回、6000回、60000回と増やしていくと分かりやすいです。


学習16 モンテカルロで円周率」(src on GitHub)
乱数を使った円周率の求め方、モンテカルロ法。点の数を増やすほどに精度が高くなることがわかります。グラフのtypeは、bubbleを使用。

<body style="margin:0"> <canvas id="chart" width="100" height="100"></canvas> 円周率: <span id="pi"></span> <script type="module"> import Chart from "https://code4sabae.github.io/kafumon/lib/Chart.mjs"; const red = []; const blue = []; const totalcount = 2000; // ランダムに打つ点の総数 let incount = 0; // 円に入った点の数 for (let i = 0; i < totalcount; i++) { const x = Math.random(); // 0-1 の範囲の値 const y = Math.random(); // 0-1 の範囲の値 if (x ** 2 + y ** 2 < 1.0) { // 単位円の中に入ったら incount++; // 入ったらカウンターに1を加える red.push({ x, y }); // 赤色でプロット準備 } else { blue.push({ x, y }); // 青色でプロット準備 } } pi.textContent = incount * 4.0 / totalcount; // 求まった円周率 const config = { type: 'bubble', data: { datasets: [ { data: red, backgroundColor: 'rgb(255, 99, 132)' }, { data: blue, backgroundColor: 'rgb(132, 99, 255)' } ] }, options: { animation: { duration: 0 }, title: { display: true, text: "Monte Carlo method" }, legend: { display: false } } }; new Chart.Chart(chart, config); </script>

JavaScriptを使ってもプログラミング実習できることを示しました。API編、ハードウェア編も別途書いて、GitHubへ追記しようと思います。
高等学校情報科「情報I」教育研修用教材プログラム集

もし、上記内容が難しく感じたとしたら、コンピューターやパソコンに関する基礎的な学習、タイピングや操作に対するある程度の慣れが必要です。

要修正、補足
* document.writeは、alert、console.log、DOM操作に置き換える。(w3.org document.write: Warning! This method has very idiosyncratic behavior.Document.write() - Web API | MDN
* 変数スコープが分かりやすく動作する strict mode を基本にする。(* Strict モード - JavaScript | MDNJavaScript モジュール - JavaScript | MDN

神山まるごと高専の技術教育統括ディレクター候補として、情報技術やプログラミングに関する教材のオープンデータ化を推進中です。 こんな教材がほしい、ここが分かりづらかった、一緒に教材を作りたいなど、協力したいという情報系高専生、ぜひご一報を!(夏のインターンプログラムも受付中 2020-07-10まで

徳島県神山町に2023年開校予定「神山まるごと高専」の技術教育統括ディレクターとして選ばれました。新規の私立高専としては、ほぼ50年ぶり!


「神山まるごと高専」学校長候補に、クリエイティブディレクター 菱川勢一を選出|神山まるごと高専のプレスリリース」(写真は建設予定地付近)
ベンチャー友達、Sansanの寺田さんが発起人。プロジェクト代表は、神山町のシカケ人、大南さん。電通の国見さんがコンセプトワークを担当。 合流し、設立に向けた準備委員会にてカリキュラム策定を中心に活動しています。

福井高専を卒業して20年、ずっと続く高専との縁。教官室に遊びにいったり、講演したり、インターンの受け入れもそろそろ20期。 プログラミングの講義を受け持ったこともありました。

神山まるごと高専が目指す育成人物像は、何があっても生きていける「野武士型パイオニア」。 ITというステキな道具を手段として、自分だけの表現をアート作品としてアウトプットする場づくりIT面から貢献したいと思います。

技術教育統括ディレクターとして、2023年の開校に向けて、ハードからソフトまでを楽しくすばやく学べる、オープンなコンテンツづくり実験と、自分の力でどんどん学んでいくためのシクミとシカケを考案中。 詳細は、今後決まっていく予定の専門教員の人たちと詰めていきます。基礎を楽しく押さえれば、移り変わり早いITを大いに楽しむことができるでしょう。(神山まるごと高専、教員募集開始

GIGAスクール構想により、小中学校から根本的に学校のスタイルが変わろうとしている今。高専はその一歩先行く存在であってほしい。 私立ならではの自由度と、高専という仕組みを大いに活かした学校のあり方を探る議論を続けています。


発表後の初イベント、HLAB主催の高校高専生向けオンラインサマースクールで神山まるごと高専セッション。 学長予定の菱川さんの講義、映像制作に関わる様々なプロフェッショナル。監督(ディレクター)もひとつの役割。 アプリ製作でも、学校づくりでも一緒ですね。


私からも「IT未来づくり入門」と題して、ITを使った楽しさ紹介。 jig.jp版のサマースクールこと、「jigインターン」では、全国からものづくり高専生が集まって3週間の古民家での開発合宿(2020年は2週間)。 チームによるソフトウェアづくりという楽しい仕事を模擬体験してもらっています。 ともに学ぶ仲間、大事です。神山高専はこれの5年版!?


多くのIT少年少女を育てたベーマガこと、マイコンBASICマガジン。 本日、原題の少年少女にもバトンをつなぐ、復刻した別冊付録付きの電子工作マガジンの発売日! 特集マンガは、IchigoDakeのアマビエ様版、AmabieDake! 100円CPU、載ってます。


早速、改造してみました!内蔵のプログラムに居たアマビエ様をランダムな場所で表示。
AmabieDake、電池を入れるだけでもプリインストールのプログラムで光ります。お守りにもどうぞ。)


加えて、670行のSLEEPコマンドを追加。100円のCPU、低電力状態となって待機する機能を使って、ボタンが押されたら再起動する形にしています。 ボタンを押したら、3回輝く、疫病退散ペンダントのできあがり!IoTの要は、低価格と省電力。ハードもソフトも自在に操ろう!


巻頭には、先日の小中学生向け「PCNこどもプロコン」表彰式の様子が特集されていました! 今年の中学1年生、2023年の神山まるごと高専の1期生となるチャンス!

世界中で進む、新しい教育への転換チャレンジ。
海外評価も高い、日本発のユニークな教育システム「高専」を大いに活かしていきましょう!

links
- 「神山まるごと高専」学校長候補に、クリエイティブディレクター 菱川勢一を選出|神山まるごと高専のプレスリリース
- 海外から見た高専教育
- PCNこどもプロコン

第31回高専プロコンの競技部門の予定だった競技を「囲みます」と名付けて、ロゴ完成!前回に引き続き、オンラインで集まり開発進めるハックデー。

今日の5名2グループ、1時間1スプリントでの進捗は、APIサーバーがDenoで2人体制で進み、クライアントのフィールド表示の初期段階ができて、FigmaのデザインからHTMLへ起こす目処がなんとなく立つまで。 短時間の割にはまずまず?

今日の参加者 -1 (残念ながら、寮の回線状況悪かった、さよ)

囲みますプロジェクトは Code for KOSEN に移管!
codeforkosen/Kakomimasu: #procon31 競技部門 コアモジュール for Deno/Node.js
Code for KOSEN チームで作っていきます。


側面支援、C言語でJSONでやりとりする apiserver に接続するプログラムができました!

HTTP POSTを実現する post.h は、コマンド curl を popen を使って起動し、返ってきた文字列を返します。

#include <stdio.h> #define MAX_LEN_REQ (1 * 1024 * 1024) // 1Mbyte int post(const char* host, const char* path, const char* json, char* buf, int lenbuf) { char cmd[MAX_LEN_REQ]; sprintf(cmd, "curl -s -H 'Authorization: token1' -X POST %s%s -d '%s'", host, path, json); printf("[post req]\n%s\n\n", cmd); // char* cmd = "curl -s -H 'Authorization: token1' -X POST http://localhost:8880/action -d '{\"actions\":[{\"agentID\": 2, \"dx\": 1, \"dy\": 1, \"type\": \"move\"}, {\"agentID\": 3, \"dx\": 1, \"dy\": 1, \"type\": \"move\"}]}'"; // for test FILE* fp = popen(cmd, "r"); if (!fp) { fprintf(stderr, "can't popen\n"); return 1; } fgets(buf, lenbuf, fp); if (!feof(fp)) { fprintf(stderr, "too long json, check MAX_LEN_JSON\n"); return 1; } printf("[post res]\n%s\n\n", buf); pclose(fp); return 0; }

post.h を使って、受け取った文字列を、sscanf でパースし、AIロジックで使いましょう! scanfでパースしやすく、tokenなどの文字数は固定で決めておくと良さそう。 (src on GitHub)

#include <stdio.h> #include "post.h" #define MAX_LEN_JSON (1 * 1024 * 1024) // 1Mbyte #define LEN_TOKEN 6 // TOKENの長さは固定 int action_test(const char* host) { char buf[MAX_LEN_JSON]; if (post(host, "/action", "{\"actions\":[{\"agentID\": 2, \"dx\": 1, \"dy\": 1, \"type\": \"move\"}, {\"agentID\": 3, \"dx\": 1, \"dy\": 1, \"type\": \"move\"}]}", buf, MAX_LEN_JSON)) { printf("post error!\n"); return 1; } char token[LEN_TOKEN + 1]; int nActions; int res = sscanf(buf, "{\"yourToken\":\"%6s\",\"yourPath\":\"/action\",\"nActions\":%d}", token, &nActions); // 6 == LEN_TOKEN if (!res) { printf("parse error!\n"); return 1; } printf("[parsed]\n"); printf("token (%d chars): %s\n", LEN_TOKEN, token); printf("nActions: %d\n", nActions); return 0; } int main(int argc, char** argv) { const char* host = "http://localhost:8880"; return action_test(host); }

Code for KOSEN」のwebサイトも手を入れ、参加者募集も追加!

競技プロコン、ウェブサイト、その他高専に関する何かプロジェクトなどなど。
我こそはという高専生の参加、お待ちしてます!

福井県で始まった混雑状況オープンデータ。合わせて行いたい定量的なデータ計測を、鯖江市役所入り口にて設置!さすが鯖江市、依頼からスタートまで何もかも速い!

IchigoCounter - 鯖江市役所 人流オープンデータ
13時すぎに1分間に13人通ったピークが見られ、18時半からは人の流れが停止する様子が記録できています。


来庁者IoTカウンター実証実験中。ケースに入っていい感じ!IoT対応のIchigoJam、IchigoSodaのアンテナ2本はソフトバンクの4G回線につながっているので、既存の無線LANと無関係に安定的に動作します。 人流は200円の超音波センサー「HC-SR04」を使用。


超音波が返ってくるまでの時間を計測し、しきい値(T)を超えていたら人が通ったと仮定。1分間ごとにカウントした数をIoT.OUTコマンドで送信するだけのシンプルなプログラム。 反応してから一定時間待ち(W=1.5秒)を入れて、ひとりを重複してカウントしないようにするなどの調整はその場で観察しながら調整しました。 IchigoSodaにミニモニターとキーボードをつなぐだけで自由自在!

機材を持っていって、設置、プログラム、テスト、調整、設置完了まで1時間! 簡単にできるので、通りがかった中学校の校長先生にぜひ中学校でもIoTづくりをと、PRもできました。


鯖江市長、牧野さんも動作確認!
オープンデータ化、IT化、やれるところからどんどん進めていきましょう!

今回の鯖江市役所での実証実験ができたのは、スピーディーにOK出してくれた、市役所の方、市長のおかげです! 学生のみなさん、このステキすぎるまち、鯖江市に「jigインターン2020」で来てみませんか?(社会人の方の視察もぜひ)

全国の高専、夏休みが短縮されたことを受けて、今回は2週間に改定します。募集期間、延長しましたので、これなら参加できそう!という方、熱い町、鯖江でのインターン、ぜひご検討を!


古民家での共同生活、ウェルカム会!(昨年の様子)


jig.jp本店所在地、めがね会館にて、2週間のチーム開発(昨年の様子)


砂時計 - Matter.mjs」(box2d版Matter.jsmjsで移植)
今回は1週間短いので、事前サポートを充実させてカバーしようと思います。アプリづくりは、Swift / Kotlin / Java / JavaScript / Dartなどといろいろ選択肢はありますが、webアプリとしても使えて汎用性高いJavaScriptを基本言語として推奨。 その入門を作っていきます。

まずはこのスマホを傾けて楽しい砂時計プログラムを改造して遊ぶところからどうぞ!

<!DOCTYPE html><html><head><meta charset="utf-8"/> <title>sandglass - matter-es</title> <meta property="og:image" content="sandglass.png"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </head><body> <script type="module"> import { Matter, createWorld } from "https://js.sabae.cc/matter.mjs"; const { Bodies, Body } = Matter; const world = createWorld(); const [w, h] = [500, 1000]; world.width = w; const nballs = 400; const cx = w / 2; const cy = h / 2; const ww = h / 40; const createWall = (x, y, w, h, th) => { const base = Bodies.rectangle(x, y, w * 2, h * 2, { isStatic: true }); Body.rotate(base, th); return base; } world.add(createWall(cx - w / 2, cy, ww, h / 2 + ww, 0)); world.add(createWall(cx + w / 2, cy, ww, h / 2 + ww, 0)); world.add(createWall(cx, 0, ww, w / 2, Math.PI / 2)); world.add(createWall(cx, h, ww, w / 2, Math.PI / 2)); const hole = w / 6; const hw = ww / 2; const hgap = h / 15; const th = Math.PI / 6; world.add(createWall(cx - (w + hole) / 4, cy - hgap, w / 4, hw, th)); world.add(createWall(cx + (w + hole) / 4, cy - hgap, w / 4, hw, -th)); world.add(createWall(cx - (w + hole) / 4, cy + hgap, w / 4, hw, -th)); world.add(createWall(cx + (w + hole) / 4, cy + hgap, w / 4, hw, th)); const bw = w / 60; for (let i = 0; i < nballs; i++) { world.add(Bodies.circle(cx + (w - ww * 2) * (Math.random() - .5), ww + (h / 4) * Math.random(), bw)); } document.body.onclick = () => { world.useRealGravity(); // 傾きセンサーを重力に反映(対応していたら) world.gravity.y = -world.gravity.y; // 重力反転 }; </script> </body></html>

sandglass.html とか名前を付けて保存し、ブラウザで開くだけで動きます!(要、ネット)
まずは砂の大きさを変えたり、数を変えたり、いじって見ましょう!

HTML/CSSもはじめての方は、こちらからどうぞ!(追記、JSはじめのいっぽも!)
創ろう、楽しい夏!

links
- 全国高専生向けjig.jpインターンプログラム2020 ~募集のお知らせ~
- jigintern2019のブログ(昨年参加者によるブログ)

中止になった高専プロコンの競技部門、2020年の競技部門が永遠に失われるのも寂しいので、勝手開催しようと集まった仲間とオンラインハックデー。

釧路、木更津、函館、そして福井から集まった有志で開発した3時間半(16時から19時半)

実は誰も高専プロコン経験者がいなかった今回、まずは高専プロコンと競技部門の概要説明と、今回のルールをソースコードを見ながら解説。 プログラミング言語も、オブジェクト思考も実際触ってみると、理解が深まるものです。(JDK1.0.2での経験者)

スマホで遊んでみたいよねと、webアプリチーム、通信対戦するための仕様決めないとねと、プロトコルチームの2チームに分かれて開発スタート。 1スプリント1時間弱の超短縮スクラム、zoomのブレイクアウトルームでそれぞれ進めました。


GitHub、HTML、CSSがはじめての人向けレクチャーは、画面共有してもらってサポートが便利ですね!(参考、HTML/CSSはじめのいっぽ

今回の進捗はこちら!

Kakomimasu – Figma
オンラインデザインツール「Figma」を使用。イメージがあると、ワクワクしてきますね!


かこみますネットワークプロトコルを決めようの会 - HackMD
前回30回大会時のプロトコルが参考になるのと、連続出場者にも優しそうと、ひとまずそれをベースにして作ることに決まり。

2スプリント終わって、KPTでふりかえり。よかったので続けるキープ、気がついた問題点を挙げるプロブレム、次の挑戦トライ。ばばっと、それぞれ2分ずつ、Slackに書き出して、終了!

次の実装に向けて、イチオシDenoでの実装を提供。JSONで受け取り、JSONで返す。シンプルなAPIサーバーのモックを JavaScript on Deno で作ってみました。

import { createApp } from "https://servestjs.org/@v1.1.0/mod.ts"; // https://servestjs.org/ const api = (token, path, req) => { const res = { yourToken: token, yourPath: path, nActions: req.actions.length, }; return res; }; const app = createApp(); app.handle(/\/*/, async (req) => { try { const token = req.headers.get("Authorization"); const json = await req.json(); console.log("req", json); const res = api(token, req.path, json); console.log("res", res); await req.respond({ status: 200, headers: new Headers({ "content-type": "application/json" }), body: JSON.stringify(res), }); } catch (e) { console.log("err", e); } }); app.listen({ port: 8880 });

使用したフレームワークは、Servest、シンプルに書けて高機能なDeno用のHTTPサーバーです。

app.handle に受け取りたいpathを正規表現で書いて、中身を書くだけ。JSONで受け取り、JSONで返すことに特化した関数 api をいろいろ自由に作りましょう。

curlコマンドを使って、コンソール(コマンドプロンプト)から、呼び出して実験できます。C言語でも何でもコマンド呼び出しさえ使えれば、使えそうですね!

$ curl -H 'Authorization: token1' -X POST http://localhost:8880/action -d '{"actions":[{"agentID": 2, "dx": 1, "dy": 1, "type": "move"}, {"agentID": 3, "dx": 1, "dy": 1, "type": "move"}]}' {"yourToken":"token1","yourPath":"/action","nActions":2}

上記モック実装は、受け取ったactionの数を数える動作。nActionsが2となっています。(src on GitHub

次回は、6/17(水)20:00-22:00、参加希望の高専生、下記Slackまでどうぞ!
Slack: Code for KOSEN

Tweet
クリエイティブ・コモンズ・ライセンス
この作品は「Creative Commons — CC BY 4.0」の下に提供されています。
CC BY / @taisukef / アイコン画像 / プロフィール画像 / RSS