Last active
December 21, 2015 14:19
-
-
Save dermotbalson/6318887 to your computer and use it in GitHub Desktop.
school1
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--# 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