--IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII --II Functions for manipulating agents in cellular spaces II --II One cell can have zero or more agents II --II II --II There are also some extra functions for manipulating cellular spaces and cells II --II Use the command 'dofile("agents.lua")' to include this file in your code II --II II --II Pedro Ribeiro de Andrade Neto II --II Last change: 20070130 II --IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII VAG__ = {} -- vector of agents VQU__ = {} -- vector of quarentine agents, waiting for synchronization --------------------------------------------------------------------------------------------------- -- CELLULAR SPACE FUNCTIONS --------------------------------------------------------------------------------------------------- function InitAgents(cs) for i, cell in pairs( cs.cells ) do cell.agindex = i; VAG__[i] = { agents={} }; end end function NumberOfCells(cs) return table.getn(cs.cells) end function GetRandomCell(cs) return cs.cells[math.random(1, NumberOfCells(cs))] end -- creates a new neighbourhood based on a previous one function ApplyNeighbourhoodConstraint(cs, idx, func) for i, cell in ipairs( cs.cells ) do local neigh = Neighbourhood(); ForEachNeighbour(cell, idx, function(c, n) if func(c, n) then local index = TeCoord{ x = (n.x), y = (n.y)}; -- TODO: what is it for? neigh:addCell( index, cs, 1 ); end end) cell:addNeighbourhood( neigh ); end end --------------------------------------------------------------------------------------------------- -- FUNCTIONS FOR MANIPULATING CELLS WITH AGENTS --------------------------------------------------------------------------------------------------- function GetAgents(cell) return VAG__[cell.agindex].agents end function NumberOfAgents(cell) return table.getn( GetAgents(cell) ) end function AddAgent(cell, agent) table.insert(VAG__[cell.agindex].agents, NumberOfAgents(cell) + 1, agent) end function RemoveAgent(cell, agent) local ags = GetAgents(cell) for i = 1, NumberOfAgents(cell), 1 do if agent == ags[i] then table.remove(ags, i) return end end end -- remove the agent from the cell, but waits for the synchronize to put it in the new cell function MoveTo(cell, agent, newcell) local todo = {agent = agent, cell = newcell} table.insert(VQU__, table.getn(VQU__) + 1, todo) RemoveAgent(cell, agent) --print ("move "..cell.agindex.." to "..newcell.agindex) end -- number of movements in the actual turn function NumberOfMovements() return table.getn(VQU__) end function SynchronizeAgents() for i = table.getn(VQU__), 1, -1 do data = VQU__[i] AddAgent(data.cell, data.agent) table.remove(VQU__, i) end end function ForEachAgent(cell, func) local ags = GetAgents(cell) for i = 1, NumberOfAgents(cell), 1 do func(cell, ags[i]) end end function GetRandomAgent(cell) return GetAgents(cell)[ math.random( 1, NumberOfAgents(cell) ) ] end --------------------------------------------------------------------------------------------------- -- EXTRA FUNCTIONS FOR CELLS --------------------------------------------------------------------------------------------------- function NumberOfNeighbours(cell, index) local count = 0 ForEachNeighbour(cell, index, function(cell, neigh) count = count + 1 end) -- TODO: can i do 'function()'? return count -- TODO: WORK?? return table.getn(cell:getNeighbourhood(0)) -- end end function GetRandomNeighbour(cell, index) local pos = math.random(1, NumberOfNeighbours(cell, index)) local ct = 0 ForEachNeighbour(cell, 1, function(c, n) ct = ct + 1 end) local count = 1 local neighbourhood = cell:getNeighbourhood(index); neighbourhood:first(); while( not neighbourhood:last() )do neigh = neighbourhood:getNeighbour(); if count == pos then return neigh end neighbourhood:next(); count = count + 1 end print "ERROR: GET RANDOM NEIGHBOUR" end