HTA
ピクロス2017/08/13
HTAでピクロスを作ってみた。
picross.hta、main.js、style.cssを同じフォルダに配置し、picross.htaを起動することで動作する。
起動するとマス数を入力するプロンプトが表示される。

数字を入力しOKを押下するとメイン画面が表示される。

マスを左クリックすると開けることができ、右クリックすると空白マスとして開けることができる。

checkボタンを押すと正解不正解の判定を行うことができる。

answerボタンを押すと正解を確認することができる。

rボタンを押すと、マス数を入力するプロンプトが表示され、再度新しく開始することができる。
<!DOCTYPE html>
<html="ja">
<head>
<HTA:APPLICATION SCROLL="no" />
<meta charset="utf-8">
<title>picross</title>
<script src="http://code.jquery.com/jquery-1.5.1.min.js"></script>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<table border="0" cellspacing="0" cellpadding="2" id="field"></table>
<input type="button" value="check" id="check"/>
<input type="button" value="answer" id="answer" />
<input type="button" value="r" id="reload" />
<script type="text/javascript" language="JavaScript" src="main.js"></script>
</body>
</html>
main.js
var tds = new Array(); // tdタグ配列
var field = $("#field"); // 表示フィールド
var tr; // trタグ生成用
var n; // 縦横のマス数
var masu_size = "22px"; // マスの縦横のpx数
var batu = "×"; // バツ印を設定
var color_gray = "#eee"; // 灰色を定義
// 0~numまでの乱数を返す(整数)
var randNum = function(num){
return(Math.floor(Math.random()*(num+1)));
}
n = prompt("n*nマスのnを入力してください。", 5); // クリックする部分のマス数
var len = Math.ceil(n/2); // 数字部の最大マス数
var max_len = n*1 + len*1; // マスの最大長(*1で文字列から数値に変換している)
//max_len = parseInt(n) + parseInt(len); // 本来はこうやる?
// タグ作成・初期化
for(var i=0; i<max_len; i++){ // 最大長分繰り返す
tr = $("<tr/>"); // trタグ生成
tds[i] = new Array(); // tdタブ用配列生成
for(var j=0; j<max_len; j++){ // 最大長分繰り返す
tds[i][j] = $("<td/>"); // tdタグ生成
tds[i][j].css("background",color_gray); // 背景を灰色に
if(i>=len && j>=len){ // 描画フィールドなら(クリックできるマス)
tds[i][j].value = randNum(2)>0?1:0; // ランダム(66%)にマスを設定
tds[i][j].css("border","1px solid #000") // 線を表示
.css("width", masu_size).css("height", masu_size) // 縦横のサイズを設定
.click( // 左クリックされたら
(function(){ // 一時関数宣言
var x = j; // jを保持
var y = i; // iを保持
tds[y][x].flag = false; // クリックフラグを初期化
return function(){ // クリックに反応するクロージャを返す
tds[y][x].flag = !tds[y][x].flag; // フラグを切り替え
tds[y][x].css("background", tds[y][x].flag?"#aaf":color_gray) // 背景をフラグが真なら青、偽なら灰色にする
.html(" "); // xが付いている場合があるので空白にする
};
})()
).bind('contextmenu', // 右クリックされたら
(function(){ // 一時関数宣言
var x = j; // jを保持
var y = i; // iを保持
return function(){ // クリックに反応するクロージャを返す
tds[y][x].flag = false; // フラグを切り替え
if(tds[y][x].html() == batu){ // バツが付いているなら
tds[y][x].css("background", color_gray) // 背景を灰色にする
.html(" "); // バツを取る
}
else { // バツが付いていないなら
tds[y][x].css("background", "#ee8") // 背景を黄色にする
.html(batu); // バツを付ける
}
return false; // 本来の右クリック抑止
};
})()
).html(" "); // 空白を設定
}
tr.append(tds[i][j]); // trに追加
}
field.append(tr); // フィールドに追加
}
var tmp_arr; // 数字部演算用
var temp_index; // 数字部演算用
// 左側数字部設定
for(var i=0; i<n; i++){ // マス数繰り返す
tmp_arr = new Array(); // 配列を生成
tmp_index = 0; // インデックスを初期化
tmp_arr[0] = 0; // 先頭要素初期化
for(var j=0; j<n; j++){ // マス数繰り返す
if(tds[len+i][len+j].value){ // 値が真(1)なら
if(tmp_arr[tmp_index] == undefined) // 未カウントなら
tmp_arr[tmp_index] = 1; // 1を設定
else // カウントされているなら
tmp_arr[tmp_index]++; // 記録用配列インクリメント
}else{ // 値が偽(0)なら
if(tmp_arr[tmp_index] > 0) // tmp_index番目の値が0より大きいなら(すでにカウントされている)
tmp_index++; // tmp_indexをインクリメント
}
}
for(var j=0; j<tmp_arr.length; j++){ // tmp_arrの要素数繰り返す
tds[i+len][len-j-1].html(tmp_arr[tmp_arr.length-1-j]) // 数字を設定
.css("width",masu_size); // 横幅を設定
}
}
// 上部数字部設定
for(var i=0; i<n; i++){ // マス数繰り返す
tmp_arr = new Array(); // 配列を生成
tmp_index = 0; // インデックスを初期化
tmp_arr[0] = 0; // 先頭要素初期化
for(var j=0; j<n; j++){ // マス数繰り返す
if(tds[len+j][len+i].value){ // 値が真(1)なら
if(tmp_arr[tmp_index] == undefined) // 未カウントなら
tmp_arr[tmp_index] = 1; // 1を設定
else // カウントされているなら
tmp_arr[tmp_index]++; // 記録用配列インクリメント
}else{ // 値が偽(0)なら
if(tmp_arr[tmp_index] > 0) // tmp_index番目の値が0より大きいなら
tmp_index++; // tmp_indexをインクリメント
}
}
for(var j=0; j<tmp_arr.length; j++){ // tmp_arrの要素数繰り返す
tds[len-1-j][len+i].html(tmp_arr[tmp_arr.length-1-j])// 数字を設定
.css("height",masu_size); // 高さを設定
}
}
// checkボタン設定
$("#check").click( // クリックされたら
function(){ // 一時関数宣言
for(var i=0; i<n; i++){ // マス数繰り返す
for(var j=0; j<n; j++){ // マス数繰り返す
if(tds[len+i][len+j].value != tds[len+i][len+j].flag) // 値とフラグが異なるなら(値は固定、フラグは左クリックで変わる)
break; // 途中でブレイク
}
if(j<n) // 途中でブレイクしているなら
break; // 途中でブレイク
}
alert((i==n && j==n)?"正解":"不正解"); // ループが最後まで回っていれば正解、途中で終わっていれば不正解
}
);
// answerボタン設定
$("#answer").click( // クリックされたら
(function(){ // 一時関数宣言
var f = false; // 表示フラグ初期化
return(
function(){ // クロージャ
f = !f; // フラグ切り替え
for(var i=0; i<n; i++)
for(var j=0; j<n; j++)
if(tds[len+i][len+j].value){ // valueが1なら(1=true)
tds[len+i][len+j].css("border",f?"4px solid #f22":"1px solid #000") // fが真なら赤太線、偽なら黒細線
.css("width",f?(parseInt(masu_size)-6)+"px":masu_size).css("height",f?(parseInt(masu_size)-6)+"px":masu_size); // 線分(2*(4px-1)=6px)変わる
}
}
);
})()
);
// rボタン設定
$("#reload").click(
function(){
location.reload(); // リロードする
}
);
style.css
#field{
border:1px solid #555;
margin:0px;
padding:0px;
background:#000;
font-size:14px;
}
#field tr{
margin:0px;
padding:0px;
}
#field td{
margin:0px;
padding:0px;
cursor: pointer;
text-align:center;
vertical-align:middle;
}
input {
margin-top:5px;
}