JavaScript (12) レイヤーで絵を重ねる

局面のオブジェクト Pos を使って、囲碁の局面をベクトルと行列で表し、着手禁止や取りの計算を行えるようにしました。goban04.js として公開します。
図12 Goban 0.4
【図12 Goban 0.4】

取った石をスマートに消したい。と思い、レイヤーのように Canvas を重ねる手法を使いました。碁盤上は石が近いので、影が重ならないよう、影のレイヤーも設けました。最初は CSS で position: relative; top : -480px としていたのですが、微妙にずれが生じます。しかも、Chrome と Firefox でずれの度合いが違うのでこの方法はやめにしました。position: relative と position: absolute を組み合わせて、どちらのブラウザでもうまく表示できるようになりました。

今回、JavaScript の囲碁のプログラムにオブジェクト Pos を初めて組み込んだわけですが、Java では全く気にならなかった計算速度が結構遅いことに気づきました。Google Chrome の JavaScript コンソールに Profiles という性能測定ツールがあるので、それを使って遅いところを書き直しました。それでも6ベクトルの計算は時間がかかるので、今回は取り外しました。

ということで、ブラウザの JavaScript エンジンの限界が早くも見えてきました。これで AI を組むのはちょっとつらそうです。JavaScript は iPad でも表示できるグラフィックスの部分に特化させ、AI は別の方法で走らせたほうがよさそうです。

今のところ選択肢を2つ考えています。ひとつは Ajax。Google マップなどで使われているサーバーとの非同期通信です。もうひとつは囲碁のプログラムでよく使われている GTP (Go Text Protocol) というプロトコルです。

サーバー側をどのようにするか、いろいろ調べてみたいと思います。

(つづく)

JavaScript (11) ボタンの設置

グラフ理論の取り込みがまだなのですが、[パス] ボタンを設置し、それなりに石を並べられるようになったので、goban03.js として公開します。
図11 Goban 0.3
【図11 Goban 0.3】

今回は HTML 上に、

<input id="white" type="button" value="パス Pass" onclick="pass()">

といったタグでボタンを作り、JavaScript のソースの中でボタンが押されたときの関数 pass() を定義しています。JavaScript の例題としては、非常にポピュラーな内容と言えるでしょう。

それから、Aptana Studio 3 を統合開発環境 (IDE) にすると、ブラウザは Firefox を使うように促されるのですが、Goban 0.2 では石が置けないことが判明しました。調べた結果、マウスイベントの処理方法がブラウザによって違うためと分かりました。なるべく修正が少なくなるよう、対応しました。

先日、iPad を購入したことを受け、Safari もダウンロードしてみたので、私の PC には、IE, Chrome, Safari, Firefox の4種類のブラウザがインストールされています。性能や機能が微妙に違うので、時と場合に応じて使い分けています。

JavaScript も EcmaScript という標準の仕様が出てきたものの、まだまだブラウザによって非互換もあるので、大変そうですが、なるべく基本的な機能を使って、どの環境でも動くプログラムが作れるようにしたいと思います。

とにかく、今作っている JavaScript プログラムは iPad で動いているので、そのことに関しては満足しています。Small Basic も Java アプレットも iPad では動きませんでしたから。

引き続き、Goban を改良していきます。

(つづく)


JavaScript (10) グラフ理論を用いた囲碁

囲碁の局面 (position) を表すオブジェクト Pos を Java から移植しました。関連するオブジェクトも合わせて移植しました。pos01.js として公開します。
図9 Pos 0.1 テキストでの表示
【図9 Pos 0.1 テキストでの表示】

図10 Pos 0.1 TeXでの表示
【図10 Pos 0.1 TeX での表示】

今回はテキストと TeX を両方表示するようにしました。結果が違っていたので、bmatrix01.js を修正し、bmatrix02.js としました。BMatrix.toString() の行と列の扱いが逆でした。マイナーチェンジなのでソースは公開しないことにします。

Java から Pos, Move, SixVectors の3つのクラスを JavaScript のオブジェクトに書き換えました。

Java から JavaScript への変換は比較的単純に行えます。主な作業は、

(1) int やクラスを var に書き換える。
(2) class の表記を prototype の表記に書き換える。
(3) オブジェクトの変数(プロパティ)に this. を付ける。

です。現在、Eclipse と Aptana Studio 3 という IDE (統合開発環境)を使っているのですが、なにか間違えていると、セミコロンが足りないというエラーが出ます。これを真に受けて足りないセミコロンを探して見つからないという経験をしました。こういうときは、Google Chrome の JavaScript コンソールでエラーをひとつずつつぶしていくのがいいと思います。this. を付け忘れると変数が未定義というエラーが出たり、int を残したままだと知らない用語だというエラーが出ます。これらをつぶせば、Eclipse や Aptana で出ていたセミコロンが足りないというエラーも解消されます。

ちなみに、Visual Web Developer 2010 Express Edition という IDE もチャレンジしましたが、インストールが一向に進まないので断念しました。SQL Server だけがインストールされて止まってしまいました。

IDE については、もう少し理解が進んだら記事を書こうと思います。

次回は、碁盤で囲碁が打てるようにしたいと思います。今回作った Pos オブジェクトを使う予定です。

(つづく)

JavaScript (9) 2進行列の演算

2進行列の演算についても JavaScript で書きました。bmatrix01.js として公開します。
図8 BMatrix 0.1
【図8 BMatrix 0.1】

今回、2進行列を仕上げるにあたり、『JavaScript本格入門』を参考にしました。

この本を参考にして変更した点は2つあります。

ひとつは配列リテラルを使うようにしたことです。行列の初期値に1を与える要素番号を、前回までは 'i, j' のように文字列で指定していました。これを i と j に分解するため eval 関数を使っていたのですが、今回は配列リテラルを使い [i, j] のように記述することで、i は [0] 、j は [1] と配列のインデックスで参照できるようになりました。eval を使わない分、安定的でかつコードも短くできました。ちなみにリテラルは数字や引用符で囲んだ文字列のような値そのものの表記のことをいいます。

もうひとつは prototype にメソッドを追加するときに、ひとつずつ

BMatrix.prototype.clear = function() { ... };
BMatrix.prototype.setValue = function(i, j, value) { ... };
...
BMatrix.prototype.toTeX = function() { ... };

と代入していくのではなく、

BMatrix.prototype = {
 clear : function() { ... },
 setValue : function(i, j, value) { ... },
 ...
 toTeX : function() { ... }
};

とひとまとめにしたことです。これで Java のクラスにメソッドを定義するときと似た記法になってきました。

ベクトル、行列とも定義できたので、これらを使い囲碁局面を表現していきたいと思います。

(つづく)

JavaScript (8) 2進ベクトルの演算

2進ベクトルの演算をひと通り JavaScript で書き直しました。bvector02.js として公開します。

図7 BVector 0.2
【図7 BVector 0.2】

今回は、MathJax で計算結果を整形してみました。JavaScript のプログラムならではの結果といえるでしょう。

最後のクロス積の結果は行列になります。したがって2進行列のほうの定義も進める必要がありました。

2進ベクトルができていたので、2進行列は一気に書き進めたのですが、デバッグに苦労しました。特に eval 関数が暴走して往生しました。eval 関数は事前に文法のチェックができないので、いくらでもおかしなことが発生します。システムが非常に重くなって何度も Google Chrome を立ち上げ直すはめに会いました。

eval 関数を使う場合は、予め評価する式を直接コーディングしてよく確かめてから eval 関数に渡すのがいいと思います。

行列のほうを書き上げて、グラフ理論による囲碁を JavaScript でも進めていく予定です。

JavaScript を勉強しながらなので、途中いろいろと脱線することもあると思います。

(つづく)

JavaScript (7) eval 関数

2進ベクトルオブジェクトの一部を JavaScript で実装してみました。bvector01.js で公開します。

図6 BVector 0.1
【図6 BVector 0.1】

Java で2進ベクトルを実装したときは、先に2進行列を定義し、2進ベクトルは2進行列を呼び出すことで実現していました。今回は逆にしようと思います。2進ベクトルを呼び出して2進行列を実現するほうがオーバーヘッドが少ないのではないかと思います。

今回この2進ベクトルオブジェクトをテストをするにあたり2つ工夫してみました。

1つは Google Chrome の「JavaScriptコンソール」を使う他に、Windows Script Host を利用したことです。Windows Script Host は以前は Windows Scripting Host (ウィンドウズ スクリプティング ホスト)と呼ばれていたもので、DOSのバッチファイルを Windows に対応させたようなものです。Windows Script Host (以下WSH)では、VBScript や JScript (マイクロソフトの JavaScript)などのスクリプト言語で Windows のプログラムを操作することができます。JavaScript を単体で動作させる環境にもなっています。

そこで、今回のプログラムでは writeln 関数を定義し、WSHの環境では、

function writeln(str) {
 WScript.Echo(str);
}

に書き換えることで、bvector01.js を実行できるようにしました。JavaScript に誤りがあると「JavaScriptコンソール」ではソースも表示できなくなることがあります。このときは、WSH で実行すると、行番号つきでエラーメッセージが表示されます。WSH 環境では HTML を作らずにテストができるので、いろいろ試してみるには便利だと思います。WSH はコマンドラインで、

CScript bvector01.js

とタイプすると実行できます。

もう1つは、Global オブジェクトの eval 関数を使ったことです。私が最初に eval 関数に出会ったのは Lisp という言語を勉強したときです。カッコだらけのプログラムができることで有名な言語ですが、JavaScript と同様、インタプリタ言語なので、その場でプログラムを評価実行する機能があります。今回は eval 関数をテストの部分に使うことで、コードを小さくできました。

引き続き2進ベクトルの実装を続けます。

(つづく)

JavaScript (6) オブジェクト指向

これまで作ったプログラムは私が馴染んでいるスクリプト言語、DOSのバッチ(古い...)や秀丸マクロ、VBAなどと同様、手続きや関数重視の作りになっていました。

Java にはクラスの概念があり、クラス毎にソースファイルを分ける、という明確なルールがあったのですが、JavaScript ではどうすればいいのか、JavaScript はオブジェクト指向プログラミング言語と聞いていたのに、クラスはないのか?と、ふと疑問に思い調べてみました。

JavaScript にはクラスの概念がないものの、Java と同様オブジェクト指向のプログラミングができるようです。さらに言えば、手続き指向でもオブジェクト指向でも、好きなほうを選べるようです。

Java でプログラミングをしていてオブジェクト指向の概念が馴染むなぁ、と思ったのはベクトルと行列の演算を作ったときでした。ベクトル、行列、それぞれのクラスに対し and(), or() メソッドを書いて、同じように呼び出せるので、数式を書くのと同じようにプログラミングができるなぁと関心したものです。

JavaScript では作成した関数オブジェクトの prototype プロパティに「メソッド」に当たる関数オブジェクトを作ることで、Java と同様のことができるようです。例えば Java で、

public class Vector2D {
 public int x;
 public int y;
 public Vector2D(int x, int y) {
  this.x = x;
  this.y = y;
 }
 public Vector2D add(Vector v) {
  Vector2D r = new Vector2D(0, 0);
  r.x = x + v.x;
  r.y = y + v.y;
  return r;
 }
}

と書いていたものを、JavaScript では、

var Vector2D = function(x, y) {
 this.x = x;
 this.y = y;
}
Vector2D.prototype.add = function(v) {
 var r = new Vector2D(0, 0);
 r.x = this.x + v.x;
 r.y = this.y + v.y;
 return r;
};

と書けばよいようです。

この知識を元に、2進ベクトルと2進行列のプログラムを書いてみようと思います。

(つづく)

«JavaScript (5) マウスのクリックで碁石を置く

フォト

つぶやき

無料ブログはココログ

ウェブ検索

  • 毎日の検索で環境貢献
    このパーツから
    Powered by

最近のトラックバック