Мужыки нужна помощь. Есть бот для всем известной игры 2048 на языке lua помогите мне его переписать на язык пилота. Хочу переписать его для использования в другой но по алгоритму похожей
Оригинал:
То к чему хочу прикрутить:
https://www.autoitscript.com/forum/topic/161302-2048-game/
https://pastebin.com/sK7u6j5j
Как-то не серьезно нужно срочно на языке пилота запилить
Пример игры для теста скрипта(открыть файл index.html):
2048_AI_master.zip ( 231,32 килобайт )
Кол-во скачиваний: 244
А смысл? Ну используйте луа в пилоте.
grid - это массив со всеми числами.
Lua - это лишь набор синтаксиса. Функции все те же самые пилотовские остаются.
Вот нарыл есчо один код на Lua связанный с игрой 2048. Помогите пожалуйста разобраться, что здесь описано.
-- 2048
-- Clone by Richard (Rich73)
-- Hacked together 10/04/2014
g = { }
tiles = { }
tiles[1] = {" ", 1}
tiles[2] = {" 2 ", 2}
tiles[3] = {" 4 ", 4}
tiles[4] = {" 8 ", 8}
tiles[5] = {" 16 ", 16}
tiles[6] = {" 32 ", 32}
tiles[7] = {" 64 ", 64}
tiles[8] = {"128 ", 128}
tiles[9] = {"256 ", 256}
tiles[10] = {"512 ", 512}
tiles[11] = {"1024", 1024}
tiles[12] = {"2048", 2048}
bg = "icon"
size = 4
score = 0
hiscore = 0
function createBoard()
for i=1, size do
g[i] = { }
for j=1, size do
g[i][j] = 0
end
end
for j=1, 2 do
local x, y = findEmptyPos()
g[y][x] = 1
end
end
function getRandomPos()
return math.random(size), math.random(size)
end
function findEmptyPos()
while true do
x, y = getRandomPos()
if g[y][x] == 0 then return x, y end
end
end
function isFull()
local full = true
for i=1, size do
for j=1, size do
if g[i][j] == 0 then full = false end
end
end
return full
end
function canMove()
if not isFull() then return true end
local pr = nil
for i=1, size do
local k = 1
while k <= size do
if k~=size and g[i][k] == g[i][k+1] or false then break end
if pr and g[i][k] == pr[k] or false then break end
k = k + 1
end
if k ~= size+1 then return true end
pr = g[i]
end
return false
end
function moveLeft()
for i=1, size do
for j=2, size do
local k = j
while k > 1 do
if g[i][k] == 0 then break
elseif g[i][k] == g[i][k-1] then
g[i][k-1] = g[i][k] + 1
g[i][k] = 0
score = score + math.pow(2,g[i][k-1])
k = k-1
elseif g[i][k-1] == 0 then
g[i][k-1] = g[i][k]
g[i][k] = 0
else break end
k = k-1
end
end
end
end
function moveUp()
for j=1, size do
for i=2, size do
local k = i
while k > 1 do
if g[k][j] == 0 then break
elseif g[k][j] == g[k-1][j] then
g[k-1][j] = g[k][j] + 1
g[k][j] = 0
score = score + math.pow(2,g[k-1][j])
k = k-1
elseif g[k-1][j] == 0 then
g[k-1][j] = g[k][j]
g[k][j] = 0
else break end
k = k-1
end
end
end
end
function moveRight()
flipX()
moveLeft()
flipX()
end
function moveDown()
flipY()
moveUp()
flipY()
end
function drawBoard()
term.setBackgroundColor(colors.black)
term.clear()
term.setTextColor(colors.white)
for x=1, size do
for y=1, size do
term.setCursorPos(x*5-1,y*4-2)
term.setBackgroundColor(tiles[g[y][x]+1][2])
term.write(" ")
term.setCursorPos(x*5-1,y*4-1)
term.write(tiles[g[y][x]+1][1])
term.setCursorPos(x*5-1,y*4)
term.write(" ")
end
end
term.setCursorPos(4,18)
term.setBackgroundColor(colors.black)
term.write("Score: "..score)
drawScores()
end
function drawScores()
term.setCursorPos(4,18)
term.setBackgroundColor(colors.black)
term.write(" Score: "..score)
term.setCursorPos(4,19)
term.write("HiScore: "..hiscore)
end
function drawHome()
term.clear()
im = paintutils.loadImage(bg)
paintutils.drawImage(im,2,2)
end
function table.reverse(tab)
local newtab = { }
for i=1, #tab do
newtab[#tab+1-i] = tab[i]
end
return newtab
end
function flipX()
for i=1, size do
g[i] = table.reverse(g[i])
end
end
function flipY()
g = table.reverse(g)
end
function update()
drawBoard()
if not isFull() then
local x, y = findEmptyPos()
g[y][x] = 1
end
os.sleep(0.075)
end
function newGame()
if score > hiscore then
hiscore = score
end
score = 0
term.setCursorPos(9,18)
term.setBackgroundColor(colors.white)
term.setTextColor(colors.black)
term.clearLine()
term.write("GAME OVER!")
term.setCursorPos(8,19)
term.clearLine()
term.write("New game? y/n")
while true do
local event, key = os.pullEvent("key")
if event=="key" then
if key==keys.y then return true end
if key==keys.n then return false end
end
end
end
drawHome()
os.sleep(2)
while true do
createBoard()
while canMove() do
drawBoard()
event, key = os.pullEvent("key")
if event == "key" then
if key == keys.left then moveLeft()
elseif key == keys.right then
moveRight()
update()
elseif key == keys.up then
moveUp()
update()
elseif key == keys.down then
moveDown()
update()
elseif key == keys.q then
break
end
end
end
drawBoard()
if not newGame() then
term.setBackgroundColor(colors.black)
term.setTextColor(colors.white)
term.clear()
term.setCursorPos(1,1)
break
end
end
Переделал под себя для теста(испытаний) скрипта(открыть файл index.html):
2048_AI_master.zip ( 231,32 килобайт )
Кол-во скачиваний: 244
Очень долго сканирует поле.
init_arr %image 2 4 8 16 32 64 128 // имена картинок
set $path "D:\_UOPilot\_2048\" // путь к картинкам
init_arr %coord 434, 39 933, 541 // координаты для findimage
set #stepX (%coord [3] - %coord [1]) / 4 // шаг по X
set #stepY (%coord [4] - %coord [2]) / 4 // шаг по Y
set #z 0
for #i 1 size(%image) // поиск картинок
set #a findimage(%coord [1] %coord [2] %coord [3] %coord [4] ($path%image[#i].bmp) %arr 2 90 -1 3)
if #a > 0
for #j 1 size(%arr)
set #z #z + 1
init_arr %temp (#z) %arr [#j 1] %arr [#j 2] %image[#i] // добавить в массив координаты и имя картинки
end_for
end_if
end_for
for #i 1 4 // заполнить массив 4*4 нулями
init_arr %field (#i) 0 0 0 0
end_for
for #i 1 #z // подсчёт позиции картинки на поле
set #x (%temp [#i 1] - %coord [1]) / #stepX + 1
set #y (%temp [#i 2] - %coord [2]) / #stepY + 1
set %field [#y #x] %temp [#i 3] // имя картинки в нужный элемент массива
end_for
log clear
log mode compact
set delimiter ' '
for #i 1 4 // вывод в лог
log %field [#i]
end_for
set delimiter
end_script
Какой размер картинок? 5*5 будет достаточно.
Если цвета уникальные, то можно попробовать findcolor.
init_arr %number 0 2 4 8 16 32 64 128 // цифры
init_arr %number_color 11846093 14345454 13164781 7975410 6526453 6257910 3890934 7524333 // цвета
set #startX 540 // координата X начала поиска
set #startY 140 // координата Y начала поиска
set #stepX 120 // шаг по Y
set #stepY 120 // шаг по Y
log clear
log mode compact
set #endX #startX + #stepX * 4
set #endY #startY + #stepY * 4
set $str_color ""
for #i 1 size(%number_color)
set $str_color $str_color %number_color [#i] // цвета в одну строку
end_for
//log $str_color
set #a findcolor (#startX #startY #endX #endY #stepX #stepY ($str_color) %a) // поиск
hint #a
if #a = 16
for #i 1 4 // заполнить массив 4*4 нулями
init_arr %field (#i) 0 0 0 0
end_for
for #i 1 #a // для всех найденных точек
set #x (%a[#i 1] - #startX) / #stepX + 1
set #y (%a[#i 2] - #startY) / #stepY + 1
for #j 1 size(%number_color)
if %a[#i 3] = %number_color [#j] // если цвет совпадает пишем в массив число, которое находится в клетке
set %field [#y #x] %number [#j]
break
end_if
end_for
end_for
else
log Найдено меньше 16 цветов
end_if
set delimiter ' '
for #i 1 4 // вывод в лог
log %field [#i]
end_for
set delimiter
end_script
init_arr %number 0 2 4 8 16 32 64 128 // цифры
init_arr %number_color 11846093 14345454 13164781 7975410 6526453 6257910 3890934 7524333 // цвета
set #startX 540 // координата X начала поиска
set #startY 140 // координата Y начала поиска
set #stepX 120 // шаг по Y
set #stepY 120 // шаг по Y
log clear
log mode compact
set #endX #startX + #stepX * 4
set #endY #startY + #stepY * 4
set $str_color ""
for #i 1 size(%number_color)
set $str_color $str_color %number_color [#i] // цвета в одну строку
end_for
//log $str_color
set #a findcolor (#startX #startY #endX #endY #stepX #stepY ($str_color) %a) // поиск
hint #a
if #a = 16
for #i 1 4 // заполнить массив 4*4 нулями
init_arr %field (#i) 0 0 0 0
end_for
for #i 1 #a // для всех найденных точек
set #x (%a[#i 1] - #startX) / #stepX + 1
set #y (%a[#i 2] - #startY) / #stepY + 1
for #j 1 size(%number_color)
if %a[#i 3] = %number_color [#j] // если цвет совпадает пишем в массив число, которое находится в клетке
set %field [#y #x] %number [#j]
break
end_if
end_for
end_for
else
log Найдено меньше 16 цветов
end_if
set delimiter ' '
for #i 1 4 // вывод в лог
log %field [#i]
end_for
set delimiter
end_script
init_arr %number 0 2 4 8 16 32 64 128 256 521 1024 2048 // цифры
init_arr %number_color 11846093 13499135 11920639 7975410 6526453 6257910 3890934 7524333 6409453 5294317 55295 65535 // цвета
начал заниматься задачей и который час туплю, делаю блок на смещение массива (для начала на лево), так почемуто одинаковые не складывает а если с лева ноль - то смещает только на одну ячейку, в чем косяк - не пойму
log clear
set delimiter ' '
load_array %test test.txt //загружаю массив для теста
log open 1 1 450 300
for #i 1 4 //вывод в лог массива
log %test [#i] Исходник
end_for
//==cсмещение в ЛЕВО==//
for #i 1 4 //строчка
for #j 2 4 //ячейка
set #jj #j - 1 //левее ячейка
while #j > 1 //зациклюсь
if %test [#i #j] = 0 //пропущу нули
break
else //леввая и правая равны
if %test [#i #j] = %test [#i #jj]
set %test [#i #jj] %test [#i #j] + 1
set %test [#i #j] 0
end_if //левая ноль
if %test [#i #jj] = 0
set %test [#i #jj] %test [#i #j]
set %test [#i #j] 0
end_if
set #j #j - 1
end_if
break
end_while
end_for
log %test [#i] шаг в ЛЕВО //что вышло
end_for
//==считаем суммы==//
set #sum 0 //сумма всех камней
set #zero 0 //количество пустых
set size(%arr) //обнулю массив
for #i 1 4
for #j 1 4
if %test [#i #j] = 0
set #count #count + 1
else
set #sum #sum + %test [#i #j]
end_if
end_for
end_for
set #zero #count
set #sum #sum
log #zero Количество пустых #sum Сумма чисел
init_arr %arr (1) #zero #sum //потом понадобиться
end_script
Когда я пользовался AHK он очень сильно уступал по сути дела во всем.
AutoIT конструктор который сложно сравнивать. Чего нацепляли к нему то и получили. Больше админская у нее направленность. Хотя комбайн еще тот.
На самом деле после подключения Lua очень тяжело все это сравивать, т.к. мы тоже получили комбайн. Мы можем спокойно взаимодействовать с базами данных, сетью, создавать окошки, использовать шифрования, апи мессенджеров и многое другое. Это все спокойно подключается либами и используется.
Либы с трушного сайта https://luapower.com/
Runtimes
luajit
terra
nginx
Deployment
bundle
terra.binder
Standard Libraries
glue
pp
oo
events
coro
errors
lpeg
Portable OS APIs
fs
nw
socket
socketloop
thread
pthread
proc
time
hidapi
Portable UI (WIP)
ui
terra.layer
terra.tr
Portable 2D Graphics
cairo
bitmap
color
boxblur
Native OS APIs
winapi
winapi.wglpanel
winapi.cairopanel
objc
xlib
2D Geometry
path2d
affine2d
box2d
clipper
Image Formats
giflib
libjpeg
libpng
bmp
Unicode
utf8
utf8quot
ucdn
Hashing
xxhash
blake2
sha2
md5
hmac
Compression
zlib
Serialization
cjson
expat
genx
libb64
Networking
luasec
resolver
libcurl
rsync
Databases
mysql
Templating
mustache
Motion
tweening
easing
Spell Checking
hunspell
Data Structures
heap
Lua Support Libs
amoeba
eq
opengl
luastate
cbframe
path
unixperms
dynasm
rangelist
C Support Libs
pixman
libmariadb
openssl
lua-headers
shm
llvm
freetype
harfbuzz
fribidi
libunibreak
pcre
Development Tools
inspect
cplayer
gfonts
hash_benchmark
unit
testui
Web Development
webb
Terra Standard Libraries
terra.low
terra.arrayview
terra.dynarray
terra.hashmap
terra.phf
terra.linkedlist
terra.fixedfreelist
terra.arrayfreelist
terra.lrucache
terra.bitarray
terra.utf8
terra.random
Terra Support Libs
terra.bitmap
terra.cairo
terra.box2d
terra.boxblur
mingw64-headers
Package Management
luapower
luapower_db
luapower-repos
Help needed
libsoundio
videoinput
libexif
lz4
libsodium
libogg
rs232
Unmaintained
ui0
tr0
linkedlist
lrucache
bnet
ffi_reflect
struct
minizip
lanes
Misc
csv
dollar
font_db
fonts-amiri
fonts-awesome
fonts-dejavuserif
fonts-fireflysung
fonts-fixedsys
fonts-ionicons
fonts-material-icons
fonts-noto-emoji
fonts-open-sans
lx
resty-core
resty-lrucache
website
xlsxwrite
log clear
log mode compact
set delimiter ' '
load_array %arr C:\test.txt // массив для теста
log open 1 1 450 350
log Исходник
for #i 1 4 //вывод в лог массива
log %arr [#i]
end_for
//==смещение ВЛЕВО==//
log
log Сложение
for #j 1 4 // для всех строк
for #i 1 3
set #ii #i + 1
if %arr[#j #i] = %arr[#j #ii] // если два соседних элемента равны
set %arr[#j #i] %arr[#j #i] * 2 // складываем их
set %arr[#j #ii] 0 // обнуляем второй
end_if
end_for
end_for
for #i 1 4
log %arr [#i]
end_for
log
log Сдвиг
for #k 1 4 // для всех строк
for #j 1 3 // повторить 3 раза
for #i 1 3 // сдвиг элементов
set #ii #i + 1
if %arr[#k #i] = 0
set %arr[#k #i] %arr[#k #ii]
set %arr[#k #ii] 0
end_if
end_for
end_for
end_for
for #i 1 4
log %arr [#i]
end_for
end_script
Спасибо, просто и без гиморов. Остаётся открытым вопрос, после того как сделается по каждому смещению вычисление количества пустых ячеек и суммы всех чисел массива, и при их сравнении получаться 2 одинаковых результата, как в таком случае поступать. И , вообще , я верно думаю, или совсем тут не так надо решать головоломку
, чтото начал думать дальше, вот что своялось
//==cсмещение в ЛЕВО==//
for #i 1 4 //строчка
for #j 2 4 //ячейка
set #jj #j - 1 //левее ячейка
while #j > 1 //зациклюсь
if %test [#i #j] = 0 //пропущу нули
break
else
if %test [#i #j] = %test [#i #jj] //леввая и правая равны
set %test [#i #jj] %test [#i #j] + 1
set %test [#i #j] 0
set #j #j - 1
break
end_if
if %test [#i #jj] = 0 //левая ноль
set %test [#i #jj] %test [#i #j]
set %test [#i #j] 0
set #j #j - 1
else
break
end_if
set #j #j - 1
break
end_if
break
end_while
end_for
log %test [#i] шаг в ЛЕВО //что вышло
end_for
нашол, два брейка с низу лишних, забыл про них совсем
и так, с этапом сдвига разобрался, работает на ура, пошел на этап работать с зеркальным отображением - с лева в право. Думал что пройдет вариант с for #j 4 2 -1 , но это не прокатило, в общем, сделал так
// ПРАВО
log clear
set delimiter ' '
load_array %test test.txt //загружаю массив для теста
log open 1 1 450 300
for #i 1 4 //вывод в лог массива
log %test [#i] Исходник
end_for
//==делаем зеркало==//
set %tmp %test //возьмем данные их исходника
init_arr %mirror //промежуточный массив
set size(%mirror) //обнулить
for #i 1 4 //
for #j 1 4
set #a size (%tmp) - #j + 1
set %mirror [#i #j] %tmp [#i #a]
end_for
end_for
set %tmp %mirror //закрепим перемещение
set size(%mirror) //очистим промежуточный
for #i 1 4 //вывод в лог массива
log %tmp [#i] Зеркальный
end_for
save_array %tmp tmp.txt //сохраним массив
//==cсмещение в ЛЕВО==//
for #i 1 4 //строчка
for #j 2 4 //ячейка
set #jj #j - 1 //левее ячейка
while #j > 1 //зациклюсь
if %tmp [#i #j] = 0 //пропущу нули
break
else //леввая и правая равны
if %tmp [#i #j] = %tmp [#i #jj]
set %tmp [#i #jj] %tmp [#i #j] + 1
set %tmp [#i #j] 0
set #j #j - 1
break
end_if
if %tmp [#i #jj] = 0 //левее ноль
set %tmp [#i #jj] %tmp [#i #j]
set %tmp [#i #j] 0
set #j #j - 1
else
break
end_if
set #j #j - 1
end_if
end_while
end_for
end_for
for #i 1 4 //вывод в лог массива
log %tmp [#i] в ЛЕВО //что вышло
end_for
//gosub summa
//потом обратно сделать зеркало
end_script
log clear
log mode compact
set delimiter ' '
//load_array %arr C:\test.txt // массив для теста
init_arr %arr (1) 4 0 4 0
init_arr %arr (2) 0 2 2 0
init_arr %arr (3) 2 2 2 2
init_arr %arr (4) 8 8 0 0
log open 1 1 450 350
log Исходник
for #i 1 4 //вывод в лог массива
log %arr [#i]
end_for
//==смещение ВЛЕВО==//
log
log Сложение
for #j 1 4 // для всех строк
for #i 1 3
set #ii #i + 1
if %arr[#j #i] = 0
continue
end_if
while %arr[#j #ii] = 0
set #ii #ii + 1
if #ii > 4
break 2
end_if
end_while
if %arr[#j #i] = %arr[#j #ii] // если два соседних элемента равны
set %arr[#j #i] %arr[#j #i] * 2 // складываем их
set %arr[#j #ii] 0 // обнуляем второй
end_if
end_for
end_for
for #i 1 4
log %arr [#i]
end_for
log
log Сдвиг влево
for #k 1 4 // для всех строк
for #j 1 3 // повторить 3 раза
for #i 1 3 // сдвиг элементов
set #ii #i + 1
if %arr[#k #i] = 0
set %arr[#k #i] %arr[#k #ii]
set %arr[#k #ii] 0
end_if
end_for
end_for
end_for
for #i 1 4
log %arr [#i]
end_for
end_script
log clear
log mode compact
set delimiter ' '
// load_array %arr C:\test.txt // массив для теста
init_arr %arr (1) 4 0 4 0
init_arr %arr (2) 0 2 2 0
init_arr %arr (3) 2 2 2 2
init_arr %arr (4) 8 8 0 0
log open 1 1 450 350
log Исходник
for #i 1 4 //вывод в лог массива
log %arr [#i]
end_for
//==смещение ВПРАВО==//
log
log Сложение
for #j 1 4 // для всех строк
for #i 4 2 -1
set #ii #i - 1
if %arr[#j #i] = 0
continue
end_if
while %arr[#j #ii] = 0
set #ii #ii - 1
if #ii < 1
break 2
end_if
end_while
if %arr[#j #i] = %arr[#j #ii] // если два соседних элемента равны
set %arr[#j #i] %arr[#j #i] * 2 // складываем их
set %arr[#j #ii] 0 // обнуляем второй
end_if
end_for
end_for
for #i 1 4
log %arr [#i]
end_for
log
log Сдвиг вправо
for #k 1 4 // для всех строк
for #j 1 3 // повторить 3 раза
for #i 4 2 -1 // сдвиг элементов
set #ii #i - 1
if %arr[#k #i] = 0
set %arr[#k #i] %arr[#k #ii]
set %arr[#k #ii] 0
end_if
end_for
end_for
end_for
for #i 1 4
log %arr [#i]
end_for
end_script
видимо я постоянно копируюя и видоизменяя, запузырил Брейк, и в результате, из 3 2 2 1 не выходило 4 1 0 0
if %tmp [#i #j] = %tmp [#i #jj]
set %tmp [#i #jj] %tmp [#i #j] + 1
set %tmp [#i #j] 0
set #j #j - 1
break
end_if,
когда идет сравнение двух одинаковых, и по этому он что то объединял а что то нет, как сам пожелает вернее понял, после первого объединения одинаковых, он уходит дальше смотреть условия, а не возвращаеться левее), вощем, пока выход такой - как принудительно его лечить через goto на set #j #j - 1. Из твоих вариантов пока смотрел только на Лево, и там такаже фингня вышла 2 2 2 2 стало 4 4 0 0 , а по сути надо 8 0 0 0, и соответственно, 3 2 2 1 (если не линейно складывать), также выдает 3 3 1 0. А, нет, вру, смотрел я в Право, буду разбираться позже , почему у тебя for #i 4 2 -1 работает, а у меня отказался. но это уже мелочи,
все, плин, это я перегрелся, реально меньше надо за компом сидеть, тупанул, 2 2 2 2 сделает 3 3 0 0, значит было все верно, сам уже над собой ржакаю
проще джаву изучиь чем переписать https://temofeev.ru/info/articles/ii-i-2048-chast-2-minimaks-alfa-beta-otsechenie/
Русская версия Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)