The course is part of this learning path
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.
Now, we are already pretty far in our game. We can create a new game, we can join a game, and now obviously, the last part that is missing is setting stones and winning, losing, drawing, and a little bit of high scores. And in this lecture, we are going to define our game board, and we can start playing or setting stones on our game board already. Now, when we defined our function getBoard(), then it was already a hint there that our game board will be a 3x3 array of addresses. And when we set the stone to x and y, let's say we set the stone to the top left corner of our game board, then it's going to be x and y is going to be 0,0. And we're going to post the address of the player there in order to know who was setting the stone there. Now, we can achieve this quite easily, if you just say it's going to be an address[3][3], and we call this our gameBoard;. And we know by default, Solidity will automatically initialize this game board with the default values. So, if we're going to return this game board here, it will be all zeros, three times three zeros in this game board. So, if you say we're going to get the board here, then all we have to do is we have to return the gameBoard. And if we deploy our smart contract, which I'm not going to do now, you can do it if you want to see how it looks like, then you will see a large list of zeros. Obviously, just getting the game board is pretty boring. So, we can start working on our setStone function already. And we are not determining any winners or losers o a draw yet, we're just setting stones to a specific coordinates of the board. And we can do this very, very easily by just saying that board[x][y] = msg.sender; or it should be in our case the active player. And there are a couple of... sorry, boards, gameBoard obviously, good that there's zero messages here. There are a couple of requires and assert we have to take care of, and also we have to set the player, the activePlayer once. Let's say, player one's turn was it, the player one set his stone, and then it's the active player is the player number two. So, I'm not going to make this challenge quite easy this time, I'm going to make this challenge a little bit more challenging because we had a lot of easy challenges. And if you want to do the challenge, then pause the video now, and find as much as require and assert statements in order to make setting the game board secure. So obviously, one of them would be the coordinates x and y shouldn't be set yet, so it must be address zero. It should be x and y, should not be larger than the actual game board. And you should take care that the message sender is really the active player and when the active player or when the message send the plate, then the active player should be the other player. So, will pause the video now, and if you want to do the challenge, you pause the video now if you want to do the challenge and I'll explain to you after pause how this works. Okay, there are a couple of asserts and requires that unnecessary here in order to make this a little bit more secure. First of all, the most obvious one is probably require(gameBoard[x][y] == address (0));, that depends how you want to define it. So, this one really requires that you cannot set a stone to a position where already a player has set his stone. Then, we have another assert(x < 3); or a board size. And in order not to make this so static, what I usually do is a uint8 boardSize = uint8 and I have to cast this gameBoard.length. So first, I get the length of the first array which we defined here on the top as a 3x3 array. So, it will give me the number 3 but it will be a uint256. And in order to put this in a uint8, I cast this to a uint8 and get the board size and then I can say x should be smaller than 3 because our index goes from 0 to 2 and not from 1 to 3. So, in order to set the stone to the top left corner, we have to input x is 0 y is 0. Now obviously, because this is a square board, it should also be smaller than the board size or 3. And the next thing that we have to do is we have to set the players right. And this is here, if(activePlayer == player1) { activePlayer = player2; } else { activePlayer = player1; and because we also want to know who is the next player from outside, you can emit an event. The NextPlayer event that will fire and will tell us who is going to be the next player. Now, it's fun time, demo time. We're going to deploy and try our smart contract. So, I deployed game manager, I hit 'Deploy'. I have selected my first account here, and I'm going to input 0.1 ether, start a new game. I have to wait for another player to join the game, and I have to give somebody else my address here. Again, it's jumping around, I just click and I click select and hold the mouse button, I will not release the mouse button. I hit 'Control C' for copy or 'Command C' on the Mac for copy, and then release the mouse button, and then I go to my ThreeInARow contract here from the dropdown. I say this is running under this address so I can access the interface from my ThreeInARow smart contract. And I see player1 is already here, player2 is empty. I will join with my other address, this game here and I have to send 0.1 ether along in order to join this game. Now, this still works like a charm, player2 is set now. The question is, who is going to be the first player? The first player is me, the player that just joined. And I see I forgot one require here, which is the require that the active player must be the player who is setting his stone, the msg.sender must be the activePlayer. So, let's assume that I have done this, I will not really apply this for this video. And I just forgot this to put it in here, and we are going to try if you can set the stone, 0,0, set the stone, and then get the board. And I see I'm here at the first position, and you can see that here, that this is the first row, and then somewhere starts the second row, and the third row. Unfortunately, they are all separated by commas, as far as I can tell here. So, you have to use a little bit of an imagination here. But later when you get it back in JavaScript, you will get back at 3x3 array, which is easily accessible. Okay, who is our next player? Our next player is the other player. Let's select the other player, and let's try to set the stone at the same address. This doesn't work. We have to set the stone at the new coordinates, I set the stone at new coordinates, I got the board, and so on and so forth. So, this is how we set stones. And once we set the stone inside this setStone function, we are going to determine is it the player who set the stone right now to the coordinates? Does he have already three in a row full? Like, does he have three horizontal or three vertical or a diagonal at the position where he put the stone, then heiis the winner. And if you put in the last stone, so if the board is full, then there is a draw. And then somebody can or both of the players can withdraw the money. All right, this was a really, really good and one of the major recessions of how to write this game because now we can already set the stone and I think it will all come together slowly, and you will see slowly how this game is really being programmed, being developed. And I'm looking forward to seeing you in the next lecture, where we are going to determine winning or losing in this game. All right, I'll see you in the next lecture.
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.