﻿/*
* sudoku
*/

function sudoku_init(target) {
    var iExp = 60;
    var iCurCoordX = 0;
    var iCurCoordY = 0;

    /*begin build select table*/
    var select_tbl = $('<table>').attr({ 'id': 'sudoku-tbl-select' }).addClass('sudoku-tbl');
    
    var tr = $('<tr>');
    for (var v = 1; v <= 9; v++) {
        $('<td>').text(v).appendTo(tr);
    }
    tr.appendTo(select_tbl);
    $('#' + target).append(select_tbl);
    /*begin build select table*/
    
    /*begin build main table*/
    var main_tbl = $('<table>').attr({ 'id': 'sudoku-tbl' }).addClass('sudoku-tbl');
    
    for (var y = 0; y < 9; y++) {
        var tr = $('<tr>');

        for (var x = 0; x < 9; x++) {
            $('<td>').attr({
                'x':x,
                'y':y
            }).appendTo(tr);
        }

        tr.appendTo(main_tbl);
    }
    $('#' + target).append(main_tbl);
    /*end build main table*/

    /*begin insert value*/
    var data = sudoku_randomize();
    
    for (var y = 0; y < 9; y++) {
        for (var x = 0; x < 9; x++) {
            if (Math.floor(Math.random() * 100) <= iExp) {
                $('#sudoku-tbl tr:eq(' + y + ') td:eq(' + x + ')').text(data[y][x]);
            }
            if (x == 2 || x == 5) {
                $('#sudoku-tbl tr:eq(' + y + ') td:eq(' + x + ')').addClass('vtriada');
            }
            if (y == 2 || y == 5) {
                $('#sudoku-tbl tr:eq(' + y + ') td:eq(' + x + ')').addClass('htriada');
            }
        }
    }
    /*end insert value*/

    $('#sudoku-tbl td').click(function() {
        iCurCoordX = $(this).attr('x');
        iCurCoordY = $(this).attr('y');
        $('#sudoku-tbl td').removeClass('cur');
        $(this).addClass('cur');
    });

    $('#sudoku-tbl-select td').click(function() {
        if (iCurCoordX && iCurCoordY) {
            var $cell = $('#sudoku-tbl tr:eq(' + iCurCoordY + ') td:eq(' + iCurCoordX + ')');

            if (isNaN(parseInt($cell.text()))) {
                if (data[iCurCoordY][iCurCoordX] == $(this).text()) {
                    $cell.text(data[iCurCoordY][iCurCoordX]);
                    sudoku_check_finish();
                }
            }
        }
        iCurCoordX = 0;
        iCurCoordY = 0;
        $('#sudoku-tbl td').removeClass('cur');
    });
}

function sudoku_randomize() {
    var data = new Object();
    var err = false;

    while (1) {
        for (var y = 0; y < 9; y++) {
            data[y] = new Object();
            for (var x = 0; x < 9; x++) {
                var v = Math.floor(Math.random() * 9) + 1;
                var iterator = 0;
                while (1) {
                    iterator++;
                    if (sudoku_initChecker(data, x, y, v)) {
                        data[y][x] = v;
                        break;
                    }
                    (v == 9) ? v = 1 : v++;
                    if (iterator > 9) {
                        err = true;
                        break;
                    }
                }
                if (err) break;
            }
            if (err) break;
        }
        
        if (err) {
            err = false;
        } else {
            break;
        }

    }
    return data;
}

function sudoku_initCheckerHor(o, y, v) {
    for (var x = 0; x < 9; x++) {
        if (o[y][x] == undefined) return true;
        if (o[y][x] == v) return false;
    }
    return true;
}

function sudoku_initCheckerVert(o, x, v) {
    for (var y = 0; y < 9; y++) {
        if (o[y][x] == undefined) return true;
        if (o[y][x] == v) return false;
    }
    return true;
}

function sudoku_initCheckerBlock(o, i, j, v) {
    var block = new Object;
    block['x_1'] = Math.floor(i / 3) * 3;
    block['x_2'] = block['x_1'] + 2;
    block['y_1'] = Math.floor(j / 3) * 3;
    block['y_2'] = block['y_1'] + 2;
    
    for (var y = block['y_1']; y <= block['y_2']; y++) {
        if (o[y] == undefined) return true;
        
        for (var x = block['x_1']; x <= block['x_2']; x++) {
            if (o[y][x] == v) return false;
        }
    }
    return true;
}

function sudoku_initChecker(o, x, y, v) {
    return sudoku_initCheckerHor(o, y, v) && sudoku_initCheckerVert(o, x, v) && sudoku_initCheckerBlock(o, x, y, v);
}

function sudoku_check_finish() {
    for (var y = 0; y < 9; y++) {
        for (var x = 0; x < 9; x++) {
            if (isNaN(parseInt($('#sudoku-tbl tr:eq(' + y + ') td:eq(' + x + ')').text()))) {
                return false;
            }
        }
    }
    sudoku_finish();
}

function sudoku_finish() {
    alert('Congratulation)');
}
