nounai.output(spaghetiThinking);

趣味と実益を兼ねて将棋プログラム(研究ツールなど)を作ってみたいと思う私の試行錯誤とか勉強したことを綴ってゆく予定です。 主目的はプログラミングの経験値稼ぎですが、コンピュータ将棋の製作も目指してみたいとも考えています。

HTML+JavaScript+jQueryで駒の利きを表示させてみた

そのまんま。
実装検討の一環として試作してみました。

クリックするとその駒の利きが黒く表示されます。 ただし、

  • 実装に「敵の駒」「駒台」の概念がない
  • 味方の駒を突き抜ける
  • もう一回クリックしたからってキャンセル操作みたく動いたりはしない
  • ↑よって、1回黒くなったマスはページ更新しないと戻せない
  • 実装したのは小駒のみ(大駒は定義がめんどいので)

…とまあ、ガッタガタの実装です。
やってること自体はクリックイベントと連動してCSSを書き換えるだけの処理なので、定義がめんどくさいこと以外はあんまりハードルではないです。DOM操作もjQueryのおかげで楽ちん。

↓が実物。よかったら動かしてみてください。

元のソースがこちら。

↓html

<!DOCTYPE html>
<html>
<head>
        <meta charset="utf-8">
        <title>Shogi</title>
        <script src="./jquery.js"></script>
</head>

<body>

<div id="Shogi">
        <div class="KomadaiGote">
                
        </div>

        <div class="Ban">
                <div class="Masu" style="position:absolute; top:0px; left:0px"></div>
                <div class="Masu" style="position:absolute; top:30px; left:0px"></div>
                <div class="Masu" style="position:absolute; top:60px; left:0px"></div>
                <div class="Masu" style="position:absolute; top:90px; left:0px"></div>
                <div class="Masu" style="position:absolute; top:120px; left:0px"></div>
                <div class="Masu" style="position:absolute; top:150px; left:0px"></div>
                <div class="Masu" style="position:absolute; top:180px; left:0px"><p class="Koma">歩</p></div>
                <div class="Masu" style="position:absolute; top:210px; left:0px"></div>
                <div class="Masu" style="position:absolute; top:240px; left:0px"><p class="Koma">香</p></div>
                
                <div class="Masu" style="position:absolute; top:0px; left:30px"></div>
                <div class="Masu" style="position:absolute; top:30px; left:30px"></div>
                <div class="Masu" style="position:absolute; top:60px; left:30px"></div>
                <div class="Masu" style="position:absolute; top:90px; left:30px"></div>
                <div class="Masu" style="position:absolute; top:120px; left:30px"></div>
                <div class="Masu" style="position:absolute; top:150px; left:30px"></div>
                <div class="Masu" style="position:absolute; top:180px; left:30px"><p class="Koma">歩</p></div>
                <div class="Masu" style="position:absolute; top:210px; left:30px"><p class="Koma">角</p></div>
                <div class="Masu" style="position:absolute; top:240px; left:30px"><p class="Koma">桂</p></div>
                
                <div class="Masu" style="position:absolute; top:0px; left:60px"></div>
                <div class="Masu" style="position:absolute; top:30px; left:60px"></div>
                <div class="Masu" style="position:absolute; top:60px; left:60px"></div>
                <div class="Masu" style="position:absolute; top:90px; left:60px"></div>
                <div class="Masu" style="position:absolute; top:120px; left:60px"></div>
                <div class="Masu" style="position:absolute; top:150px; left:60px"></div>
                <div class="Masu" style="position:absolute; top:180px; left:60px"><p class="Koma">歩</p></div>
                <div class="Masu" style="position:absolute; top:210px; left:60px"></div>
                <div class="Masu" style="position:absolute; top:240px; left:60px"><p class="Koma">銀</p></div>
                
                <div class="Masu" style="position:absolute; top:0px; left:90px"></div>
                <div class="Masu" style="position:absolute; top:30px; left:90px"></div>
                <div class="Masu" style="position:absolute; top:60px; left:90px"></div>
                <div class="Masu" style="position:absolute; top:90px; left:90px"></div>
                <div class="Masu" style="position:absolute; top:120px; left:90px"></div>
                <div class="Masu" style="position:absolute; top:150px; left:90px"></div>
                <div class="Masu" style="position:absolute; top:180px; left:90px"><p class="Koma">歩</p></div>
                <div class="Masu" style="position:absolute; top:210px; left:90px"></div>
                <div class="Masu" style="position:absolute; top:240px; left:90px"><p class="Koma">金</p></div>
                
                <div class="Masu" style="position:absolute; top:0px; left:120px"></div>
                <div class="Masu" style="position:absolute; top:30px; left:120px"></div>
                <div class="Masu" style="position:absolute; top:60px; left:120px"></div>
                <div class="Masu" style="position:absolute; top:90px; left:120px"></div>
                <div class="Masu" style="position:absolute; top:120px; left:120px"></div>
                <div class="Masu" style="position:absolute; top:150px; left:120px"></div>
                <div class="Masu" style="position:absolute; top:180px; left:120px"><p class="Koma">歩</p></div>
                <div class="Masu" style="position:absolute; top:210px; left:120px"></div>
                <div class="Masu" style="position:absolute; top:240px; left:120px"><p class="Koma">玉</p></div>                
                
                <div class="Masu" style="position:absolute; top:0px; left:150px"></div>
                <div class="Masu" style="position:absolute; top:30px; left:150px"></div>
                <div class="Masu" style="position:absolute; top:60px; left:150px"></div>
                <div class="Masu" style="position:absolute; top:90px; left:150px"></div>
                <div class="Masu" style="position:absolute; top:120px; left:150px"></div>
                <div class="Masu" style="position:absolute; top:150px; left:150px"></div>
                <div class="Masu" style="position:absolute; top:180px; left:150px"><p class="Koma">歩</p></div>
                <div class="Masu" style="position:absolute; top:210px; left:150px"></div>
                <div class="Masu" style="position:absolute; top:240px; left:150px"><p class="Koma">金</p></div>
                
                <div class="Masu" style="position:absolute; top:0px; left:180px"></div>
                <div class="Masu" style="position:absolute; top:30px; left:180px"></div>
                <div class="Masu" style="position:absolute; top:60px; left:180px"></div>
                <div class="Masu" style="position:absolute; top:90px; left:180px"></div>
                <div class="Masu" style="position:absolute; top:120px; left:180px"></div>
                <div class="Masu" style="position:absolute; top:150px; left:180px"></div>
                <div class="Masu" style="position:absolute; top:180px; left:180px"><p class="Koma">歩</p></div>
                <div class="Masu" style="position:absolute; top:210px; left:180px"></div>
                <div class="Masu" style="position:absolute; top:240px; left:180px"><p class="Koma">銀</p></div>
                
                <div class="Masu" style="position:absolute; top:0px; left:210px"></div>
                <div class="Masu" style="position:absolute; top:30px; left:210px"></div>
                <div class="Masu" style="position:absolute; top:60px; left:210px"></div>
                <div class="Masu" style="position:absolute; top:90px; left:210px"></div>
                <div class="Masu" style="position:absolute; top:120px; left:210px"></div>
                <div class="Masu" style="position:absolute; top:150px; left:210px"></div>
                <div class="Masu" style="position:absolute; top:180px; left:210px"><p class="Koma">歩</p></div>
                <div class="Masu" style="position:absolute; top:210px; left:210px"></div>
                <div class="Masu" style="position:absolute; top:240px; left:210px"><p class="Koma">桂</p></div>
                
                <div class="Masu" style="position:absolute; top:0px; left:240px"></div>
                <div class="Masu" style="position:absolute; top:30px; left:240px"></div>
                <div class="Masu" style="position:absolute; top:60px; left:240px"></div>
                <div class="Masu" style="position:absolute; top:90px; left:240px"></div>
                <div class="Masu" style="position:absolute; top:120px; left:240px"></div>
                <div class="Masu" style="position:absolute; top:150px; left:240px"></div>
                <div class="Masu" style="position:absolute; top:180px; left:240px"><p class="Koma">歩</p></div>
                <div class="Masu" style="position:absolute; top:210px; left:240px"></div>
                <div class="Masu" style="position:absolute; top:240px; left:240px"><p class="Koma">香</p></div>
        </div>

        <div class="KomadaiSente">
        
        </div>
</div>

</body>
</html>

css

        html, body{
                height: 100%;
                width: 100%;
                background: rgba(236,236,236,1.0);
        }
        
        div#Shogi{
                position: absolute;
                top: 0;
                left: 0;
                width: 390px;
                height: 270px;1
                overflow: hidden;
                display: block;
                background: rgba(255,255,255,0);
                z-index: 10;
        }
        
        .Ban{
                position:absolute;
                top: 0px;
                left: 60px;
                width: 270px;
                height: 270px;
                border-width: 1px;
                border-style: solid;
                margin: -1px;
                z-index: 20;
        }
        .KomadaiGote{
                position: absolute;
                background: rgba(0,255,0,0.1);
                top:0px;
                left: 0px;
                width: 60px;
                height: 270px;
                z-index: 20;
        }
        .KomadaiSente{
                position: absolute;
                background: rgba(0,0,255,0.1);
                top: 0px;
                left: 330px;
                width: 60px;
                height: 270px;
                z-index: 20;
        }
        .Masu{
                position: absolute;
                width: 30px;
                height: 30px;
                border-width: 1px;
                border-top-style: solid;
                border-left-style: solid;
                margin: -1px;
                overflow: hidden;
                z-index: 30;
        }
        p.Koma{
                position: relative;
                margin: 0;
                padding: 0;
                line-height:30px;
                text-align: center;
        }

JavaScript (with jQuery)

$(function(){
        $("p.Koma").click(function(e){
                var name = $(this).text();
                console.log($(this).parent());
                
                var top = Number($(this).parent().css("top").replace(/px/,''));
                var left = Number($(this).parent().css("left").replace(/px/,''));
                
                var rel = [];
                switch(name){
                        case "歩":
                                rel.push([0,-1]);
                                break;
                        case "香":
                                rel.push([0,-1]);
                                rel.push([0,-2]);
                                rel.push([0,-3]);
                                rel.push([0,-4]);
                                rel.push([0,-5]);
                                rel.push([0,-6]);
                                rel.push([0,-7]);
                                rel.push([0,-8]);
                                break;
                        case "桂":
                                rel.push([+1,-2]);
                                rel.push([-1,-2]);
                                break;
                        case "銀":
                                rel.push([0,-1]);
                                rel.push([-1, -1]);
                                rel.push([+1, -1]);
                                rel.push([+1, +1]);
                                rel.push([-1, +1]);
                        case "金":
                                rel.push([0,-1]);
                                rel.push([-1, -1]);
                                rel.push([+1, -1]);
                                rel.push([-1, 0]);
                                rel.push([+1, 0]);
                                rel.push([0, +1]);
                                break;
                        case "玉":
                                rel.push([-1, -1]);
                                rel.push([-1, 0]);
                                rel.push([-1, +1]);
                                rel.push([0, -1]);
                                rel.push([0, +1]);
                                rel.push([+1, -1]);
                                rel.push([+1, 0]);
                                rel.push([+1, +1]);
                                break;
                        default: break;
                }

                for(var i=0; i<rel.length; i++){
                        var x = rel[i][0]*30;
                        var y = rel[i][1]*30;
                        
                        $(".Masu").each(function(){
                                var t = Number($(this).css("top").replace(/px/,''));
                                var l = Number($(this).css("left").replace(/px/,''));
                                if(top+y==t && left+x==l){
                                        $(this).css("background","rgba(0,0,0,0.5)");
                                }
                        });
                }
        });
});

ゲームは状態に関する定義の仕方とかが非常に難しいですね。 良し悪し見境なくやろうと思えば、実装方法なんていくらでもありますし。より良いやり方を!なんて考えてたら一向に収束しませんし。

BonanzaやらGPSやらうさぴょんやらソースを見るのが一番の勉強だとは思いますけど、私がやりたいのはどちらかというとUI寄りの話ですし、何より気力が足りない。実装のしかたも知りたいけど、私としては設計・実装した人が「なぜ」そうしたのか、って考え方の道筋が知りたいなぁ。