basic_robot/scripts/games/2d rubik square.lua

142 lines
2.8 KiB
Lua

-- 2d rubik cube slide puzzle by rnd in 40 mins
if not init then init = true
m=4;
n=m;
data = {};
nodelist = {};
for i = 1,m do
for j = 1,n do
nodelist[(i-1)*n+j] = "basic_robot:button_"..(64+(n-j+1-1)*n+i)
end
end
for i = 1,m do
data[i] = {};local dat = data[i];
for j = 1,n do
dat[j] = (i-1)*n+j;
end
end
spos = self.spawnpos(); spos.x=spos.x+1; spos.z=spos.z+1
render = function(t,mode) -- mode 1:row, 2: coloumn
if not mode then
for i=1,m do
for j = 1,n do
minetest.swap_node({x=spos.x+i,y=spos.y,z=spos.z+j},{name = nodelist[data[i][j]]})
end
end
return
end
if mode == 1 then -- row only
for i=1,m do
minetest.swap_node({x=spos.x+i,y=spos.y,z=spos.z+t},{name = nodelist[data[i][t]]})
end
return
else -- coloumn only
for j=1,n do
minetest.swap_node({x=spos.x+t,y=spos.y,z=spos.z+j},{name = nodelist[data[t][j]]})
end
return
end
end
pnames = find_player(4);
if not pnames then self.remove() end
player = minetest.get_player_by_name(pnames[1]);
check_rot_dir = function()
local vdir = player:get_look_dir()
local mode = 0;
if math.abs(vdir.x)<math.abs(vdir.z) then
if vdir.z>0 then
mode = 2
else
mode = -2
end
else
if vdir.x>0 then
mode = 1
else
mode = -1
end
end -- rotate in z dir
return mode
end
rotx = function(col,dir)
if dir > 0 then
local tmp = data[1][col]
for i = 1,m-1 do
data[i][col] = data[i+1][col]
end
data[m][col] = tmp
else
local tmp = data[m][col]
for i = m,2,-1 do
data[i][col] = data[i-1][col]
end
data[1][col] = tmp
end
end
rotz = function(row,dir)
if dir > 0 then
local tmp = data[row][1]
for j = 1,n-1 do
data[row][j] = data[row][j+1]
end
data[row][m] = tmp
else
local tmp = data[row][n]
for j = n,2,-1 do
data[row][j] = data[row][j-1]
end
data[row][1] = tmp
end
end
rndshuffle = function(steps)
for step = 1,steps do
local mode = math.random(4);
if mode <=2 then
local z = math.random(m);
if mode == 2 then mode = -1 end
rotx(z,mode)
else
local x = math.random(n);
if mode == 3 then mode = -2 else mode = 2 end
rotz(x,mode)
end
end
end
self.listen_punch(self.pos())
self.label("try to get all letters sorted started with A top left")
rndshuffle(m*n)
render()
end
event = keyboard.get()
if event then
--self.label(serialize(event))
local x = event.x-spos.x;
local z = event.z-spos.z;
local mode = check_rot_dir()
if x>0 and x<=m and z>0 and z<=n then
if math.abs(mode) == 1 then
rotx(z,-mode)
render(z,1)
else
rotz(x,-mode)
render(x,2)
end
end
end