In this last lesson, we will see how to approach much more ambitious projects than those we have considered until now. Thus, we'll see how to split such a project into subproblems, easier to solve, until we may write the final program. In order to make our point clear, we have chosen a "Connect Four" game. You probably know the rules of the Connect Four. This two-player game requires a 6 high, 7 wide grid. The players take turns, dropping disks of their own color into the column of their choice. The game will keep going until a player manages to connect 4 disks of his own color or until the grid is completely filled. First of all, please note that we are not going to develop a fancy graphical interface. Here, we are interested in programming the game mechanics and will thus merely print the grid and the disks using characters. The end result will look like this. In a general way, how should we proceed when confronted with a substantial problem such as this one? Above all, we should not try to write the whole program in one go; it would just not work. We will have to split the problem into subproblems., writing the program step by step. At every step, we will test the newly-written code in order to continue with solid bases. First of all, we will need to identify the types necessary to the program to run, that is needed to represent the data needed by the program. In the case of our example, we will essentially need to represent the grid. Then, we will have to indentify the functions related to these types, write these functions and test them as we go. And, if we are confronted with a particularly complicated function, we may introduce a subfunction for each difficult point. As we said, we have to start by indentifying the types. What does it mean, concretely? Well, we will start by identifying the data required by the program and find a way to represent these data. In this case, for our Connect Four program, the main data is the grid and the disks it contains. More exactly, we wish to know, for every square, what this square contains: Is it a red risk, a yellow disk or nothing at all? There are several possible ways to represent the grid. A way to proceed is to see the grid as made of rows where each element of a row corresponds to a square. Namely, we will represent the lines as arrays. There are several possibilities to represent arrays in C++ We remind you that you can either the use the "array" type, or the "vector" type. Here, since the number of squares, or rather, the number of possible elements for each row is known a priori, that is, we know that each row will contain 7 elements, we will rather use the "array" type to represent a row. In order to store all the rows, we may use another array whose elements will contain the rows of the grid. And, since the number of rows is also known a priori (a Connect Four grid has always 6 rows) we will, once again, resort to the "array" type. The type representing the Connect Four grid and its content is thus an array of arrays, or, more exactly, a 6 elements array, whose elements are themselves 7 elements arrays, corresponsding to a row of the grid. Now, we still need to define the type of the elements of a row, that is, the type of what is contained in a square of the grid. Before that though, please note that, although we have decided to represent the grid as a 6 rows array, we could have proceeded differently. For exemple, we could have represented the grid as a 7 columns array. In general, there are several ways to write a program tasked with solving the same problem. Here, we will give you one solution of a Connect Four program; obviously there are many other ways to produce the same result. Now, we will use the "typedef" keyword in order to define a new type "Grille" (TN: "grille" means "grid") which is an appropriately sized array of arrays for a Connect Four grid. Thanks to this new type, we will be able to define variables which will be array of arrays representing a Connect Four grid. The question now is: How will we represent the elements of the grid? For example, we could use the int type and come up with a convention that, if an element contains the value 0, this element corresponds to an empty square. If the element contains 1, it will correspond to a square occupied by a red disk. And if it contains 2, it will correspond to a square occupied by a yellow disk. Also, we could use a char-type and decide that, for example, a blank space corresponds to an empty square; the character "O" corresponds to a square occupied by a yellow disk; and the character "X" corresponds to a square occupied a red disk. However, these two solutions beget an incovenience: If, for example, we choose the int type, nothing prevents an element of the grid to contain, for example, the value 3. However, the value 3 does not correspond to anything in our program. Even if we choose the char type, an element of the grid could contain the character "z" which does not correspond to anything in our game. In such a case, it's much better to define a new type using the "enum" keyword, thus limiting the number of possible values for the elements of our grid. Indeed, in C++, we can give names to the entities of an enumeration. An enumeration could, for example, be all the possible colors for a disk or the list of a continent countries. This will be done thanks to the "enum" keyword, respecting the following syntax. First comes the keyword "enum" followed by the name we wish to give to the enumeration, followed by, between braces, the list of the names for the enumeration values, the names being separated by commas. The instruction is concluded by a semicolon. In our program, we will use the enumeration we define as follows: "enum" followed by the enumeration name. In our case, this enumeration will be used to define the value of the elements of a grid. A good idea would be, for example, to call this enumeration "couleur (TN: means "color") These elements will correspond to an empty square, a square containing a red disk or a square containing a yellow disk. Thus, for the names of the enumeration entities, we will simply use "vide" (TN:"empty"), "rouge" (TN:"red) and "jaune" (TN:"yellow"). Once this enumeration has been defined, we can use it just like any other type in order to declare variables. This instruction, for example, will declare a Couleur-type variable called "element" initialized to the value "vide". We can then change the value of this element thanks to an assignment. In this assignment instruction, we are changing the value "vide" to the value "jaune". We may also test what the variable "element" contains with such a condition: does the variable "element" contain the value "rouge"? In this case, the test is obviously false. The types in our program will thus be our new "Couleur" enumeration as well as the type "Grille" which we can finally define like this. As you can see, we have here used the type "Couleur" in order to define the element type. Now that our "Grille" type has been defined we can use it to declare variables. Here, we declare a variable called "grille". This variable, an array, can then be modified through instructions such as these ones. This instruction assigns the value "jaune" to the index 3 element of the index 2 row of our "grille" array. However, we must know what element of the grid we are referencing in this assignment. For that, we must make a choice. Does the index 0 row of our "grille" array correspond to the uppermost row of the true grid? Or does the index 0 row correspond to the lowermost row of the true grid? There is no unique correct way to make the decision; no way is strictly better than the other. Therefore, we will arbitrarily decide that, in our case, the 0 line corresponds to the uppermost line of the true grid. Now we can understand the result of this assignment for our true grid. Considering the row 0, 1, 2 and the index 3 element of this row. This element has the index 0, this one the index 1, 2 3. Therefore, our assignment will modify the value of this element, giving it the value "jaune", meaning that this square now contains a yellow disk. In the next video, we will discuss how to write functions letting us initialize and print the grid.