Files @ 20564ed695fc
Branch filter:

Location: games/Awakening/london_checkers.lua - annotation

Silverwing
Typo
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
08bed57892a3
checkers_game = room {
    var {
        board = {};
        selected = 0;
        select_lock = false;
    };
    nam = "checkers_game";
    nosave = true;
    noautosave = true;
    forcedsc = true;
    randomness = 15;
    depth = 6;
    cutoff_lo = -3;
    cutoff_hi = 3;
    draw_board = function(board)
        rval = {
            {0,0,0,0,0,0,0,0};
            {0,0,0,0,0,0,0,0};
            {0,0,0,0,0,0,0,0};
            {0,0,0,0,0,0,0,0};
            {0,0,0,0,0,0,0,0};
            {0,0,0,0,0,0,0,0};
            {0,0,0,0,0,0,0,0};
            {0,0,0,0,0,0,0,0};
        };
        
        for i = 1, #board do
            if board[i][3] then
                if board[i][4] then
                    rval[board[i][1]][board[i][2]] = 3;
                else
                    rval[board[i][1]][board[i][2]] = 1;
                end;
            else
                if board[i][4] then
                    rval[board[i][1]][board[i][2]] = 4;
                else
                    rval[board[i][1]][board[i][2]] = 2;
                end;
            end;
        end;
        
        return rval;
    end;
    calc_take = function(s, x, y, w, q, map)
        local rval = {};
        local r = nil;
        if w then
            -- белый рубит черного - рубит вверх
            if (map[x - 1][y - 1] == 2 or map[x - 1][y - 1] == 4)
                and map[x - 2][y - 2] == 0 and x - 2 > 0 and y - 2 > 0 then
                mcopy = deepcopy(map);
                r = s:calc_take(x - 2, y - 2, w, q or y == 2, mcopy);
                if #r == 0 then
                    rval[#rval + 1] = {1, {{x-1, y-1}}, q or y == 2, x-2, y-2};
                end;
                for i = 1, #r do
                    r[i][1] = r[i][1] + 1;
                    r[i][2][#r[i][2] + 1] = {x-1, y-1};
                    r[i][3] = r[i][3] or q or y == 2;
                    rval[#rval + 1] = r[i]
                end;
            end;
            if (map[x + 1][y - 1] == 2 or map[x + 1][y - 1] == 4)
                and map[x + 2][y - 2] == 0 and x + 2 < 9 and y - 2 > 0 then
                mcopy = deepcopy(map);
                r = s:calc_take(x + 2, y - 2, w, q or y == 2, mcopy);
                if #r == 0 then
                    rval[#rval + 1] = {1, {{x+1, y-1}}, q or y == 2, x+2, y-2};
                end;
                for i = 1, #r do
                    r[i][1] = r[i][1] + 1;
                    r[i][2][#r[i][2] + 1] = {x+1, y-1};
                    r[i][3] = r[i][3] or q or y == 2;
                    rval[#rval + 1] = r[i]
                end;
            end;
            --Дамка может рубить и вниз
            if q and (map[x - 1][y + 1] == 2 or map[x - 1][y + 1] == 4)
                and map[x - 2][y + 2] == 0 and x - 2 > 0 and y + 2 < 9 then
                mcopy = deepcopy(map);
                r = s:calc_take(x - 2, y + 2, w, q, mcopy);
                if #r == 0 then
                    rval[#rval + 1] = {1, {{x-1, y+1}}, q, x-2, y+2};
                end;
                for i = 1, #r do
                    r[i][1] = r[i][1] + 1;
                    r[i][2][#r[i][2] + 1] = {x-1, y+1};
                    r[i][3] = r[i][3] or q;
                    rval[#rval + 1] = r[i];
                end;
            end;
            if q and (map[x + 1][y + 1] == 2 or map[x + 1][y + 1] == 4)
                and map[x + 2][y + 2] == 0 and x + 2 < 9 and y + 2 < 9 then
                mcopy = deepcopy(map);
                r = s:calc_take(x + 2, y + 2, w, q, mcopy);
                if #r == 0 then
                    rval[#rval + 1] = {1, {{x+1, y+1}}, q, x+2, y+2};
                end;
                for i = 1, #r do
                    r[i][1] = r[i][1] + 1;
                    r[i][2][#r[i][2] + 1] = {x+1, y+1};
                    r[i][3] = r[i][3] or q;
                    rval[#rval + 1] = r[i];
                end;
            end;
        else
            --черный рубит белого - рубит вниз
            if (map[x - 1][y + 1] == 1 or map[x - 1][y + 1] == 3)
                and map[x - 2][y + 2] == 0 and x - 2 > 0 and y + 2 < 9 then
                mcopy = deepcopy(map);
                r = s:calc_take(x - 2, y + 2, w, q or y == 6, mcopy);
                if #r == 0 then
                    rval[#rval + 1] = {1, {{x-1, y+1}}, q or y == 6, x-2, y+2};
                end;
                for i = 1, #r do
                    r[i][1] = r[i][1] + 1;
                    r[i][2][#r[i][2] + 1] = {x-1, y+1};
                    r[i][3] = r[i][3] or q or y == 6;
                    rval[#rval + 1] = r[i]
                end;
            end;
            if (map[x + 1][y + 1] == 1 or map[x + 1][y + 1] == 3)
                and map[x + 2][y + 2] == 0 and x + 2 < 9 and y + 2 < 9 then
                mcopy = deepcopy(map);
                r = s:calc_take(x + 2, y + 2, w, q or y == 6, mcopy);
                if #r == 0 then
                    rval[#rval + 1] = {1, {{x+1, y+1}}, q or y == 6, x+2, y+2};
                end;
                for i = 1, #r do
                    r[i][1] = r[i][1] + 1;
                    r[i][2][#r[i][2] + 1] = {x+1, y+1};
                    r[i][3] = r[i][3] or q or y == 2;
                    rval[#rval + 1] = r[i]
                end;
            end;
            --Дамка может рубить и вниз
            if q and (map[x - 1][y - 1] == 1 or map[x - 1][y - 1] == 3)
                and map[x - 2][y - 2] == 0 and x - 2 > 0 and y - 2 > 0 then
                mcopy = deepcopy(map);
                r = s:calc_take(x - 2, y - 2, w, q, mcopy);
                if #r == 0 then
                    rval[#rval + 1] = {1, {{x-1, y-1}}, q or y == 6, x-2, y-2};
                end;
                for i = 1, #r do
                    r[i][1] = r[i][1] + 1;
                    r[i][2][#r[i][2] + 1] = {x-1, y-1};
                    r[i][3] = r[i][3] or q;
                    rval[#rval + 1] = r[i];
                end;
            end;
            if q and (map[x + 1][y - 1] == 1 or map[x + 1][y - 1] == 3)
                and map[x + 2][y - 2] == 0 and x + 2 < 9 and y - 2 > 0 then
                mcopy = deepcopy(map);
                r = s:calc_take(x + 2, y - 2, w, q, mcopy);
                if #r == 0 then
                    rval[#rval + 1] = {1, {{x+1, y-1}}, q or y == 6, x+2, y-2};
                end;
                for i = 1, #r do
                    r[i][1] = r[i][1] + 1;
                    r[i][2][#r[i][2] + 1] = {x+1, y-1};
                    r[i][3] = r[i][3] or q;
                    rval[#rval + 1] = r[i];
                end;
            end;
        end;
        return rval;
    end;
    calc_turn = function(s, d, w, board)
        if d > s.depth then
            return nil, 0;
        end;
        local cost = 0;
        local turns = {};
        local bmap = s.draw_board(board);
        local takes = false;
        for i = 1, #board do
            --Рубка обязательна, поэтому сперва проверяем рубки
            if board[i][3] == w then
                -- своя фигура. Проверяем рубки
                local r = s:calc_take(board[i][1], board[i][2], w, board[i][4], bmap);
                if #r > 0 then
                    takes = true;
                    for j = 1, #r do
                        --Восстанавливаем состояние поля после рубки и уходим глубже
                        local bcopy = deepcopy(board);
                        for k = #bcopy, 1, -1 do
                            for l = 1, #r[j][2] do
                                if r[j][2][1] == bcopy[k][2] and r[j][2][1] == bcopy[k][2] then
                                    table.remove(bcopy, k);
                                    break;
                                end;
                            end;
                        end;
                        local rr, pts = s:calc_turn(d + 1, not w, bcopy);
                        turns[#turns + 1] = {board[i][1], board[i][2], r[j][4], r[j][5], r[j][2], r[j][1] - pts};
                    end;
                end;
            end;
        end;
        -- Если была рубка, не обрабатываем дальше
        if takes then
            table.sort(turns, function(a,b) 
                return a[6] > b[6];
            end);
            return turns[0], turns[0][6];
        end;
        for i = 1, #board do
            if board[i][3] == w then
                --Проверяем ходы
                if q or w then
                    --белая или дамка - ходит вверх
                    if bmap[board[i][1] - 1][board[i][2] - 1] == 0 then
                        local bcopy = deepcopy(board);
                        bcopy[i][1] = bcopy[i][1] - 1;
                        bcopy[i][2] = bcopy[i][2] - 1;
                        local rr, pts = s:calc_turn(d + 1, not w, bcopy);
                        turns[#turns + 1] = {board[i][1], board[i][2], bcopy[i][1], bcopy[i][2], nil, - pts};
                    end;
                    if bmap[board[i][1] - 1][board[i][2] + 1] == 0 then
                        local bcopy = deepcopy(board);
                        bcopy[i][1] = bcopy[i][1] - 1;
                        bcopy[i][2] = bcopy[i][2] + 1;
                        local rr, pts = s:calc_turn(d + 1, not w, bcopy);
                        turns[#turns + 1] = {board[i][1], board[i][2], bcopy[i][1], bcopy[i][2], nil, - pts};
                    end;
                end;
                if q or not w then
                    --черная или дамка - ходит вниз
                    if bmap[board[i][1] + 1][board[i][2] - 1] == 0 then
                        local bcopy = deepcopy(board);
                        bcopy[i][1] = bcopy[i][1] + 1;
                        bcopy[i][2] = bcopy[i][2] - 1;
                        local rr, pts = s:calc_turn(d + 1, not w, bcopy);
                        turns[#turns + 1] = {board[i][1], board[i][2], bcopy[i][1], bcopy[i][2], nil, - pts};
                    end;
                    if bmap[board[i][1] + 1][board[i][2] + 1] == 0 then
                        local bcopy = deepcopy(board);
                        bcopy[i][1] = bcopy[i][1] + 1;
                        bcopy[i][2] = bcopy[i][2] + 1;
                        local rr, pts = s:calc_turn(d + 1, not w, bcopy);
                        turns[#turns + 1] = {board[i][1], board[i][2], bcopy[i][1], bcopy[i][2], nil, - pts};
                    end;
                end;
            end;
        end;

        table.sort(turns, function(a,b) 
            return a[6] > b[6];
        end);
        return turns[0], turns[0][6];
    end;
    enemy_turn = function(s)
    end;
    click = function(s, x, y)
        x = math.floor((x - 4) / 24) + 1;
        y = math.floor((y - 4) / 24) + 1;
        if x > 0 and x < 9 and y > 0 and y < 9 then
            for i = 1,#s.board do
                if s.board[i][1] == x and s.board[i][2] == y then
                    if s.board[i][3] then
                        s.selected = i;
                        walkin(here());
                        return;
                    else
                        --Может рубим?
                        if s.selected > 0 then
                            print("q");
                            local dx = x - s.board[s.selected][1];
                            local dy = y - s.board[s.selected][2];
                            if s.board[s.selected][4] then
                                if math.abs(dx) == 1 and math.abs(dy) == 1 then
                                    s.board[s.selected][1] = s.board[s.selected][1] + dx * 2;
                                    s.board[s.selected][2] = s.board[s.selected][2] + dy * 2;
                                    s.selected = 0;
                                    walkin(here());
                                    return;
                                end;
                            else
                                if math.abs(dx) == 1 and dy == -1 then
                                    s.board[s.selected][1] = s.board[s.selected][1] + dx * 2;
                                    s.board[s.selected][2] = s.board[s.selected][2] + dy * 2;
                                    s.selected = 0;
                                    walkin(here());
                                    return;
                                end;
                            end;
                    end;
                        return;
                    end;
                end;
            end;
            
            if s.selected > 0 then
                local dx = x - s.board[s.selected][1];
                local dy = y - s.board[s.selected][2];
                print(dx, dy);
                if s.board[s.selected][4] then
                    if math.abs(dx) == 1 and math.abs(dy) == 1 then
                        s.board[s.selected][1] = x;
                        s.board[s.selected][2] = y;
                        s.selected = 0;
                        walkin(here());
                        return;
                    end;
                else
                    if math.abs(dx) == 1 and dy == -1 then
                        s.board[s.selected][1] = x;
                        s.board[s.selected][2] = y;
                        print(s.board[s.selected][1], s.board[s.selected][2])
                        s.selected = 0;
                        walkin(here());
                        return;
                    end;
                end;
            end;
            s.selected = 0;
        
            
        end;
        walkin(here());
    end;
    disp = "Шашки";
    reset = function(s)
        s.board = {
            {2, 3, false, false};
            {4, 3, false, false};
            {6, 3, false, false};
            {8, 3, false, false};
            
            --{1, 2, false, false};
            --{3, 2, false, false};
            --{5, 2, false, false};
            --{7, 2, false, false};
            
            {2, 5, false, false};
            {4, 5, false, false};
            {6, 5, false, false};
            {8, 5, false, false};
            
            {1, 6, true, false};
            {3, 6, true, false};
            {5, 6, true, false};
            {7, 6, true, false};
            
            {2, 7, true, false};
            {4, 7, true, false};
            {6, 7, true, false};
            {8, 7, true, false};
            
            {1, 8, true, false};
            {3, 8, true, false};
            {5, 8, true, false};
            {7, 8, true, false};
        };
    end;
    pic = function(s)
        local rval = "images/checkerboard.png";
        if s.selected > 0 then
            rval = rval .. [[;box:24x24,red,32@]] .. tostring(s.board[s.selected][1] * 24 - 20) .. "," .. tostring(s.board[s.selected][2] * 24 - 20);
        end;
        for i = 1, #s.board do
            if s.board[i][3] and s.board[i][4] then
                rval = rval .. [[;images/checkerwhiteq.png@]] .. tostring(s.board[i][1] * 24 - 20) .. "," .. tostring(s.board[i][2] * 24 - 20);
            elseif not s.board[i][3] and s.board[i][4] then
                rval = rval .. [[;images/checkerblackq.png@]] .. tostring(s.board[i][1] * 24 - 20) .. "," .. tostring(s.board[i][2] * 24 - 20);
            elseif s.board[i][3] and not s.board[i][4] then
                rval = rval .. [[;images/checkerwhite.png@]] .. tostring(s.board[i][1] * 24 - 20) .. "," .. tostring(s.board[i][2] * 24 - 20);
            elseif not s.board[i][3] and not s.board[i][4] then
                rval = rval .. [[;images/checkerblack.png@]] .. tostring(s.board[i][1] * 24 - 20) .. "," .. tostring(s.board[i][2] * 24 - 20);
            end;
        end;
        return rval;
    end;
};