* Алгоритм можно усилить
#!/usr/bin/env lua
-- Copyright (C) Igor Salnikov 2015 --
local SX=8
local SY=8
local FIELD={}
function n2pos(n)
return {
x = (n-1) % SX + 1,
y = math.floor((n-1) / SX) + 1
}
end
function pos2n(p)
if (p.x<1) or (p.x>SX) or (p.y<1) or (p.y>SY) then
return -1
end
return ((p.y-1) * SX + p.x)
end
function plus(n,d)
p = n2pos(n)
p.x = p.x + d.x
p.y = p.y + d.y
return pos2n(p)
end
function walk_invert(fig,n,d)
local r=false
if not on_field(n) then
r=false
elseif get_figure(n).fig==0 then
r=false
elseif get_figure(n).fig==fig then
r=true
elseif walk_invert(fig,plus(n,d),d) then
set_figure(n, {fig=get_figure(n).fig, mark=1}, false)
r=true
end
return r
end
function invert(f,n)
walk_invert(f,plus(n,{x=-1,y=-1}),{x=-1,y=-1});
walk_invert(f,plus(n,{x=-1,y= 0}),{x=-1,y= 0});
walk_invert(f,plus(n,{x=-1,y= 1}),{x=-1,y= 1});
walk_invert(f,plus(n,{x=0, y=-1}),{x=0, y=-1});
walk_invert(f,plus(n,{x=0, y= 1}),{x=0, y= 1});
walk_invert(f,plus(n,{x=1, y=-1}),{x=1, y=-1});
walk_invert(f,plus(n,{x=1, y= 0}),{x=1, y= 0});
walk_invert(f,plus(n,{x=1, y= 1}),{x=1, y= 1});
for p=1, SX*SY do
if get_figure(p).mark==1 then
set_figure(p,{fig=f,mark=0},false)
end
end
end
function set_figure(n, F, inv)
FIELD[n] = F
if inv==true then
invert(F.fig, n)
end
end
function get_figure(n)
return FIELD[n]
end
function on_field(n)
return (n>=1) and (n<=SX*SY);
end
function figure(fig)
local r = '.'
if fig==1 then r='B' elseif fig==-1 then r='r' end
return r
end
function field_power(n)
local p=n2pos(n)
if (p.x==1) or (p.x==SX) or (p.y==1) or (p.y==SY) then
return 2
end
return 1
end
function get_new_pos(F)
local max_p = 0
local max_count = 0
local max_save = {}
for n=1, SX*SY do
if get_figure(n).fig==0 then
local p=pos_power(F.fig, n)
fp = 0
if p>0 then fp = field_power(n) end
if (p>0) and ((fp+p)>max_p) then
max_p = p+fp
max_count = max_count + 1
max_save[max_count] = n
end
end
end
for n=1, SX*SY do
if get_figure(n).fig==0 then
local p=pos_power(F.fig, n)
fp = 0
if p>0 then fp = field_power(n) end
if (p==max_p) then
max_count = max_count + 1
max_save[max_count] = n
end
end
end
return max_save[math.random(max_count)]
end
function walk(fig,n,d)
local r = 0
while true do
if not on_field(n) then
r=0; break;
end
if get_figure(n).fig==0 then
r=0; break;
end
if get_figure(n).fig==fig then
break
end
r=r+1
n=plus(n,d)
end
return r
end
function pos_power(fig, n)
return (
walk(fig, plus(n,{x=-1,y=-1}), {x=-1,y=-1}) +
walk(fig, plus(n,{x=-1,y= 0}), {x=-1,y= 0}) +
walk(fig, plus(n,{x=-1,y= 1}), {x=-1,y= 1}) +
walk(fig, plus(n,{x= 0,y=-1}), {x= 0,y=-1}) +
walk(fig, plus(n,{x= 0,y= 1}), {x= 0,y= 1}) +
walk(fig, plus(n,{x= 1,y=-1}), {x= 1,y=-1}) +
walk(fig, plus(n,{x= 1,y= 0}), {x= 1,y= 0}) +
walk(fig, plus(n,{x= 1,y= 1}), {x= 1,y= 1})
)
end
function has_pos(F)
local r=false
for n=1,SX*SY do
if (get_figure(n).fig==0) and (pos_power(F.fig,n)>0) then
r=true
break
end
end
return r
end
function setup()
math.randomseed(os.time())
for n=1,SX*SY do
set_figure(n, {fig=0,mark=0}, false)
end
set_figure(pos2n({x=4,y=4}),{fig=1,mark=0})
set_figure(pos2n({x=5,y=5}),{fig=1,mark=0})
set_figure(pos2n({x=4,y=5}),{fig=-1,mark=0})
set_figure(pos2n({x=5,y=4}),{fig=-1,mark=0})
end
function stat()
b=0; r=0;
for n=1,SX*SY do
if get_figure(n).fig==1 then b=b+1
elseif get_figure(n).fig==-1 then r=r+1
end
end
print('B='..b..', R='..r)
end
function show()
for n=1,SX*SY do
io.write( figure(get_figure(n).fig) )
if n % SX == 0 then print() end
end
stat()
print()
end
function OnClick(n)
if pos_power(1,n)>0 then
set_figure(n,{fig=1,mark=0},true)
show()
--Pause
--SetLock(true)
--CopyField()
local wait=false
while has_pos({fig=-1}) do
n=get_new_pos({fig=-1})
set_figure(n,{fig=-1,mark=0},true)
if has_pos({fig=1}) then
wait=true
break
end
print('ONE MORE')
end
--SetLock(false)
--if not wait then TheEnd end
end
end
setup()
show()
local n=1
while has_pos({fig=1}) do
print('CYCLE='..n)
OnClick(get_new_pos({fig=1}))
show()
n=n+1
end
Справочник алгоритмов v0.05 © 2007-2025 Igor Salnikov aka SunDoctor