Registering High Scores - Part 2
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 our previous lecture, we were actually implementing that our ThreeInARow game instance that we create is talking back to our HighscoreManager. But our HighscoreManager is pretty empty and we are going to change that now. So, in order to actually save high scores, we have a couple of limitations in solidity. The biggest problem is the gas usage. So, we cannot just keep an endless high score list because once our user base grows, the amount of gas that we need in order to find the right position in that list will grow as well until it might reach the maximum amount of gas, the maximum amount of computational operations that we can do on the blockchain, and then our smart contracts will just fail. So, in order to avoid that in our game, we opted for a top 10 list. So, we always have the top 10 elements and the list is going to be a linked list. I'm not going too much into the details of the data structure itself.

I'm going to show you how it's done and we're going to use all of the previously learned elements, structs, mappings, addresses that we learned in the previous section and make really good use of them now. So, the first thing that we want to define is our own struct and struct starts with the keyword struct as we heard and then in Cape Verde style, we are going to define our own data type and we call it Highscore. And I'm going to add a linked list here because I'm going to have a mapping from an address to an Highscore element, so that we always know a specific address had so and so many wins, and was the last time when it played. So, the first thing that we know is there's an unsigned integer uint numberOfWins and an unsigned integer  unit timeOfLastWin and there is coming a lot more of these elements but let me start with those. And we have a mapping( address => Highscore).

So, we have really our own data type and I'll make this public for now mapping( address => Highscore) public highscoreMapping. And then in case we just have one, let's start with one high score holder. That is an address highscoreHolder. So, we know who has the largest number of wins in our list. If we add a win for a specific person, all we have to do here really we go to the highscoreMapping[_for].numberOfWins++. The ++ is the same as numberOfWins+1. So, if you just type in ++ then you increment number of wins by one, if you have never seen it before and the highscoreMapping[_for].timeOfLastWin = now because now will be the largest timestamp in the latest transaction where he won. Then we have just one last thing which is the the highscoreHolder. If our person who won here has the largest number of wins, larger than the highscoreHolder then it will be the new highscoreHolder.

So, that is I guess fairly easy and it's going to be the challenge. I'm sorry it's going to be the challenge for this one. If you have a new highscoreHolder then it should replace the old highscoreHolder. So, if you want to do the challenge then pause the video now or else I will show you in a second how this is done. All right we have here if(highscoreMapping[highscoreHolder].numberOfWins <= highscoreMapping[_for].numberOfWins). Then the highscoreHolder = _for  is the address that just won. And the reason why I can't just do this is because if you remember back these arcade games, then if you have the same high score but you were the latest one who won, then you're replacing the highscoreHolder. So, even if you have just the same points, if you were the last one to play then you're going to replace this person.

All right, I would say we just give it a try and see how that works and then we are talking about the actual top 10 list because right now we just have one person who is the current highscoreHolder, but we want to have a top 10 list of the best highscoreHolders. And that's a little bit more tricky than you would think on the blockchain. So, there is a lot of brainpower going into that and I will explain to you later how each and every single line of code works exactly. But first, the fun part. We have a JavaScript VM we are going to deploy the GameManager. All right we are starting a new game, and it's 0.1 ether. And that might be a little bit tricky now because first of all, we have to get highscoreManager in order to get, where is it? highscoreHolder. Let's make this public here. And let me redeploy our GameManager. So, we can interact with a highscoreManager and the highschoolHolder is currently the 000 address. So, let's create this game and let's see if this is working startNewGame. Where was the game? The game is here, under this address. Let me copy this, control C. I just copied the game and I'm going to the ThreeInARow instance here and I say running under this address so I can interact with my address and I'm going to select the second player 0.1 ether. It's already pretty complex.

So, no doubt here that it's one of the more complex smart contracts. We have joined the game and our next player is, where is it? 14.  So, the one that is currently selected, setStone 0,0, setStone 0,1, setStone 1,1 so in the centre,  setStone 1,2. And now you're going to win buddy. 2,2 the bottom corner and we have a winner. And let's see if this is our new highscoreHolder with this address, and how many times did he win? He won one time and this is the timestamp where he won. Now that's working just great, but now we actually want to have to get the top 10 back up. The top 10 here in the GameManager, they are not delivering anything yet. So, this is where we want to start the next lecture. We're going to implement the top 10 list for our high scores.

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.