1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

オストルのゲームAIを作る GUI編

Last updated at Posted at 2019-06-15

オストルのGUIをJavaScriptで作成しました。
連続した駒をオス処理は再帰を使って記述しました。

こちらで遊べます。
千日手ルールは未実装です。遊ぶ人が気を付けてください。

ostle.html
<html><head><meta charset="Shift_JIS">
<title>Ostle</title><script>
<!--
var canvas;  //オブジェクト
var ctx;     //コンテキスト
var nametbl=[
 "","",""
];
var x1=[ 0, -1, 0, 1];    //移動量x
var y1=[-1, 0, 1, 0];    //移動量y
var movtbl=[
    [ 1, 1, 1, 1 ], //0:■
    [ 1, 1, 1, 1 ], //1:□
    [ 1, 1, 1, 1 ], //2:●
];
var setup=[
    [  1,  1,  1,  1,  1],
    [ -1, -1, -1, -1, -1],
    [ -1, -1,  2, -1, -1],
    [ -1, -1, -1, -1, -1],
    [  0,  0,  0,  0,  0],
];
var fontcolor=["black","maroon"];    //文字の色
var boxcolor=["LimeGreen","gray" ,"blue" ,"red"];        //線の色
var fillcolor=["LimeGreen","Khaki","white","LightPink"];  //盤面の色
var psize=32;           //マスのピクセル数
var board=[];           //盤バッファ
var bw=7,bh=7;      //盤バッファのサイズ
var ofsx=1,ofsy=1;    //盤のオフセット座標
var turn=0;             //0=先手/1=後手
var startx=-1,starty=-1;   //選択した座標
var username=["ipad","iphone","android"];    //端末の名前
var playtbl=["先手","後手"];
var connect=0;
//盤の情報
function piece() {
    this.id=-1;         //駒の種類(-1=駒がない)
    this.player=0;      //駒の向き(0=先手/1=後手/2=穴)
    this.movable=false; //移動可能フラグ
}
//初期化処理
function init(){
    canvas=document.getElementById("world");
    canvas.width=psize*bw;
    canvas.height=psize*bh;
    ctx=canvas.getContext('2d');
    ctx.font="24px 'MS Pゴシック'";
    user=window.navigator.userAgent.toLowerCase();
    for(i=0; i<username.length; i++){
        if(user.indexOf(username[i]) > 0)break;
    }
    if(i < username.length){
        document.addEventListener("touchstart", touchstart);
    }else{
        document.addEventListener("mousedown", mousedown);
    }
    board=new Array(bh);
    for(y=0; y<bh; y++){
        board[y]=new Array(bw);
        for(x=0; x<bw; x++){
            board[y][x]=new piece();   //盤バッファの初期化
        }
    }
    for(x=0; x<5; x++){
        for(y=0; y<5; y++){
            board[ofsy+y][ofsx+x].id=setup[y][x];
            board[ofsy+y][ofsx+x].player=setup[y][x];
        }
    }
    redraw();    //画面全体を再描画
}
//スマホ/タブレット用のタッチイベント
function touchstart(e){
    if (e.targetTouches.length==1){
        touch=e.targetTouches[0];
        touchpiece(touch.pageX ,touch.pageY);
    }
}
//PC用のクリックイベント
function mousedown(e){
    touchpiece(e.clientX ,e.clientY);
}
//駒の移動処理
function touchpiece(tx,ty){
    cx=Math.floor((tx-8)/psize);
    cy=Math.floor((ty-8)/psize);
    if(isinside(cx,cy,0,0,bw,bh)==false)return;
    if(startx==-1){
        movestart(cx,cy);    //移動開始
    }else{
        moveend(cx,cy);      //移動終了
        startx=-1;
        redraw();    //画面全体を再描画
    }
}
//移動開始
function movestart(cx,cy){
    id=board[cy][cx].id;
    if(id==-1)return;    //駒が存在しないと無効
    player=board[cy][cx].player;
    if(!(player==turn || player==2))return;    //自分の駒と穴のみ動かせる
    startx=cx;
    starty=cy;
    drawpiece(startx,starty,id,player,2);    //駒を白色に
    if(isinside(startx,starty,ofsx,ofsy,5,5)==false){
        for(x=ofsx; x<(ofsx+5); x++){  //配置可能マスを描画
            for(y=ofsx; y<(ofsx+5); y++){  //配置可能マスを描画
                while(isinside(x,y,ofsx,ofsy,5,5)==true){
                    drawpiece(x,y,-1,0,3);
                    board[y][x].movable=true;
                }
            }
        }
    }
    for(dir=0; dir<4; dir++){    //移動可能マスを描画
        x=startx;
        y=starty;
        while(movtbl[id][dir] > 0){
            x +=x1[dir];
            y +=y1[dir];
            id2=board[y][x].id;
            player2=board[y][x].player;
            if(isinside(x,y,ofsx,ofsy,5,5)==false) break; //盤の外へ
            if((id==2) && (id2==0)) break;
            if((id==2) && (id2==1)) break;
            drawpiece(x,y,id2,player2,3);    //盤面を赤色に
            board[y][x].movable=true;
            if(movtbl[id][dir]==1) break;
        }
    }
}
//移動終了
function moveend(endx,endy){
    if(board[endy][endx].movable==false)return;    //移動不可能
    dx=endx - startx;
    dy=endy - starty;
    if(board[endy][endx].id==-1){    // 移動先が空白マスの場合
        board[endy][endx].id=board[starty][startx].id;
        board[endy][endx].player=board[starty][startx].player;
        board[starty][startx].id=-1;
        board[starty][startx].player=-1;
    }else if(board[endy][endx].id==2){    // 移動先が穴の場合
        board[starty][startx].id=-1;
        board[starty][startx].player=-1;
    }else if(isinside(endx,endy,ofsx,ofsy,5,5)==false){    // 移動先が盤外の場合
        board[starty][startx].id=-1;
        board[starty][startx].player=-1;
    }else if((board[endy][endx].id==0) || (board[endy][endx].id==1)){    // 移動先に駒がある場合
        // 1マス隣の駒を再帰処理する
        moveend(endx+dx,endy+dy)
    	// 押した駒を1マス隣にずらす
        board[endy][endx].id = board[starty][startx].id;
        board[endy][endx].player = board[starty][startx].player;
        // 押した駒があった場所を空白マスにする
        board[starty][startx].id = -1;
        board[starty][startx].player = -1;
    }
    turn ^=1;    // プレイヤーの切り替え
}
//駒を描画
function drawpiece(x,y,id,player,color){
    px=x*psize;
    py=y*psize;
    ctx.fillStyle=boxcolor[color];
    ctx.fillRect(px, py, psize, psize);
    ctx.fillStyle=fillcolor[color];
    ctx.fillRect(px+1, py+1, psize-2, psize-2);
    if(id==-1)return;
    ctx.fillStyle=fontcolor[(id >> 3)& 1];
    if(player){
        px=-px-psize;
        py=-py-psize;
        ctx.rotate(Math.PI);
    }
    ctx.fillText(nametbl[id],px+4,py+24,300);
    if(player)ctx.rotate(Math.PI);
}
//駒が範囲内に存在するか判定
function isinside(x,y,ax,ay,w,h){
    if((x<ax)||(x>=(ax+w))||(y<ay)||(y>=(ay+h)))return(false);
    return(true);
}
//画面全体を再描画
function redraw(){
    for(y=0; y<bh; y++){
        for(x=0; x<bw; x++){
            if(isinside(x,y,ofsx,ofsy,5,5))c=1; else c=0;
            id=board[y][x].id;
            player=board[y][x].player;
            drawpiece(x,y,id,player,c);    //駒を描画
            board[y][x].movable=false;
        }
    }
    ctx.fillStyle=fontcolor[0];
    ctx.fillText(playtbl[turn],80,(1-turn)*196+24,300);
}
//-->
</script></head><body onload="init()">
<canvas id="world"></canvas></body></html>

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?