Reading High Scores - Getting the Top 10
Start course
2h 36m

In this course, we begin building a game in Solidity, and more specifically, we begin to look at defining the mechanics and the components of the game.


In the previous lecture, we implemented the HighscoreManager and it was fairly complicated and we haven't tested it yet. And the reason is we still have to implement this getTop10( ) and that on the other hand is fairly easy. And we have two places where the getTop10( ) are being called and actually I don't want to call it in the HighscoreManager. I want to have the GameManager return the getTop10( ). But before the GameManager can return the Top10( ) list, we have to implement it in the HighscoreManager. And I'm going to show you now how we can do this, and it shouldn't be too hard. So, first of all, we cannot just return 10 high scores, and I'll show you what I mean by this. So, if you try to return(Highscore[10]), then our Solidity compiler will complain about the data type Highscore, but that's only supported in the new experimental ABI encoder, and we're talking about ABI's later. But the reason is, Highscore is not a standard data type which is known by outside libraries. So, to reality itself and all the code that is running on the EVM very well understands what happens if you return Highscore, but if you want to work outside it doesn't. So, we have to kind of break down what kind of data types that are predefined in Solidity, we want to return. And there are two data types that I want to return. The one is the Top10( ) addresses and their wins. I'm not really interested in the timestamp, you can add this later on yourself. For me it's only interesting the 10 addresses and how many times each of these addresses won. So, we have two things that we're going to return, (address [10] memory, uint [10]  memory). And all we have to do then is we're going to populate topTenAddresses; and we're going to populate topTenWins; and we're going to return (topTenAddresses and topTenWins);. Great. Now here's the coding challenge for this lecture. Populate the two arrays, topTenAddresses; and topTenWins;, so at the end we start from the current highscoreHolder, going back lowerHighscoreAddresses and populate the topTenAddresses and topTenWins. If you want to do this coding challenge then pause the video now. Obviously, just as a reminder, you'll find the code in our code repository and if you have any questions or if there's something not working or if you get stuck, please reach out to us in the course Q&A. That's how you find us and that's where we're going to help you. So, rest assured we are here for you. All right, pause the video now if you want to do the coding challenge and I'll explain in a second how it's done. Great. I hope it wasn't too hard if you tried to do it. I think 15 or 20 minutes should be enough to finish this. So, first of all, we again get a currentPosition which is the highscoreHolder; and then we are going 10 times, and I'm choosing an for loop here because we just haven't used it yet, and we're going 10 times through this list. And we're going to say the topTenAddresses[i] for the currentPosition; and the topTenWins[i] for the currentPosition in our topTenWins array is the highscoreMapping [currentPosition]. numberOfWins; and our currentPosition is going to be our new lowerHighscoreAddress. All right, I could also add here another check that if our lower address is the address zero, then we can actually break here. I'm not going to add this here simply because for me this functionality will always be only a reading functionality from outside. So, gas costs aren't that much of an issue here. But if you want to be on the beautiful side or on the gas cost saving side, then you could actually do a if (currentPosition == address (0)) { break;. Again, I want to plot the code here. For me this is enough. Second coding challenge for this lecture and it's not going to be too hard. In the GameManager we have another getTop10( ) function which should talk to the highscoremanager and return from the highscoremanager the same information that we return in the highscoremanager. Shouldn't be too hard. This is just like a proxy functionality to the highscoremanager. Give it about 10 minutes and give it a try, and pause the video now, as I just program it in a second. All right, it's going to return the same data and that return  highscoremanager  getTopTen. Now, our game is finished. Kind of, some smaller architectural things are missing like the right events at every point where something happens. But basically, it is finished and now we're going to give it a try. First we are going to select the JavaScript VM, we are deploying our GameManager. Not deploying our GameManager because we don't have enough gas here. So, we're going to up the gas a little bit. We're going to deploy our GameManager. We're going to 'startNewGame'. Let me get the Top10 here. Nothing yet in there, which is great. So, let me get the game address. All right, let's start playing a game between our two addresses here. Join the game. Who is player1, who is player2? That is perfect. Who is our next player? The next player event. This is the next player, 0xCA35, okay? He is going to be a lucky winner today and he is going to set the stone to the top-middle, and he is going to set the stone to the center element, and he is going to set the stone to the top-right corner, and he is going to set the stone to the bottom-right corner. All right, and this should be the end of the game. And now let's see our top 10 list. Our player has now won one time and obviously we want to see if the top number one position is going to replace by another player who also wins one time now. So, let's start a new game. All right, this one we can close. We're going to give our game address to someone, and someone is going to join our game by sending 0.1 Ether to the joinGame function. Who is going to be the first player? The first player is the player that is currently selected. He is going to set the stone to the top-right corner. The other one is setting the stone to the to the bottom-left corner. He is going to set the stone to the center corner. He is going to set the stone to the top-right corner, and he is going to close this game by setting the stone to the bottom-right corner. And let's check our Top10 list. Our winner, our top number one player is now the one who just won also one time, but he has the newest timestamp and that makes him the winner of this game. All right, this is how the game looks in Solidity and it is fairly complex. We did everything, pretty much everything that you would see in a normal smart contract. The only thing we haven't really talked about is libraries, but they are not that huge and we are talking about libraries a little bit later again. And if you see this right now here, then obviously something is missing. Nobody want to interact with smart contracts this way, and especially because we just worked in the JavaScript VM. But from a Solidity standpoint, you are on solid grounds now. If you followed along in this course so far, there is nothing that should surprise you in Solidity. All we're going to do now is we're going to add to your tool box. We're going to add another JavaScript libraries. We're going to add some knowledge about how to interact with smart contracts, and we're going to add some knowledge how to deploy smart contracts to actual blockchains because this one is not a real blockchain. So, stay tuned, and I'll see you in the next lecture.


About the Author

Tom is a CTO, senior back-end developer, and systems architect with over twenty years of hands-on development experience in a variety of languages and systems. He has a CS master's degree and has been working with Ethereum and blockchain technologies since 2016.