1.9.1 Algorithm

An initial flowchart might be as shown in Figure 1.5(a). If the three tasks can be carried out correctly, in the sequence indicated, then the problem is solved. The flowchart breaks down the original problem into three smaller problems. Obtaining their solutions and sequencing them correctly provides the solution to the original problem. This is the top-down approach to problem solving. Next, it is applied to each of the three problems.

(a) Initial Flowchart

(b) The Refined Flowchart

(c) A Loop for Processing the Games

Figure 1.5 Flowcharts of the Bowling Scores Algorithm

Problem 1 is transparent enough. Problem 3 is clearly solved by the expanded or refined flowchart shown in Figure 1.5(b).

Problem 2 needs to be refined. It seems clear that the basic structure for its solution is a loop, within which each game is processed. When all games have been processed, the loop should be exited. (See Figure 1.5(c).)

The new problem introduced as task 4 must be solved next. The input for this new problem will be the roll scores that must be processed for the new game. A basic looping structure can accomplish the task. The loop task will be executed ten times, once for each frame. Each execution calculates the score for the current frame and updates the game score and a frame counter, frame. Prior to entering the loop, frame must be initialized to 1, and gamescore to 0. Other initialization may be required. After the loop is exited, the game score must be printed, and proper updating must occur. This refinement is shown in Figure 1.6.

Suppose that each time the programmer expands a task, the expanded version of the task does in fact solve the problem introduced by that task. Then the programmer knows that, whatever the current structured flowchart, it must represent a solution to the original problem as long as each of its tasks can be carried out correctly. The detailed structured flowchart of Figure 1.7 is thus a solution to the problem, as long as each of its tasks can be carried out correctly. It is detailed enough so that we know how to carry out (or program) each of its tasks except for 5, 6, 7, and 8. However, if the high-level language chosen for the program allows direct implementation of those tasks, then no more detail is needed to complete the solution.

Figure 1.6 Refinement of Task 4

Figure 1.7 Refinement of Initial Flowchart

Instead of increasing the complexity of the flowchart of Figure 1.7, tasks 5-8 can be functionally modularized.

Functions for tasks 7 and 8 appear in Figures 1.8 and 1.9. The solution to the original problem will then consist of Figure 1.7 plus the functions for tasks 5-8. This illustrates the application of structured programming to a relatively simple problem. Note again the importance of choosing variable names that convey information about the meaning and use of the variables. Good names make the algorithm clearer. Note that C compilers normally treat names as distinct only when they differ in the first eight characters, so some care must be taken. In this text, however, this constraint is ignored for clarity.

Figure 1.8 Refinement of Task 7

Figure 1.9 Refinement of Task 8

When task 7 is entered, the variables rollscore and r1 must contain, respectively, the first roll score of the current frame and the next roll score. Consequently, before entering task 6, the first two roll scores of the game must be read into rollscore and r1. This is the "other initialization" required of task 5.

The conditions "strike" and "spare" (Figure 1.8) are actually implemented as "rollscore equals 10" and "(rollscore + r1) equals 10," respectively. To emphasize the fact that complexity in a flowchart should be limited, Figure 1.10 is the complete detailed flowchart for the solution as it could appear without functional modularization. Descriptions do not appear; the chart simply indicates the structure of the solution. The flowchart can be derived by adding the detailed expansions of tasks 5-8 to Figure 1.7.

Figure 1.10 Too Detailed a Refinement