Can someone explain the High Scores exercise?

Hi,

I’mm trying to do the High Scores exercise, but it does not make much sense to me. What is it that they’re actually asking me to do there? It is said that it’s a simple exercise in arrays as lists, but then when I look at the exercises, the functions have no explanation whatsoever. What does for example the scoresAfterBest property do?

the exercise JSON is as follows:

{
  "exercise": "high-scores",
  "comments": [
    "This is meant to be an easy exercise to practise: ",
    "* arrays as simple lists",
    "* instantiating a class",
    "Consider adding a track specific recommendation in the track's hint.md.",
    "Consider linking to a explanatory blogpost or beginner level tutorials for both topics.",
    "See Ruby Track hint.md for an example."
  ],
  "cases": [
    {
      "uuid": "1035eb93-2208-4c22-bab8-fef06769a73c",
      "description": "List of scores",
      "property": "scores",
      "input": {
        "scores": [30, 50, 20, 70]
      },
      "expected": [30, 50, 20, 70]
    },
    {
      "uuid": "6aa5dbf5-78fa-4375-b22c-ffaa989732d2",
      "description": "Latest score",
      "property": "latest",
      "input": {
        "scores": [100, 0, 90, 30]
      },
      "expected": 30
    },
    {
      "uuid": "b661a2e1-aebf-4f50-9139-0fb817dd12c6",
      "description": "Personal best",
      "property": "personalBest",
      "input": {
        "scores": [40, 100, 70]
      },
      "expected": 100
    },
    {
      "description": "Top 3 scores",
      "cases": [
        {
          "uuid": "3d996a97-c81c-4642-9afc-80b80dc14015",
          "description": "Personal top three from a list of scores",
          "property": "personalTopThree",
          "input": {
            "scores": [10, 30, 90, 30, 100, 20, 10, 0, 30, 40, 40, 70, 70]
          },
          "expected": [100, 90, 70]
        },
        {
          "uuid": "1084ecb5-3eb4-46fe-a816-e40331a4e83a",
          "description": "Personal top highest to lowest",
          "property": "personalTopThree",
          "input": {
            "scores": [20, 10, 30]
          },
          "expected": [30, 20, 10]
        },
        {
          "uuid": "e6465b6b-5a11-4936-bfe3-35241c4f4f16",
          "description": "Personal top when there is a tie",
          "property": "personalTopThree",
          "input": {
            "scores": [40, 20, 40, 30]
          },
          "expected": [40, 40, 30]
        },
        {
          "uuid": "f73b02af-c8fd-41c9-91b9-c86eaa86bce2",
          "description": "Personal top when there are less than 3",
          "property": "personalTopThree",
          "input": {
            "scores": [30, 70]
          },
          "expected": [70, 30]
        },
        {
          "uuid": "16608eae-f60f-4a88-800e-aabce5df2865",
          "description": "Personal top when there is only one",
          "property": "personalTopThree",
          "input": {
            "scores": [40]
          },
          "expected": [40]
        },
        {
          "uuid": "2df075f9-fec9-4756-8f40-98c52a11504f",
          "description": "Latest score after personal top scores",
          "scenarios": ["immutable"],
          "property": "latestAfterTopThree",
          "input": {
            "scores": [70, 50, 20, 30]
          },
          "expected": 30
        },
        {
          "uuid": "809c4058-7eb1-4206-b01e-79238b9b71bc",
          "description": "Scores after personal top scores",
          "scenarios": ["immutable"],
          "property": "scoresAfterTopThree",
          "input": {
            "scores": [30, 50, 20, 70]
          },
          "expected": [30, 50, 20, 70]
        },
        {
          "uuid": "ddb0efc0-9a86-4f82-bc30-21ae0bdc6418",
          "description": "Latest score after personal best",
          "scenarios": ["immutable"],
          "property": "latestAfterBest",
          "input": {
            "scores": [20, 70, 15, 25, 30]
          },
          "expected": 30
        },
        {
          "uuid": "6a0fd2d1-4cc4-46b9-a5bb-2fb667ca2364",
          "description": "Scores after personal best",
          "scenarios": ["immutable"],
          "property": "scoresAfterBest",
          "input": {
            "scores": [20, 70, 15, 25, 30]
          },
          "expected": [20, 70, 15, 25, 30]
        }
      ]
    }
  ]
}

Hello kapitaali,

I am suprised you have found the json file, but have not mentioned a language track.

Did you go through a github repository to search for exercises? Normally you would use the exercism.org website, pick a language and get the full testing suite and editor setup with more explanation for the exercise. For example the high scores c++ version.

Hi,

it seems that not even the C++ track actually explains what you are required to do.

I mean I can look at community solutions to get an idea, but why do I have to guess what scoresAfterBest does? Why can’t they give some instructions as to what it does?

I was looking at the JSON because I was going to contribute to exercism in various languages. I got the files from github. Then I noticed that not even those github files have proper explanation for the exercise.

scoresAfterBest isn’t something you need to implement. The instructions read,

Your task is to build a high-score component of the classic Frogger game, one of the highest selling and most addictive games of all time, and a classic of the arcade era. Your task is to write methods that return the highest score from the list, the last added score and the three highest scores.

The stub has all the functions you need to implement:

#include "high_scores.h"

#include <algorithm>

namespace arcade {

    std::vector<int> HighScores::list_scores() {
        // TODO: Return all scores for this session.
        return {0, 1, 2};
    }

    int HighScores::latest_score() {
        // TODO: Return the latest score for this session.
        return 0;
    }

    int HighScores::personal_best() {
        // TODO: Return the highest score for this session.
        return 0;
    }

    std::vector<int> HighScores::top_three() {
        // TODO: Return the top 3 scores for this session in descending order.
        return {0, 1, 2};
    }

}  // namespace arcade

Is there anything in the exercise you are having trouble understanding? Are you trying to solve this exercise? Are you having trouble reading test failures? What are you trying to do and what are you having trouble understanding?

The general scheme of the practice exercise can be challenging at the start of an exercism journey. Tthe practice exercises are written a lot more general to fit all language tracks.

To really understand what functions, methods, classes, enumerations, modules, etc have to be written, the students have to read the test files. This is specification. The file contains everything that is expected from the exercise. Names, returns, behaviour and so on. The goal is to have a sort of Test Driven Development path.

Hi,

thanks. So what you wrote there, “methods that return the highest score from the list, the last added score and the three highest scores” is totally understandable. Highest score is the maximum of a list, last added is the last element of a list and three highest are the three first if you sort the list.

But if you look at the JSON there, input and output for “scoresAfterBest”, “scoresAfterTopThree” or “latestAfterBest” do not make sense. Can you explain in words how those work?

Or even better would be if you could just come up with 3 more examples of input and output for each property so that I understand them.

The problem-spec repository serves as a starting point to implement the actual exercises on the track and as a central hub to push changes in the wording or corrections in the tests.

The json file you cited is from that repository and outlines the tests the tracks might implement. The resulting test file from that json data can vary starkly - depending on the level of automation on the track and the person who writes the test.

The students are not supposed to work with the intermediate json file, but with the test file for the respective language. The description, scenario, and properties might have very different forms when you compare Java and GDScript. So it is up to the maintaining person to chose a style that fits the testing framework for the tests and also a position in the syllabus where that exercise might make sense.

By chance, I am the person who implemented the high-scores exercise from that very json file on the cpp track.

As the track’s syllabus is young and not complete, I had to add some introductory words to the description, so people knew that it expects certain things that are not yet in the learning path. Also, I have chosen to give students a lot of the code they need, so it is not as overwhelming as a completely blank file.

One of the topics that can be shown with this exercise is immutability. That means that the function does not change the input arguments. scores is a function that returns the original scores. The top 3 function will return the highest elements from the input, but the score should be the same after the top 3 function has been called. Thus “scores after top three” as a name for the test case in the json file (which should not be visible to the students).

If you look into the cpp test file you will see that order as well. I change the description from the json file to make it more obvious for students.

TEST_CASE("Latest score after personal best", "[immutable, latestAfterBest]") {
    // Test if latest_score is still valid after calling personal_best
    std::vector<int> scores{20, 70, 15, 25, 30};
    int expected{30};
    arcade::HighScores hs{scores};
    hs.personal_best();
    REQUIRE(hs.latest_score() == expected);

Looking at tests, is what the practice exercises are all about. The test shows you, that it wants the last entry of the vector to be 30 even if the personal_best function has been called.

Does that help?

1 Like

Yes that helps. Thank you.