Skip to content

Instantly share code, notes, and snippets.

@dermotbalson
Last active December 21, 2015 14:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dermotbalson/6318887 to your computer and use it in GitHub Desktop.
Save dermotbalson/6318887 to your computer and use it in GitHub Desktop.
school1
--# Code1
--Code1
--here, we learn a little about Lua
--later, we'll draw on the screen
--but we can't do that until we know just a little Lua
--put all your code inside this function
function Code1()
--this is how we define variables
--Lua figures out what type they are, by itself
--you can use almost any name (one word, starting with alphabetic character)
a=3 --integer
bob=3.1567 --non integer
charlie="string"
A=46 --Lua is case sensitive, ie capitals matter. A is different from a
--this is how we do arithmetic
d = a+bob-5
d=a*bob
d=a/bob
d=(a-2)^bob --a to the power of b
--Lua has a lot of math functions (look in the help)
d=math.floor(bob) --gives the integer part of bob (3)
d=math.fmod(3,2) --gives remainder when 3 is divided by 2 (=1)
--now go look in the help to see what else there is
--while we're just doing Lua, we can print out our results at left of screen when the program runs
--let's check what I said earlier, that A is different from a
print("a=",a,"A=",A) --put print items in brackets, and separate different items with commas
--we add strings together with two dots, like so.
d=charlie .. ", this is, said Yoda"
print(d)
-- NOW IT'S YOUR TURN --
--Answer these simple questions with code
end
--# Code2
--Code2
--this time, we'll learn about "if" statements
function Code2()
a=68
b=17
c=19
--bigger than test a>b
--bigger than or equal a>=b
--equal test a==b --note DOUBLE equals sign
--NOT equal test a~=b --note squiggle
--less than test a<b
--less than or equal a<=b
if a>b then
print("a is bigger than b")
elseif a==b then
print("a equals b")
else
print("a is NOT bigger than b")
end --NOT end if
--in Lua, you can put more than one statement on a line, separated by at least one space
--(in VB, you would have to put a colon between different statements)
if a>=b then print("a is bigger than or equal to b") end
-- is a divisible by b? We can use math.fmod to help us (remember, it gives the remainder)
if math.fmod(a,b)==0 then
print (a,"is divisible by",b)
else
print(a,"is NOT divisible by",b)
end
--if we put this test in a separate function (see underneath) then
--we can use it lots of times without having to write out the same code repeatedly
TestDivisible(a,b) --you make a function run by just typing its name
TestDivisible(a,c) --you must always include brackets, even if there is nothing inside them
end
--This function prints out whether one number is divisible by another
function TestDivisible(n1,n2) --is n1 divisible by n2?
if math.fmod(n1,n2)==0 then
print (n1,"is divisible by",n2)
else
print(n1,"is NOT divisible by",n2)
end
end
--# Code3
--Code3
--now we'll learn looping
function Code3()
--let's add the numbers 1 to 50
--define a number to keep the total in
t=0
--now the loop
for i=1,50 do --ie from i=1 to 50
t=t+i
end --NOT "next i"
print("The total of 1-50 is",t)
--to count every 5th number up to 1000
--add an extra number in the "for" statement, as the "step" between numbers
t=0
for i=5,1000,5 do --ie from i=5 to 1000 in steps of 5, ie 5,10,15,20,....
t=t+i
end --NOT "next i"
--to loop backwards, make the "step" negative
t=0
for i=50,1,-1 do --ie go from 50 to 1 in steps of -1
t=t+i
end
--to loop in fractional numbers
--this example loops through 1, 4.22, 7.44, 10.66, ......
for i=1,100,3.22 do
t=i
end
--when does this loop stop? As soon as i is greater than 100
print("The last number was",t) --print the last value of i before the loop stopped
end
--# Code4
--Code4
--Now we'll try a real problem, the first one from ProjectEuler.net
--If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9.
--The sum of these multiples is 23.
--Find the sum of all the multiples of 3 or 5 below 1000.
function Code4()
--we did something like this in the previous tab
--we added up all the numbers to 1000, in steps of 5
t5=0
for i=5,1000,5 do
t5=t5+i
end
--so we could do that again here
--then we could change it slightly so it looped in steps of 3
t3=0
for i=5,1000,5 do
t3=t3+i
end
--then we could add the two numbers together
print("Answer is",t5+t3)
--not so fast!
--each number can only be counted once
--but 15 is divisible by both 3 and 5
--so we need to add all numbers which are divisible by EITHER 3 or 5
--we can use the TestDivisible function from Code2 to help us
--but we don't want it to print out messages
--it would be better if it just told us if a number was divisible by another number
--we can do this, because functions can send back a result
--so I've created a new function IsDivisible, that returns true (ie is divisible) or false (not divisible)
--see at the bottom
--now we can do a loop
t=0
for i=1,999 do --up to 999 because the question says "BELOW 1000"
if IsDivisible(i,3) or IsDivisible(i,5) then
t=t+i
end
end
print("Euler 1 answer=",t)
end
--returns true if n1 is divisible by n2, else returns false
function IsDivisible(n1,n2)
if math.fmod(n1,n2)==0 then
return true --is divisible
else
return false --is NOT divisible
end
end
--# Code5
--Code5
--The second Euler problem is this
--Each new term in the Fibonacci sequence is generated by adding the previous two terms.
--By starting with 1 and 2, the first 10 terms will be:
--1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
--By considering the terms in the Fibonacci sequence whose values do not exceed four million,
--find the sum of the even-valued terms.
function Code5()
--if we call the 10th Fibonacci term F10, then
-- F11 = F10 + F9
-- F12 = F11 + F10
--so we need to remember the last two results all the time, and have another variable to store
--the total, ie we need three variables
--let's call them F1, F2 and F3
--and F3 = F2 + F1 --ie F3 is the lastest total, F2 is the previous one, and F1 is the one before that
--so here is our basic loop, let's just print the first 10 Fibonacci numbers without worrying about
--even numbers or values up to four million. One baby step at a time is the best way to program.
--We can check our results against the list at the top.
F1=1 --set the first two numbers
F2=2
for i=3,10 do --only start looping from 3, because we already have the first 2 numbers
F3=F2+F1 --be careful to capitalise correctly. I would get an error with f1, f2 or f3
print(i,F3)
--now we need to move the numbers along. Next time round F2 becomes F1, and F3 becomes F2
F1=F2
F2=F3
end
--now how about the other conditions?
--we only need the even valued terms, ie divisible by 2
--we know how to do this because we have a function IsDivisible
--but what about "whose values do not exceed four million" ? How do we know how big to make our loop?
--Do we just guess? How will we know if we included all the numbers up to 4 million?
--We could just make a very big loop, and use an "if" test to only add numbers up to 4 million
--but then we want to stop. There's no point carrying on once the numbers get bigger than that
--So how do we tell a "for" loop to stop?
--with the "break" command (like Exit For in VB)
--So here is the whole thing
F1=1 --set the first two numbers
F2=2
t=F2 --to hold the total. It must include all even numbers, so we'll start with F2
for i=1,100000 do --make a big loop because we'll exit before the end
F3=F2+F1
--test if we've hit the limit, "break" if we have exceeded it
if F3>4000000 then
print("stopped when i=",i) --just to see how many terms it took
--print the total - sorry, had to use special formatting to get the number to print properly
print("Fibonacci total",string.format("%d",t))
break
end
--add this number if it's even
if IsDivisible(F3,2) then
t=t+F3
end
--now we need to move the numbers along. Next time round F2 becomes F1, and F3 becomes F2
F1=F2
F2=F3
end
end
--# Code6
--code 6
--now we're going to learn about tables (or arrays in VB)
--they allow us to make lists
function Code6()
--suppose we have some warrior classes
--we want to make some lists of their names and fighting qualities
--so here is our first list
names={} --this tells Lua that names will be a table/list
names[1]="elf" --the first item, note we use square brackets
names[2]="dwarf"
names[3]="orc"
names[4]="ranger"
names[5]="nazgul"
count=5 --number of warriors.
--(I could also say count=#names, because #names gives me the number of items in names)
--now their fighting qualities
--first their hitting power 0-10
--in the same order as above
--there is a shortcut way of making the list, like this
--so we can define the table and fill it all at once
power={3,9,7,7,10} --(orcs are actually more powerful, but are a bit slow, so you can dodge)
--now endurance, ie how their hitting power degrades as they get tired
endurance={8,7,8,6,10}
--now range, ie how far away they can hit from.
range={4,1,2,3,3}
--now I need a function that fights battles and gives us winners
--I want it to look like this
--result = Fight(a,b) where a and b are numbers 1-5
--so Fight(2,4) means the dwarf and ranger are fighting
--result = a or b, whichever is the winner
--then I can loop through all the combinations of warriors like this
print("TEST THE MATCHUPS")
for i=1,count do --choose the first warrior
for j=i+1,count do --choose the second warrior
--let's check this works, by just printing out the names of each match up.
--later, we'll try it for real
--it's important to test your program one step at a time, like this
print(names[i],names[j])
end
end
--ok, that looked good, so here is the actual match up
print("ACTUAL FIGHTS")
for i=1,count do --choose the first warrior
for j=i+1,count do --choose the second warrior
k=Fight(i,j) --returns the winner, ie i or j
print(names[i],"vs",names[j],"=",names[k])
end
end
--just one problem, we haven't programmed the Fight function yet
--so we better go down to the bottom and do that
--and yes, I know you will be thinking "I could do better than that"
--so what are you waiting for?
--ok, so we ran all the fights and got all the results
--but one match could be a fluke, so let's run a series of say 50 each and see who wins the most
print("50 FIGHT TOUR")
for i=1,count do --choose the first warrior
for j=i+1,count do --choose the second warrior
--let's check this works, by just printing out the names of each match up.
--below, we'll try it for real
--make a little table to keep the score
score={0,0,0,0,0} --initialise scores to nil
for u=1, 50 do --run 50 fights for this matchup
k=Fight(i,j) --returns the winner, ie i or j
score[k]=score[k]+1 --add to score of winner, will be score[i] or score[j]
end
print(names[i],"(",score[i],") vs",names[j],"(",score[j],")")
end
end
end
function Fight(a,b)
--these two fighter are going to make alternate hits
--I don't know which one will get first hit at this stage
--and it could take a while to finish, so I don't want to repeat all the fighting code over and over
--what I need is a loop that continues until one fighter wins
--the easiest way is to have a little list with two items, the first being the fighter doing the hitting
--and then swap the list around for the next hit
--follow me carefully on this
--I'll use the same list names as above, but put f in front so we don't get confused or overwrite those lists
fID={a,b} --store the numbers of the two fighters
fPower={power[a],power[b]} --make a new list with two items from the original list
fEndurance={endurance[a],endurance[b]}
fRange={range[a],range[b]}
--now a new list specially for fighting
fHealth={1,1} --start at 100%, they lose when they get to 0
--now the fighting. You can change this any way you like, but this is what I'm going to do
--First the fighter with the biggest range gets a free hit for each extra point
--so an elf gets 5 free hits on a dwarf (6 - 1)
--I want the hits to be skewed so that the probability of a really big one isn't too great
--so I'll take random numbers 0-1 and square them so they are skewed to lower numbers
--the power of a hit is random number x fPower
--and fPower gets multiplied by fEndurance/10 after each hit (they get weaker)
--health = health - hit
--so let's try it out
--first do the free hits
--if one of them is positive, they get free hits
free={}
free[1]=fRange[1]-fRange[2]
free[2]=fRange[2]-fRange[1]
--decide who goes first
if free[1]>0 then --warrior 1 has more range
Attacker=1
elseif free[2]>0 then --warrior 2 has more range
Attacker=2
else --both the same
--choose one at random - if the random number < 0.5 choose number 1, else number 2
if math.random()<.5 then Attacker=1 else Attacker=2 end
end
--now the fighting
--if the attacker is 1, then the defender is 2, and vice versa, therefore......
Defender=3-Attacker --simple way to calculate one if you know the other
--can you see how we can now swap which one is attacked and defender quite easily
for i=1,1000 do --allow for lots of fighting
r=math.random() --random number used for hit, 0-1
hit=r*r*fPower[Attacker] --square the random number and x hitting power
fHealth[Defender]=fHealth[Defender]-hit
if fHealth[Defender]<0 then
return fID[Attacker] --Attacker wins, return his ID number and exit the function
end
--apply endurance
fPower[Attacker]=fPower[Attacker]*fEndurance[Attacker]
--decide if it's time to give the other guy a turn
--not if the attacker still has free hits
free[Attacker]=free[Attacker]-1 --reduce the number of free hits by 1 (doesn't matter if it goes negative)
if free[Attacker]<=0 then --swap over if there are no more free hits
Attacker=3-Attacker
Defender=3-Attacker --this looks the same as the previous line, but the Attacker values has changed
end
end
end
--# Main
--This code manages which Code tab is run
--it remembers your last choice, and if you select a different one, it runs that instead
function setup()
LastCode=readProjectData("Code") or 1
parameter.integer("Choose_a_tab",1,6,LastCode,RunCode)
end
function RunCode()
output.clear()
saveProjectData("Code",Choose_a_tab)
print("CODE "..Choose_a_tab)
CodeToRun=loadstring("Code"..Choose_a_tab .."()")
CodeToRun()
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment