Tutorials‎ > ‎

Otello using canvas html5

posted Dec 23, 2011, 2:40 AM by Sofia _   [ updated Aug 15, 2016, 11:34 PM by Surya Wang ]

In this article, I would like to introduce a simple game ‘Othello’ using jquery and canvas. I use canvas in html5 to create the pieces of othello and the board.

Here is the html code :

    <div style="text-align:center;padding-top:10px;">
        <canvas style="border:6px double black" id="myCanvas" width="400px" height="400px"></canvas>
        <div style="font-weight:bold;font-size:22px;font-family:'Comic Sans MS', cursive">
            Total Black: <span id="spanDesc1">2</span><br/>
            Total White: <span id="spanDesc2">2</span>
        </div>
    </div>

The global variable

var boxSize = 50;
var boxCount = 8;
var pieces = [];
var now = 0;
var canvasOffset = { x: 0, y: 0 };
var isBlack = true;
var availablePieces = [];
var nowColor = 'black';
var reverseColor = 'white';
var flag = 0;

Here is the setup function that will run when the page is loaded.


$(function() {
          //to get canvas offest
           canvasOffset.x  = $('#myCanvas').offset().left;
           canvasOffset.y  = $('#myCanvas').offset().top;
 
           //inizialize pieces. I am setting the pieces from 0 to 64 in an array of json
            var k = 0;
            for (var i = 0; i < boxCount; i++) {
                for (var j = 0; j < boxCount; j++) {
                    pieces[k] = { x: (i * boxSize) + 25, y: (j * boxSize) + 25, visible: false, color: 'white' };
                    k++;
                }
            }
 
          //setting the four pieces in the game beginning
            pieces[27].visible = true;
            pieces[36].visible = true;
 
            pieces[28].visible = true;
            pieces[35].visible = true;
            pieces[28].color = 'black';
            pieces[35].color = 'black';
 
          //call function to check the possible move and to draw into canvas
           check();
           draw();
 
    /* event handler */
    /* ……………………………………*/
    /* event handler */        
 
        });

What to do when the mouse is move. It is to find out which box is the user choose.

    
$('#myCanvas').mousemove(function(e) {
            var xNow = e.pageX - canvasOffset.x;
            var yNow = e.pageY - canvasOffset.y;
            for (var i = 0; i < boxCount * boxCount; i++) {
                if((xNow >= (pieces[i].x - 25) && xNow <= (pieces[i].x + 25))
&& (yNow >= (pieces[i].y - 25) && yNow <= (pieces[i].y + 25)))
          {
    now = i;
    break;
          }
            }
            draw();
        });

What to do if the canvas is click by use. If the pieces in the current block haven’t be places and it’s available to be placed, it will call the fReverse function to reverse the pieces and checkgame to update pieces available moves in the board.


$('#myCanvas').click(function(e){
    if(pieces[now].visible == false && $.inArray(now,availablePieces)>=0)
    {
    flag = 0;
    fReverse();
    checkGame();
   }
});

The checkGame function is use to turn the current color and make it visible. It will call check function to check avaiable moves and function to draw all over again. If there’s no more move it will call itself again to turn to the other color and if there no more moves for both it will check the win and lose.


function checkGame()
{
    if(isBlack){
        isBlack = false;
        nowColor = 'white';
        reverseColor = 'black';
        if(flag==0)pieces[now].color = 'black';
    }
    else{
        isBlack = true;
        nowColor = 'black';
        reverseColor = 'white';
    }
    if(flag==0)pieces[now].visible = true;
    check();
    draw();
    if(availablePieces.length == 0)
    {
        flag++;
        if(flag == 2)
        {
            checkWinLose();
        }
        else checkGame();
    }
}

This function is used to reverse the color for the current move. It will check by calling another function in 8 ways (left, right, top, bottom, diagonal left up, diagonal left bottom, diagonal right up, diagonal right bottom).


function fReverse()
{
    //left right
    checkSide(now,boxCount*-1,now,true);
    checkSide(now,boxCount,now,true);
    //up down
    checkSide(now,-1,now,true);
    checkSide(now,1,now,true);
    //diagonal
    checkSide(now,(boxCount*-1)+1,now,true);
    checkSide(now,(boxCount*-1)-1,now,true);
    checkSide(now,boxCount+1,now,true);
    checkSide(now,boxCount-1,now,true);
}

This function is to check the win and lose. The color has most pieces will will the game, if count is same for the both side, the game is draw. After alert, the page will be reloaded.


function checkWinLose()
{
    var totalWhite = 0,totalBlack = 0;
    for (var i = 0; i < boxCount * boxCount; i++) {
        if(pieces[i].visible == true)
        {
            if(pieces[i].color == 'white')
                totalWhite++;
            else
                totalBlack++;
        }
    }
    if(totalWhite > totalBlack)
        alert("White is won ");
    else if(totalWhite < totalBlack)
        alert("Black is won");
    else
        alert("The game is draw");
    location.reload(true);
}

Function check is used to check possible ways to all pieces which is in the board for the current color. It also will count the current pieces and show it in html.


function check()
{
    availablePieces = [];
    var totalPieces = 0;
    var totalWhite = 0,totalBlack = 0;
    for (var i = 0; i < boxCount * boxCount; i++) {
        if(pieces[i].visible == true)
        {
            totalPieces++;
            if(pieces[i].color == 'white')
                totalWhite++;
            else
                totalBlack++;
        }
        if(pieces[i].visible == true && pieces[i].color == nowColor)
        {
            checkSide(i,boxCount*-1,i,false); //left
            checkSide(i,boxCount,i,false); //right
            checkSide(i,-1,i,false); //up
            checkSide(i,1,i,false); // down
            checkSide(i,(boxCount*-1)-1,i,false); //left up
            checkSide(i,(boxCount*-1)+1,i,false); //left down
            checkSide(i,boxCount-1,i,false); //right up
            checkSide(i,boxCount+1,i,false); //right down
        }
    }
    $('#spanDesc1').html(totalBlack);
    $('#spanDesc2').html(totalWhite);
    if(totalPieces == boxCount * boxCount)
        checkWinLose();
}

This function will validate the pieces and will validate the pieces for available moves and to change the color pieces if isReverse is true.


function checkSide(ori,plus,i,isReverse)
{
    if((i+plus) >= 0 && (i+plus) < (boxCount*boxCount) &&
       ((plus != 1 && plus != (boxCount*-1)+1 && plus != boxCount+1) || ((i+plus)%boxCount) != 0)
    && ((plus != -1 && plus != (boxCount*-1)-1 && plus != boxCount-1) || ((i+plus)%boxCount) != 7))
    {
        if(pieces[i+plus].visible == true)
        {
            if(pieces[i+plus].color == reverseColor)
            {
                checkSide(ori,plus,i+plus,isReverse);
            }
            else if(isReverse == true && ori != i)
            {
                if(ori < i)
                {
                    for(var j=ori+plus;j<=i;j+=plus)
                    {
                        if((j+plus) >= 0 && (j+plus) < (boxCount*boxCount) &&
                           ((plus != 1 && plus != (boxCount*-1)+1 && plus != boxCount+1) || ((j+plus)%boxCount) != 0)
                        && ((plus != -1 && plus != (boxCount*-1)-1 && plus != boxCount-1) || ((j+plus)%boxCount) != 7))
                            pieces[j].color = nowColor;
                        else break;
                    }
                }
                else
                {
                    for(var j=ori+plus;j>=i;j+=plus)
                    {
                        if((j+plus) >= 0 && (j+plus) < (boxCount*boxCount) &&
                           ((plus != 1 && plus != (boxCount*-1)+1 && plus != boxCount+1) || ((j+plus)%boxCount) != 0)
                        && ((plus != -1 && plus != (boxCount*-1)-1 && plus != boxCount-1) || ((j+plus)%boxCount) != 7))
                            pieces[j].color = nowColor;
                        else break;
                    }
                }
            }
        }
        else if(ori != i)
        {
            if($.inArray(i+plus,availablePieces)<0)
                availablePieces.push(i+plus);
        }
    }
}

This function to draw the entire board and the pieces.

function draw() {
    var canvas = document.getElementById('myCanvas');
    var myContext = canvas.getContext('2d');
 
    canvas.width = canvas.width;
    //background
    myContext.fillStyle = 'green';
    myContext.fillRect(0, 0, boxCount * boxSize, boxCount * boxSize);
 
    //board line
    for (var i = 1; i < boxCount; i++) {
        myContext.moveTo(0, boxSize * i);
        myContext.lineTo(boxCount * boxSize, boxSize * i);
    }
    for (var i = 1; i < boxCount; i++) {
        myContext.moveTo(boxSize * i,0);
        myContext.lineTo(boxSize * i, boxCount * boxSize);
    }
    myContext.stroke();
 
    //board circle
    myContext.beginPath();
    myContext.fillStyle = 'black';
    myContext.arc((6 * boxSize), (6 * boxSize), 4, Math.PI * 2, false);
    myContext.arc((6 * boxSize), (2 * boxSize), 4, Math.PI * 2, false);
    myContext.fill();
    myContext.beginPath();
    myContext.arc((2 * boxSize), (2 * boxSize), 4, Math.PI * 2, false);
    myContext.arc((2 * boxSize), (6 * boxSize), 4, Math.PI * 2, false);
    myContext.fill();
 
    //draw pieces
    for (var i = 0; i < boxCount * boxCount; i++) {
        if (pieces[i].visible == true) {
            myContext.beginPath();
            myContext.fillStyle = pieces[i].color;
            myContext.arc(pieces[i].x, pieces[i].y, 20, Math.PI * 2, false);
            myContext.shadowBlur = 5;
            myContext.shadowColor = 'black';
            myContext.fill();
        }
    }
 
    myContext.strokeRect(pieces[now].x - 25, pieces[now].y - 25, 50, 50);
 
    for (var i = 0; i < availablePieces.length ; i++) {
        myContext.globalAlpha = 0.1;
        myContext.beginPath();
        myContext.fillStyle = nowColor;
        myContext.arc(pieces[availablePieces[i]].x, pieces[availablePieces[i]].y, 20, Math.PI * 2, false);
        myContext.shadowBlur = 5;
        myContext.shadowColor = 'black';
        myContext.fill();
    }
}


Here is the result


ċ
Otellousingcanvashtml5.zip
(34k)
Sofia _,
Dec 23, 2011, 2:49 AM