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; };