センター試験「情報関係基礎」2007年のブロック落としをJavaScriptで書く
センター試験「情報関係基礎」2007年の第3問をJavaScriptで書いてみた。
問題と,CindyScript,Python で書いた話はつぎの note にあるので,参照しながら読み進めてもらうのがよいだろう。
JavaScript は,Pythonと同様,初心者でわからないことだらけ。1日かかったが満足のいくものにはならなかった。
まず,開発環境に慣れていない。テキストエディタでソースを書き,デバッグはブラウザの開発ツールを使うのだが,これがわからないことばかり。
初心者といっても,HTMLに書くぐらいは知っている。授業をやったから。
ともかく,表示は後回しにしてリスト処理だけでできる calc() と drop() を書く。
JavaScriptの書法はCindyScriptに近い。コメント文は // だし,行末にはセミコロン。ブロックの書き方もほぼ同じ。
関数 isop()
まず,「演算ブロック」と「数ブロック」の判定。演算ブロックの判定をするために,やはり isop() 関数を作った。
真偽値は True / False か true / false か,そこから調べなければならない。コードを書く上では使わないが,知っておく必要はある。Python はTrue / False,CindyScript と JavaScript はtrue / false だ。
動作を確かめるために,document.write() で表示してみる。
function isop(block){
var ret = false;
if (block == "+" || block == "-" || block == "×"){
ret = true;
}
return true;
}
docment.write(isop("+"));
エラー。開発ツールで表示してみると次のようになっている。
function isop(block){ の定義がおかしい?
console.log でコンソールに表示してみる。
いろいろやり直してみる。
エラーが消えない。
ばかだった。document のつづりが間違っている。生徒と同じレベルだ。
一昨年,教科書のプログラムをもとに,授業で扱ったときに,綴り間違いで動かない例が結構あった。簡単なエラーなのに,気がつきにくい。
この例は,Can't find variable : docment とアラートがでているからましな方。何がエラーなのか理解に苦しむこと多数。上のように,エラー箇所をちゃんとは示してくれないからだ。ちなみに,これは Safari の開発ツールで「JavaScriptコンソールを表示」したもの。
結局,この形に落ち着く。
function isop(block){
return (block == "+" || block == "-" || block == "×")
}
なお,今までと違って,かけ算ブロックは "*" ではなく"×"だ。
「×」は漢字入力なので,あまりやりたくないのだが,表示の都合上,最終的にこの形になった。(後述)
なぜ漢字入力にしたくないか。授業でやると,×を書いたあと半角入力モードに戻さずにそのあとを書いてエラー,という例が続出するからだ。
関数 calc()
isop() を作って「演算ブロック」の判定はできた。数ブロックの判定:整数かどうか:は,調べた結果,typeof() を使った。
AND や OR も,言語によって違う。情報の教科書の例題では使っていないから改めて調べなければならない。CindyScriptは 「A & B」あるいは「and(A,B)」,Python は「A and B」,JavaScript は「A && B」だ。
// 計算を実行し,計算回数を返す
function calc(){
var ret = 0;
for (x = 1; x < 7; x++){
if (typeof(T[0][x-1]) == "number" && isop(T[0][x]) && typeof(T[0][x+1]) == "number"){
if (T[0][x] == "+" ){
T[0][x] = T[0][x-1] + T[0][x+1]
}
else if (T[0][x] == "×"){
T[0][x] = T[0][x-1] * T[0][x+1]
}
else if (T[0][x] == "-"){
T[0][x] = T[0][x-1] - T[0][x+1]
}
T[0][x-1] = " ";
T[0][x+1] = " ";
ret = ret + 1;
keisan = keisan + 1;
kosuu = kosuu - 2;
}
}
return ret;
}
Python で起こった,変数のスコープの問題は生じなかった。
関数 drop()
// ブロックを下に落とす
function drop(){
for (x = 0 ; x < 8; x++){
if (T[0][x] == " "){
for ( y = 0 ; y < 3 ; y++){
T[y][x] = T[y+1][x];
}
T[3][x] = " ";
}
}
}
これはほとんど問題なし。
画面表示
ここがPythonと同様,予想された難関。
JavaScriptでの図形描画についてWebで調べる。入門書として「改訂新版 JavaScript 本格入門」(山田祥寛:技術評論社)を持っているが,載っていない。Web上では,Canvas を使う方法がいくつか見つかる。しかし,表を作るための線分の書き方,その中に文字を表示する方法で簡単なものが見つからない。
では,Python のときのように,表にしたらどうか。
「Javascript】表(table)の動的作成」というページがあった。
2次元の配列データから表をつくる,ということで使えそうだ。
ソースを読んで,まねしてみる。
// 表の作成
function makeTable(list,tableId){
var rows=[];
var tbl = document.createElement("table");
// 表に2次元配列の要素を格納
for(i = 3; i >=0; i--){
rows.push(tbl.insertRow(-1)); // 行の追加
for(j = 0; j < 8; j++){
cell=rows[3-i].insertCell(-1);
cell.appendChild(document.createTextNode(list[i][j]));
cell.style.backgroundColor = "#ddd";
}
}
// 指定したdiv要素に表を加える
document.getElementById(tableId).appendChild(tbl);
}
// 表の動的作成
function dispblock(){
window.onload = function(){
makeTable(T,"table1");
};
};
表はできたが,今までの配列データだと次のようになる。
「空」を "" にしているからだ。
そこで,前述のように,「空」を " " と全角スペースにした。
全角スペースは禁じ手だろうが,ひとまずしかたがない。
"空"にすると次のようになるからよくない。
ついでに,"*" も "×" にした。
さて,これでそれらしい形はできた。
しかし,初期状態と出来上がり図の両方を表示するのがうまくいかない。
HTML の table と,document.createElement メソッドをちゃんと理解していないから応用が利かないのだ。
というわけで,ま,やってみた,という話でおわり。