Skip to content

Instantly share code, notes, and snippets.

@routevegetable
Created July 16, 2018 20:48
Show Gist options
  • Save routevegetable/247fa5b105a70c5cdf5c0bb835bcd99e to your computer and use it in GitHub Desktop.
Save routevegetable/247fa5b105a70c5cdf5c0bb835bcd99e to your computer and use it in GitHub Desktop.
Computercraft fish
local fishStringL = "<'((>-<";
local fishStringR = ">-<))'>";
local fishLength = 7;
local foodDist = 5;
-- A float between -1 and 1
local randFloat = function()
return math.random(-100, 100) / 100;
end
local renderFish = function(t, fish)
-- t.write(fish.x .. ", " .. fish.y)
t.setCursorPos(fish.x, fish.y);
local fs;
if fish.xv >= 0 then
fs = fishStringR;
else
fs = fishStringL;
end
t.write(fs);
end
local renderFood = function(t, food)
t.setCursorPos(food.x, food.y);
t.write("O")
end
local clampFish = function(fish, w, h)
if fish.x > (w - (fishLength - 1)) then
fish.x = w - (fishLength - 1)
end
if fish.x < 1 then
fish.x = 1
end
if fish.y > h then
fish.y = h
end
if fish.y < 1 then
fish.y = 1
end
end
local maxTime = 10;
local maxVFactor = 0.05;
local directFish = function(fish, w, h, time)
if time - fish.epoch > maxTime then
fish.xv = randFloat() * maxVFactor * w;
fish.yv = randFloat() * maxVFactor * h;
fish.epoch = time;
end
end
local moveThing = function(fish, time)
local dt = time - fish.ltime;
fish.x = fish.x + fish.xv * dt;
fish.y = fish.y + fish.yv * dt;
fish.ltime = time;
end
local initFish = function(w, h, e)
return {
x = math.random(1, w),
y = math.random(1, h),
xv = 0,
yv = 0,
epoch = e,
ltime = e
}
end
local initFood = function(w, h, e)
return {
gone = false,
ltime = e,
x = math.random(1, w),
y = 0,
xv = 0,
yv = maxVFactor * h -- That's some fast food..
}
end
local simFish = function(trm, fish, w, h, time)
directFish(fish, w, h, time);
moveThing(fish, time);
clampFish(fish, w, h);
renderFish(trm,fish);
end
local simFood = function(trm, food, w, h, time)
moveThing(food, time);
renderFood(trm, food);
end
local dist = function(a, b)
local dx = b.x - a.x;
local dy = b.y - a.y;
return (dx * dx) + (dy * dy);
end
local collide = function(fish, food)
local dx = 0;
if fish.xv >= 0 then
dx = fishLength;
end
return dist({x=fish.x + dx, y = fish.y}, food) <= 5
end
local simulate = function(config)
local trm = config.Term;
local tw = config.Width;
local th = config.Height;
local nfish = config.NFish;
local fishies = {};
local nfood = 0;
local noms = {};
-- Initialize fishies
for i = 0, nfish-1,1 do
fishies[i] = initFish(tw, th, 0)
end
local fishTime = 0;
while true do
trm.clear();
for i = 0, nfish-1, 1 do
simFish(trm, fishies[i], tw, th, fishTime);
end
for i = 0, nfood-1, 1 do
simFood(trm, noms[i], tw, th, fishTime);
end
-- Check for food collisions
for i = 0, nfish-1, 1 do
for j = 0, nfood-1, 1 do
if collide(fishies[i], noms[j]) then
noms[j].gone = true; -- Om nom
end
end
end
for i = 0, nfood-1, 1 do
if noms[i].y > th then
noms[i].gone = true
end
end
-- Clear out the old food
local nNewNoms = 0;
local newNoms = {};
for i = 0, nfood-1, 1 do
if not noms[i].gone then
newNoms[nNewNoms] = noms[i];
nNewNoms = nNewNoms + 1;
end
end
noms = newNoms;
nfood = nNewNoms;
-- FEEED!
if redstone.getInput("left") then
noms[nfood] = initFood(tw, th, fishTime)
nfood = nfood + 1;
end
trm.setCursorPos(1,1);
trm.write("Food: " .. nfood)
-- Tick Tock
fishTime = fishTime + 1;
os.sleep(0.25);
end
end
local terminal = term;
local termWidth;
local termHeight;
termWidth, termHeight = terminal.getSize()
simulate({
Term = terminal,
Width = termWidth,
Height = termHeight,
NFish = 9
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment