顯示具有 Lua程式 標籤的文章。 顯示所有文章
顯示具有 Lua程式 標籤的文章。 顯示所有文章

2024年5月10日 星期五

引用Lua的一些事

 Lua有分成Load及call二段。Load是將使用者輸入段落轉成binary code。然後用lua_pcall()去執行。

本來是想直接用dll方式引入使用,沒有想到這種型式沒有任何stdio可以用。
用起來可以動作但沒有輸出入,所以判定是沒有用到stdio。只能改用原始碼再引入重編,果然有輸出。
原始的lua.c中有從stdin/stdout做為輸出入。我習慣自己處理輸入而不是用scanf,因為這個函式會卡住其他行程。
故改用loadbuffer()從記憶體做為輸入來源。因為MCU也常常要處理多程序。
再來就是去執行lua_pcall()就會動作。

架好lua核心,當然是要加入使用者要的指令。Lua做得很方便。
使用 luaL_Reg 這個結構矩陣,將指令及函式排起來。最後再用luaLregister()掛進去就可以了。

再來就是寫給Lua調用的C函式。它的外型是固定的,回傳值是放回多少個Lua回傳數目。
以我最常用的招呼函式來寫,會是以下的樣子。




要取用輸入參數,範例如下:
就是取用參數1做為要用的axis,參數2為要啟用的狀態。



要放入回傳值給Lua的範例如下:

可以看到有push三個數值,就是要給lua的值,最後return值就是數目,故這裏給的是3


在某些平台上有時會遇到一個問題,在載入使用者函式庫就當掉,回報原因是釋放了一個空指標。
我又回去看lua.c 發現在載入函式庫時要先停用GC(垃圾收集器),載完後再啟用。


2011年4月13日 星期三

Lua排名急升

在這個月Lua成長到歷史新高,突破1%的佔有率,而且是"急升"。
一切都要感謝Apple。因為Lua已是iPhone上開發的語言。
另一個受惠於Apple的是Objective-C,可見Apple媚力很大。

以Bee猜想,Apple選用Lua是有原因的,其中之一是因為有coroutine。
因為iOS好像是單工(這個是聽來的),所以需要使用者管理多工問題。
而Lua的Coroutine可以在單工下解決多工問題,讓管理變簡單。

再來,可以預測Lua會進前十名。


2009年9月11日 星期五

找質數

function prime(max_value)


    local value = 5;


    local index = 2;


    local root_index = 2;


    local limit = value * value;


    local p = {};


--  local count = 0;


--  initial first value start at 5


    p[1]=2;


    p[2]=3;


--  start find prime


    while value <= max_value do


        local sub_index=2;


        local check_not_prime = 0;


        while sub_index <= root_index do


--          count = count + 1; print(count,value,limit,index,sub_index,p[sub_index]);


        if (value % p[sub_index]) == 0 then check_not_prime = 1; break; end


            sub_index = sub_index + 1;


        end


        if check_not_prime == 0 then


          index = index + 1;


          p[index] = value;


        end


        value = value + 2;


        if( value >= limit ) then


            root_index = root_index + 1;


            limit = p[root_index+1] * p[root_index+1];


        end


    end


-- print all prime


    for i,j in pairs(p) do


        print(i,j);


    end


end


 


-- test


prime(100);


 


-- 程式結束


 


結果使用矩陣p{}儲存,所以要知道目前已有多少數目以index記錄。


已知只要找到現在驗證值value的開根以下的質數做驗證,所以加入root_index告知。


而現值超過上次有效質數平方limit,則要再更新。


2009年2月13日 星期五

為何使用Lua

Lua原先是在尋找小語言時發現的。它是使用C語言寫成的,所以可以用於小型的系統上。原先希望可以用在微控器上。所以才學來玩。
因為自己對電腦語言的產生有興趣,所以也想看看電腦語言是如何做的。
後來發覺這個語言不錯,有一些C語言沒有的特色。像是多回傳值、無指標資料結構。
另外有函式語言的特性及簡單物件的表示法。
在實際使用上,用順了之後,發現這個語言雖小,但很好使用。
不用考量資料要多少欄位,就想到時再加上去,所以使用Lua開發時資料結構都不用擔心。
且具交談式開發的功能,可以不用寫程式直接試函式功能。

Lua真正出名是於"魔獸世界"中採用做為UI語言。不幸的是我完全沒有玩"魔獸世界"。它如何做為嵌入語言,我是沒有那麼清楚。
但是對於Lua如何改善應用程式,使之對於使用者界面,有很好的適應性。這方面我是很有期望。
所以個人認為Lua的使用比BASIC簡單,可以很容易讓一般User使用。這在推廣上有一定的吸引力。

以下為個人整理的特色:
說明文件
    有手冊,但沒有太多入門書
    
學習及除錯
    學習快
    除錯器功能不如商用語言方便
    
使用記憶體大小
    執行檔小
    
函式庫
    移植自C的函式庫很多
    
和其他語言連接能力
    和C有很好的連接性
    
資料操作
    很好
    
其他特性
    物件表示
    函式語言


2008年12月23日 星期二

Lua圖像迷宮


修改成長時轉向的生成機率,讓它和現在位置有關,就可以產生這樣的迷宮圖。

不平衡成長迷宮


加入調整成長的機率,好像會走比較長

找迷宮解程式修改

-- reslove maze
--]]
path={};
search_count = 1;
search_pos={x=start_pos.x, y=start_pos.y, dir=0};
table.insert(path,search_pos);
function read_north()
    if( search_pos.y == 1 ) then return end;
    if( maze[search_pos.x][search_pos.y-1].s == true ) then
        return;
    else
        if ( maze[search_pos.x][search_pos.y-1].v == true ) then
            maze[search_pos.x][search_pos.y-1].v = false;
            local node = {x=search_pos.x, y=search_pos.y-1, dir=3, r=search_count};
            table.insert(path,node);
        end
    end
end
function read_south()
    if( search_pos.y == size.y ) then return end;
    if( maze[search_pos.x][search_pos.y].s == true ) then
        return;
    else
        if ( maze[search_pos.x][search_pos.y+1].v == true ) then
            maze[search_pos.x][search_pos.y+1].v = false;
            local node = {x=search_pos.x, y=search_pos.y+1, dir=1, r=search_count};
            table.insert(path,node);
        end
    end
end
function read_east()
    if( search_pos.x == size.x ) then return end;
    if( maze[search_pos.x][search_pos.y].e == true ) then
        return;
    else
        if ( maze[search_pos.x+1][search_pos.y].v == true ) then
            maze[search_pos.x+1][search_pos.y].v = false;
            local node = {x=search_pos.x+1, y=search_pos.y, dir=4, r=search_count};
            table.insert(path,node);
        end
    end
end
function read_west()
    if( search_pos.x == 1 ) then return end;
    if( maze[search_pos.x-1][search_pos.y].e == true ) then
        return;
    else
        if ( maze[search_pos.x-1][search_pos.y].v == true ) then
            maze[search_pos.x-1][search_pos.y].v = false;
            local node = {x=search_pos.x-1, y=search_pos.y, dir=2, r=search_count};
            table.insert(path,node);
        end
    end
end
while ( not (search_pos.x == target_pos.x and search_pos.y == target_pos.y) ) do
    read_north();
    read_south();
    read_east();
    read_west();
    search_count = search_count + 1;
    search_pos.x = path[search_count].x;
    search_pos.y = path[search_count].y;
    search_pos.dir = path[search_count].dir;
--    print(search_count, search_pos.x, search_pos.y, path[search_count].r );
end
修改為使用訪問過的座標標記的方式。這樣可以解有廻路的迷宮。

2008年12月22日 星期一

Lua程式開發心得:迷宮程式撰寫

迷宮程式在寫的時候,不用考量資料要多少欄位,就想到時再加上去,所以使用Lua開發時資料結構都不用擔心。
再加上Lua for Windows有許多可用的模組,在使用Windows也不用想太多和資源取用的問題。
所以程式可以在沒有規劃下180行就做出來了。
用其他靜態語言,又要改宣告,或改回傳值。光是對資料型別就花了不少時間,一下子就把想法給遺忘了。
Lua真是不錯用。


2008年12月21日 星期日

GD:迷宮產生器及解


require "gd"
grid={x=10,y=10};
size={x=50,y=50};
start_pos={x=1,y=1};
target_pos={x=50,y=50};
maze={};
for u=1,size.x,1 do
    maze[ u]={};
    for v=1,size.y,1 do
        maze[ u][v]={v=false,s=true,e=true};
    end
end
math.randomseed(os.time());
total_count = size.x*size.y;
magic= math.random(1,total_count);
cur_pos={};
function magic_to_pos()
    local x,y;
    magic = (magic + 997)% total_count;
    x = magic % size.x + 1;
    y = math.floor(magic / size.x) + 1;
    return x,y;
end
cur_pos.x , cur_pos.y = magic_to_pos();
cur_pos.dir = math.random(1,4);
maze[cur_pos.x][cur_pos.y].v = true;
cur_count = 1;
function move_north()
    if( cur_pos.y == 1 ) then return false end;
    if( maze[cur_pos.x][cur_pos.y-1].v == true ) then
        return false;
    else
        cur_pos.y = cur_pos.y - 1;
        maze[cur_pos.x][cur_pos.y].s=false;
        maze[cur_pos.x][cur_pos.y].v=true;
        return true;
    end
end
function move_south()
    if( cur_pos.y == size.y ) then return false end;
    if( maze[cur_pos.x][cur_pos.y+1].v == true ) then
        return false;
    else
        maze[cur_pos.x][cur_pos.y].s=false;
        cur_pos.y = cur_pos.y + 1;
        maze[cur_pos.x][cur_pos.y].v=true;
        return true;
    end
end
function move_east()
    if( cur_pos.x == size.x ) then return false end;
    if( maze[cur_pos.x+1][cur_pos.y].v == true ) then
        return false;
    else
        maze[cur_pos.x][cur_pos.y].e=false;
        cur_pos.x = cur_pos.x + 1;
        maze[cur_pos.x][cur_pos.y].v=true;
        return true;
    end
end
function move_west()
    if( cur_pos.x == 1 ) then return false end;
    if( maze[cur_pos.x-1][cur_pos.y].v == true ) then
        return false;
    else
        cur_pos.x = cur_pos.x - 1;
        maze[cur_pos.x][cur_pos.y].e=false;
        maze[cur_pos.x][cur_pos.y].v=true;
        return true;
    end
end
move={move_north,move_east,move_south,move_west};
function gen_path()
    while (move[cur_pos.dir]()) do
        local dir = math.random(-1,1);
--        print("Dir=",dir);
        cur_count = cur_count + 1;
        cur_pos.dir = (dir+cur_pos.dir-1)%4+1;
--        print(cur_pos.x,cur_pos.y,cur_pos.dir);
    end
end
function new_path()
    cur_pos.x, cur_pos.y = magic_to_pos();
    while (maze[cur_pos.x][cur_pos.y].v == false) do
        cur_pos.x, cur_pos.y = magic_to_pos();
    end
    cur_pos.dir = math.random(1,4);
end
while ( cur_count < total_count ) do
    gen_path();
    new_path();
end
-- print(cur_count);
-- plot maze
im = gd.createTrueColor(grid.x*size.x+1,grid.y*size.y+1);
white = im:colorResolve(255,255,255);
red   = im:colorResolve(255,  0,  0);
green = im:colorResolve(  0,255,  0);
blue  = im:colorResolve(  0,  0,255);
im:line(  0, 0, grid.x*size.x, 0, green);
im:line(  0, 0, 0, grid.y*size.y, green);
for v=1,size.y,1 do
    for u=1,size.x,1 do
        if(maze[ u][v].e) then
            im:line(  grid.x*u, grid.y*(v-1),  grid.x*u,  grid.y*v, green);
        end
        if(maze[ u][v].s) then
            im:line(  grid.x*(u-1), grid.y*v,  grid.x*u,  grid.y*v, green);
        end
    end
end
-- im:png("maze.png");
-- reslove maze
--]]
path={};
search_count = 1;
search_pos={x=start_pos.x, y=start_pos.y, dir=0};
table.insert(path,search_pos);
function read_north()
    if( search_pos.y == 1 ) then
        return;
    else
        if ( not maze[search_pos.x][search_pos.y-1].s ) then
            local node = {x=search_pos.x, y=search_pos.y-1, dir=3, r=search_count};
            table.insert(path,node);
        end
    end
end
function read_south()
    if( search_pos.y == size.y ) then
        return;
    else
        if ( not maze[search_pos.x][search_pos.y].s ) then
            local node = {x=search_pos.x, y=search_pos.y+1, dir=1, r=search_count};
            table.insert(path,node);
        end
    end
end
function read_east()
    if( search_pos.x == size.x ) then
        return;
    else
        if ( not maze[search_pos.x][search_pos.y].e ) then
            local node = {x=search_pos.x+1, y=search_pos.y, dir=4, r=search_count};
            table.insert(path,node);
        end
    end
end
function read_west()
    if( search_pos.x == 1 ) then
        return;
    else
        if ( not maze[search_pos.x-1][search_pos.y].e ) then
            local node = {x=search_pos.x-1, y=search_pos.y, dir=2, r=search_count};
            table.insert(path,node);
        end
    end
end
while ( not (search_pos.x == target_pos.x and search_pos.y == target_pos.y) ) do
    if( search_pos.dir ~= 1 ) then read_north() end;
    if( search_pos.dir ~= 3 ) then read_south() end;
    if( search_pos.dir ~= 2 ) then read_east() end;
    if( search_pos.dir ~= 4 ) then read_west() end;
    search_count = search_count + 1;
    search_pos.x = path[search_count].x;
    search_pos.y = path[search_count].y;
    search_pos.dir = path[search_count].dir;
--    print(search_count, search_pos.x, search_pos.y, path[search_count].r );
end
-- print(search_count, search_pos.x, search_pos.y, path[search_count].r );
r_count  = path[search_count].r;
rr_count = search_count;
while ( r_count > 1 ) do
--    print( path[r_count].x, path[r_count].y );
    im:line(path[rr_count].x*grid.x-grid.x/2, path[rr_count].y*grid.y-grid.y/2, path[r_count].x*grid.x-grid.x/2, path[r_count].y*grid.y-grid.y/2, red);
    rr_count= r_count;
    r_count = path[r_count].r;
end
im:line(path[rr_count].x*grid.x-grid.x/2, path[rr_count].y*grid.y-grid.y/2, start_pos.x*grid.x-grid.x/2, start_pos.y*grid.y-grid.y/2, red);
im:jpeg("r-maze.jpg",100);



GD:迷宮產生器


require "gd"
grid={x=10,y=10};
size={x=50,y=50};
maze={};
for u=1,size.x,1 do
    maze[u]={};
    for v=1,size.y,1 do
        maze[u][v]={v=false,s=true,e=true};
    end
end
math.randomseed(os.time());
total_count = size.x*size.y;
magic= math.random(1,total_count);
cur_pos={};
function magic_to_pos()
    local x,y;
    magic = (magic + 997)% total_count;
    x = magic % size.x + 1;
    y = math.floor(magic / size.x) + 1;
    return x,y;
end
cur_pos.x , cur_pos.y = magic_to_pos();
cur_pos.dir = math.random(1,4);
maze[cur_pos.x][cur_pos.y].v = true;
cur_count = 1;
function move_north()
    if( cur_pos.y == 1 ) then return false end;
    if( maze[cur_pos.x][cur_pos.y-1].v == true ) then
        return false;
    else
        cur_pos.y = cur_pos.y - 1;
        maze[cur_pos.x][cur_pos.y].s=false;
        maze[cur_pos.x][cur_pos.y].v=true;
        return true;
    end
end
function move_south()
    if( cur_pos.y == size.y ) then return false end;
    if( maze[cur_pos.x][cur_pos.y+1].v == true ) then
        return false;
    else
        maze[cur_pos.x][cur_pos.y].s=false;
        cur_pos.y = cur_pos.y + 1;
        maze[cur_pos.x][cur_pos.y].v=true;
        return true;
    end
end
function move_east()
    if( cur_pos.x == size.x ) then return false end;
    if( maze[cur_pos.x+1][cur_pos.y].v == true ) then
        return false;
    else
        maze[cur_pos.x][cur_pos.y].e=false;
        cur_pos.x = cur_pos.x + 1;
        maze[cur_pos.x][cur_pos.y].v=true;
        return true;
    end
end
function move_west()
    if( cur_pos.x == 1 ) then return false end;
    if( maze[cur_pos.x-1][cur_pos.y].v == true ) then
        return false;
    else
        cur_pos.x = cur_pos.x - 1;
        maze[cur_pos.x][cur_pos.y].e=false;
        maze[cur_pos.x][cur_pos.y].v=true;
        return true;
    end
end
move={move_north,move_east,move_south,move_west};
function gen_path()
    while (move[cur_pos.dir]()) do
        local dir = math.random(-1,1);
--        print("Dir=",dir);
        cur_count = cur_count + 1;
        cur_pos.dir = (dir+cur_pos.dir-1)%4+1;
--        print(cur_pos.x,cur_pos.y,cur_pos.dir);
    end
end
function new_path()
    cur_pos.x, cur_pos.y = magic_to_pos();
    while (maze[cur_pos.x][cur_pos.y].v == false) do
        cur_pos.x, cur_pos.y = magic_to_pos();
    end
    cur_pos.dir = math.random(1,4);
end
while ( cur_count < total_count ) do
    gen_path();
    new_path();
end
-- print(cur_count);
-- plot maze
im = gd.createTrueColor(grid.x*size.x+1,grid.y*size.y+1);
white = im:colorResolve(255,255,255);
red   = im:colorResolve(255,  0,  0);
green = im:colorResolve(  0,255,  0);
blue  = im:colorResolve(  0,  0,255);
im:line(  0, 0, grid.x*size.x, 0, green);
im:line(  0, 0, 0, grid.y*size.y, green);
for v=1,size.y,1 do
    for u=1,size.x,1 do
        if(maze[u][v].e) then
            im:line(  grid.x*u, grid.y*(v-1),  grid.x*u,  grid.y*v, green);
        end
        if(maze[u][v].s) then
            im:line(  grid.x*(u-1), grid.y*v,  grid.x*u,  grid.y*v, green);
        end
    end
end
im:jpeg("maze.jpg",100);


2008年12月16日 星期二

GD:葉形線


require "gd"
n = 3.1;
m = 20;
size = 200;
im = gd.createTrueColor(size+1,size+1);
white = im:colorResolve(255,255,255);
red   = im:colorResolve(255,  0,  0);
green = im:colorResolve(  0,255,  0);
blue  = im:colorResolve(  0,  0,255);
offset = { x=size/2 , y=size/2 };
last = {};
for u=0, m*math.pi, 0.001 do
    r=size/2.5 * math.sin(n*u) + 10;
    new={ x = r*math.cos(u)+offset.x , y = r*math.sin(u)+offset.y};
    if last.x == nil then
        first = { x=new.x , y=new.y};
    else
        im:line(  last.x, last.y,  new.x,  new.y, green);
    end
    last= {x = new.x , y = new.y};
end
im:line(  last.x, last.y,  first.x,  first.y, green);
im:jpeg("tt.jpg",100);
-- 程式結束
Lua其實還满好用的,很快就可以得到結果了。
又因任http://bbs.luaer.cn/index.php版主,所以寫了點程式交代一下。