コアダンプの数だけ強くなれるよ

見習いエンジニアの備忘log

Javascriptでオセロ(その2)


前回に引き続き、不足していた機能を追加してみた。
























----------------------------------
こんな感じのオセロが完成。申し訳程度の対AIもサポート。


# ソースコード

// define constant value
var BOARD_SIZE = {
    'WIDTH' :8,
    'HEIGHT':8,
};

var BLOCK_KIND = {
    'NONE'   : 0,
    'BLACK'  : 1,
    'WHITE'  : 2,
    'MAX'    : 3,
};

var SQUARE_SIZE = {
    'WIDTH'  : 31,
    'HEIGHT' : 31,
};

var SLEEP_KIND = {
    'TURNOVER'  : 1000,
};

var isComputer = false;
var isFirst = false;
var stone;
var board = [];
var player_color;

var getCountIsPossibleToTurnOver = function(x, y, dx, dy) {

    var count = 0;
    var cx = x + dx;
    var cy = y + dy;

    if (( cx < 0 || BOARD_SIZE.WIDTH < cx) ||
        ( cy < 0 || BOARD_SIZE.HEIGHT < cy)) {

        return 0;
    }

    while(board[cx][cy] == BLOCK_KIND.MAX - player_color) {
        count++;
        cx += dx;
        cy += dy;

        if (( cx < 0 || BOARD_SIZE.WIDTH < cx) ||
            ( cy < 0 || BOARD_SIZE.HEIGHT < cy)) {

            return 0;
        }
    }

    if (count > 0 && board[cx][cy] == player_color) {
        return count;
    }

    return 0;
};

var turnOverStraight = function(x, y, dx, dy) {

    var cx = x + dx;
    var cy = y + dy;

    while(board[cx][cy] == BLOCK_KIND.MAX - player_color) {
        board[cx][cy] = player_color;
        cx += dx;
        cy += dy;
    }
};

var turnOverBlock = function(x, y, flip) {

    var total = 0;

    // can not put block
    if (board[x][y] != BLOCK_KIND.NONE) {
        return total;
    }
    
    // check for 8 direction whether it is possible to turn over block
    for (var dx = -1; dx <= 1; dx++) {
        for(var dy = -1; dy <= 1; dy++) {

            if (dx == 0 && dy == 0) {
                continue;
            }
            
            var cnt = getCountIsPossibleToTurnOver(x, y, dx, dy);
            if (cnt > 0) {
                total += cnt;
                if (flip) {
                    turnOverStraight(x, y, dx, dy);
                }
            }
        }
    }

    return total;
};

var showBoard = function() {

    var b = document.getElementById("board");

    while(b.firstChild) {
        b.removeChild(b.firstChild);
    }
    
    for(var y = 0; y < BOARD_SIZE.HEIGHT; y++) {
        for(var x = 0; x < BOARD_SIZE.WIDTH; x++) {
            var square = stone[board[x][y]].cloneNode(true);
            
            square.style.left = ((x) * SQUARE_SIZE.WIDTH) + "px"; 
            square.style.top = ((y) * SQUARE_SIZE.HEIGHT) + "px"; 
            b.appendChild(square);
            
            (function() {
                var _x = x;
                var _y = y;
                square.onclick = function() {
                    if (turnOverBlock(_x, _y, true) > 0) {
                        board[_x][_y] = player_color;
                        showBoard();
                        if (!changePlayer()) {
                            doAiPlayer();
                        } 
                    }
                };
            })();
        }
    }

    showProgress();
};

var showProgress = function() {

    var black = 0;
    var white = 0;

    for(var y = 0; y < BOARD_SIZE.HEIGHT; y++) {
        for(var x = 0; x < BOARD_SIZE.WIDTH; x++) {
            if (board[x][y] == BLOCK_KIND.BLACK) {
                black++;
            } else if (board[x][y] == BLOCK_KIND.WHITE) {
                white++;
            } else {
                // no opereation
            }
        }
    }

    var msg = document.getElementById("msg");
    
    msg.innerHTML = "progress of territory  black:"+black+" white:"+white;
};

var changePlayer = function() {
    
    var pass = false;

    player_color = BLOCK_KIND.MAX - player_color;

    if (isPass()) {
        if(player_color == BLOCK_KIND.BLACK) {
            alert("Black is pass");
        } else if (player_color == BLOCK_KIND.WHITE) {
            alert("White is pass");
        } else {
            alert("invalid status");
        }
        
        player_color = BLOCK_KIND.MAX - player_color;

        if(isPass()) {
            alert("Game set");
        }

        pass = true;
    }

    return pass;
};

var doAiPlayer = function() {

    if(!isComputer) {
        return false;
    }

    if( (isFirst && (player_color == BLOCK_KIND.BLACK)) ||
        (!isFirst && (player_color == BLOCK_KIND.WHITE)) ) {
        return false;
    }

    for(var y = 0; y < BOARD_SIZE.HEIGHT; y++) {
        for(var x = 0; x < BOARD_SIZE.WIDTH; x++) {
            
            if (turnOverBlock(x, y, true) > 0) {
                board[x][y] = player_color;
                showBoard();
                if(changePlayer()) {
                    doAiPlayer();
                }
                return true;
            }
        }
    }
    
    return false;
};

var isPass = function() {
    
    for(var y = 0; y < BOARD_SIZE.HEIGHT; y++) {
        for(var x = 0; x < BOARD_SIZE.WIDTH; x++) {
            
            if (turnOverBlock(x, y, false) > 0) {
                return false;
            }
        }
    }

    return true;
};

var msleep = function(ms) {

    var d1 = new Date().getTime();
    var d2 = new Date().getTime();
    while ( d2 < (d1 + ms) ) {
        d2 = new Date().getTime();
    }
};

var initBoard = function() {

    player_color = BLOCK_KIND.BLACK;

    // 0:none, 1:black, 2:white
    stone = [
        document.getElementById("none"),
        document.getElementById("black"),
        document.getElementById("white")
    ];

    // init zero value
    for (var i = 0; i < BOARD_SIZE.HEIGHT+1; i++) {
        board[i] = [];
        for (var j = 0; j < BOARD_SIZE.WIDTH+1; j++) {
            board[i][j] = BLOCK_KIND.NONE;
        }
    }

    // initial position
    board[3][4] = BLOCK_KIND.BLACK;
    board[4][3] = BLOCK_KIND.BLACK;
    board[3][3] = BLOCK_KIND.WHITE;
    board[4][4] = BLOCK_KIND.WHITE;

};

onload = function() {
    // just in case
    Object.freeze(BLOCK_KIND);
    Object.freeze(BOARD_SIZE);
    Object.freeze(SQUARE_SIZE);
    
    // initialize board
    initBoard();
    // start game
    showBoard();
};

var OnClickButton = function() {
    if(document.form1.Computer.checked) {
        isComputer = true;
    } else {
        isComputer = false;
    }
    
    if(document.form1.First.checked) {
        isFirst = true;
    } else {
        isFirst = false;
    }

    // initialize board
    initBoard();

    // start game
    showBoard();

    if(!isFirst) {
        doAiPlayer();
    }
};

© 2019 GitHub, Inc.
Terms
Privacy
Security
Status
Help
Contact GitHub
Pricing
API
Training
Blog
About