math.randomseed(os.time()) --local debugging = false if not debugging then print = function(...) end end --local cam = scene.newcamera({10,10,10},{0,0,0},0) --print("Hello from mahjong.lua") --local w = 54 --local h = 90 --local img = video.newiimage(video.R8G8B8,{w,h}) --local tex = video.newtexture("whatever",img) --[[ Represent the world as a 3d grid, where each tile covers a 2x2x1 space, so that we don't have to worry about half-grids. Each space is either "empty", "occupied by tile X" or "tile X" ]] local tiles = {} do for i = 1,9 do tiles[#tiles + 1] = "bamboo" .. tostring(i) tiles[#tiles + 1] = "circle" .. tostring(i) end for i = 1,15 do tiles[#tiles + 1] = "pinyin" .. tostring(i) end tiles[#tiles + 1] = "fall" tiles[#tiles + 1] = "spring" tiles[#tiles + 1] = "summer" tiles[#tiles + 1] = "winter" tiles[#tiles + 1] = "lotus" tiles[#tiles + 1] = "orchid" tiles[#tiles + 1] = "peony" end local function print_puzzle(puzzle) print(debug.traceback()) for l,layer in ipairs(puzzle.tiles) do print("Layer",l) local guide1 = {} local guide2 = {} for i = 1,puzzle.unused_spots.columns do guide1[i] = math.floor(i / 10) guide2[i] = i % 10 end print(" " .. table.concat(guide1," ")) print(" " .. table.concat(guide2," ")) print() for i = 1, puzzle.unused_spots.rows do local bld = {string.format("%02d ",i)} for j=1,puzzle.unused_spots.columns do if puzzle.tiles[l][i][j] then bld[#bld + 1] = puzzle.tiles[l][i][j].n else bld[#bld + 1] = 0 end bld[#bld] = string.format("%2d",bld[#bld]) end print(table.concat(bld," ")) end end end function math.round(num) if num % 1 > 0.5 then return math.ceil(num) else return math.floor(num) end end function rep(value,times) local ret = {} for i = 1,times do ret[i] = value end return unpack(ret) end local turtle = { columns = 15 * 2, rows = 8 * 2, layers = 5, --First layer { --First row {0,0, 1,2, 1,2, 1,2, 1,2, 1,2, 1,2, 1,2, 1,2, 1,2, 1,2, 1,2, 1,2, 0,0, 0,0}, {0,0, 2,2, 2,2, 2,2, 2,2, 2,2, 2,2, 2,2, 2,2, 2,2, 2,2, 2,2, 2,2, 0,0, 0,0}, --Second row {0,0, 0,0, 0,0, 1,2, 1,2, 1,2, 1,2, 1,2, 1,2, 1,2, 1,2, 0,0, 0,0, 0,0, 0,0}, {0,0, 0,0, 0,0, 2,2, 2,2, 2,2, 2,2, 2,2, 2,2, 2,2, 2,2, 0,0, 0,0, 0,0, 0,0}, --Third row {0,0, 0,0, 1,2, 1,2, 1,2, 1,2, 1,2, 1,2, 1,2, 1,2, 1,2, 1,2, 0,0, 0,0, 0,0}, {0,0, 0,0, 2,2, 2,2, 2,2, 2,2, 2,2, 2,2, 2,2, 2,2, 2,2, 2,2, 0,0, 0,0, 0,0}, --Fourth row {0,0, 1,2, 1,2, 1,2, 1,2, 1,2, 1,2, 1,2, 1,2, 1,2, 1,2, 1,2, 1,2, 0,0, 0,0}, {1,2, 2,2, 2,2, 2,2, 2,2, 2,2, 2,2, 2,2, 2,2, 2,2, 2,2, 2,2, 2,2, 1,2, 1,2}, --Fifth row {2,2, 1,2, 1,2, 1,2, 1,2, 1,2, 1,2, 1,2, 1,2, 1,2, 1,2, 1,2, 1,2, 2,2, 2,2}, {0,0, 2,2, 2,2, 2,2, 2,2, 2,2, 2,2, 2,2, 2,2, 2,2, 2,2, 2,2, 2,2, 0,0, 0,0}, --Sixth row {0,0, 0,0, 1,2, 1,2, 1,2, 1,2, 1,2, 1,2, 1,2, 1,2, 1,2, 1,2, 0,0, 0,0, 0,0}, {0,0, 0,0, 2,2, 2,2, 2,2, 2,2, 2,2, 2,2, 2,2, 2,2, 2,2, 2,2, 0,0, 0,0, 0,0}, --Seventh row {0,0, 0,0, 0,0, 1,2, 1,2, 1,2, 1,2, 1,2, 1,2, 1,2, 1,2, 0,0, 0,0, 0,0, 0,0}, {0,0, 0,0, 0,0, 2,2, 2,2, 2,2, 2,2, 2,2, 2,2, 2,2, 2,2, 0,0, 0,0, 0,0, 0,0}, --Eighth row {0,0, 1,2, 1,2, 1,2, 1,2, 1,2, 1,2, 1,2, 1,2, 1,2, 1,2, 1,2, 1,2, 0,0, 0,0}, {0,0, 2,2, 2,2, 2,2, 2,2, 2,2, 2,2, 2,2, 2,2, 2,2, 2,2, 2,2, 2,2, 0,0, 0,0}, }, --Second layer { --First row {0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}, {0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}, --Second row {0,0, 0,0, 0,0, 0,0, 1,2, 1,2, 1,2, 1,2, 1,2, 1,2, 0,0, 0,0, 0,0, 0,0, 0,0}, {0,0, 0,0, 0,0, 0,0, 2,2, 2,2, 2,2, 2,2, 2,2, 2,2, 0,0, 0,0, 0,0, 0,0, 0,0}, --Third row {0,0, 0,0, 0,0, 0,0, 1,2, 1,2, 1,2, 1,2, 1,2, 1,2, 0,0, 0,0, 0,0, 0,0, 0,0}, {0,0, 0,0, 0,0, 0,0, 2,2, 2,2, 2,2, 2,2, 2,2, 2,2, 0,0, 0,0, 0,0, 0,0, 0,0}, --Fourth row {0,0, 0,0, 0,0, 0,0, 1,2, 1,2, 1,2, 1,2, 1,2, 1,2, 0,0, 0,0, 0,0, 0,0, 0,0}, {0,0, 0,0, 0,0, 0,0, 2,2, 2,2, 2,2, 2,2, 2,2, 2,2, 0,0, 0,0, 0,0, 0,0, 0,0}, --Fifth row {0,0, 0,0, 0,0, 0,0, 1,2, 1,2, 1,2, 1,2, 1,2, 1,2, 0,0, 0,0, 0,0, 0,0, 0,0}, {0,0, 0,0, 0,0, 0,0, 2,2, 2,2, 2,2, 2,2, 2,2, 2,2, 0,0, 0,0, 0,0, 0,0, 0,0}, --Sixth row {0,0, 0,0, 0,0, 0,0, 1,2, 1,2, 1,2, 1,2, 1,2, 1,2, 0,0, 0,0, 0,0, 0,0, 0,0}, {0,0, 0,0, 0,0, 0,0, 2,2, 2,2, 2,2, 2,2, 2,2, 2,2, 0,0, 0,0, 0,0, 0,0, 0,0}, --Seventh row {0,0, 0,0, 0,0, 0,0, 1,2, 1,2, 1,2, 1,2, 1,2, 1,2, 0,0, 0,0, 0,0, 0,0, 0,0}, {0,0, 0,0, 0,0, 0,0, 2,2, 2,2, 2,2, 2,2, 2,2, 2,2, 0,0, 0,0, 0,0, 0,0, 0,0}, --Eighth row {0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}, {0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}, }, --Third layer { --First row {0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}, {0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}, --Second row {0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}, {0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}, --Third row {0,0, 0,0, 0,0, 0,0, 0,0, 1,2, 1,2, 1,2, 1,2, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}, {0,0, 0,0, 0,0, 0,0, 0,0, 2,2, 2,2, 2,2, 2,2, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}, --Fourth row {0,0, 0,0, 0,0, 0,0, 0,0, 1,2, 1,2, 1,2, 1,2, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}, {0,0, 0,0, 0,0, 0,0, 0,0, 2,2, 2,2, 2,2, 2,2, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}, --Fifth row {0,0, 0,0, 0,0, 0,0, 0,0, 1,2, 1,2, 1,2, 1,2, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}, {0,0, 0,0, 0,0, 0,0, 0,0, 2,2, 2,2, 2,2, 2,2, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}, --Sixth row {0,0, 0,0, 0,0, 0,0, 0,0, 1,2, 1,2, 1,2, 1,2, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}, {0,0, 0,0, 0,0, 0,0, 0,0, 2,2, 2,2, 2,2, 2,2, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}, --Seventh row {0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}, {0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}, --Eighth row {0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}, {0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}, }, --Fourth layer { --First row {0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}, {0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}, --Second row {0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}, {0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}, --Third row {0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}, {0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}, --Fourth row {0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 1,2, 1,2, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}, {0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 2,2, 2,2, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}, --Fifth row {0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 1,2, 1,2, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}, {0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 2,2, 2,2, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}, --Sixth row {0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}, {0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}, --Seventh row {0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}, {0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}, --Eighth row {0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}, {0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}, }, --Fifth layer { --First row {0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}, {0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}, --Second row {0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}, {0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}, --Third row {0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}, {0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}, --Fourth row {0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}, {0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,1, 2,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}, --Fifth row {0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,2, 2,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}, {0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}, --Sixth row {0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}, {0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}, --Seventh row {0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}, {0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}, --Eighth row {0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}, {0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}, } } local types = { empty = 0, tile = 1, usedby = 2 } local current_tile = nil local tilewidth = 28 local tileheight = 40 local layeroffx = 8 local layeroffy = -8 local function create_tile(number) number = (number % #tiles) + 1 local tex = video.newtexturefromfile("../data/fulltiles/" .. tiles[number] .. ".png") local newtile = { tiletype = types.tile, iguitexture = gui.newiguiimage({0,0},true,tex), rect = {{0,0},{tilewidth,tileheight}}, n = number } current_tile = newtile return newtile end local tileactualx = 32 local tileactualy = 48 local function set_tile_pos(tile,layer,row,column) print("Setting a tile to", layer,row,column) local x = (row * tilewidth) + (layer * layeroffx) local y = (column * tileheight) + (layer * layeroffy) tile.iguitexture:move({x,y}) tile.rect = {{x,y},{x+(tileactualx*2),y+(tileactualy*2)}} tile.position = {layer,row,column} end --Checks if a tile is free to move local function is_free(puzzle,tile) local layer,col,row = unpack(tile.position) --print("Checking if tile at ", layer, row, col , " is free") local has_tile_over = false for i = layer+1,puzzle.unused_spots.layers do for j = col-1,col+1 do for k = row - 1, row + 1 do --print("Checking if there is a tile at ", i, k, j) if puzzle.tiles[i] and puzzle.tiles[i][k] and puzzle.tiles[i][k][j] ~= nil then --print("There was!") has_tile_over = true end if has_tile_over then break end end if has_tile_over then break end end if has_tile_over then break end end if has_tile_over then return false end local can_move_left = true for i = col-1,0,-1 do if not can_move_left then break end for j = -1,1 do --print("Checking for any tiles at ",layer,row + j,i) if puzzle.tiles[layer] and puzzle.tiles[layer][row + j] and puzzle.tiles[layer][row + j][i] ~= nil then --print("Cannot move left") can_move_left = false break end end end if can_move_left then return true end local can_move_right = true for i = col+1,puzzle.unused_spots.columns do if not can_move_right then break end for j = -1,1 do --print("Checking for any tiles at ",layer,row + j,i) if puzzle.tiles[layer] and puzzle.tiles[layer][row + j] and puzzle.tiles[layer][row + j][i] ~= nil then --print("Cannot move right") can_move_right = false break end end end return can_move_right end local function any_free(puzzle) local free = {} for layer = 1,puzzle.unused_spots.layers do for row = 1,puzzle.unused_spots.rows do for col = 1,puzzle.unused_spots.columns do local tile = puzzle.tiles[layer][row][col] if tile then print("Found a tile at", layer, row, col) end if tile and is_free(puzzle,tile) then print("Found a free tile at", layer, row, col) print("n was", tile.n) if free[tile.n] == nil then free[tile.n] = 1 else free[tile.n] = free[tile.n] + 1 end end end end end for k,v in pairs(free) do if v > 1 then return true end end return false end local function deepcopy(tbl) print(debug.traceback()) print("making a deep copy of",tbl) for k,v in pairs(tbl) do print(k,":",v) end local ret = {} for k,v in pairs(tbl) do local key,value if type(k) == "table" then key = deepcopy(k) else key = k end if type(v) == "table" then value = deepcopy(v) else value = v end ret[key] = value end return ret end --Generates a puzzle local function gen_puzzle(pattern) print("Pattern is", pattern) local puz = { unused_spots = deepcopy(pattern), tiles = {} --Layers } for l,layer in ipairs(puz.unused_spots) do puz.tiles[l] = {} for r,row in pairs(layer) do puz.tiles[l][r] = {} end end --Returns canfit,layer,row,column if a peice can fit in this row in this puzzle local function find_unused_spot(puzzle) print("finding unused spots") print(debug.traceback()) local potential_spots = {} local layernum = 1 print("Looking for unused positions in :") for l,layer in ipairs(puzzle.unused_spots) do print("Layer",l) local guide1 = {} local guide2 = {} for i = 1,puzzle.unused_spots.columns do guide1[i] = math.floor(i / 10) guide2[i] = i % 10 end --print(" " .. table.concat(guide1," ")) --print(" " .. table.concat(guide2," ")) --print() for r,row in pairs(layer) do local sb = {} for c,col in pairs(row) do sb[c] = col end --print(string.format("%02d ",r) .. table.concat(sb," ")) end end print("Continueing...") for row = 1,puzzle.unused_spots.rows do --print("Looking at row", row) local from_left = 0 for col=(puzzle.unused_spots.columns/2),1,-1 do --print("Looking at column", col) for layer=1,puzzle.unused_spots.layers do --print("Looking at layer", layer) --print("From_left was", from_left) local tel = puzzle.unused_spots[layer][row][col] --print("tel was", tel) if from_left == 0 and tel == 1 then --print("found an unused spot") from_left = {layer,row,col} --elseif from_left == 0 and tel == 2 then ----print("Hit no left") ---- there's not from_left avaliable for this row --from_left = -1 --break elseif from_left ~= 0 then --print("found something, breaking...") break end end if from_left ~= 0 then break end end --print("Got from_left") local from_right = 0 for col=puzzle.unused_spots.columns/2,puzzle.unused_spots.columns,1 do for layer=1,puzzle.unused_spots.layers do if from_right== 0 and puzzle.unused_spots[layer][row][col] == 1 then from_right = {layer,row,col} --elseif from_right == 0 and puzzle.unused_spots[layer][row][col] == 2 then ----Theres no from_right avaliable for this row --from_right = -1 --break elseif from_right ~= 0 then break end end if from_right ~= 0 then break end end --print("Got from_right") --print("from left is", from_left) --print("from right is", from_right) local spots_same = true if type(from_left) == "table" and type(from_right) == "table" then --print("Checking if spots same",table.concat(from_left,","),table.concat(from_right,",")) for i = 1,3 do if from_left[i] ~= from_right[i] then spots_same = false break end end elseif from_left == 0 or from_right == 0 then spots_same = false end --print("Spots_same is", spots_same) --print("Looking at same spots") if not spots_same then if from_left ~= 0 then potential_spots[#potential_spots + 1] = from_left end if from_right ~= 0 then potential_spots[#potential_spots + 1] = from_right end elseif spots_same and type(from_left) == "table" then potential_spots[#potential_spots + 1] = from_left end end --print("Found ", #potential_spots, " unused spots...") return potential_spots end --print("Finding an unused spot:") local spots = find_unused_spot(puz) for spotnum,spot in pairs(spots) do --print("Spot", spotnum, ":", spot[1],",",spot[2],",",spot[3]) end --Iterate through integers, putting the same number of each kind of tile on the board. local tilenum = 0 while true do local can_place_into = false local potential_spots = find_unused_spot(puz) print("Number of potential spots is", #potential_spots) --print("Potential spots is:") --for k,v in pairs(potential_spots) do --print(k,":") --print("\t",table.concat(v,",")) --end if #potential_spots == 0 then print("Potential spots is 0! break!") break end if #potential_spots == 1 then --We've generated ourselves into a corner, try again print("I want to crash!") print("Generated into corner!") coroutine.yield() local pn = gen_puzzle(pattern) return pn end local numpotspots = #potential_spots local rng1 = math.random(1,numpotspots) local rng2 = math.random(1,numpotspots-1) --print("rng1 is", rng1) --print("rng2 is", rng2) local spot1 = potential_spots[rng1] local spot2 = potential_spots[rng2] --if spot1 == spot2 then --spot2 = potential_spots[rng2+1] --end --print("spot1 is", spot1, "(" .. table.concat(spot1,",") .. ")") --print("spot2 is", spot2, "(" .. table.concat(spot2,",") .. ")") if not spot1 or not spot2 then crash() end local spots_same = true for i = 1,3 do if spot1[i] ~= spot2[i] then spots_same = false break end end if not spots_same then puz.tiles[spot1[1]][spot1[2]][spot1[3]] = tilenum puz.tiles[spot2[1]][spot2[2]][spot2[3]] = tilenum for i = 0,1 do for j = 0,1 do local x1,y1,z1 = spot1[1],spot1[2] + i,spot1[3] + j local x2,y2,z2 = spot2[1],spot2[2] + i,spot2[3] + j puz.unused_spots[x1][y1][z1] = 0 puz.unused_spots[x2][y2][z2] = 0 end end for k,v in pairs({spot1,spot2}) do --local tile = create_tile(tilenum) --set_tile_pos(tile,v[1],v[3],v[2]) --puz.tiles[v[1]][v[2]][v[3]] = tile end tilenum = tilenum + 101 end coroutine.yield(puz) end for layer = 1,puz.unused_spots.layers do for col = puz.unused_spots.columns,1,-1 do for row = 1,puz.unused_spots.rows do local tilenum = puz.tiles[layer][row][col] if tilenum then local tile = create_tile(tilenum) set_tile_pos(tile,layer,col,row) puz.tiles[layer][row][col] = tile coroutine.yield() end end end end return puz end for i = 1,10 do print(math.round(math.random(1,2))) end local puzzle = nil local e local co = coroutine.create(function() return gen_puzzle(turtle) end) local ogt = GAME.tick local game_generated = false function GAME.tick() print("Running tick...\n") if coroutine.status(co) == "suspended" then e,puzzle = coroutine.resume(co) if not e then error(puzzle) co = coroutine.create(function() return gen_puzzle(turtle) end) end else print("After generation, puzzle was", puzzle) game_generated = true end if ogt then ogt() end end --print_puzzle(puzzle) local xoff = 36 local yoff = 30 local rectx = tilewidth local recty = tileheight local selected = nil local game_has_ended = false function GAME.onMouseDown(x,y,mouse) local possible_tiles = {} for layernum,layer in pairs(puzzle.tiles) do for rownum,row in pairs(layer) do for colnum,tile in pairs(row) do local clip = tile.rect if x > clip[1][1] and x < clip[2][1] and y > clip[1][2] and y < clip[2][2] then possible_tiles[#possible_tiles + 1] = tile end end end end local toptile = possible_tiles[#possible_tiles] if toptile == nil then return end local has_removed = false -- Check if the tile we selected can move if is_free(puzzle,toptile) then if selected == nil then selected = toptile selected.iguitexture:setcolor({255,0,0,255}) else if toptile.n == selected.n and toptile ~= selected then toptile.iguitexture:remove() selected.iguitexture:remove() toptile.iguitexture = nil selected.iguitexture = nil tl,tc,tr = unpack(toptile.position) sl,sc,sr = unpack(selected.position) puzzle.tiles[tl][tr][tc] = nil puzzle.tiles[sl][sr][sc] = nil selected = nil has_removed = true else selected.iguitexture:setcolor({255,255,255,255}) selected = toptile selected.iguitexture:setcolor({255,0,0,255}) end end end --Check to see if the tile we removed has finished the game local numtiles = 0 if has_removed then for layernum,layer in pairs(puzzle.tiles) do if numtiles > 0 then break end for rownum,row in pairs(layer) do if numtiles > 0 then break end for columnnum,tile in pairs(row) do if tile ~= nil then numtiles = numtiles + 1 break end end end end else numtiles = 1 -- don't finish the game if we didn't remove a tile end --We're done! End the game! if numtiles == 0 then game_has_ended = true end if not any_free(puzzle) and not game_has_ended then error("You fail! (no moves left)") end --::foundtile:: end local fireworks = {} local stars = {} local screenw = scrw() local screeny = scrh() print("About to create firework star image") local starwidth = 3 local starheight = 3 local riseimg= video.newiimage(video.A8R8G8B8,{starwidth,starheight}) for i = starheight - starwidth,1,-1 do print("Going through loop, i is",i) local color = {255,255,255,255} --alpha = 127 it's not there, alpha = 128 it's there riseimg:setPixel({0,i},color,true) riseimg:setPixel({1,i-1},color,true) riseimg:setPixel({2,i},color,true) end local bloomwidth,bloomheight = 100,100 local starimg = video.newiimage(video.A8R8G8B8,{bloomwidth,bloomheight}) for i = -bloomwidth,bloomwidth do for j = -bloomheight, bloomheight do if math.abs(i^2 + j^2) > 50^2 then starimg:setPixel({i + (bloomwidth / 2),j + (bloomheight / 2)},{255,255,255,255},true) end end end local fizzleimg = video.newiimage(video.A8R8G8B8,{3,3}) for i = 0,2 do for j = 0,2 do fizzleimg:setPixel({i,j},{255,255,255,255},true) end end local sparkimg = video.newiimage(video.A8R8G8B8,{1,1}) sparkimg:setPixel({0,0},{255,255,255,255},true) print("Done creating firework star image") print("video is:") for k,v in pairs(video) do print(k,":",v) end local risetex = video.newtexture("rise",riseimg) local startex = video.newtexture("w/e",starimg) local fizzletex = video.newtexture("fizz",fizzleimg) local sparktex = video.newtexture("spark",sparkimg) local fadetest = video.newiimage(video.A8R8G8B8,{100,100}) for i = 0,99 do for j = 0,99 do fadetest:setPixel({i,j},{i+j,i+j,i+j,i+j},true) end end print("video:",video) for k,v in pairs(video) do print(k,":",v) end for k,v in pairs(fadetest) do print(k,":",v) end local fadetex = video.newtexture("test",fadetest) local left = true local loadpos = 0 GAME.draw = function() if not game_generated then if left then loadpos = loadpos + 1 end video.drawtexture(fadetex,{screenw/2 - 100,screeny/2 - 5},{{0,0},{loadpos,10}},{255,255,255,255},true) end for _,v in pairs(fireworks) do for i = 1,3 do local tcolor = {} for k,v in pairs(v.color) do tcolor[k] = v end tcolor[4] = 255 - (i * 15) video.drawtexture(risetex,{v.x,v.y + i},{{0,0},{starwidth,starheight}},tcolor,true) end end local fw, fh = 20,20 local stars_to_remove = {} for _,v in pairs(stars) do local fizzle_in = false for i,j in pairs(v.fizzles) do video.drawtexture(fizzletex,{j.x,j.y},{{0,0},{3,3}},v.color,true) j.x = j.x + j.vx j.y = j.y + j.vy if math.random(0,1) == 1 then j.vy = j.vy + 1 end if j.y < screenw then fizzle_in = true end end if not fizzle_in then stars_to_remove[v] = true end end local cursor1 = 1 local cursor2 = 1 local starlen = #stars while cursor1 < starlen do if stars_to_remove[stars[cursor1]] then cursor2 = cursor2 + 1 else cursor1 = cursor1 + 1 cursor2 = cursor2 + 1 end stars[cursor1] = stars[cursor2] end end local function create_firework() local xstart = math.random(50,screenw) local rngcolor = {} --Only generate "bright" colors: -- 1 color should be close to 255 -- 1 color should be close to 0 -- the last color can range from 0 to 255 local bright = math.random(1,3) local dark = math.random(1,2) local brightval = math.random(200,255) local darkval = math.random(0,55) local medval = math.random(0,255) local colorset = {brightval,medval,darkval} for i = 1,3 do local toplace = math.random(1,#colorset) rngcolor[i] = colorset[toplace] for j = toplace,#colorset do colorset[j] = colorset[j + 1] end end rngcolor[4] = 255 local firework = { x = xstart, y = screeny, color = rngcolor, yexp = math.random(150,screeny - 150), } --firework.img:setcolor(rngcolor) fireworks[#fireworks + 1] = firework end local function create_star(pos,color) --print("creating star at pos") for k,v in pairs(pos) do print(k,":",v) end --print("with color") for k,v in pairs(color) do print(k,":",v) end local star = {} star.x = pos.x star.y = pos.y star.color = color star.life = 0 star.fizzles = {} for i = 1,10 do local ang = math.random(0,2 * math.pi) local pow = math.random(0.5,5) star.fizzles[i] = { x = pos.x, y = pos.y, vx = math.sin(ang) * pow, vy = math.cos(ang) * pow } end stars[#stars + 1] = star end local tryimg = gui.newiguiimage({0,0},true,risetex) local ogt = GAME.tick function GAME.tick() if game_has_ended then if math.random() < 0.10 then create_firework() end end local fireworks_to_remove = {} local crash = false local numtoremove = 0 for _,firework in pairs(fireworks) do firework.y = firework.y - 3 if firework.y < firework.yexp then fireworks_to_remove[firework] = true if not firework.exploded then create_star({ x = firework.x, y = firework.y },firework.color) firework.exploded = true end numtoremove = numtoremove + 1 crash = true end end local cursor1 = 1 local cursor2 = 1 local fwlen = #fireworks while cursor1 < fwlen+1 do local firework = fireworks[cursor2] if fireworks_to_remove[firework] then cursor1 = cursor1 + 1 else cursor2 = cursor2 + 1 cursor1 = cursor1 + 1 end fireworks[cursor2] = fireworks[cursor1] end if ogt then ogt() end end print("At end of mahjong, GAME.tick is", GAME.tick)