High Scores in Cobol: Complete Solution & Deep Dive Guide
The Complete Guide to Managing High Scores in Cobol
This guide provides a comprehensive walkthrough for managing a high-score list in Cobol. You will learn to leverage Cobol's powerful data structures, specifically tables (arrays), and its built-in SORT verb to efficiently find the highest score, the last added score, and the top three scores from any given list.
Ever feel a wave of nostalgia for the golden age of arcade games? The frantic challenge of Frogger, the relentless pace of Pac-Man—these classics were defined by a simple, yet powerful motivator: the high-score list. It was your digital monument, a testament to your skill. But have you ever wondered how developers in that era, using languages like Cobol, managed this seemingly simple task? You might think Cobol is just for dusty mainframes and financial reports, but its data manipulation capabilities are surprisingly robust and perfectly suited for this challenge.
If you've found yourself staring at a Cobol program, puzzled by its verbose structure and wondering how to perform basic data operations like sorting and searching, you're not alone. Many developers transitioning from modern languages find Cobol's approach to data handling unfamiliar. This article is your solution. We will demystify Cobol's data structures and procedural logic, guiding you step-by-step to build a fully functional high-score component. You'll not only solve the problem but also gain a deep appreciation for the power hidden within this legendary language.
What is Data Manipulation in Cobol?
Before diving into the code, it's essential to understand the fundamental concepts of how Cobol handles data. Unlike modern languages where you might declare a dynamic list or array with a single line of code, Cobol requires a more structured and explicit approach, primarily managed within the DATA DIVISION.
The Working-Storage Section
The WORKING-STORAGE SECTION is the primary area within a Cobol program where you define your variables, constants, and data structures that are not part of input or output files. Think of it as the program's internal memory or scratchpad. Every piece of data your program will manipulate—from a simple counter to a complex record—must be declared here first.
This section is hierarchical, using level numbers (like 01, 05, 10) to define relationships between data items. A level 01 item is a top-level record, and higher numbers like 05 or 10 represent subordinate fields within that record.
Cobol Tables: The Power of the `OCCURS` Clause
In Cobol, what modern languages call an "array" or a "list" is referred to as a table. A table is simply a repeating data item or group of items. You create a table using the OCCURS clause, which specifies how many times an item should be repeated.
For our high-score list, we need a list of numbers. We can define this in WORKING-STORAGE as follows:
01 WS-HIGH-SCORE-DATA.
05 WS-SCORE-COUNT PIC 9(04) COMP.
05 WS-SCORES-TABLE.
10 WS-SCORE PIC 9(06) OCCURS 1 TO 100 TIMES
DEPENDING ON WS-SCORE-COUNT.
In this example, WS-SCORES-TABLE contains WS-SCORE, which OCCURS up to 100 times. The DEPENDING ON WS-SCORE-COUNT clause makes the table size dynamic up to the maximum limit, which is a powerful feature for handling lists of varying lengths. Accessing an element is done using an index in parentheses, like WS-SCORE (3) to get the third score.
Why is Sorting Crucial for a High Score List?
The core of our task is to identify the "best" scores. This inherently means we need to establish an order. A raw, unsorted list of scores is just a collection of numbers; it doesn't tell us which one is the highest or what the top three are without inspecting every single element. Sorting brings order to this chaos.
Introducing the Cobol `SORT` Verb
Cobol includes a highly optimized and powerful built-in utility for sorting: the SORT verb. This is not a simple library function; it's a core language feature designed for high-performance batch processing, capable of handling massive datasets that won't even fit into memory by using temporary work files.
The SORT verb is declarative. You don't tell Cobol how to sort (e.g., bubble sort, quicksort); you simply tell it what to sort, on which keys, and what to do with the result. This makes the code cleaner and far more efficient than writing a manual sorting algorithm.
A typical SORT statement looks like this:
SORT SD-WORK-FILE
ON DESCENDING KEY SD-SCORE-VALUE
USING INPUT-FILE
GIVING OUTPUT-FILE.
For our high-score list, we will adapt this to sort a table from WORKING-STORAGE. The DESCENDING KEY clause is vital, as it ensures the highest scores appear at the top of the sorted list, making it trivial to pick out the personal best and the top three.
ASCII Logic Diagram: The `SORT` Verb Flow
Here is a conceptual flow of how the SORT verb helps us find the top scores. It takes an unordered list, sorts it from highest to lowest, and then we can easily extract the top elements.
● Start with Unordered Scores
│ [100, 40, 250, 180]
│
▼
┌─────────────────────────┐
│ Execute Cobol SORT │
│ (ON DESCENDING KEY) │
└───────────┬─────────────┘
│
▼
● Sorted Score List
│ [250, 180, 100, 40]
│
▼
┌─────────────────────────┐
│ Extract Top N Elements │
│ (e.g., Top 1 or Top 3) │
└───────────┬─────────────┘
│
▼
● Final Result
[250] or [250, 180, 100]
How to Implement the High Score Logic: The Complete Code Solution
Now, let's combine these concepts into a complete Cobol program. This program is structured as a subprogram with multiple entry points, a common design pattern in Cobol for creating reusable modules. Each entry point corresponds to one of our required functions: getting the latest score, the personal best, and the top three.
The Full Cobol Source Code
Below is the complete, well-commented source code from the kodikra.com learning path. It demonstrates the setup of data structures and the procedural logic required to manage the high scores.
******************************************************************
* kodikra.com Cobol Learning Path
* Module: High Scores
*
* This program manages a list of game scores. It can return:
* 1. The last score added to the list.
* 2. The highest score (personal best) from the list.
* 3. The top three highest scores from the list.
******************************************************************
IDENTIFICATION DIVISION.
PROGRAM-ID. HighScores.
AUTHOR. Kodikra.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
* The SORT verb requires a work file defined here.
SELECT SD-SORT-WORK-FILE ASSIGN TO "sortwork.tmp".
DATA DIVISION.
FILE SECTION.
* SD defines a Sort Description file, used by the SORT verb.
SD SD-SORT-WORK-FILE.
01 SD-SORT-RECORD.
05 SD-SCORE PIC 9(06).
WORKING-STORAGE SECTION.
* Defines the maximum number of scores we can handle.
01 WS-CONSTANTS.
05 MAX-SCORES PIC 9(04) VALUE 100.
* This is the structure for the sorted list of scores.
01 WS-SORTED-SCORES.
05 WS-SORTED-SCORE PIC 9(06) OCCURS 100 TIMES
INDEXED BY IDX-SORTED.
* Variables to hold the final results passed back to the caller.
01 WS-LATEST-SCORE PIC 9(06).
01 WS-PERSONAL-BEST PIC 9(06).
01 WS-TOP-THREE-SCORES.
05 WS-TOP-SCORE PIC 9(06) OCCURS 3 TIMES.
* Internal work variables.
01 WS-WORK-VARIABLES.
05 I PIC 9(04).
05 J PIC 9(04).
* The LINKAGE SECTION maps data from the calling program.
LINKAGE SECTION.
01 LS-SCORES-IN-COUNT PIC 9(04).
01 LS-SCORES-IN.
05 LS-SCORE PIC 9(06) OCCURS 100 TIMES.
01 LS-LATEST-SCORE PIC 9(06).
01 LS-PERSONAL-BEST PIC 9(06).
01 LS-TOP-THREE-SCORES.
05 LS-TOP-SCORE PIC 9(06) OCCURS 3 TIMES.
PROCEDURE DIVISION.
* This is the main entry point, but we use specific ENTRYs below.
GOBACK.
******************************************************************
* ENTRY "get-latest-score"
* Returns the last score added to the list.
******************************************************************
ENTRY "get-latest-score" USING LS-SCORES-IN-COUNT, LS-SCORES-IN,
LS-LATEST-SCORE.
* The last score is at the index equal to the count.
MOVE LS-SCORE(LS-SCORES-IN-COUNT) TO LS-LATEST-SCORE.
GOBACK.
******************************************************************
* ENTRY "get-personal-best"
* Returns the single highest score from the list.
******************************************************************
ENTRY "get-personal-best" USING LS-SCORES-IN-COUNT, LS-SCORES-IN,
LS-PERSONAL-BEST.
* First, perform the sort.
PERFORM SORT-THE-SCORES.
* The highest score is now the first element in the sorted table.
MOVE WS-SORTED-SCORE(1) TO LS-PERSONAL-BEST.
GOBACK.
******************************************************************
* ENTRY "get-top-three"
* Returns the three highest scores from the list.
******************************************************************
ENTRY "get-top-three" USING LS-SCORES-IN-COUNT, LS-SCORES-IN,
LS-TOP-THREE-SCORES.
* First, perform the sort.
PERFORM SORT-THE-SCORES.
* Initialize the output table to zeros.
INITIALIZE LS-TOP-THREE-SCORES.
* Move the top 3 scores from the sorted list to the output.
PERFORM VARYING I FROM 1 BY 1 UNTIL I > 3
IF I <= LS-SCORES-IN-COUNT
MOVE WS-SORTED-SCORE(I) TO LS-TOP-SCORE(I)
END-IF
END-PERFORM.
GOBACK.
******************************************************************
* PARAGRAPH "SORT-THE-SCORES"
* A reusable paragraph that sorts the input scores in descending
* order and stores them in WS-SORTED-SCORES.
******************************************************************
SORT-THE-SCORES.
SORT SD-SORT-WORK-FILE
ON DESCENDING KEY SD-SCORE
INPUT PROCEDURE IS POPULATE-SORT-FILE
GIVING WS-SORTED-SCORES.
POPULATE-SORT-FILE.
* This procedure feeds the data from our input table into the
* sort utility.
PERFORM VARYING I FROM 1 BY 1 UNTIL I > LS-SCORES-IN-COUNT
MOVE LS-SCORE(I) TO SD-SCORE
RELEASE SD-SORT-RECORD
END-PERFORM.
Detailed Code Walkthrough
Let's break down the program section by section to understand its inner workings.
1. `IDENTIFICATION` and `ENVIRONMENT` Divisions
The IDENTIFICATION DIVISION is straightforward; it names our program HighScores. The ENVIRONMENT DIVISION is more technical. Here, we use FILE-CONTROL to declare a logical file named SD-SORT-WORK-FILE and assign it to a physical temporary file on disk. The Cobol SORT verb requires this "work file" to perform its operations, especially for large datasets.
2. `DATA DIVISION`
This is where all our data is defined.
- `FILE SECTION`: We define the structure of a single record in our sort work file (
SD-SORT-WORK-FILE). TheSDlevel indicator marks it as a Sort Description. - `WORKING-STORAGE SECTION`: This holds our program's internal data.
WS-SORTED-SCORESis a table that will receive the output from theSORTverb.WS-LATEST-SCORE,WS-PERSONAL-BEST, andWS-TOP-THREE-SCORESare variables to hold the results. - `LINKAGE SECTION`: This is crucial for subprograms. It defines the data structures that are passed into the program from a calling program. It acts as a function signature or API contract.
LS-SCORES-INis the input list, and the other variables are pointers to where we should place our results.
3. `PROCEDURE DIVISION`
This is where the logic resides. Instead of one continuous flow, we use the ENTRY statement to create multiple entry points.
ENTRY "get-latest-score": This is the simplest function. It directly accesses the input tableLS-SCORES-INusing the countLS-SCORES-IN-COUNTas the index. This works because the last item added is always at the end of the list.ENTRY "get-personal-best": This logic first calls theSORT-THE-SCORESparagraph. After the sort is complete, the highest score is guaranteed to be at the first position of theWS-SORTED-SCOREStable, so we just moveWS-SORTED-SCORE(1)to the output.ENTRY "get-top-three": Similar to the personal best, it starts by sorting. It then uses aPERFORM VARYINGloop to copy the first three elements from the sorted table into the output table. It includes a check (IF I <= LS-SCORES-IN-COUNT) to handle cases where the input list has fewer than three scores.
4. The `SORT-THE-SCORES` Paragraph
This is the heart of the sorting logic.
SORT SD-SORT-WORK-FILE ON DESCENDING KEY SD-SCORE: This tells Cobol to sort the work file, ordering the records so that theSD-SCOREfield is in descending (highest to lowest) order.INPUT PROCEDURE IS POPULATE-SORT-FILE: Instead of using a physical input file, we tell theSORTverb to get its data from a procedure (a paragraph) namedPOPULATE-SORT-FILE.GIVING WS-SORTED-SCORES: This tells theSORTverb to write the sorted output not to a file, but directly into ourWORKING-STORAGEtable,WS-SORTED-SCORES. This is incredibly convenient for in-memory sorting.POPULATE-SORT-FILE: This paragraph loops through our input table from theLINKAGE SECTION(LS-SCORES-IN) and, for each score, uses theRELEASEverb to pass it to the sort utility.RELEASEis the counterpart toWRITEwhen using anINPUT PROCEDURE.
Where is this Pattern Used in the Real World?
While managing game scores is a fun example, the underlying pattern of sorting records to find top performers is a cornerstone of enterprise computing, especially on mainframes where Cobol thrives. This exact logic is applied in countless real-world scenarios:
- Financial Reporting: Generating a report of the top 10 sales representatives for the quarter.
- Banking: Identifying the largest transactions in a day for fraud detection or auditing.
- Insurance: Calculating the highest-risk policies based on claim history.
- Inventory Management: Listing the top-selling products to inform restocking decisions.
In all these cases, a batch program reads a large dataset, uses the SORT utility to order it by a specific key (sales amount, transaction value, etc.), and then processes the top N records to generate a report or feed another system. The efficiency of Cobol's `SORT` makes it ideal for these large-scale data processing tasks.
Alternative Approaches & Performance Considerations
The built-in SORT verb is almost always the best choice. However, for academic purposes or to understand fundamental algorithms, it's useful to know how you could sort a table manually in Cobol.
Manual Sorting with `PERFORM VARYING` (Bubble Sort)
You could implement a classic sorting algorithm like a Bubble Sort using nested loops. The logic involves repeatedly stepping through the list, comparing each pair of adjacent items, and swapping them if they are in the wrong order.
PERFORM VARYING I FROM 1 BY 1 UNTIL I > WS-SCORE-COUNT - 1
PERFORM VARYING J FROM 1 BY 1 UNTIL J > WS-SCORE-COUNT - I
IF WS-SCORE(J) < WS-SCORE(J + 1)
* Swap the elements
MOVE WS-SCORE(J) TO WS-TEMP-SCORE
MOVE WS-SCORE(J + 1) TO WS-SCORE(J)
MOVE WS-TEMP-SCORE TO WS-SCORE(J + 1)
END-IF
END-PERFORM
END-PERFORM.
ASCII Logic Diagram: Bubble Sort Flow
The flow of a manual sort is much more granular and iterative. The program must manage every comparison and swap itself, which is far less efficient than the highly optimized internal `SORT` utility.
● Start with Unordered List
│
▼
┌────────────────────────┐
│ Loop 1 (Outer Pass) │
└──────────┬─────────────┘
│
▼
┌───────────────────┐
│ Loop 2 (Inner) │
│ Compare adjacent │
└─────────┬─────────┘
│
▼
◆ A > B ?
╱ ╲
Yes (Swap) No (Continue)
│ │
▼ │
┌──────────┐ │
│ Swap A, B│ │
└──────────┘ │
╲ ╱
└──────┬──────┘
│
▼
◆ Inner Loop Done?
╱ ╲
No ----------------- (Back to Inner Loop)
╱
Yes
│
▼
◆ Outer Loop Done?
╱ ╲
No ----------------- (Back to Outer Pass)
╱
Yes
│
▼
● Sorted List
Pros and Cons: `SORT` Verb vs. Manual Sorting
| Aspect | Cobol `SORT` Verb | Manual Sorting (e.g., Bubble Sort) |
|---|---|---|
| Performance | Highly optimized, extremely fast. Uses efficient algorithms and can offload to disk for huge datasets. | Very slow, especially for large lists (O(n²) complexity for bubble sort). Inefficient. |
| Readability | High. The code is declarative and clearly states the intent ("sort this data"). | Low. The logic is complex, with nested loops and swap variables, obscuring the primary goal. |
| Development Time | Fast. Writing a `SORT` statement is quick and standardized. | Slow. Requires writing, testing, and debugging a complex algorithm from scratch. |
| Robustness | Extremely robust and reliable. A core, heavily tested feature of the language. | Prone to off-by-one errors and other logical bugs. |
| Use Case | The standard for nearly all sorting tasks in professional Cobol development. | Primarily for educational purposes or very small, specific in-memory sorting tasks where `SORT` might be overkill (rare). |
Frequently Asked Questions (FAQ)
- 1. What is a `TABLE` in Cobol?
-
A
TABLEin Cobol is the equivalent of an array or list in modern programming languages. It is defined using theOCCURSclause on a data item in theDATA DIVISION, which specifies a fixed or variable number of times the item repeats. - 2. How does the `SORT` verb work in Cobol?
-
The
SORTverb is a powerful, high-level command that sorts a file or, through procedures, an in-memory table. You specify the data to be sorted, the key(s) to sort on (ascending or descending), and where the output should go. It uses highly optimized system routines to perform the sort efficiently. - 3. Why use `DESCENDING KEY` for high scores?
-
We use
DESCENDING KEYbecause we want the highest scores to appear first in the sorted list. Sorting in descending order arranges the numbers from largest to smallest, making it easy to find the "top" scores by simply taking the first few elements. - 4. What is the `LINKAGE SECTION` for?
-
The
LINKAGE SECTIONis used in subprograms to define the layout of data that is passed from a calling program. It doesn't allocate memory itself; instead, it provides a map or template that overlays the memory of the arguments passed during aCALL, allowing the subprogram to access and modify them. - 5. Can Cobol handle a list if I don't know the exact size beforehand?
-
Yes. While you must specify a maximum size for a table, you can use the
OCCURS... DEPENDING ON...clause. This links the actual size of the table to a variable, allowing it to handle a variable number of elements up to the defined maximum, which is how our solution is designed. - 6. Is Cobol still relevant for tasks like data sorting?
-
Absolutely. For the domains where Cobol operates—primarily mainframe-based batch processing in finance, insurance, and government—its ability to process and sort massive files with extreme efficiency is a key reason for its continued relevance. The
SORTutility is a prime example of its strengths.
Conclusion: Timeless Logic in a Classic Language
Successfully building a high-score management component in Cobol is a fantastic achievement that bridges the gap between classic gaming logic and enterprise programming techniques. Throughout this guide, we've deconstructed the problem, explored the fundamentals of Cobol's DATA DIVISION, and harnessed the immense power of the built-in SORT verb. You've learned that despite its age and verbosity, Cobol provides robust, efficient, and surprisingly readable solutions for complex data manipulation tasks.
The key takeaways are clear: proper data definition is paramount, and leveraging built-in features like SORT over manual implementations is crucial for performance and maintainability. This foundational knowledge is not just for solving puzzles; it's directly applicable to the real-world batch processing and reporting tasks that keep global industries running.
Disclaimer: The code and concepts presented are based on standard GnuCOBOL or IBM Enterprise COBOL. Syntax and feature availability may vary slightly between different Cobol compilers and versions. Always consult your specific compiler's documentation.
Ready to tackle your next challenge? Continue your journey on the Cobol 4 learning roadmap or explore our complete collection of tutorials on the main Kodikra Cobol page.
Published by Kodikra — Your trusted Cobol learning resource.
Post a Comment