算法案例包括一些实用算法,部分比较复杂,适合有脚本基础的玩家学习,也可以直接复制使用。
调用getNum()即可返回长度81的表num,可依次排列为9×9的数独:
local num={}
--填充是否有效
local function isRowLegal(i,v)
local row,i1=math.floor(i/9),0
for i1=0,8 do
if (v==num[row*9+i1])and(i~=row*9+i1) then
return false
end
end
return true
end
local function isColLegal(i,v)
local col,i1=i%9,0
for i1=0,8 do
if (v==num[i1*9+col])and(i~=i1*9+col) then
return false
end
end
return true
end
local function isSubLegal(i,v)
local row=math.floor(i/9)
local col=i%9
local x1=math.floor(row/3)*3
local y1=math.floor(col/3)*3
local i1,i2=0,0
for i1=0,2 do
for i2=0,2 do
if (v==num[(x1+i1)*9+y1+i2])and(i~=(x1+i1)*9+y1+i2) then
return false
end
end
end
return true
end
local function isLegal(i,v)
if (not(isRowLegal(i,v)))or(not(isColLegal(i,v)))or(not(isSubLegal(i,v))) then
return false
end
return true
end
--递归填充数字
local function setN(i)
if i==81 then
return true
elseif num[i]~=0 then
return setN(i+1)
else
local randOrder,i1={},0
for i1=0,9 do
randOrder[i1]=i1
end
for i1=1,9 do
local r=math.random(0,9)
local t1=randOrder[r]
randOrder[r]=randOrder[i1]
randOrder[i1]=t1
end
for i1=1,9 do
if isLegal(i,randOrder[i1]) then
num[i]=randOrder[i1]
if setN(i+1) then
return true
end
end
end
end
num[i]=0
return false
end
--获取随机数独
local function getNum()
math.randomseed(os.time())
local i1=0
for i1=0,80 do
num[i1]=0
end
setN(0)
return num
end
首先调用mCreat()初始化,然后调用delMo()生成迷宫。迷宫数据存在二维表mox中,1为墙壁,0为空白。调用之前可给w、h、w0、h0赋值,调整迷宫尺寸(必须为奇数)与遍历起点(必须为偶数且小于尺寸):
local mox={}--迷宫数据
local w,h=51,51--迷宫宽高(奇数)
local w0,h0=24,24--生成起点(偶数)
local i,j=0,0--循环
--生成迷宫
local x,y=0,0--当前格
local rec={}--已遍历记录
local st=0--当前步数
local last={}--当前路径
local function isRed(pos)--pos是否可行
i=1
while (i<=#rec)and(rec[i]~=pos)
do
i=i+1
end
if i==#rec+1 then
return true
else
return false
end
end
local function getDr()--获取剩余方向
local dr={}
local c=0
if (y~=2)and(isRed((y-3)*w+x)) then--上0
c=c+1
dr[c]=0
end
if (x~=2)and(isRed((y-1)*w+x-2)) then--左1
c=c+1
dr[c]=1
end
if (y~=h-1)and(isRed((y+1)*w+x)) then--下2
c=c+1
dr[c]=2
end
if (x~=w-1)and(isRed((y-1)*w+x+2)) then--右3
c=c+1
dr[c]=3
end
return c,dr
end
--+--+--
local function mCreat()--初始化
for i=1,h do
mox[i]={}
for j=1,w do
if (i%2==0)and(j%2==0) then
mox[i][j]=0
else
mox[i][j]=1
end
end
end
x=w0
y=h0
rec[#rec+1]=(y-1)*w+x
st=1
last[st]={y,x}
end
local function delMo()--递归生成
--math.randomseed(tostring(os.time()*math.random(1,9999999999)):reverse():sub(1,7))
--math.randomseed(os.time()*math.random(1,9999999999))
local c,dr=getDr()
if c~=0 then
c=dr[math.random(1,c)]
if c==0 then
mox[y-1][x]=0
y=y-2
elseif c==1 then
mox[y][x-1]=0
x=x-2
elseif c==2 then
mox[y+1][x]=0
y=y+2
elseif c==3 then
mox[y][x+1]=0
x=x+2
end
rec[#rec+1]=(y-1)*w+x
st=st+1
last[st]={y,x}
delMo()
elseif st~=1 then
st=st-1
y=last[st][1]
x=last[st][2]
delMo()
end
end
较为简单的排序算法,使用时只需调用bSort(as)即可,传入需要排序的数组:
local function bSort(as)
local t=0
for i=1,#as-1 do
for j=1,#as-i do
if as[j]>as[j+1] then
t=as[j]
as[j]=as[j+1]
as[j+1]=t
end
end
end
end
快速排序效率较高。使用时只需调用qSort(as,t1,t2)即可,传入需要排序的数组和一对基数(一般取t1=1,t2=#as):
local function qSort(as,t1,t2)
local i,j=t1,t2
if i<j then
local t=as[i]
while i<j do
while j>i and as[j]>=t do
j=j-1
end
as[i]=as[j]
while i<j and as[i]<=t do
i=i+1
end
as[j]=as[i]
end
as[i]=t
qSort(as,t1,i-1)
qSort(as,i+1,t2)
end
end
效率较低,一般只在容量较小的数组中使用。调用sSort(as),传入需要排序的数组即可:
local function sSort(as)
for i=1,#as do
local t=i
for j=i+1,#as do
if as[j]<as[t] then
t=j
end
end
as[i],as[t]=as[t],as[i]
end
end