Let us keep on following the demanding path of the programming of our Connect Four game. At this point, we know how to represent the game: the grid (type "Grille"). We also know how to represent the player's colors, initialize the game, and print it. Finally, we have coded a more complex function to drop a disk in the grid if the inidicated move is valid. However, right now, we are still not able to effectively play. Let's try to play, then! To that end, we will try to write a "main" method which will let us play. We start just like usual : " int main() " then the body of the "main". Let us begin, of course, by defining a game, that is, a "grille" (TN: means "grid"), which we will initialize. This is very usual. Also, at the beginning, we will have to show it to the players, thus printing it. Now, what should we do? We need a player which will be represented by a color. Therefore, we will start by declaring a "Couleur"-type variable; this will be the color of the current player. Now, let us initialize it, for example to, "jaune" (TN: means "yellow"). What should we do now? Well, we should of course strive to run through the game, as long as we can play. We will thus need a loop. Should this be a "while loop" or a "do while loop"? Will we start by testing something? Or will we start by playing? Here, all the conditions are fulfilled, the game is initialized, we have a player: we can start playing right away. Therefore, we resort to a "do while loop". Here, we thus write "do". Now, what will we do exactly inside this loop? The first thing is, of course, to ask the player to inidicate his move. So, let us start by printing a message to the player to inform him that we expect him to enter a move. In this message, we will also indiciate the player's color. To that end, we should use a "print_player" function, but, here we will write it directly to show right now how it looks like. Thus, if the color of the player is yellow, we will print : "joueur jaune entre un coup" (TN: "yellow player, enter a move") Otherwise, if the red player is at turn, we will print that the red player, that is, according to our convention, 'O', has to enter a move. They must thus enter a column number. Then we should, of course, read their answer. To that end, we will declare a "colonne" (TN: means "column") variable, a "size-t"-type variable, since we will use it to index our grid. In this variable, we will retrieve the player's answer. By the way, we should not forget that the players will play between 1 and 7. However, in C++, the arrays are indexed between 0 and 6. Therefore, it is absolutely necessary to decrement, subtract 1 from the column. Now that we have a column number, given by the player, we can play our move thanks to the "joue" function, which we have developped in the previous episodes. Thus, we declare a boolean variable "valide" which will test the validity of the move. We will thus call the "joue" function here, in the initialization of the boolean. Now, here a little comment regarding this line. Here, we declare a bool-type variable "valide" initialized directly with the return value of the "joue" function call. By the way, please remember that we passed the grid, the column we just declared here and the color of the current player to the "joue" function. Thus, since this function is testing if the move is valid, and that the result is stored inside the variable "valide", we need to inform the player if the move was not valid. Therefore, if "not valid", we will print a message, warning the player. Once the move has been played or once the player has been warned that his move was invalid, in both cases, we will print the game again. Therefore, the player will see what is happening. Let us shift this all. Now, we can move to the other player. Thus, simply, if the player's color is yellow, then the current player's color will become red. Otherwise, that is, "else", the color of the current player will become yellow. Here, out of this little portion of code here, similarly to the previous printing a little while ago, we should have made a function called, for example, "alternate_player". For this episode though, it is enough to have it in the "main"; we simply wanted to show you how to globally organize the game. Now, at this point, we have asked the player to enter a move, retrieved his answer and tested the validity of the move. If the move was valid, we effectively dropped the disk in the grid. If it wasn't valid, we warned the player. One way or the other, we printed the game and swapped the player's colors. We have thus terminated a game turn. We can thus finish our "do while loop", making it possible to alternate game turns. Now, the question is: what test should we put here, for the game stopping condition? We will leave this aside for now since this will be the topic of the next episode. For now, we will leave this blank. Our version is now almost complete. Only this test here is missing, finishing the almost complete version of the game. At this point, we can criticize our work a little bit and try to improve our code. The problem here, is that the "main" is way too big; it does not even fit on one slide! This proves that our "main" function is way too big. We will thus need to "modularize", try to split this big "main", into smaller functions. Thus, we propose here to regroup all this in a function. What does this portion of code do? This is where we ask the player to enter a move. We were testing the validity and playing this move. If the move was invalid, we warned the player. This all corresponds indeed to a functionality which can thus be grouped in a function. We will call it "demande_et_joue" (TN: means "ask_and_play"). This is a possible example of modularization; there are many others. If you so desire, you may create your very own modules(= functions). What matters is to identify the key concepts and, mostly, to decompose in order to render our code all the more modular, readable and maintainable in a independent way. Now, let us go back the function methodology. If we have identified a portion of code that is either repeated (never ever copy-paste!!) or important by itself, which is the case here. We wish to make a function out of this portion of code. What we start by doing is simply to cut it. Voilà ! We have suppressed this portion of code. We then replace it by a call to our function "demande_et_joue". So, what will this function receive as parameters? Of course, the game -- the grid -- and the color of the current player. This should be enough for our function. Now, let us move on to the writing of this function. As a reminder, we added here in a comment how to call this function. Thus, the function "demande_et_joue" is called directly; its return type is thus "void". The function is called "demande_et_joue". As parameters, it will receive a grid, which we had defined with the "Grille" type. Is the grid modified? Yes! "demande_et_joue" will let us play in the grid; the grid is thus modified and will be passed by reference. Then, we pass the player's color. Is the player's color modified? Obviously, the answer is no. Therefore, a passage by value is enough here. Here is now the prototype of our "demande_et_joue" function. We can now move on to its body. This is simple; we simply need to paste the portion of code we had suppressed from the "main". At this point, when you practice this kind of exercise, it is a good idea to reread your code in order to verify that you have not omitted anything or made a mistake. Then, you should compile because you could have erred in the names. For example, we could have called this "couleur" instead of "couleur_joueur". Because of this mistake, we would have triggered a compiling error. Finally, we should test our function. Let us keep modularizing and improve this portion of code here. We have already mentioned, previously in this episode, that we could make a function out of it. We would call it "affiche_joueur" (TN: means "print_player"). But here, even without making a function out of it, we can still improve this code, regrouping the common parts. Do not ever resort to copy- pasting. And there is copy-pasting here. Indeed, "joueur" (TN: means "player") has been copied twice. Also, the message "entrez un numéro de colonne" (TN: means "enter a column enter") has been repeated twice. Here, we can thus rearrange our code a little, beginning by printing the common part. Thus, we will print the message "joueur". Here, we do not need the "endl" since we will print either "X" or "O" just after and resume the "message"; there is thus no "endl". Then, we will keep the test that was there previously, regarding the color. Thus, if the player's color is yellow, we will print X". Otherwise, we will print "O". At this point, it is this part we can modularize and turn it into a function : for example, "affiche_couleur" (TN: means "print_color"). This function will thus print 'X' if the color received as parameter is yellow and 'O' otherwise. Let us conclude our printing of the common part following the printing of the player's color. Namely, the message "entrez un numéro de colonne" and, of course, the line break. Let us conclude by improving another aspect, algorithmic, this time, of our "demande_et_joue" function. What will happen if a player enters an invalid move? In the current version, we will simply print that the entered move is invalid. Then, we will switch to the other player. This does not, in fact, correspond to the reality of the game. What should we do, then? Well, as long as the player does not enter a valid move, we will not let him free; we will keep asking and asking. Therefore, we will once more resort to a "do-while loop", since we will start by asking the player to enter a move, verify that the move is valid, and keep asking as long as the entered move is invalid. We thus have a "do" loop on all the block asking the player to enter a move. Then, we will verify if the move is valid and, finally, inform them if the move was invalid. Therefore, we will move all this block inside a "while". While what? While the move is not valid, that is, "while not valide". However, this code will not compile. Indeed, we use the "valide" variable here and the scope of "valide", which has been declared here, is this block. Therefore, we have a utilization of "valide" beyond its scope. Consequently, at this point, the compiler will produce an error. What we have to do is to pull the declaration of "valide" outisde the loop. For example, we could put the declaration up here, or just before the loop. Here, we thus declare "valide", which we could initialize to "false". Of course, we should not keep this declaration here, for we would then have two variables "valide". We would have this one here, with a scope local to the block controlled by the "while" instruction. And we would have another "valide" here, with a scope local to the function body. Obviously, this would not work, and we will thus change this declaration-initialization to an assignment. This is it for our function "demande_et_joue". A last comment though. We could obviously have put the printing of the question inside the "do-while loop"; this is a variant. Namely, after every valid move, we will print which player is to play. In the previous version, we simply repeated the entered answer. Let us conclude by a last comment regarding the "joue" function. This is related to a quiz of the previous episodes. The problem with this "joue" function is that the column number is never verified before we access the array here. It is not verified, neither in the "joue" function here, nor in the function "demande_et_joue". Here, we simply trust the player and decrement 1 from the entered column. However, we do not verify if the player has entered, for example, 100,000 as the column number. Now, we thus have to correct our "joue" function, making sure that the access to the column here is indeed valid. We start, as usual, by explaining it in a comment before coding it. So, if the "colonne" parameter is greater than the grid size, then the entered move is not valid and we can return "false". We systematically need to check the access condition to an array cell. This concludes this episode. Today, we have added 3 functionalities to our program. We have asked the player to enter a move. We have coded the main loop, making it possible to repeat the game. And we have alternated between the two players. Now, we only need, in order to exit the loop, to define the loop stopping condition -- we left it blank here. This condition is either that the grid is full or that a player has won. This will be the subject of the next episode.