オセロプログラムの話11

オブジェクト指向っぽくオセロを作る(まとめ)で作ったプログラムをもう少し発展させます。まず、駒を置いた箇所をハイライトする機能を作ります。次に、ここで作った駒をハイライトするという機能を使い、自分の番が回ってきたとき、駒が置ける場所をハイライトするという機能を作ります。これによって、より視覚的に面白いオセロゲームになります。

highlightメソッドの導入

まずは以下のようなハイライトメソッドをViewオブジェクトに追加

//Viewオブジェクト内

/**
 * 指定した駒を指定した色でハイライトする(公開)
 * colorはcssで使っているのと同じ値が指定できる
 */
function highlight(x,y,color){
    if (!board) 
        throw new Error("board is null/undefined. please call setBoard method before paint.");
    var board_element = document.getElementById("board");
	var element = getElement(x,y);
	if (element && color && board_element) {
		board_element.removeChild(element);
		element.style.backgroundColor = color;
		//element.style.border = "1px solid "+color;
		var child = element.firstChild;
		while (child.nodeType != 1 && child){ //firstChildのクロスブラウザ対策
			child=child.nextSibling;
		}						
		child.style.left = "2px";
		child.style.top = "2px";
		child.style.width = "29px";
		child.style.height = "29px";
		board_element.appendChild(element);
	}
}

次にOthelloオブジェクトの駒をひっくり返すようのメソッドdoFlip内で、駒を置いた後に、以下のようにしてhighlightメソッドを呼び出し。

//OthelloオブジェクトのdoFlipメソッド内

board.setPiece(piece, x, y); //最後に中央に駒を置く
view.paint(); //まずは普通に盤を描写
view.highlight(x,y,"red"); //指定した座標だけハイライト

これで、指定した駒の回りが赤くなります。

paintメソッドも変更

Viewオブジェクトのpaintメソッドでは、駒を描写するとき、オセロの盤の変更があったセルだけ駒を再描写していました。しかし、ハイライトされた部分も次のターンでは、再描写しなくてはいけなくなります。ハイライト部分が変更されたのをチェックする処理が面倒だったので、毎ターン、全てのセルを描写しなおすように変更します。

//Viewオブジェクト内

/**
 * boardの情報を実際に盤として描写するための処理(外部公開)
 */
function paint(){
    if (!board) 
        throw new Error("board is null/undefined. please call setBoard method before paint.");
    var board_element = document.getElementById("board");
	board_element.innerHTML ="";
    for (var y = 0; y < 8; y++) {
        for (var x = 0; x < 8; x++) {
            var nPiece = board.getPiece(x, y);
            var nType = getPieceType(nPiece); //boardオブジェクトの示す駒の種類
            //新たに追加するDOM要素を作る
            var nElement = makeElement(nType, x, y);
            //イベントを埋め込む
            (function(){
                var _x = x, _y = y, _othello = othello;
                nElement.onclick = function(){
                    _othello.selectEvent(_x, _y);
                };
            })();
            //最後にDOMツリーに追加
            if (nElement) {
                board_element.appendChild(nElement);
            }
        }
    }
}

駒を置ける場所をハイライト

次に、先ほど作ったハイライトの機能を使って、自分のターンがまわってきたとき、駒を置ける場所をハイライトしてくれる機能を追加します。ここではこれをアシストモードと呼びます。ターンを変更するための処理は、もともとOthelloオブジェクトのchangeTurnメソッドで管理していました。ここで、ターンが回ってきたとき、駒を置く場所があるのか調べるという処理を記述していました。この部分を少し改造して、アシストモードが有効なら、駒を置く場所を探すのと同時に、駒が置けるならハイライトするという処理を入れました。なお、アシスタントモードが無効になっている場合、1つでも駒を置ける場所が見つかればよいので、1つでも駒を置ける場所を見つけた時点でループを抜けています。

var isAssist = true; //最初のほうでこの変数をtrueにしておく//OthelloオブジェクトのchangeTurnメソッド内

var canPut = false; //駒を置けるかどうか
checkLoop: for (var y = 0; y < 8; y++) {
    for (var x = 0; x < 8; x++) {
        var piece = turn.getPiece();
        if (0 < checkPiece(piece, x, y)) { //駒を置ける
			canPut = true;
            if( isAssist ){ //アシストモードが有効か
				view.highlight(x,y,"blue"); //ハイライトしていく.最後まで続ける
			}else{
				break checkLoop; //最後まで続けなくていい
			}
        }
    }
}
//以下に駒を置ける場合と置けない場合の分岐が続く
if(canPut)
	…
else{}

これを使うと、以下のようになりました。