AI for Everyone LESSON 19 HOMEWORK SOLUTION: Gesture Based Pong Arcade Game

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello guys this is paul mcquarter with toptechboy.com and we're here today with episode number 19 in our incredible new tutorial series where you're going to learn artificial intelligence or you're gonna die trying what i'm gonna need you to do is pour yourself a nice tall glass of ice cold coffee that would be straight up black coffee poured over ice no sugar no sweeteners none needed and as you're pouring your coffee as always i want to give a shout out to you guys who are helping me out over at patreon it is your support and your encouragement that keeps this great content coming you guys are not helping out yet take a look down in the description there is a link over to my patreon account think about hopping on over there and hooking a brother up but enough of this shameless self-promotion let's jump in and talk about what i am going to teach you today and what i'm going to show you today is i'm going to show you my solution to the homework assignment that i gave you in lesson number 19. and if i remember correctly and i do think that i do remember correctly your homework assignment was to develop a gesture-based version of the classic arcade game pong now we agreed for this assignment that it would be a one player game and so the ball would just be bouncing around you'd have a paddle at the top and the position of that paddle would depend on the position of your index finger and so it's a gesture-based version sort of a remixed version of the classic pong game so how many of you guys were successful if you were successful leave a comment down below i am legend or if you were not successful leave the comment i folded up like a cheap walmart lawn chair okay so leave the comment down below what i'm really hoping is i'm hoping you guys will post your solutions to youtube and in the comments leave a link over to your solution and also then in the description of your video leave a link back to this lesson so anybody watching it will have context of what you're uh what you're talking about but i love going over and watching your videos and and some of you guys are really just taking your work to the next level and that really makes me happy as someone who's kind of helping or teaching or uh you know kind of coaching you along to see you take getting solutions much better than the ones i did so i hope a couple of you guys just took this game to the next level and post it and share it with the rest of us but enough of this introductory chit chat let's jump in and let's get ready to start coding and looking at my solution so we'll come over here i will get out of your way i will need you to fold uh to fire up the most excellent visual studio code and we're going to come over here and we are going to be in our main python working folder we will create the little plus page icon and then we will create the new program open cv dash 32 dot p y and the dot p y is kind of important and bam fresh new python program just waiting to be written okay now we don't want to write this completely from scratch we want to start with the program that we left off with in lesson number 19. if you guys have it call it up if you don't have it you can go to the most excellent www boy you can come over here to the happy little search bar and you can search on something like ai for everyone developing a gesture based arcade game or just gesture based arcade games should get you here and then you can come down and you're going to click on these two little icons right mouse click and copy and then we're going to come over here and paste and now we're starting with that introductory program that we worked on last week where there's a little bar a little paddle at the top of your frame and that paddle moves back and forth based on where your finger is so let's just run that to make sure the universe is in proper order and that we can copy and paste without breaking something so we will run it and boom we got it look at that boom so i'm moving that bar based on my fingers so you can see well it's kind of okay one of the things guys is remember it's not looking for your finger as much as it's looking for your hand so just make sure that you're giving it a good hand to see there all right so very good let's quit out of this okay take another sip of coffee so now what we're going to do is we're going to base we're going to build the pong based game a lot of the hard work's done because our paddle is defined our paddle is defined based on parameters and the paddle is moving based on finger position so now we got to do is we got to go in and kind of turn it into a game well the first thing i want to do in turning this into a game is we let's see we came down here let's see i'm trying to find all right here's where we're talking about the paddle so we said the paddle width the paddles little thing moving it was 125 and 25 i think that looked pretty good the paddle color we had is blue green red we made it green i don't like that against a green background and so i think i will want that to be red and so i'm going to get 0 0 255 and that should be red okay now we got to start thinking is the pong game the key to the pong game is the little ball that's bouncing around so we better start thinking about getting some parameters to make ourselves a cool little ball and so the first thing is we need to have a ball radius and so how big do we want to have the ball we'll have to play with it to see what looks good but let's say what if we started with [Music] trying to think i think i'll make it 15 a ball radius of 15. we're going to need a ball color and since we made the paddle red and we don't like green why don't we make the ball blue and so that would be 255 comma zero comma zero that should be blue in our warped parameter space of blue green red that should be blue if i'm thinking about it right now we ought to think about the ball's got to have a position so we better have a variable for position and the ball would have an x position and the ball would have a y position well where do we want to start when the game starts the ball let's just start it in the middle so x position is equal to where would the middle be an x it would be width divided by 2 okay it would be we've already defined width up here so whatever the width is it should be width divided by 2. now since if width is odd with divided by 2 would be not an integer so we better force this to be an integer width width divided by 2. because a lot of these opencv commands if you pass it a floating point number and not an integer it will crash and sometimes it's a very cryptic a very cryptic error message so we want to make sure that we're passing integers and i find it just easier to take care of that right at the top so if x position is integer width divided by 2 what would y position be class class y position height divided by two okay quick trivia question what was uh what movie had that line where the teacher was up there class class class probably you guys know okay all right so we will go x position y position now if we have that ball it's going to need to be moving so we've given it a position but now we've got to think about moving it and so it's going to be moving at some velocity in the x direction and moving by some velocity in the y direction and so we should probably have like a delta x for like how many pixels does the ball jump how many pixels does the wall jump each time in x and uh this is going to kind of define your game place so if you make it a larger number the ball is going to be moving really fast if you make it a small number it's going to be so slow to be boring but let's start with kind of easy game place we'll say delta x is 2 and we'll say delta y is equal to 2 as well and so that will be a reasonable place to start uh okay and then what we're also going to need to do is we're probably going to need to keep score and so when you start the game your score is going to be 0 and then we need to have some number of lives and so let's say that we're going to give the guy five lives all right i think i don't know the old arcade games i think some of the things or maybe like it was pinball you got like three balls or something pinball was quite addicting how many of you guys remember pinball and how many of you guys dropped more than a few quarters in a pinball machine i did i wasted time and money on pinball machines i found them quite addicting all right now we are also going to what happened how did i end up with an extra y position here i don't know but i will alleviate it okay so we've got scores we've got lives also we're going to be putting text on our frame and so we better just go ahead and set up a font because it's easier to do it here than do it later so we'll say a cv2 dot font hershey i kind of like the font hershey simplex in this particular application and so i think we've got things set up to start playing the game i think we have things set up to start playing the game and so uh we're gonna have our frame and after getting our frame okay after getting our frame i think what i will need to do is i need to probably go ahead and put the ball on there okay let's go ahead and put that ball on there and so that's going to be a cv2 dot circle okay and then where uh where do we want to put the circle we want to put it on the on the frame we want to put the circle on the frame and then where do we want to put it well we want to put it on at uh it's a tuple so make note that i open the parentheses there we want to put it at x position y position and so that will say where the ball starts it's going to start at the tuple x position y position how big is the circle well it is ball radius two l's and ball radius okay ball radius and then what color do you want it ball color and then i want it to be solid so i'm going to make it a minus 1 and that will make it solid this is line width and a minus 1 makes it soft you see how much easier it is to do these commands when we are good about defining our parameters up front i think it just makes things a lot easier okay now there's a couple of things that we are going to need to do we're going to need to do a cv2 we want to put our score on the frame and we also want to put how many lives we have on the frame so let's do a cv2 dot put text and you guys know i hate put text i always mess up the put text it seems like today is the day that we dominate put text my goal is i'm going to do two put text commands in this program and i want to make a mistake on either one of them so cv2 dot put text where do i want to put it i want to put it on the frame i want to put it on the frame let me do a little windows management here you guys can probably see like you know i'm having to think about what i'm doing i'm having to write the program i'm having to talk about what i'm doing and i'm having to manage my studio software all at the same time so if you see me glass glancing to the side i've got to kind of see what you guys are seeing in my studio software but i digress so we come back to cv2 dot put text okay we want to put it on frame what do we want to put well we want to put the score the score is a number and put text wants a string so we've got to take the string of the number and which number score okay score and then where do we want to put it well we want to put it it's x y and so we want to put it over let's see how would i do this okay we want to put it over some number of pixels i'm just going to say 25 and so rather than having the score right against the edge of the frame we're going to pull it over by about 25 pixels and we'll probably have to adjust that a little bit and again it's a pixel i mean it's a tuple it's an open parenthesis x comma y comma close parenthesis so we got the open we got the 25 and now what we need is we need like how big do we want it to be no not how big but like how we've gone across now how far down well i'm just going to kind of scale it with the paddle height so i'm going to take the integer and i'm just going to say bring it down by about six times the paddle height right because we don't want the paddle running into it and so we want to bring it down by about six times the paddle height i think that should be fairly good so then we close the end and then we close the tuple and then that next close parenthesis that's going to close the whole put text commands but we got some more parameters that we needed to need in here we got to tell it the font that we want we've already defined that above so we can just type in font how big do i want it well i wanted about a font of six so that's going to be a pretty big a pretty big number up in the upper left corner and then what color do i want it uh let's make it uh did i do like a color paddle yeah i did a paddle color let's make it the same thing as the as the paddle so i'll say paddle color we'll use we'll use that same color again okay and then how heavy do i want it well i wanted about a five okay i wanted about a five i am thinking we might go ahead and run this just to see if it's you know if how many errors we've already made i like to run the program a lot because it's easier to find errors one at a time than to run a program that's got 20 errors i like to kind of debug as i go so let's run this thing let's enjoy a little coffee okay look at that okay that zero looks pretty good and that sort of makes sense and even look we've got the uh we've got the uh ball is already there okay our game is coming along quite nicely i do believe okay now we said that we wanted to put text for the uh for the score we also need to put text for the live so i'm just going to copy and paste but now instead of frame string score we want frame screen lives okay now we are also going to have to think about where we put this and you see you want to put it you want to kind of scale it with width on the x position of the uh score since it's on the left it's always going to be reference to zero no matter how big the screen is so we just said come 25 over from the left well here i think we want to go like 25 125 over from the right and where is the right the right is at width okay and i better put my uh no they're already there so i want width minus 125. so the uh so the number of lives is going to be on the right of your frame but so it doesn't go off the frame you got to back off by about 125 so that is where your x position is going to be and now with -125 now we've got to think about the height and i do believe the height would be the same because we want them or the the y position would be the same we want them both lined up the same distance from the top so we would just again six times paddle height font uh the font still the font the color is still the color and the line width is still the line width so now we should see a big o five over there to the right of the screen boom look at that hey we could we could play the game tracing on coffee but it's not tracing on coffee it's really tracing on my index finger that looks pretty good i got a little chunk of ice here like a little tasty nugget all right so now we're going to quit that and we're going to come back over here let me see okay so so now where are we now we've got our basic elements put together that we need all right and then let's see what we're doing here okay so now i go out and i find the position of my hand and then since there's could be multiple hands i step through the hands and then what i'm doing here is this is creating that paddle right that is what creates the paddle okay so now that gets me to the paddle and the paddle is there and it's working now we got to think about game play okay and to think about game play we need to kind of go ahead and define some things associated with that ball and if you do it with parameters it's going to be way way easier to give the commands because everything is going to be a parameter and the name of the parameter is going to kind of make sense now i've got to do this down in the loop because the ball is moving and because the ball is moving the edge of the ball is going to be in different positions so you got to kind of do this in the loop but you want to like when the ball hits the wall when the edge of the ball hits the wall you want to bounce so i got to keep track of what the left edge of the ball the right edge of the ball the top edge of the ball and the bottom edge of the ball i better just go go ahead and define those and then it will make creating my if statements much easier so i'm going to say top edge ball well what is that that is going to be the y position of the ball the y position of the ball and since y is coming down the top edge would be the y position the y position of the ball minus the radius minus ball radius now since y position is an integer and ball radius is an integer this has to be an integer so i don't need to int it but if i have a top edge of the ball i'm also going to need a bottom edge ball like that and that's going to be y position what y position plus the ball radius plus the ball radius okay now i'm also going to need the left left edge ball and that is going to be on the left edge that's going to be reference to what the x position and so that's going to be x position and that is going to be minus ball with two l's ball ray d s okay and then the right edge ball is going to be x position plus ball radius so now i have parameters for these four critical spots on the bulb that will allow it to bounce properly okay that will allow it to bounce properly well the first thing let's think about is if the ball hits the left wall or if the ball hits the right wall the edge of the ball hits the left wall the other edge of the ball if it's the right wall we want to what we want to bounce and so what i want to do then is i want to say if left edge ball is less than or equal to less than or equal to zero so if this comes all the way back to zero pixels which is the edge of the frame or the other time that i want to bounce in x is if the right edge ball hits the right edge and so that would be the right of the frame so that would be or if right edge ball if right edge ball is what greater than or equal to the width of the frame and so here's the frame width when the ball the edge of the ball gets over there and hits the edge of the of the frame it needs to bounce so if either one of those things happen we want to change the x direction so we want to say delta x is equal to delta x times minus 1. now why do i put the parentheses in there just because order of operations can be so confusing and so such an opportunity to have things do something unexpectedly if i say delta x times minus one then it's forcing it to understand that this is a negative one it's times a negative one it's not subtracting one and then multiplying so it's just like i like to force order of operations with parentheses and it has served me well in my life okay and so now that will change directions if it hits the left wall or the right wall now we can't do the top and bottom the same because the top and the bottom are different the top and the bottom are different because the bottom you're just looking have you gotten to the bottom on the top you got to see did you hit the paddle or did you hit something else okay or did you hit the paddle or did you miss the paddle so let's go ahead and do the easy one which is if [Music] bottom bottom edge of the ball if the bottom edge of the ball is greater than or equal to what the height then what do you want to do well there you change delta y you change the y direction delta y is equal to delta y times parenthesis minus one okay there's four walls we've got to bounce off of we got three done but we did the three easy ones but i like to kind of build my confidence as i go so i do the easy ones first all right now what are we going to have to do well first of all we're going to have to think about it how do we see whether we bounce off the paddle or go off the screen well first of all you have to see has the ball gotten to the y value of the paddle has the top of the ball gotten to the y value of the bottom of the paddle that's the first thing and then if it has is it in the right x position to bounce off the paddle like here it's at the right y value but the paddle isn't in the right position so the ball's going to go on here it's at the right position and y and it is in x going to hit the paddle and so that i bounce so i got to decide whether to bounce or not and so this if statement needs to be in the other if statement so now the way i would do that is i would say if okay if x position is what it's got to be if x position is greater than the left of the paddle and if x position is less than the right of the paddle so it needs to be greater than the left of the paddle and it needs to be less than the right of the paddle and in that case you get a bounce so it has to be both of them so i've got to say and if x position is greater than okay if x position is greater than where is the edge of the paddle well the center of the paddle should be at what it should be at your finger position and where is your finger position well that was hand okay and hand of what hand of the index and then somewhere i've got to say what the index is so this is just uh what i'm doing is hand is the array of landmarks which landmark do i want i want the index finger and i i'm trying to think uh okay forehand in okay i am just getting too fancy what we remember is i'm trying to get too fancy here we remember that the index finger is eight okay we get remember that the index finger is eight so what i'm going to do up here i'm just gonna go ahead and set that just because the the finger that we're tracking on is the index finger and so i'm gonna go let's go ahead and set that to eight if that makes sense okay does that make sense all right let me come back over here and do my little management again okay so now i set the index to eight and now we gotta think where is the hand okay so we want hand is all the landmarks which landmark do i want i want the landmark of index which is eight which we figured out a second ago okay but that is the position of the center of the paddle but i need to know the position of the left of the paddle well that would be where my index finger is okay that hand of index minus half of the width of the paddle so it would be hand index minus paddle width what divided by two and it's just the paddle width that's divided by two okay now what do you see there you see that this whole thing could be a float so we better change it to an int so if x position is greater than or equal to i think i should say greater than or equal to the left edge of the paddle what is the left edge of the paddle it is the center of the paddle minus half the paddle width where is the paddle centered it's centered on my finger position my finger position is my hand array of landmarks and it is landmark eight which is my finger does that make sense i sure hope it does i know i talk too much but man i want you guys to see how this is really working i don't want you just typing in stuff you don't understand now i've got to do the right edge which is also it has to and it also and has to be x position has to be less than the right edge of the paddle well where is the right edge of the paddle the right edge of the panel would be hand index okay and i forgot wounding dir okay hand index is hand of 8 which is indeed the position of my index finger but remember it's a tuple that has an x value first and then a y value and if i want the x value then what i want is the 0th position if i wanted y i would get the 1 position so now hand of end gets me to my index finger now i got to figure out do you want the x value or the y value of it i want x and that is in the zero position and same thing over here hand of index and then i want the zero position and now that is the middle of the paddle the right of the paddle is that plus paddle width divided by two and then we're going to put a close our if and then remember this needs to be an int to this whole thing right and so you see i've got the int and then this opens the end this closes the end i think that's good okay so if that is the case okay [Music] and you know what i think i think that i only do this okay i've got one more statement here i only look for that i only look for that when the ball is at the paddle level so up here i've got to put another if statement before this and i kind of described this but i didn't put this one in if the top edge of the ball is less than or equal to because right less than means below if it's if it's below or equal to the bottom of the paddle well where is the bottom of the paddle it is at paddle paddle height right because the top of the frame is at zero and then how far down does the paddle go it goes down paddle height like that okay so if the ball has reached the bottom of the paddle then if it's reached there then you want to see are you lined up with the paddle so you have an if statement inside of an if statement okay now if both of those are true if you get into both of these then what do you want to do you want to change y direction delta y is equal to delta y times minus 1. so if the top of the ball is even with the bottom of the paddle and if it's lined up with the panel with the paddle then what do you do well then what you do is you change directions which has done that okay now uh else if that's not true okay if that is not true then what you want to do is you got to start over because if you missed it then you've lost the ball you didn't change direction you've lost the ball you know that life is over you've got to deal with the fact that you've lost the ball so what does that mean well that means that x position is equal to int with divided by 2 so you're going to start over you're going to put the ball back in the middle okay and then y position is going to be equal to int of height divided by 2. okay so you're starting the game over and what also happens well if you if the guy died because you lost the ball because you didn't bounce it what needs to happen it needs to be the lives is equal to lives minus one and we're already showing the life you know when we grab the frame so all we got to do is just decrement lives and now we say okay now you've lost one of your lives okay [Music] now what else we need to do is after we have decided all these things about what direction we should be moving and whether we should bounce or not now we need to go ahead and move the ball so how do we do that well we say x position x position is going to be equal to x position plus delta x x and y position is equal to y position plus delta y okay and then remember we're gonna we're gonna put the ball you know then when we come back up to the top of the loop and we do the circle the ball is put at x position in y position so by incrementing x position y position here the ball will move but what we've got to do is we've got to do all of these if statements to see if we should bounce if we should bounce if we should bounce if we should bounce if we don't need to bounce it just keeps moving but if you end up in one of these if statements you you change one of the directions and then it changes okay so that looks pretty good so now could it really be that easy okay i think then that all right i think then after now we got to figure out how to end the game and so what we're going to do is after we show the frame we got to see is the game continuing and so we say if lives equal equals zero okay if you're out of lives what do we do we gotta break out of here and then the game is over and if you guys were good you would probably come up and put some game over something in here like you would do something with game over but i'm just going to have the program stop at the point that the game is over because i don't want this video to go on too much longer okay so if lives is equal to zero then we break now the one thing that we didn't do here okay we need to get a point every time we effectively bounce okay every time that we effectively bounce off the paddle we increment our score by one and so where would that be that would be inside of all this if the top edge of the ball is at the paddle height and if it is in the right x position then we're going to bounce off the paddle and when we bounce off the paddle then we need to say that the score the score is equal to score plus 1. what is the chance that i didn't make like 150 mistakes but i feel pretty good because this has been one very refreshing ice cold coffee so i'm gonna run this thing look at that ah it's going the game gameplay has begun ready player one oops don't let it see don't let it see two hands okay for me the one thing that's a little confusing for me is as i'm watching it on the screen it's showing me the mirror image and so it's going kind of opposite of what my real finger is going okay so i'm going to come here boom score 2 for tub techboy.com sometimes you got to kind of give it a clear picture of your hand okay now i admit the game play is kind of slow here but it's good because i'm trying to get oriented bim taptecboy.com i score three okay so i want to go kind of slow because i'm getting oriented to moving this paddle okay because like i say it is moving in the opposite direction four okay and i'll go i'll go to five and then i'll let it go off the screen look at that we're getting beautiful motion okay i want to let it go bounce okay five and now i'm just gonna let it go off the screen to make sure that then it restarts and it decrements we want to make sure that it decrements the five as far as the number of lives i gotta like deliberately mess miss okay so now it should restart okay and then it restarted coming my way all right boom now what is the way that you could make this a little more interesting you saw that within a couple of times i kind of mastered it so it's going to get kind of boring and so i think that we need to make the game harder and there's two ways that we could make the game harder one way is that we can make the paddle smaller as the game went on and the other way is we could make the ball go faster and so i think down here when we look at a successful bounce after we have done the successful bounce which is right here okay so we increment the score okay because we got a successful bounce what we want to do is we want to say well if the score is equal to 5 if the score is equal to 5 so if you've made it to 5 or if the score equal equal 10 or the score equal equal 15 or the score equal equal 20. can you guys still see that yeah you can still see that or the score equal equal 25 then what do you want to do well you want to in that case you want to make it go faster and so you want to do is you want to say delta y is equal to delta y times 2. why do i not use parentheses there because there's no confusion in order of operations it's a single operation and then delta x is equal to delta x times 2. so you see the gameplay is going to get significantly harder the higher the score is okay so now all of a sudden it's going to get harder and harder so let's go ahead and play this again i have a quick sip of coffee okay so there we go i'm still kind of getting used to this paddle and yes it is quite pim lovely it is a quite lovely thing there score of one and this is kind of slow but i do appreciate being able to get my bearing score too okay there's all types of things you could imagine this doing right uh you could imagine a two player game let me bounce this and i'll kind of talk to you about a two player game okay because you see already we should be able to get two paddles so i could have one paddle down here and i could have one paddle i could have two paddles and i could have one on the top and i could have one on the bottom but to do that you kind of need to know what is the right hand and what is the left hand or it's going to get confused and it's going to be hopping back and forth as to which one of your hands is controlling which paddle and that would take the game to an incredibly new ooh boom five now look at that go okay we got to concentrate here okay try to kind of anticipate where it's going right and if it with that case it would just be too hard so we've got to kind of learn the commands there's a command where you can learn whether it's a left hand or a right hand and then maybe with that we could make it a two player game okay we're doing pretty good it is quite a bit harder at the double speed okay and i think okay 9 10 is coming 10 is coming okay so now it is going to get ah did you see that ah i was folding up before we even got to this really fast one okay at least i got i i'm down to one life can i get to i missed okay i missed but anyway that was a pretty fun game that was indeed a pretty fun game so if we wanted to make it a two-player game what we would need to be able to do is we would need to tell the difference between a right hand and a left hand and even like if you thought there was a person sitting here next to me i would be playing with my right hand and that person would be playing with their left hand right because their left hand would be in the picture my right hand would be in the picture so in order to have two players or if you wanted to play both paddles you know with with your two hands we need to know kind of like what is the right hand and what is the left hand and so there's some things in media pipe that we could that we could do that but what i'm hoping right now is i'm hoping you guys would just take this and see if you could take it to the next level if you could just really add some snazzy things to this guys you know you've learned a lot about opencv you've learned a lot about python you've learned a lot about media pipe and so there's just all types of different interesting directions you could go like maybe maybe you could imagine something like one paddle but you got to move the paddle up and down so like like you've got to be here but the bottom instead of having a wall you got to bring your paddle down and you got to catch it at the top and the bottom or maybe you could imagine having a square paddle and you've got to kind of bounce it you know in two dimension on the screen so you see there's a lot of different things you could do with it you know putting some like game overs in there maybe when these things start start with ready player one or something like that you see there's just some different things that you could put in there that would make this uh really exciting and you've really got all the tools to do it and i kind of think these old school arcade games are kind of neat because when i first played these it was just so amazing to me and even today i think it's pretty cool that we have the skill that we could sit and we could actually program up some of those original uh original uh arcade games those classic arcade games okay guys enough room is innocent about uh my early days playing these uh playing these arcade games i really hope you guys are having as much fun taking these lessons as i am making the lessons if you enjoyed this lesson make sure you give us a thumbs up if you haven't subscribed already make sure you subscribe to the channel when you do ring that bell so you'll get notification from uh from youtube when these uh when these videos are released and then also share this with people share these lessons share this channel with people on your social media because the world needs more people knowing how to code and fewer people sitting around watching silly cat videos paul mcquarter with toptechboy.com i will talk to you guys later
Info
Channel: Paul McWhorter
Views: 1,783
Rating: undefined out of 5
Keywords:
Id: e7uZSA1LYgI
Channel Id: undefined
Length: 47min 6sec (2826 seconds)
Published: Thu Nov 11 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.