<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); })(window,document,'script','dataLayer','GTM-KRS8CM');</script>

算数・数学をちゃんと勉強しておけばよかった、と思った話


盤が折りたためる小さなオセロのセットがウチにあります。セブン-イレブンで買いました。
久しぶりに息子がやり始めたものの、石も小さいのでときどきなくなるし、なにより小さくてめくりづらいので、自分としてはあまり好きではありません。

自分も一応ウェブ業界の端くれだし、オセロみたいなもんならJavaScriptでもわりと簡単にできるんじゃないか(AIまでは無理だけど)と思って、金曜日と週末のすきま時間に、スマホでできるオセロ(リバーシ)を作ろうと手を付け始めました。

JavaScriptでつくったリバーシ

で、できたのがこれです。ちゃんと動いてる?

見た目は、すぐできた。

見た目は簡単にできました。ひとマスがdivになってて、クラスを付与することで、中に白黒の石が入ります。

石を置く動作もすぐにできました。click/touchendのイベントで、divにクラスをつけるだけです。

アンドゥとコマ数の勘定は機能としてありましたが、この時点では、石をめくるのは人力でした。

遊んでみたところ、最低限、当初の目的は果たしていたのでまあまあ満足。
しかし、ポチポチ画面を叩いているうちに、せっかくコンピューターを使っているんだから、めくるのくらいは自動にしたいよな…と欲が出てきました。

どうやって数えれば…?

めくる動作自体はできていたので、問題は、人間が頭でやっていた「めくれるコマを探す」動作をどうプログラムに置き換えるか、というところです。
とりあえず、自分が実際のプレイでどうやってめくれるコマを探しているか、考えてみました。

  1. 確認するのは、置いたコマを通るタテ・ヨコ・ナナメの4方向
  2. 置いたコマから直線両方向に同じ色の石を探して、その間に連続して違う色の石があった場合はめくれる
  3. 同じ色の石が直線上にあっても、間に空のコマがあった場合はめくれない

というわけで、

  • 置いたコマを通る直線上のコマの状態を全部拾う
  • 拾ったコマの状態を、タテ・ヨコ・ナナメそれぞれに評価して、めくれるところをめくる

と、漠然と方針を決定。ところが。

斜めがわからない

タテとヨコは、さすがに問題なく拾えましたが、ナナメをどう取得したらいいかわからない。
どう試行錯誤したか忘れましたが、いろいろと試してみたものの、どう考えてもスマートじゃなかったり、間違えがあったりしてうまく行きません。
ウンウン唸っているうちに、なにかの拍子で「一次関数」を思い出しました。あ、これナナメの直線グラフやん?

しかし今度は、その一次関数がわからない(!)。そりゃ数学は赤点取るほど苦手でしたが、まさか、一次関数までわからないとは…!
二次関数の因数分解まではついていけてたつもりだったのに!
しかたがないので、ググって、一次関数について勉強しなおしです。
結果的に、通る1点と傾きが与えられた直線の方程式と考えることで、ナナメ方向の座標を取得できるとわかりました(傾き???とか、式を利用するのにずいぶん遠回りしました。勉強した記憶すらない…)。

あとは、ただ愚直にプログラムに置き換えです。

  1. 一列を取得する
  2. 置いたコマが、その中の何番目かを調べる
  3. 置いたコマのひとつ前に違う色が置いてあったら調査を続ける
  4. 同じ色のコマが来たら、調査を終了してその位置を記憶しておく。その前に空のコマが来たら、めくれないから処理を終わる
  5. 置いたコマのひとつ後からも、同じ処理をする
  6. 以上を、タテ・ヨコ・ナナメで繰り返す
  7. 記憶したコマと置いたコマの間をひっくりかえす

で、できあがったのが先のリバーシです
自分にはこんなもんですが、きっともっとスマートな方法があることでしょう。

算数や数学をちゃんと勉強しておけばよかった!!

大人になってから「数学をわかっていたらなぁ!」と思う場面がたくさん出てきました。
生活の中でもぼちぼちありますが、今回みたいにゲームっぽいものを作ってみようかな、となったときは、端的に数学の必要性を感じます。
3Dのゲームなんて、端から端までもう完全に数学の固まりでしょう。

学生時代は、ただただ算数や数学が苦手で、嫌で、赤点取って夏休みに特別講習まで受けさせられて、本当に大っ嫌いでした。
それこそ「何の役に立つんだ」と思っていたに違いありません。

当時でも、おそらく少し見方を変えたら、具体的に役に立ったり、生活の中でも数学の知識を使う場面はあったんだと思います。
ただ、今回のリバーシの例と同じく、数学的な素養がなかったために、それが使えるということにすら気が付かなかったんでしょう。
今でこそ「学習したことに一切の無駄はない」と思いますが、当時は、ただやらされていただけでした。

息子が公文式で算数を勉強していて、今は割り算にとりかかっているところです。
四則演算はいろいろな場面で容易に使うことができるので、生活の中でできるだけ具体的に算数が活きるということを気づいてもらえるよう、いろいろ話を振って一緒に考えています。

インカの黄金というゲームがあるんですが、これの点数計算で割り算を使います(出た宝の数÷プレイヤー数=もらえる数 余りはストック)。
公文でやるまでは親がやっていましたが、今は、息子がやってくれています。
ちょうど勉強していることが利用できて、うれしいようです。
算数・数学を嫌いにならないといいなぁ…算数・数学はいいぞ。がんばれ息子。

もしタイムマシンがあったら、中学生の自分をグーパンチして「BASICでいいから、オセロとかババ抜きとか七並べとか、動きのないゲームを作ってみろ」と言ってやりたい。


<script type="text/javascript" id="zsiqchat">var $zoho=$zoho || {};$zoho.salesiq = $zoho.salesiq || {widgetcode: "siq61aecceb7ad0c24af4e4670187f03564ddd615eb71422e1b7169309fa9b25e89", values:{},ready:function(){}};var d=document;s=d.createElement("script");s.type="text/javascript";s.id="zsiqscript";s.defer=true;s.src="https://salesiq.zohopublic.com/widget";t=d.getElementsByTagName("script")[0];t.parentNode.insertBefore(s,t);</script>