Right now, we are nearing the conclusion of our Connect Four game. We have managed to let both players play alternatively and to test if a player has won. Now, we still have to tweak a little our main program in order to indicate to our players who has won. Also, we will have to deal with the draw situation. This will be the topic of this episode. As a reminder, our Connect Four game is a struggle between two players : the player 'X', in charge of the yellow disks and the player 'O', in charge of the red disks. These two players play alternatively. Thus, we have made sure that, after every loop iteration, the current player's color will alternate between red and yellow. Both players will keep playing until one of them has won. We still need to tweak our program a little bit. The first natural thing to do is, once the loop has finished its execution -- which means that either one of the two players has won -- is to indeed signify who has won the Connect Four game. Another thing to do is to consider the situation where no player has won. The draw situation is not yet covered by our program; which does not correspond to a realistic simulation. Let us now obviate these two holes. Let us now begin by having our program indicate who the winner is. Therefore, after the loop, we will have to add a few instructions, testing the color of the current player. If the color of the current player is yellow, for example, we will print the the winner is the red player. But, why the red player instead of the yellow player? Well, remember: at the end of the loop iteration, we switch the color of the current player. Therefore, if the current player's color is the yellow color, that means the winner is the player with the other color, that is, red. This means that the red player has indeed won the game when the current player was the yellow player. This explains why, in the case where the color of the current player is yellow, the winner is indeed the red player. We will cover the situation where the yellow player has won similarly. We have thus covered the two possible cases. Now, we will take the precaution to comment this particular test indicating that we have first switched of the players' colors, which explains the conter-intuitive nature of this test. Also, as we have said at the beginning of this episode, there are situations where both players will be playing and eventually fill out the whole grid, without anyone having won. This corresponds to the draw situation. Consequently, we have to deal with this situation aswell, thus exiting the loop if one player has won or if the grid is full. We thus have to complete our code so that this case will be covered aswell. If we do not, the program will behave incorrectly and keep on looping even once the grid has been filled, forever asking the same player to indicate a column number where to play. This does not make sense since the grid is full and it is not possible to drop disks anymore. This corresponds to an erroneous situation we have to correct. The modifications required in order to solve this problem are rather natural. Thus, we have to signify that we are iterating, looping, as long as we do not have a winner -- this part is already covered -- and as long as the grid is not full. This can be written this way. We will be foresseing the existence of a function called "plein" (TN: means "full") which will test if the grid is full or not. This will also require a few modifications after the execution of the loop. Indeed, at this point, once we have exited the loop, we will not be confronted with a unique situation anymore where, fatally, one player has won. Now, there is another possibility aswell: a draw which we will have to signal. Therefore, we will have to modify our program so that if there is a winner, then we will find ourselves in the situation where we will signify who has won. However, this will not always be the case; it is also possible not to have any winner. In this second case, we will indicate the game ended in a draw. Now, we have covered all the possible situations. Let us now move on to the coding of the "plein" function. Remember that our program will ask the red and yellow player in what column they intend to drop their disk. Let us suppose that it is the yellow player's turn. If, for example, they decide to drop their disk down the first column, the filling will occur from bottom to top. Namely, the disk will be automatically placed on the first available square, starting from the bottom. Therefore, in order to test if the grid is full, we do not need to test all the squares of the grid, testing if they are occupied by a particular color. We simply need to test the squares of the very first line. Indeed, in the case where the grid is full, we will have filled all the columns starting from the bottom. This means that all the squares of the first row will also have been filled. Now, we should be able to effectively code our "plein" function. Methodologically speaking, we have briefly wondered, since it is a rather simple function, about the "what": what does the "plein" function do? In the main program, we have planned for this function to take, as argument, the grid and to test whether it is full or not. This corresponds naturally to the following prototype: the function returns a boolean indicating if the grid is full or not. The only parameter of the function is a grid. In the previous episodes, we have seen that, for all the functions having, as parameter, a rather voluminous object used only in reading, in consultation, which we did not want to modify, it was a good idea to resort to passing by constant reference. We will do just that here. Here, the "plein" function aims only to consult the content of certain squares of the grid in order to know if they are filled or not. It thus does not aim to modify the grid. This is precisely the reason why are resorting to a passage by constant reference here. Let us now focus on the "how". How should effectively write the body of this "pleine" function? We have already sketched the algorithm on the previous slide. Namely, if we encounter an empty square on the first row, we know that the grid is not yet full. This is what we will concretely code. We will iterate square by square on the first row, "grille[0]", and test the squares. If one or more squares are empty, then we know that the grid is not full. Therefore, the "plein" function will return "false". Otherwise, obviously, the grid is full and we will thus return the value "true", signifying that the grid is full. Now, we have finished coding our little Connect Four application. The goal of this case study was to show you how to tackle the programming of such an application when we are programming begginers. Several key ideas are to be remembered. First of all, always proceed bottom-up. Start by identifying the essential types, the fundamental functionalities before dealing with the details. Each fundamental function can then, at its turn, be modularized, call other functions or more details helping to fulfill the process. For each function, proceed with methodology. Ask yourself "what", what is the role of the funciton in your program? What informations does it need in order to perform effectively? What will the function deliver as return information? Then ask yourself "how" and consider the algorithm which will help to realize the desired processing. Focus on the essential aspects before dealing with cosmetic tweaking aspects. Finally, last essential point, be systematic when testing the different functionalities as you are progressing in the development of the application program. Voilà ! These were some of the key points we wished to illustrate through this case study. We hope they will prove useful to you once you will be facing yourselves the programming of such applications.