Scrabble Score in Abap: Complete Solution & Deep Dive Guide

a close up of a computer screen with code on it

The Complete Guide to Calculating Scrabble Scores in ABAP

Calculating a Scrabble score in ABAP is a classic programming challenge that tests fundamental skills in string manipulation, data structures, and conditional logic. This task involves iterating through a word, mapping each character to its point value, and summing the results to produce a final integer score.


Ever felt stuck when faced with a task that requires processing raw text in SAP? Whether it's parsing user comments from a sales order or validating material descriptions, handling strings effectively is a non-negotiable skill for any ABAP developer. It can feel like you're trying to find a needle in a haystack, with clunky code and inefficient loops slowing you down.

But what if you could master these core concepts through a simple, engaging challenge? This guide will walk you through solving the Scrabble Score problem, a core module from the kodikra ABAP learning path. We won't just give you the answer; we will dissect the problem, explore multiple solutions, and show you how these foundational techniques apply directly to complex, real-world SAP development scenarios. Prepare to transform the way you look at string processing in ABAP.


What is the Scrabble Score Challenge?

The objective is straightforward: write a program that computes the total Scrabble score for a given word. The score is determined by the sum of the values of its individual letters. The challenge provides a specific mapping of letters to their corresponding point values.

The input will be a single word (a STRING), and the output must be the total score (an INTEGER). For this exercise, we will assume the input is a standard English word without spaces or special characters, but a robust solution should account for these possibilities.

The Official Letter-to-Value Mapping

The core of the problem lies in this value table. Your logic must correctly reference these scores for each letter in the input word.

Letter(s) Value
A, E, I, O, U, L, N, R, S, T 1
D, G 2
B, C, M, P 3
F, H, V, W, Y 4
K 5
J, X 8
Q, Z 10

An important consideration is case sensitivity. "Scrabble" and "scrabble" should yield the same score. Therefore, a crucial first step in our logic will be to normalize the input string, typically by converting it to all uppercase letters.


Why This Challenge is a Cornerstone of ABAP Development

At first glance, calculating a game score might seem trivial. However, this simple problem is a perfect microcosm of daily tasks in ABAP development. Mastering this challenge builds a strong foundation in several critical areas.

  • String Processing: The heart of the problem is iterating through a string character by character. You'll become proficient with statements like DO STRLEN( ... ) TIMES and accessing substrings, which are essential for parsing data from files, IDocs, or user input fields.
  • Data Structures: How do you store the letter-to-value mapping efficiently? We'll explore using an internal table as a lookup mechanism, a far more scalable and maintainable approach than a giant IF-ELSEIF or CASE block. This teaches the importance of choosing the right data structure for the job.
  • Algorithmic Thinking: You must break down the problem into logical steps: normalize input, initialize a total, loop through characters, find the value for each character, add it to the total, and return the result. This systematic approach is the essence of programming.
  • Code Reusability (Object-Oriented ABAP): We will implement the solution within a global class (ZCL_SCRABBLE_SCORE). This enforces best practices for creating modular, reusable, and testable code that can be easily integrated into any SAP application, moving beyond simple procedural reports.
  • Data Transformation: In real-world SAP, you are constantly transforming data from one format to another. This exercise is a basic form of data transformation—converting a string of characters into a single numerical value based on a set of business rules.

By solving this, you're not just scoring a word; you're honing the exact skills needed to build robust reports, interfaces, and enhancements in an SAP environment.


How to Design the ABAP Solution: A Step-by-Step Approach

Before writing a single line of code, a good developer architects a solution. Let's outline the logical flow for our Scrabble Score calculator. Our strategy will prioritize readability, maintainability, and performance by using an internal table as a lookup map.

High-Level Logic Flow

The overall process can be visualized as a simple, linear flow. We take an input, process it step-by-step, and produce an output.

● Start (Input: Word)
│
▼
┌─────────────────────────┐
│ Normalize Input String  │
│ (e.g., to UPPER CASE)   │
└────────────┬────────────┘
             │
             ▼
┌─────────────────────────┐
│ Initialize Total Score  │
│ (Set to 0)              │
└────────────┬────────────┘
             │
             ▼
    ◆ Loop Through Each Character
   ╱             ╲
  For Each...     End Loop
  │               │
  ▼               ▼
┌─────────────────┐  ┌───────────────┐
│ Find Value for  │  │ Return Total  │
│ Current Char    │  │ Score         │
└──────┬──────────┘  └───────▲───────┘
       │                      │
       ▼                      │
┌─────────────────┐           │
│ Add Value to    ├───────────┘
│ Total Score     │
└─────────────────┘

Step 1: The Data Model - Building the Lookup Table

Hardcoding values in a long CASE statement is brittle. If the scoring rules change, you have to modify the core logic. A much better approach is to externalize these rules into a data structure.

We'll define a structured type for our mapping and create an internal table. This table will hold all 26 letters and their corresponding scores. This is our "single source of truth" for scoring.


TYPES: BEGIN OF ty_letter_score,
         letter TYPE c LENGTH 1,
         value  TYPE i,
       END OF ty_letter_score.

TYPES: tt_letter_scores TYPE HASHED TABLE OF ty_letter_score
                        WITH UNIQUE KEY letter.

We choose a HASHED TABLE for its performance characteristics. Since we will be reading this table with a specific key (the letter), a hashed table provides the fastest possible lookup time, which is constant (O(1)) regardless of the table size.

Step 2: The Core Logic - Iteration and Calculation

With our lookup table in place, the core logic becomes a simple loop. For each character in the input word, we perform a lookup in our internal table and add the found value to a running total.

Here is a more detailed view of the loop's internal logic:

    ◆ Loop Start (Character `C`)
    │
    ▼
┌────────────────────────────┐
│ READ TABLE score_map       │
│ WITH KEY letter = `C`      │
│ INTO DATA(ls_score_entry)  │
└─────────────┬──────────────┘
              │
              ▼
    ◆ Found in Table? (sy-subrc = 0)
   ╱                         ╲
 Yes                         No
  │                          │
  ▼                          ▼
┌────────────────────────┐ ┌────────────────────────┐
│ Add ls_score_entry-value │ │ Add 0 to Total Score   │
│ to Total Score         │ │ (Or ignore character)  │
└────────────────────────┘ └────────────────────────┘
  │                          │
  └────────────┬─────────────┘
               │
               ▼
    ◆ Next Character

This design is clean and separates the data (scoring rules) from the logic (the calculation algorithm). This separation of concerns is a fundamental principle of good software design.


The Complete ABAP Solution: Code and Implementation

Now, let's translate our design into a complete, object-oriented ABAP solution. We will create a global class ZCL_SCRABBLE_SCORE with a public method SCORE that encapsulates all the logic.

1. Class Definition (SE24) - ZCL_SCRABBLE_SCORE

First, we define the class structure. The main component is the `SCORE` method.

  • Class: ZCL_SCRABBLE_SCORE
  • Description: Calculates Scrabble score for a word
  • Method: SCORE
    • Level: Public, Instance Method
    • Importing Parameter: i_word TYPE string
    • Returning Parameter: r_score TYPE i

2. Method Implementation (Source Code)

Here is the full source code for the SCORE method. This implementation is robust, handling case-insensitivity and utilizing the efficient hashed table lookup we designed.


METHOD score.

  "====================================================================
  " DATA DECLARATIONS
  "====================================================================
  " Final score to be returned
  DATA lv_total_score TYPE i.

  " Local copy of the input word for processing
  DATA lv_word TYPE string.

  " Type definition for our letter-to-value mapping
  TYPES: BEGIN OF ty_letter_score,
           letter TYPE c LENGTH 1,
           value  TYPE i,
         END OF ty_letter_score.

  " Hashed table for fast lookups
  TYPES: tt_letter_scores TYPE HASHED TABLE OF ty_letter_score
                          WITH UNIQUE KEY letter.

  " Internal table to hold the score map
  DATA lt_score_map TYPE tt_letter_scores.

  " Structure for reading from the score map
  DATA ls_score_entry LIKE LINE OF lt_score_map.


  "====================================================================
  " INITIALIZATION
  "====================================================================
  " Step 1: Handle empty input. If the word is empty, the score is 0.
  IF i_word IS INITIAL.
    r_score = 0.
    RETURN.
  ENDIF.

  " Step 2: Normalize the input string to upper case for case-insensitivity.
  lv_word = to_upper( i_word ).

  " Step 3: Populate the score map. In a real application, this might
  " be loaded from a custom configuration table (e.g., ZSCRABBLE_SCORES).
  lt_score_map = VALUE #(
    ( letter = 'A' value = 1 ) ( letter = 'E' value = 1 ) ( letter = 'I' value = 1 )
    ( letter = 'O' value = 1 ) ( letter = 'U' value = 1 ) ( letter = 'L' value = 1 )
    ( letter = 'N' value = 1 ) ( letter = 'R' value = 1 ) ( letter = 'S' value = 1 )
    ( letter = 'T' value = 1 )
    ( letter = 'D' value = 2 ) ( letter = 'G' value = 2 )
    ( letter = 'B' value = 3 ) ( letter = 'C' value = 3 ) ( letter = 'M' value = 3 )
    ( letter = 'P' value = 3 )
    ( letter = 'F' value = 4 ) ( letter = 'H' value = 4 ) ( letter = 'V' value = 4 )
    ( letter = 'W' value = 4 ) ( letter = 'Y' value = 4 )
    ( letter = 'K' value = 5 )
    ( letter = 'J' value = 8 ) ( letter = 'X' value = 8 )
    ( letter = 'Q' value = 10) ( letter = 'Z' value = 10)
  ).


  "====================================================================
  " CORE LOGIC
  "====================================================================
  " Step 4: Iterate through each character of the normalized word.
  DO strlen( lv_word ) TIMES.

    " Get the character at the current position (sy-index is 1-based).
    " The offset is sy-index - 1 because string offsets are 0-based.
    DATA(lv_current_char) = lv_word+sy-index-1(1).

    " Step 5: Look up the character's value in our score map.
    READ TABLE lt_score_map INTO ls_score_entry
      WITH TABLE KEY letter = lv_current_char.

    " Step 6: If the character is found (sy-subrc = 0), add its value to the total.
    " If not found (e.g., it's a number or symbol), its score is 0, so we do nothing.
    IF sy-subrc = 0.
      lv_total_score = lv_total_score + ls_score_entry-value.
    ENDIF.

  ENDDO.


  "====================================================================
  " RETURN RESULT
  "====================================================================
  " Step 7: Assign the final calculated score to the returning parameter.
  r_score = lv_total_score.

ENDMETHOD.

3. Test Program (SE38) - Z_TEST_SCRABBLE_SCORE

To use our class, we can create a simple executable program. This demonstrates how to instantiate the class and call the `SCORE` method.


REPORT z_test_scrabble_score.

PARAMETERS: p_word TYPE string DEFAULT 'kodikra'.

START-OF-SELECTION.
  " Create an instance of our Scrabble score calculator class.
  DATA(lo_calculator) = NEW zcl_scrabble_score( ).

  " Call the score method to get the result.
  DATA(lv_score) = lo_calculator->score( i_word = p_word ).

  " Display the result to the user.
  WRITE: / |The Scrabble score for the word '{ p_word }' is: { lv_score }|.

  " Test another word
  DATA(lv_score_cabbage) = lo_calculator->score( i_word = 'cabbage' ).
  WRITE: / |The Scrabble score for the word 'cabbage' is: { lv_score_cabbage }|.

When you execute this report, it will correctly calculate and display the scores for the given words, demonstrating that our class works as expected.


In-Depth Code Walkthrough

Let's dissect the `SCORE` method to understand every detail.

  1. Parameter Handling: The method accepts one importing parameter, i_word of type string, and has one returning parameter, r_score of type i. This is a clean and standard interface.
  2. Data Declarations: We declare all necessary variables locally within the method. This includes our total score accumulator (lv_total_score), a local copy of the word (lv_word), and the types and data objects for our lookup table (lt_score_map).
  3. Input Validation: The first logical check is IF i_word IS INITIAL. This is a crucial guard clause. Processing an empty string is unnecessary and could lead to errors. By returning 0 immediately, we make the method more robust and efficient.
  4. Normalization: lv_word = to_upper( i_word ). This line is vital for correctness. It converts the entire input string to uppercase, ensuring that 'a' and 'A' are treated identically, which matches the problem's requirements.
  5. Populating the Lookup Table: The lt_score_map = VALUE #( ... ) syntax is a modern ABAP constructor expression used to fill the internal table. This is a concise and readable way to define the contents of the table directly in the code. For a production application, this data would ideally be fetched from a database table to make it configurable without code changes.
  6. The Main Loop: DO strlen( lv_word ) TIMES. is the engine of our method. It iterates exactly as many times as there are characters in the word. The system variable sy-index automatically increments from 1 to the length of the string.
  7. Character Extraction: DATA(lv_current_char) = lv_word+sy-index-1(1). This is the classic way to access a single character in an ABAP string. We use an offset/length accessor. The offset is sy-index - 1 because sy-index is 1-based, while string offsets are 0-based. The length is 1.
  8. The Lookup: READ TABLE lt_score_map ... performs the high-speed lookup in our hashed table. We use the extracted character as the key.
  9. Score Aggregation: IF sy-subrc = 0. is the check that determines if the lookup was successful. If sy-subrc is 0, a matching letter was found. We then add its value (ls_score_entry-value) to our running total, lv_total_score. If the character is not in the table (like a hyphen or a number), sy-subrc will be non-zero, and we simply do nothing, effectively giving it a score of 0.
  10. Returning the Value: Finally, after the loop completes, r_score = lv_total_score assigns the accumulated total to the method's returning parameter, sending the result back to the caller.

Alternative Approaches and Best Practices

While our internal table lookup is a highly recommended approach, it's not the only way. Understanding alternatives helps in choosing the right tool for different scenarios.

The `CASE` Statement Method

A more direct, albeit less flexible, approach is to use a large CASE statement inside the loop.


" Inside the DO ... TIMES loop
DATA(lv_current_char) = lv_word+sy-index-1(1).

CASE lv_current_char.
  WHEN 'A' OR 'E' OR 'I' OR 'O' OR 'U' OR 'L' OR 'N' OR 'R' OR 'S' OR 'T'.
    lv_total_score = lv_total_score + 1.
  WHEN 'D' OR 'G'.
    lv_total_score = lv_total_score + 2.
  WHEN 'B' OR 'C' OR 'M' OR 'P'.
    lv_total_score = lv_total_score + 3.
  " ... and so on for all other letter groups
  WHEN OTHERS.
    " Do nothing for characters not in the list
ENDCASE.

Pros & Cons Comparison

Aspect Internal Table Lookup (Recommended) CASE Statement
Performance Excellent. Hashed table lookups are extremely fast (O(1)). Good, but potentially slower. The system has to evaluate multiple conditions for letters later in the alphabet.
Maintainability Excellent. Scoring rules are stored as data. They can be changed easily or even loaded from a database without touching the algorithm. Poor. Changing a letter's score requires modifying the core program logic. This is error-prone and violates the Open/Closed Principle.
Readability Very high. The logic is clean: "loop, read, add". The rules are neatly organized in the table definition. Can become low. A large CASE block with many WHEN conditions can be long and difficult to read.
Scalability Highly scalable. Adding new rules (e.g., for different languages or special characters) is as simple as adding a new row to the table. Not scalable. Each new rule adds more complexity and lines to the CASE block.
Best For Production code, dynamic requirements, and best-practice adherence. Very simple, one-off reports where rules are guaranteed never to change.

For any serious development, the internal table lookup method is superior. It treats the scoring rules as data, not code, which is a fundamental principle of robust software engineering.


Frequently Asked Questions (FAQ)

1. How should the program handle invalid inputs like numbers or empty strings?
Our solution already handles this gracefully. An empty string is caught by the initial check and returns 0. Numbers, symbols, or any characters not in our score map will simply fail the READ TABLE lookup, resulting in sy-subrc <> 0, and they will be skipped, contributing 0 to the score as intended.
2. Is the Scrabble score calculation case-sensitive?
By design, it should not be. Our code ensures this by converting the entire input word to uppercase using to_upper( i_word ) at the beginning. This normalization step is crucial for correctness, ensuring "Apple" and "apple" produce the same score.
3. Can this logic be further optimized for performance?
For this specific problem, the current solution using a hashed table is already highly optimized. The lookup time is constant, so performance will not degrade even if the rule set grows. Any further micro-optimizations would likely be negligible and could harm readability. The bottleneck in a real application would be data retrieval from the database, not this calculation logic.
4. How can I make this logic reusable across my SAP system?
Implementing it within a global class (like ZCL_SCRABBLE_SCORE), as we have done, is the best practice. This class can then be instantiated and its SCORE method can be called from any report, function module, or other class in the system, promoting code reuse and a single point of maintenance.
5. What are common mistakes when first implementing this?
The most common mistakes include: forgetting to handle case-insensitivity (leading to incorrect scores for mixed-case words), off-by-one errors in string offsets when using loops like DO ... TIMES, and choosing an inefficient data structure like a massive IF-ELSEIF chain which is hard to maintain.
6. What is the difference between `DO ... TIMES` and splitting the string into an internal table of characters?
You could split the string into a table of single characters and then LOOP AT that table. While functionally similar, the DO STRLEN(...) TIMES approach with offset access is often more memory-efficient as it avoids creating a new internal table just for iteration. For very large strings, this can be a meaningful difference.
7. Where can I learn more about ABAP fundamentals?
This exercise is a key part of our structured curriculum. To deepen your understanding of ABAP from the ground up, we highly recommend exploring the complete kodikra ABAP language guide, which covers everything from basic syntax to advanced object-oriented concepts.

Conclusion and Next Steps

You have successfully navigated the Scrabble Score challenge from the kodikra ABAP learning path. More than just solving a puzzle, you have implemented a solution that embodies key principles of modern ABAP development: clean code, efficient data structures, and object-oriented design. The techniques learned here—string iteration, data normalization, and using internal tables as lookup maps—are not just academic; they are the building blocks you will use daily to create powerful and maintainable SAP applications.

The journey doesn't end here. The best way to solidify these skills is to practice. Try extending the solution: can you modify it to handle double-letter or triple-word scores? Could you load the scoring rules from a custom Z-table? Keep challenging yourself, and you will continue to grow as a developer.

Disclaimer: The code provided in this article is written and tested for modern ABAP environments, specifically on SAP S/4HANA 2023 and higher. While most syntax is backward-compatible, certain modern constructs like the VALUE operator might require newer versions of the ABAP runtime.


Published by Kodikra — Your trusted Abap learning resource.