JavaScript の書き方と動かし方

1. はじめに

JavaScript とは何か?という問いかけへの簡潔な答えは、

HTMLとWebを使うプログラム言語(スクリプト)

だ。HTML と Web それぞれについてある程度の知識を持っていれば、JavaScriptを理解することはそれほど難しくはない。はじめは、Webページのソースを見る方法を知っている程度で十分だ。Webページを開いて、Ctrl + uを押せば隣に新しくタブが開きページのソースが表示される。

Web ブラウザは、Google Chrome を使うことにする。

Script(スクリプト)は、短いプログラムを示す言葉である。JavaScriptはそのなかの1つである。他にも、PHP、Python、Ruby、Perlなどがある。スクリプトはWeb開発に利用されている。

もっと知りたい人は、w3schools のJavaScript入門などを読んで、その中の例題(example)を実行してほしい。

HTMLWebについては、この授業の中で要点を解説する。しかし初心者が言語の細かな書き方や意味を理解するには時間がかかるが、自分で書いてそれをWebブラウザで実行し、エラーの修正やソースの修正をするのが良い。Hyper Text Markup Language (HTML)と World Wide Web (Web)については実際に例題の中でJavaScriptを使う書き方やその動作を見て理解できるようする。


1.1 エディタとブラウザ

スクリプトは短かいコード(プログラム)から出来上がった文字列である。スクリプトを書いてファイルに保存するため、まずエディタが必要となる。

  • Windows 10 メモ帳 (notepad.exe) などのエディタ。開発者向けの Sublime text などの高機能エディタを、ダウンロードして利用してみるのもよい。2018年度は、Brackets を主に使用する。他に、AtomSublimeも使用することがある。特に、プログラムやコードを書くことに興味のある人は、自分の好みを大切にしていくつもダウンロードして試してほしい。エディタはおそらく一生ほぼ同じものを使うことになる。私的にはいまだにEmacsを使っているが、これからコードを書く人にはそれほどおすすめしない。私的には40年近く使い続けている道具の一つである。

  • Android iA Writerなどのエディタ

  • iPhone

  • Windows 10 、 Android、 Webブラウザ (Chrome) を授業では使用する。

1.2 HTMLとScriptの動かし方

HTML と Script タグで動かす原始的なやり方で HTML と JavaScript を書いて、動かしてみよう。Windows で動かすには、エディタとブラウザがあればよい。titleタグは空欄にしてあるから、スクリプトにあわせて自分で適当に埋める。ただ空欄のままでも問題はない。

適当な名前.html

<html>
<head>
  <title>ここには適当なタイトルを書く</title>
</head>
<body>
 
<script>
console.log("JavaScript 動いてる!");
</script>
</body>
</html>

次にScript(コード)とHTMLを分けて書くやり方。

script.js

<script>
console.log("JavaScript 動いてる!");
</script>

HTMLファイルのなかでJavaScriptファイルを呼び出す

<script src="script.js"></script>

1.3 操作編 HTMLとJavaScriptの動かし方

エディタで「HTMLとJavaScript で記述したファイル」を保存する。ファイル名は自分で考えて付ける。ファイルの拡張子はhtmlとする。

例:
Windows 10
Notepad(メモ帳)

User: sumio\Document

ファイル名: test1.html

Save as type: All Files

Encoding: UTF-8

Save As 名前、拡張子(html)、コード(UTF-8)指定で保存する。

notepad test1
Save as

このファイルをChrome で読み込む。URLに `file:///ドライブ名:/ユーザ名/Documents/test1.html を入力する。

Chrome URL

ここで、test1.htmlを読み込んだのに、何も起きないじゃないか! 失望する人がたくさん出ます。これは、ChromeがJavaScriptのコンソール・ログは、メインの画面ではなくコンソール画面に出力するためだ。標準ではコンソール画面は表示されていない。そこでコンソール画面を出すにはどうするか。

コンソール画面を開くためには、Ctrl + Shift + Jを押す。すなわち、コントロールキーとシフトキーと英字Jキーを同時に押す。シフトキーを忘れないように。コントロールキーとJキーではダウンロードファイルの一覧が出る。

Console

コンソール画面に「JavaScript 動いてる!」とでる。


2. The Game of Chaos

The Game of Chaos のHTMLファイルを次のように記述する。

chaosGame

スクリプト chaosGame()

function chaosGame() {
var canv = document.getElementById('sierpinski').getContext('2d');
var x = Math.random() * 400;
var y = Math.random() * 346;
for (var i=0; i<30000; i++) {
    var vertex = Math.floor(Math.random() * 3);
    switch(vertex) {
    case 0:
        x = x / 2;
        y = y / 2;
        canv.fillStyle = 'green';
        break;
    case 1:
        x = 200 + (200 -x) / 2;
        y = 346 - (346 -y) / 2;
        canv.fillStyle = 'red';
        break;
    case 2:
        x = 400 - (400 - x) / 2;
        y = y / 2;
        canv.fillStyle = 'blue';
    }
    canv.fillRect(x,y, 1,1);
}}

function chaosGame() が使用する JavaScriptの命令、メソッドについて解説する。

  • Math.random()は、0から1の範囲で乱数を発生する関数。

  • 命令for(var i=0; i<30000; i++)の条件で { ... }の範囲の命令を繰り返す。この例では、変数i0から29999まで1ずつ増加i++させながら{}までを繰り返す。

  • 絵を描くためのキャンバスを、メソッド getContext('2d')を使って用意する。

  • メソッドfillStyleは、図形を塗りつぶす色を指定する。canv.fillStyle('red')は、赤色で塗りつぶす。赤色は、16進数で canv.fillStyle('#FF0000')のように指定することもできる。色を示す数値はRed Green Blueの順で、それぞれ00からFFまで。16進数であることを示すために先頭には#をつける。

  • メソッドfillRect(x,y, 1,1) は、長方形の左上のX座標、Y座標から幅1ピクセル、縦1ピクセルの長方形を塗りつぶす。fillRect(x,y,幅,縦)のように左上のXY座標から幅と縦をピクセル数で示す。

上記の関数 chaosGame() は、シェルピンスキー3角形を描く。このJavaScriptコードを次のHTMLファイルの「ここにスクリプトを埋め込む。」の行を削除して、埋め込む。

HTML ファイル

<html>
  <head>
    <meta charset="UTF-8">
    <title>Chaos Game</title>
  </head>

  <body>
    <p>
      <canvas id="sierpinski" width=400 height=346></canvas>
    </p>

    <p>
      <button onclick="chaosGame()">Click here to see a Sierpinski triangle</button>
    </p>

<script>

この行にスクリプトを埋め込む。

</script>

  </body>
</html>

Sierpinski triangle

数学者シェルピンスキー, 1882 - 1969については、フラクタル図形、暗号解読、月面クレータなどのエピソードを解説したサイトがある。

この単純なルールで生成される複雑な図形のことを知るには、ゲオルク・カントールカントール集合とその次元から話をしなければならない。非常に興味深い数学理論の入り口だが、ジャバスクリプトの範囲を超えるため。別稿で解説する予定。

  • シェルピンスキー3角形

シェルピンスキー3角形は、フラクタルの一種でそのハウスドルフ次元は log3/log2 = 0.4771.../0.3010... = 1.585...である。作り方は、正3角形を1辺の長さが半分の4つの小正3角形に分け、中央の小正3角形を取り除く。次に残りの小正3角形のそれぞれに同じ操作をする。この操作を無限回繰り返すことで得られる。

sierpinski triangle - wikipedia

  • フラクタル

自然数ではない次元を持つ図形のこと。古くから数学で取り上げてきた図形は、いくつかの実数の組でその上の点に名前をつけることができる。実数の個数が次元であった。したがって次元は整数である。実数の組で点に名前をつけることができない図形が、数学者によって構成された。カントール集合やシェルピンスキー3角形である。これらの場合、ハウスドルフ次元を計算すると自然数でない値になる。マンデルブロによりフラクタルが広く知られるようになった。

  • 次元

1点は0次元、直線は1次元、平面は2次元である。数直線上の点は1つの実数であらわされる。平面上の点は2つの実数の組(x,y)であらわされる。一般に、その図形の上の点をあらわすのにn個の数が必要であるとき、図形の次元はnである。

  • ハウスドルフ次元

距離空間に対して定義される次元の一種である。自然数とは限らない。部分多様体のハウスドルフ次元は普通の意味での次元に一致する。

  • ハウスドルフ次元の例

コッホ曲線

koch curve

自己相似コッホ曲線の例でわかるように、1つの線が4個の線になり、4個の線の長さはそれぞれ元の線の1/3になっている。これを個数 N=4、スケール S=3 という。したがって、コッホ曲線のハウスドルフ次元は log(N) / log(S) = log4 / log3 = (log2 + log2) / log3 = およそ (0.301+0.301)/0.4771 = およそ 1.26 であることがわかる。

  • 距離空間

2点間の「遠近」距離を、量的に計算できる空間をいう。

  • 多様体 manifold

曲線や曲面の概念を高次元に一般化したもので、「曲がった」空間を数学的に表現するためにリーマン(1826 - 1866)によって導入された。

  • カントール集合

カントール(1845 - 1918)が1883年に構成してみせた集合Cのこと。単位区間[0,1]を3等分し、まず中央の開区間(1/3,2/3)を取り除く。次に、残る2つの区間[0,1/3],[2/3,1]を3等分し、それぞれの中央の長さ1/9の開区間(1/9,2/9),(7/9,8/9)を取り除く……
この操作を無限に繰り返して最後に残る集合がCである。Cのハウスドルフ次元はlog2/log3 = 0.6309...である。さてCは、閉区間[0,1]から開区間を取り除いたものである。では、取り除いたすべての開区間の和を計算すると、

1/3+2/32+22/33+ ... = 1

Cantor set - wikipedia

練習問題
  • シェルピンスキー3角形、カントール集合、コッホ曲線をハウスドルフ次元の小さい順に並べる。

  • シェルピンスキー3角形のハウスドルフ次元が log3 / log2 であることを確かめる。


HTML と JavaScriptをつなぐ考え方 - ハイパーテキストとオブジェクト

Chaos Game の中に HTML と JavaScript のつながりを見つけることができる。

HTML

<canvas id="sielpinski" width=400 height=346></canvas>

JavaScript

document.getElementById('sielpinski').getContext('2d')

HTML とJavaScript をつなぐ考え方は DOM と名付けられた文書をオブジェクト化する思想となっている。そもそもHTMLも文書をハイパーテキスト化する思想から生まれた。

DOM = (Document Object Model)

オブジェクト document のなかでもクラス Element はよく使われる基本的クラスである。

Element.id

Element を識別するIDで名前である。getElementByIdを使って取り出せる。

document.getElementById('sielpinski')によりsielpinskiと名前を付けられたキャンバス<canvas id="sielpinski" width=400 height=346></canvas>を文書オブジェクトとしてJavaScriptで使うことができる。さらにgetContext('2d')でこのシェルピンスキーと名付けた文書オブジェクトを2次元キャンバスで絵を描くようにする用意ができることになる。

名前はDOMStringとして、それぞれ自分の国の文字で書けるようになっている。母国語で書いた例を示す。

"中文 español deutsch English हिन्दी العربية português বাংলা русский 日本語 ਪੰਜਾਬੀ 한국어 தமிழ் עברית"

HTML page API = DOM + JavaScript

DOM について最新の内容は、DOM入門を参照する。各国の言語で表示される。右上の「Language」から日本語を選択する。

DOM


2.1 3角形の色

例えば、JavaScript コード中の canv.fillStyle = 'green'命令中の色指定greengoldにすれば左上の緑色が金色に変わる。色の名前の一覧を見て試してみよう。

補色の効果を活かしたシェルピンスキーの3角形を考えてみよう。

2.2 正3角形の大きさ

  • 3角形の辺をそれぞれ2倍にするには、どうすればよいだろうか。

ヒント:400と346は、X軸方向とY軸方向のドット数に関係している。

  • ある正3角形とその2倍の面積をもつ3角形を並べて描け。

2.3 正3角形の向き

3角形の上下を逆にする。正3角形の頂点を上に、底辺を下にする。

ヒント:

2.4 紙と鉛筆で描く Chaos Game

カオスゲームのルールは、次のように命令をならべたものを命令1の次は命令2というように、命令を書かれている通り実行することである。カオスゲームのアルゴリズムである。

紙と鉛筆を用意して、図形を実際に描いてみるとより興味深いことがわかる。

  1. 正3角形(ABC)を用意する。
  • 正3角形の中にランダムに1つ点(O)を打つ。
  • サイコロを投げる。
  • 1か2なら頂点Aと点(O)をつなぐ。3か4なら頂点Bと点(O)をつなぐ。5か6なら頂点Cと点(O)をつなぐ。
  • 命令4で頂点と点(O)をつないだ距離の中心点を、あたらしい点(O)とする。
  • 3に戻る。

JavaScriptとDOM でキャンバスを使う

キャンバスのサイズは縦横、1000×1000にする。idの canvasの文字列は自分で名前を自由につける。

<canvas id="canvas" width="1000" height="1000"></canvas>

Chromeでキャンバスを検査する

Sublime Textなどのエディタで HTML を記述しファイル名 canvasDOM.html をつけてフォルダ Src に保存する。

canvasDOM.html

  • Chrome に canvasDOM.html を読み込ませる。

    file:///C:/shiki/Src/canvasDOM.html

  • Chrome 窓は白紙のまま。

  • Ctrl + Shift + J

  • Chrome 窓の右側に開発者用ツールが表示される。Elementsを選択する。

Elements

  • canvas id="canvas" width=1000 height=1000>の行にカーソルをのせる。

  • Chrome窓に水色でキャンバスが現れ、左下に canvasの大きさ 1000×1000も表示される。

JavaScriptでキャンバスに線を引く

このキャンバスにJavaScriptにより線を引く。そのためにキャンバスの2次元Context(コンテキスト)に対してmoveToとlineToのメソッドを使うことにしよう。

その前にキャンバスと2次元平面を、スクリプトが変数として使えるように準備する。変数名を canvasとctxにしたが、この名前もプログラマが自由に選んでかまわない。

var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');

キャンバスに作図するペンの色と線の幅をfillStyleとlineWidthで指定する。ここでは、ペンの色を黒、幅を15にした。JavaScriptでは命令の終わりにセミコロン(;)をつけることを忘れないように注意する。

ctx.fillStyle = '#000';
ctx.lineWidth = 15;

それでは実際にキャンバスに直線を描く。メソッドは beginPath()、moveTo()、lineTo()、stroke()を使う。これらの描画に関するプロパティ(canvas, fillStyle, font など)とメソッド(beginPath, fillRect など)は、CanvasRenderingContext2Dに詳細が記述されている。

ctx.beginPath();
ctx.moveTo(0,0);
ctx.lineTo(100,100);
ctx.stroke();

DOM(ドキュメント・オブジェクト・モデル)を理解するには、実際にブラウザで動かしてみた方が、個々のメソッドを説明するよりも早い。

このファイルを作成して保存し、実際にファイルをChromeに読み込ませてみよう。

canvasDOM

次のような直線が座標(0,0)から(100,100)へ引かれる。

line


簡単なグラフィックスの練習

直角3角形をキャンバスに描く

  • 直角3角形の3辺をそれぞれ幅1ピクセルの直線にして、長方形を描く。3頂点ABCの座標は適当に決めてよい。3辺の色を黒にする。

スクリプトを次のようにする。

Triangle

直角3角形が描かれる。実際に描いてみるとわかるがキャンバスの原点(0,0)は、Chrome窓の左上隅ではなく少しマージンが上と左にとられている。

triangle

  • 3辺の色を変化させる。

四角形をキャンバスに描く

rectメソッドを使う。

rect(x, y, width, height);

rect

ただしこのスクリプトを実行しても何も描かれない。10行目の ctx.rect メソッドで四角形を描くパスが準備された。この次に実際にどのように描くかを stroke か fill のどちらかのメソッドで指定することによって線画の四角形か塗りつぶされた四角形かを描くことができる。

線画

ctx.stroke();

塗りつぶす

ctx.fill();

なお、この四角形を描くキャンバスは

<canvas id="canvas"></canvas>

のように幅と横を省略している。ではこのとき実際にはChromeでどのくらいの大きさのキャンバスが出てくるだろうか。Chromeのデベロッパーツールで確認してみよう。

三角関数とグラフ

TrigGraph

緑色がcosθ、青色がsinθのグラフになっている。青色のグラフを90度ずらすと重なる。

TG

練習問題

tanθのグラフを赤色で追加する。


Android app

  • DroidScript

DroidScript

このアプリのなかでは PC と WiFi でリンクできる。例えば、アプリのソースを PC で編集したりも可能である。


人工知能とQWOP

QWOP AI

JavaScriptでQWOPを実現させる。

github.com/whsieh/qwop-ai

このサイトから次のファイルをダウンロードし、解凍する。

qwop-ai-master.zip

このファイルを解凍すると、index.htmlの下にjsという名前のフォルダがある。QWOPのプログラムは、index.htmlから呼び出されるこのjsフォルダ内にある。


JSON

データ交換用言語 JSON

これまでスクリプトというプログラムを記述するための言語の書き方を話してきた。このスクリプトは、ファイル形式としてはテキスト形式で保存される。その編集にはテキストエディタを使う。短いスクリプトの例の中に登場するデータは、スクリプトの中に埋め込まれた。例えば、座標やグラフの色などだ。しかし、現実社会で処理されているような相当な量のデータをプログラムに埋め込めば、データが大量であればあるほどスクリプト自体がデータの中に埋められる。

スクリプトをこれまで皆さんは、テキストエディタ、例えば Sublime textのようなアプリで書いてきた。Sublime text を使うとJavaScriptの文法として間違った箇所が発見しやすくなることに気が付いたはずだ。

データもデータ交換用の言語 JSON を使って、Sublime textで書くことにしよう。JSONで書くと、データ記述の構文的な間違いを発見しやすくなる。また、JSONの文法は、JavaScriptと同様の記述方法である。

例を実行してみよう。

<!DOCTYPE html>
<html>
<body>

<h2>localStorage へのデータ収納と取り出し</h2>

<p id="demo"></p>

<script>
var myObj, myJSON, text, obj;

//データを収納する
myObj = { "name":"一郎", "age":31, "city":"伊予" };
myJSON = JSON.stringify(myObj);
localStorage.setItem("testJSON", myJSON);

//データを取り出す
text = localStorage.getItem("testJSON");
obj = JSON.parse(text);
document.getElementById("demo").innerHTML = obj.name;
</script>

</body>
</html>

このHTMLコードをテキストエディタで入力し適当な名前を付けて保存する。例えば、jsonTest.html。保存したフォルダの場所も覚えておく。例えば、C:\Users\ichiro\

次にこのjsonTest.htmlをChromeブラウザで読み込んでみよう。

file:///C:/Users/ichiro/jsonTest.html

結果はどうなっただろうか?何も見えない?そのときは、'Shift + Ctrl + J`を押してみる。

赤字でエラーが表示されていないだろうか。

実は、file:///では直接コンピュータのlocalStorageを操作することになりセキュリティで禁止されている。

では、どうすればいいのか。それは、自分のコンピュータでWebサーバを動かすことである。ローカルホストをサーバにし、HTMLファイルをサーバ上の公開ファイルとして呼び出さなければいけない。具体的には、

http://localhost/jsonTest.html

とURLで指示しなければならない。

Webサーバのインストールと起動、停止方法は次の章を参照してほしい。

国政選挙結果

JSONで2017年衆議院選挙結果の一部を記述してみる。

2017衆議院選挙結果の一部

{
  "千葉": {
    "千葉1区": [
      {
        "partyName": "自民",
        "shoto": true,
        "voteNums": 82838,
        "name": "門山宏哲",
        "votePercentage": "40.69%"
      },
      {
        "partyName": "希望",
        "shoto": false,
        "voteNums": 81481,
        "name": "田嶋要",
        "votePercentage": "40.03%"
      }
    ],
    "千葉6区": [
      {
        "partyName": "自民",
        "shoto": true,
        "voteNums": 76323,
        "name": "渡辺博道",
        "votePercentage": "43.50%"
      },
      {
        "partyName": "立憲",
        "shoto": false,
        "voteNums": 65281,
        "name": "生方幸夫",
        "votePercentage": "37.21%"
      },
      {
        "partyName": "希望",
        "shoto": false,
        "voteNums": 23701,
        "name": "遠藤宣彦",
        "votePercentage": "13.51%"
      }
    ],
    "千葉13区": [
      {
        "partyName": "自民",
        "shoto": true,
        "voteNums": 93081,
        "name": "白須賀貴樹",
        "votePercentage": "45.84%"
      },
      {
        "partyName": "立憲",
        "shoto": false,
        "voteNums": 57431,
        "name": "宮川伸",
        "votePercentage": "28.28%"
      }
    ]
  },
  "福島": {
    "福島1区": [
      {
        "partyName": "無所",
        "shoto": true,
        "voteNums": 126664,
        "name": "金子恵美",
        "votePercentage": "52.74%"
      },
      {
        "partyName": "自民",
        "shoto": false,
        "voteNums": 113514,
        "name": "亀岡偉民",
        "votePercentage": "47.26%"
      }
    ],
    "福島3区": [
      {
        "partyName": "無所",
        "shoto": true,
        "voteNums": 92930,
        "name": "玄葉光一郎",
        "votePercentage": "56.62%"
      },
      {
        "partyName": "自民",
        "shoto": false,
        "voteNums": 60006,
        "name": "上杉謙太郎",
        "votePercentage": "36.56%"
      }
    ]
  }
}

JSON構文規則

JSONのサイトから図を引用した。

object - オブジェクト

オブジェクトは、"名前"と"値"をコロン記号で接着したペアである。左ブレース { で始まり右ブレース } で終わる。名前と値の各ペアは、それぞれコンマ記号で区切り並べられる。並べるときに順序はない。

オブジェクトの例

{}
{ "name": "ポチ" , "legs": 4 }


Object

array - 配列

配列は、"値"を順序をつけて集めたものである。配列は、左ブラケットで始め、右ブラケットで閉じる。"値"はコンマ記号で区切って並べる。

配列の例

[ ]
[ "ライオン" , "ヒョウ" , "トラ" ]

array

value - 値

value

string - 文字列

string

number - 数

C言語での書き方と似ているが8進数や16進数による表現はなく、10進数での表現のみに限られる。

number

JavaScript構文規則

variable 変数

変数は名前であり、データを保持するための場所であるともいえる。

変数の例

var money = 10;

var length = 8;

イコール記号は、変数に値を割り当てる演算子である。

console.log(money);

変数 money の初期値を 10 と定義したが、値を変更することがイコール演算子で可能である。

money = 12;

console.log(money);

変数 temp にはどんな数を割り当てることができるだろうか?

2.718
34
-10

var temp =

console.log(temp);

JavaScript の変数は、整数でも小数でも入れることができる。

変数 name に次のような文字列を入れることはできるだろうか?

'イチロー'
"太郎"

var name =

console.log(name);

変数に trueまたはfalse の値を入れることもできる。

var sunny = true;
sunny = false;
console.log(sunny);

JavaScriptは、ゆるい型の言語である。つまり変数の保有する型をあらかじめ宣言する必要がない。予約語 var を前に書けば変数ができ、変数はどんな型のデータでも保有することができる。あとでオブジェクトと配列を保有する変数について述べる。


アプリで練習

次のどちらかのアプリをインストールし、練習問題をやってみる。

Py - android

Py - iOS


Emoji

Twitter での絵文字の利用頻度をリアルタイムで見てみよう。

Emoji tracker

Google chrome の拡張機能を使って、絵文字フォントを入力する。

Emoji no plus

Emoji と JavaScript

Emoji in JavaScript

参考資料
Emoji


Web サーバ

ここまで HTML + JavaScriptのファイルを実行、テストするためにChromeでコンピュータ内部のファイルを(file:///)読み込んできた。このテスト方法では、HTML+JavaScriptとChromeの組み合わせテストはできるが、WebサーバにHTML+JavaScriptを置いたときにどうなるかは検証することができない。

file:///パス/(HTML+JavaScript)ファイル

http://ホスト/パス/ファイル

そもそもHTTP+JavaScriptは、クライアント・サーバ・モデルの環境で出来上がってきたものだから、それをサーバ抜きでテストしても実際の環境とは違っている。

またサーバ側がどうなっているかを知ることも重要である。しかし、自分のChromeを動かしているコンピュータの他にもう一台コンピュータを用意するのは時間と金が余分に必要になってしまう。

そこで、自分のコンピュータをWebサーバにする。1台のコンピュータでサーバとクライアントを兼ねる。サーバのプログラムとクライアントのプログラム、両方を自分のコンピュータで動かすことにする。

クライアントのプログラムは、Chromeだ。ではサーバのプログラムは?

一般的にWebサーバのプログラムは、httpdと呼ばれる。

nginx

nginxは「エンジンX」と発音する。サーバhttpdプログラムの一種 nginx をWindows 10にインストールすることにしよう。他にもhttpdサービスを提供するプログラムはある。

Windows版nginxを、このURLからダウンロードする。ここでメインラインのバージョンを選んでダウンロードする。

ダウンロードした圧縮ファイルnginx-1.13.6.zip をC:\解凍し、nginxをスタートさせる。

cd c:\

unzip nginx-1.13.6.zip

cd nginx-1.13.6

start nginx

nginx のディレクトリは次のようになっている。nginx.exeがプログラム本体である。

Directory of D:\nginx-1.13.6

<DIR>          .
<DIR>          ..
<DIR>          conf
<DIR>          contrib
<DIR>          docs
<DIR>          html
<DIR>          logs
     3,070,464 nginx.exe
<DIR>          temp

ディレクトリhtml中にindex.htmlファイルがある。localhostをアクセスしてindex.htmlファイルが見えればエンジンX(nginx)がhttpdとして動いていることがわかる。

http://localhost/index.html

ディレクトリhtmlの中にHTML+JavaScriptファイルを入れるとWebサーバで公開される。

エディタで作成したファイルをディレクトリhtmlにコピーする。

copy canvasDOM.html C:\nginx-1.13.6\html

これで HTML+JavaScript ファイルを 自分のWebサーバ(httpd = nginx)でサービスをはじめたことになる。

Chrome からのアクセスは

https://localhost/canvasDOM.html

によりできる。

nginx スタートとストップ

cd 「nginxのディレクトリ」
start nginx      ... スタート
nginx -s stop    ... ストップ

自分のコンピュータでWebサーバを動かす前に、start させ、Webサーバが必要なくなったら stop させる。

nginx プロセスチェック

Webサービス (nginx) が動いているかどうかチェックできる。

tasklist /fi "imagename eq nginx.exe"

tasklist コマンドで何も出なかった場合は、start nginx でエラーがなかったか調べる必要がある。

nginx 1.13.6 のディレクトリは次のようになっている。

nginx dir

localhost にブラウザからアクセスする

URL に localhost と入力しエンターキーを押す。

localhost

次のWelcome画面が出れば成功!

nginx welcome

URL の前にある丸にiのマークをクリックすると、ローカルホストの設定が見える。

info localhost

nginx -s stop

HTTPサービスを停止する。

nginx -?

Options:
  -?,-h         : this help
  -v            : show version and exit
  -V            : show version and configure options then exit
  -t            : test configuration and exit
  -T            : test configuration, dump it and exit
  -q            : suppress non-error messages during configuration testing
  -s signal     : send signal to a master process: stop, quit, reopen, reload
  -p prefix     : set prefix path (default: NONE)
  -c filename   : set configuration file (default: conf/nginx.conf)
  -g directives : set global directives out of configuration file

テキストをキャンバスに書く

キャンバスをオブジェクトとして定義し、それにfontプロパティとstrokeTextメソッドをつかって文字列を書くことができる。

プロパティ:: font = '大きさ 書体';

メソッド:: strokeText('文字列' , x, y);

seiseki

seiseki

<!DOCTYPE html>
<html>
<head>
    <title>Drill Max, Min, Avg, Graph</title>
</head>

<body>
<canvas id="canvas" width="1000" height="1000"></canvas>

<script>
	var canvas = document.getElementById('canvas');
	var ctx = canvas.getContext('2d');

	ctx.font = '24px serif';
	ctx.strokeText('           国語  数学 合計 平均 順位 成績', 50, 100);
	ctx.strokeText('山田      90    95', 50, 130);
	ctx.strokeText('田村      88    60', 50, 160);
	ctx.strokeText('村川      70    50', 50, 190);
	ctx.strokeText('川本      60    55', 50, 220);
	ctx.strokeText('本田      60    82', 50, 250);		
</script>
</body>
</html>

Web グラフィックス

Graphics on the Web

2D Graphics, 3D Graphics, Video を説明する。

2Dグラフィックス

canvasエレメントをAPIに利用し、キャンバスへJavaScriptによって、Web上に 2D図形を描く。

3Dグラフィックス

ビデオ

2D グラフィックス 具体例


ピタゴラスの定理を証明する図を描く


マンデルブロー集合の図形

複雑な図形をHTML + JavaScript で描く。

mandelbrot script

このスクリプトをChromeに読み込ませると、次のような図形が描かれる。

mandelbrot


サウンド

オーディオコンテクストをオブジェクトとして

new AudioContext()

により新しく生成し、そのオブジェクトの1変数として、次のスクリプトでは audioCtx を定義している。

次のHTMLファイルをChromeに読み込ませると、JavaScript により440ヘルツの単音が出続ける。出力ハードウェアは、oscillator.connect(gainNode)とgainNode.connect=audioCtx.destination)で指定している。周波数はoscillator.frequency.valueの値で決まる。

440Hz

<!DOCTYPE html>
<html>
<body>
<script>
	var audioCtx = new AudioContext();
	var oscillator = audioCtx.createOscillator();
	var gainNode = audioCtx.createGain();

	oscillator.connect(gainNode);
	gainNode.connect(audioCtx.destination);

	oscillator.type = 'sin';
	oscillator.frequency.value = 440;
	oscillator.start();
</script>
</body>
</html>

Violent Theremin

GitHubの[ここに] (https://github.com/mdn/violent-theremin) Web Audio API と HTML5 を使った良い例がある。

Web Audio API

使い方

ビートルズ「ハード・デイズ・ナイト」

『アルゴリズムが世界を支配する』の「ビートルズの謎を解く」にあるハード・デイズ・ナイトの冒頭のギターサウンドをAudioContextで再現することはできるだろうか、市販の楽譜がまちがっているらしくやはり無理だろうか。

ギターはハリスンの12弦ギターらしい。

George Harrison Yahoo! Chat Transcript
02/15/2001

a_t_m98 asks: Mr. Harrison.. what is the opening chord you used for "A Hard Days Night"?

george_harrison_live: It is F with a G on top (on the 12-string)

george_harrison_live: But you'll have to ask Paul about the bass note to get the proper story.


15パズル

Wikipedia にある 15-puzzle の解説

15パズルのJavaScript

p15.js のファイル名で保存する。

var board, zx, zy, clicks, possibles, clickCounter, oldzx = -1, oldzy = -1;
function getPossibles() {
    var ii, jj, cx = [-1, 0, 1, 0], cy = [0, -1, 0, 1];
    possibles = [];
    for( var i = 0; i < 4; i++ ) {
        ii = zx + cx[i]; jj = zy + cy[i];
        if( ii < 0 || ii > 3 || jj < 0 || jj > 3 ) continue;
        possibles.push( { x: ii, y: jj } );
    }
}
function updateBtns() {
    var b, v, id;
    for( var j = 0; j < 4; j++ ) {
        for( var i = 0; i < 4; i++ ) {
            id = "btn" + ( i + j * 4 );
            b = document.getElementById( id );
            v = board[i][j];
            if( v < 16 ) {
                b.innerHTML = ( "" + v );
                b.className = "button"
            }
            else {
                b.innerHTML = ( "" );
                b.className = "empty";
            }
        }
    }
    clickCounter.innerHTML = "Clicks: " + clicks;
}
function shuffle() {
    var v = 0, t; 
    do {
        getPossibles();
        while( true ) {
            t = possibles[Math.floor( Math.random() * possibles.length )];
            console.log( t.x, oldzx, t.y, oldzy )
            if( t.x != oldzx || t.y != oldzy ) break;
        }
        oldzx = zx; oldzy = zy;
        board[zx][zy] = board[t.x][t.y];
        zx = t.x; zy = t.y;
        board[zx][zy] = 16; 
    } while( ++v < 200 );
}
function restart() {
    shuffle();
    clicks = 0;
    updateBtns();
}
function checkFinished() {
    var a = 0;
    for( var j = 0; j < 4; j++ ) {
        for( var i = 0; i < 4; i++ ) {
            if( board[i][j] < a ) return false;
            a = board[i][j];
        }
    }
    return true;
}
function btnHandle( e ) {
    getPossibles();
    var c = e.target.i, r = e.target.j, p = -1;
    for( var i = 0; i < possibles.length; i++ ) {
        if( possibles[i].x == c && possibles[i].y == r ) {
            p = i;
            break;
        }
    }
    if( p > -1 ) {
        clicks++;
        var t = possibles[p];
        board[zx][zy] = board[t.x][t.y];
        zx = t.x; zy = t.y;
        board[zx][zy] = 16;
        updateBtns();
        if( checkFinished() ) {
            alert( "WELL DONE!" );
            restart();
        }
    }
}
function createBoard() {
    board = new Array( 4 );
    for( var i = 0; i < 4; i++ ) {
        board[i] = new Array( 4 );
    }
    for( var j = 0; j < 4; j++ ) {
        for( var i = 0; i < 4; i++ ) {
            board[i][j] = ( i + j * 4 ) + 1;
        }
    }
    zx = zy = 3; board[zx][zy] = 16;
}
function createBtns() {
    var b, d = document.createElement( "div" );
    d.className += "board";
    document.body.appendChild( d );
    for( var j = 0; j < 4; j++ ) {
        for( var i = 0; i < 4; i++ ) {
            b = document.createElement( "button" );
            b.id = "btn" + ( i + j * 4 );
            b.i = i; b.j = j;
            b.addEventListener( "click", btnHandle, false );
            b.appendChild( document.createTextNode( "" ) );
            d.appendChild( b );
        }
    }
    clickCounter = document.createElement( "p" );
    clickCounter.className += "txt";
    document.body.appendChild( clickCounter );
}
function start() {
    createBtns();
    createBoard();
    restart();
}

HTMLファイル

JavaScript で書いたプログラム「p15.js」を読み込むHTMLファイル。これが15パズルの本体である。

<!DOCTYPE html>
<html><head><meta charset="UTF-8">
<title>15 Puzzle</title>
<script src="p15.js"></script>
<style>
    html,body{padding:0; margin:0;padding-top:8vh;background:#222;color:#111}
    .txt{color:#fff;text-align:center;font-size:5vh}
    .board{padding:0;margin:auto;width:33vh;height:33vh}
    .button, .empty{border:0;font-size:3.5vh;margin:0.5vh;padding:0;height:6vh;width:7.25vh;line-height:5vh;
    vertical-align:middle;background:#fff;text-align:center;border-radius:3px;cursor:pointer;float:left}
    .empty{background:#333;border:1px solid #111}
</style>
</head><body onload="start()"></body></html>

このファイルを「p15.html」の名前で、「p15.js」と同じフォルダに保存する。 Chromeを起動して、このp15.htmlを読み込ませてみよう。

15 パズル

練習問題

15パズルのタイルの色を選んで変えて実行できるようにしてみよう。

15 パズルを解くためのアルゴリズム

  • 12を左上の最終位置に移動する。

  • a. 駒は、空きが動かしたい駒の隣にできるように動かす。

  • b. 動かしたい駒を空きに移動する。

  • a, b の操作を、12が正しい位置になるまで反復する。

  • 次に34を目標にする。

  • 43の最終位置へ動かす。

  • 34の直下へ動かす。

Imgur

  • 34を最終位置へ動かす。

  • 右上を空ける。

  • 34がつながれた駒のように動かして空きに入れる。

  • 56を最終位置へ移動する。

  • 56を見付ける。

  • 12」と同じやり方で最終位置へ動かす。

Imgur

  • 78を最終位置へ移動する。
  • 87の最終位置へ持っていく。
  • 78の直下へ動かす。
  • 8の右に空きをつくる。
  • 87がつながれた駒のように動かして空きに入れる。
    Imgur

Imgur

  • 139を次のように動かしセットする。
  • 139の最終位置に動かす。
  • 913の右に動かす。

Imgur

  • 139を最終位置へ動かす。

  • 5つの駒がつながれたように反時計回りに動かす。

Imgur

  • 1410を次のように動かしセットする。

  • 149の右位置(10の最終位置)へ動かす。

  • 1014の右へ動かす。
    Imgur

  • 1410を最終位置へ動かす。

Imgur

  • 完成形

  • 1112を反時計回りに回して正しい位置にセットする。

wikiHow to solve a 15 puzzle

練習問題 ジグソーパズル

1から14までの数字のかわりに、駒に図形などを描きジグソーパズルをつくる。

練習問題 モバイル端末で動かす

Windowsのコンピュータだけでなく、アンドロイドやアイフォーンの端末で15パズルを動かしてみる。

14-15 PUZZLE

From the history of the 15 puzzle.

解法が存在しないパターンがある

15パズルは、駒を盤上ですべらせて動かし、最後に右下隅を空けた状態になれば完成である。駒を盤上から取り上げて動かしてはいけない。

盤面1

 6  1 10  2
 7 11  4 14
 5     9 15
 8 12 13  3

盤面2(完成)

 1  2  3  4
 5  6  7  8
 9 10 11 12
13 14 15

盤面3

 1  2  3  4
 5  6  7  8
 9 10 11 12
13 15 14

例えば14と15をひっくり返した盤面3の15パズルは解けない。

解法が存在するかしないかを調べるために盤のマス目を横に並べて考えることにする。

盤面4

 7  2  6  3
 9  1 10 15    7  2  6  3  9  1 10 15  8 13    12 11  4  5 14
 8 13    12
11  4  5 14

盤上に駒を置くかわりに、右上を左端に置きあとその右へ順に横1列に駒を並べる。

ここで、ある駒とその右の駒についての関係「逆転」を定義する。

逆転駒の数とは、その駒の後にある自分より小さい駒の個数である。盤面2のように完成すると逆転駒数はゼロである。盤面3の逆転駒数は1である。

逆転駒数の奇偶と、その盤面が解けるか解けないかが関係していることが知られている。

例えば、盤面4の場合について逆転駒の数を数える。駒のペアを(a,b)とするとき、aのあとにくる駒bで、a>bの関係が成り立つ駒bを数える。

  • 7の逆転駒数は6。(2,6,3,1,4,5)
  • 2は1
  • 6は4
  • 3は1
  • 9は4
  • 1は0
  • 10は3
  • 15は7
  • 8は2
  • 13は4
  • 12は3
  • 11は2
  • 4は0
  • 5は0

したがって、31。

この15パズルをのマス目4x4を2x2、3x3、5x5…と一般化したゲームに関して、次のような公式が知られている。

Solvability of the Tiles Game

a. ボードの幅が奇数のとき、逆転駒の数が偶数のとき解ける。
b. ボードの幅が偶数のとき、もし空白が下から数えて偶数行にあるなら、逆転駒の数が奇数のとき解ける。
c. ボードの幅が偶数のとき、もし空白が下から数えて奇数行にあるなら、逆転駒の数が偶数のとき解ける。

これを記号化すると次のような論理式になる。

((奇数幅)&&(逆転駒偶数)) || ((偶数幅)&&((空白奇数行)==(逆転駒偶数)))

この公式は、Kevin Gongがウェブに証明をのせている。


絵をならべかえる

アクションゲームの作り方

参考リンク 15 PUZZLE Algorithm and Solver


2048 Game

次のGithubのHTMLソースコードを動かしてみよう。ソースコードの修正で、タイルの色を変更することもできる。

Java で書いたプログラム


5目並べ

GitHubのこのgomokuをやってみよう。

このサイト Gomoku JS には、JavaScript、 CSS、 HTML のコードがそれぞれ掲載されているため、コード作成時に参考になる。


ボードゲーム

JavaScript でボードゲームを動かす。3目並べ(tic-tac-toe)、コーンウェイのライフゲーム(Game of Life)など。

danielborowski/jsboard

jsboardは、jQueryなどのJavaScriptライブラリーを使っていない。したがって、HTMLとJavaScriptファイルだけでゲームを作れる。

Github にある上のリンクからファイルをまとめてダウンロードする。次にダウンロードされたファイル jsboard-master.zip を解凍する。解凍するとexamplesとimagesディレクトリの他に、HTMLファイルは、index.htmlがひとつ出る。JavaScriptファイルは、 jsboard.jsとjsboard.min.jsの2つが出る。

examples - tictactoe.js などのJavaScript
images   - チェスの駒など
index.html - HTML
jsboard.js - JavaScript
jsboard.min.js - JavaScript

準備

ファイル index.html

<html>
<head>
  <title>Title</title>
</head>
<body>
  <table id='game'></table>
  <script src="jsboard.min.js"></script>
  <script src="index.js"></script>
</body>
</html>

ファイル index.js

空のファイル

はじめる

ライブラリ jsboardを利用する。

ボードとピースの例

var b = jsboard.board({ attach: "game", size: "3x3" });
var x = jsboard.piece({ text: "X", fontSize: "40px", textAlign: "center" });

テスト1

ブラウザでindex.htmlを開く。縦横3×3のボードが表示されただろうか。

ボードに機能性をもたせる

最初、3×3のボードには何もない。このボードのピースを1箇所クリックすれば、そのピースに何かを置くようにする。

b.cell("each").on("click", function() {
  if (b.cell(this).get()===null) {
    b.cell(this).place(x.clone());
  }
});

この例では、X印を置く。

それでは、3目並べのボードを作ろう。XとOの印が付いたピースを交互に置くようにする。

index.jsである。

var b = jsboard.board({ attach: "game", size: "3x3" });
var x = jsboard.piece({ text: "X", fontSize: "40px", textAlign: "center" });
var o = jsboard.piece({ text: "O", fontSize: "40px", textAlign: "center"});

var turn = true;
b.cell("each").on("click", function() {
  if (b.cell(this).get()===null) {
    if (turn) { b.cell(this).place(x.clone()); }
    else      { b.cell(this).place(o.clone()); }
    turn = !turn;
  }
});

ボード全体とセルのスタイルを変えることもできる。

b.style({ borderSpacing: "8px" });
b.cell("each").style({ 
  width: "75px", 
  height: "75px", 
  background: "lightblue", 
  borderRadius: "15px" 
});

RSA暗号

RSA暗号のプログラム


ホントの蛇足

ブラウザだけで、ブラウザのURL入力フィールドに何か文字列を入れて、JavaScriptを動かす方法はないだろうか。

Chrome

次のコードを、Chromeのアドレスバー(URL)に入力する。

javascript:[console.log("できた!")]

すると、どうなるだろうか。

次のような窓が開けば成功だ。

できた!


W3C JavaScript Quiz

リンク先にある25問のJavaScriptのクイズをやってみよう。

Javascript Quiz Test

25問解き終わると、画面に正答率と経過時間が出力される。スクリーンショットを取っておこう。間違いをチェックして、再度挑戦してみるのもいい。