(P) Binairo again

Goal: I will learn to design and implement a graphical user interface with Qt. I will learn to use Qt documentation. I will practice modularity and especially how to separate user interface from the action logic of the program.

Instructions: Code for a working binairo game is given in templates/12/binairo/. The program has no graphical user interface, but it works with ASCII prints, which enables you to test playing the game. Your task is to implement a graphical user interface on the existing game.

Create a new project: student/12/binairo_gui/ (note the name different from the template code). Add the class GameBoard in the Qt project, and copy code to it from the corresponding class in the template code (in the same way as in total grade exercise (11.6.2)).

Using template code is mandatory. Note especially that you shall not implement again things given in the template code, but use existing operations and data.

Important

Before starting to write code, read carefully the whole assignment, especially the point Special requirements. Remember also to use version control with a sufficient number of commits.

Recall the section 12.1 Introduction. Based on it you can decide what are the most important examples of this round when you are selecting the properties you are going to implement in the project.

Note

This project will be done independently. Working in pairs is not allowed, but it will be considered as plagiarism.

The task is to implement a graphical user interface for the given binairo game. You can find rules for the game from the subsection Game rules below, and they have also been coded in the given template code (so you need not know the rules in detail). This is the same game that was implemented non-graphically in the first project, so you can read about the functionality of the game from the assignment of the first project.

In this project, you will write a document describing those features you have implemented, the structure of your program, and design decisions.

The section Minimal requirements tells which features there at least must be in your implementation.

Header comment and feedback language

In the same way as earlier, the header comment is again required. You can use the first project’s assignment as an example (see 4.5 (P) Binairo). It is sufficient to add header comments in the files you modify.

As in the previous projects, the feedback language will be chosen in the submission box (at the very end of this page). We will only use the language you have given in the submission box of the final submission.

Game rules

The game has very simple rules: The aim is to achieve a game board that fulfills the following requirements:

  • each row and each column must contain an equal number of 0s and 1s
  • more than two of the same digits cannot be adjacent.

The original Binairo game has one more rule: each horizontal and vertical line must be different from each other. (You can implement this as an extra feature.)

Assignment

Your task is to implement a graphical user interface in the binairo game, the action logic of which is given in the template code. You shall now implement the user interface functionality graphically, i.e.:

  • asking for the starting way
  • depending on the starting way, asking either a seed value or an input
  • displaying the game status and preventing non-acceptable additions.

Besides the functionalities listed above, the game must include:

  • possibility to start the game again (reset)
  • timer telling the time used so far.

You can implement the user interface (game window) in a way you like. Squares can be implemented e.g. as labels (QLabel) or push buttons (QPushButton), or you can use QGraphicsScene.

Note

When implementing graphical user interface, do not reimplement those things that can be found from the template code.

In evaluating the project, a special attention will be paid to how well you have separated user interface code from the action logic of the game. The action logic is (mainly) already implemented in the template code, and thus, it is principally enough to write all user interface code in the MainWindow class. However, most probably you will need more functions in other classes, too. If the functions you add are not related to user interface at all, you should place them in the GameBoard class. Note that the code should be as close as possible to the data it deals with. When following this principle, it is easily possible that an implementation of a property requires a new method in both of the aforementioned classes.

If necessary, you can move methods in the GameBoard class from the private part to the public one, or you can modify a void method to return a value of a suitable type. In any modification, take care that the non-graphical game still works in the same way as earlier.

Important

Take especially care about that the ready-made code should know nothing about the user interface. Instead, the user interface code must (of course) know the given code, i.e. the action logic of the game.

Minimal requirements

By implementing the minimum functionality of the project, you can earn 50 points at maximum. At least, you must implement the following features:

  • To play the game, the game window and game grid are shown for the user.
    • These elements must be graphical user interface components (e.g. push buttons/rectangles/squares/labels), not just text.
    • It is enough to show zeros and ones as numbers in aforementioned elements.
  • It must be possible to select a starting way (filling the gameboard randomly or from the given input).
    • This can be done e.g. with clicking a button, with a key command, with a radio button, or such.
  • It must be possible to change the size of the gameboard, but it is enough to do this by changing the value of a constant in the program code (NUMBER_OF_SYMBOLS in the template code file gameboard.hh in line 13). Remember to mention the name and location of this constant in the document.
    • This should work already, if you remember to use the aforementioned constant in your code.
    • Take the previous requirement into account. The program must not crash, even if the size of the given input does not match with current size of the gameboard.
  • The game status must be shown for the user (empty and filled squares).
  • It is possible to start the game again (reset). This must be possible after the game is over, as well as in the middle of the game.
  • At the end the program tells the time used.
  • You must document the functionality of the game. The document must include instructions to play the game, for example, which dependences the actions have. It must tell what happens and what can happen in different situations. The document must also describe the program structure and the design decisions you have made.

You must implement the points above in such a way that they work. The better your implementation is and the better programming style you have followed, the more points you will get.

To get more points, pay attention also to the user-friendliness of the game. You can, for example, control the push buttons or other widgets to make them either enabled or disabled. For this purpose, the class QWidget has the slots setEnabled and setDisabled.

It is especially important to pay attention to the robustness of the game. This means that the program works in a sensible way (and do not, for example, crash), even if the user does something stupid. For example, in the case of push buttons, you can disable those ones that cannot be used in a sensible way at the moment. In any case, try to think beforehand, which kind of use cases there can be. Test your program by imaging that you are an evil enemy, whose purpose is to make the program crash. If you succeed in this, fix your code to prevent such situations.

In general, we will pay attention to the naming convention used in your code. However, the names generated by Qt do not always follow a good programming style. For example, if you automatically generate a slot, the name can be as on_pushButton_clicked. This can be considered as a bad style, since it uses both underscores and CamelCase style in dividing the name into parts. However, you should keep the names given by yourself consistent in their style.

Extra features

As told earlier, by implementing the minimum functionality of the game, you can earn 50 points at maximum. By implementing extra features for the game, you can earn another 50 points at maximum. You can get points only from working and documented extra features, i.e. also the extra features must be documented.

Assistants will add bonus points into the later section in Plussa while reviewing the projects. Besides the functionality of extra features, assistants take into account how clean your solution is.

Examples of extra features are listed below (approximate maximum points given in parenthesis):

  1. Chips have been implemented as figures (e.g. black and white circles instead of zeros and ones). (10 p.)
    • To use figures in a correct way (i.e. to get points from the extra feature), follow the steps below:
      1. Click the name of the project (binairo_gui) with the right mouse button. From the opening menu, select Add New … -> Qt -> Qt Resource File.
      2. Add Prefix (give a name e.g. pictures).
      3. Press Add Files.
      4. Instructions as figures
  2. The user can set the size of the gameboard in the user interface. (5 p.)
  3. The game has a third starting way: Solvable input is drawn randomly. (15 p.)
    • This requires a file consisting of solvable inputs, and one of them is drawn.
    • You can either use a default file or a user-given file. If you implement both of these, you can get 5 more points, i.e. totally 20 p.
    • Take into account that based on minimal requirements, the size of the gameboard can be changed. However, it is enough to make default file work with a certain size. Anyway, the program must not crash even if the size of the game board and the length of the line in the input file do not match.
  4. The game lets user make an erroneous addition, but it shows this error in a graphical way (e.g. as red). (15 p.)
  5. The players can collect points in a way you can invent by yourself. Remember to document your rules. (15 p.)
  6. The game includes a score board for storing the results (points) the players have earned. The stored data is preserved between games (i.e. the data is stored into a file). (10 p.)
  7. The background color of the user interface changes, when the game is over. Resetting the game sets the original color. (5 p.)
  8. The game has a pause button, from which the user can pause the timer. This is possible only when the game is on. Pause has e.g. the effect that the game does not response to key commands any more. The game informs about the pause for the user. (10 p.)
  9. Non-GUI feature: the game follows also the third rule, i.e. each horizontal and vertical line must be different from each other.
  10. The program has a Help button or such for showing instructions of the game. (10 p.)
  11. The program has a separate window where you can give the starting way, or some other thing is done in a separate window. (15 p.)

In addition you can suggest an additional feature of your own. The suggestions must be made at least a week before the deadline. Suggestions can be made after the exercise classes or by sending e-mail to the course’s e-mail address. The course staff has the right to accept/reject the suggestions, and define the maximum points for the feature. Accepted extra features will be added in the above list.

Note that by successfully implementing all the features listed above, you seem to get more than 50 points. However, the maximum amount of points is 50, so if you get more of them, they are decreased to 50. It is still worth trying to implement as much extra features as you can, since you might not get the maximum points from each implemented feature. (Note that the evaluation criteria of the projects at the end of the course are stricter than at the beginning.)

Testing your program and user instructions

In this project, you are the main responsible person for testing the program with sufficient coverage. However, you must still submit your work in Plussa to get it evaluated. Note that the program must work on Linux desktop.

From a Plussa submission, it will be checked if the program can be compiled. In such case, it earns one point. A submission with zero points will not end up to assistant’s evaluation.

Create the file instructions.txt and write in it short instructions on how to use the program, what are the rules of your game, and which functionalities you have implemented. The instructions must be clear and exact enough to enable the assistant to test and evaluate your program. Check from the minimal requirements all the points, the document must contain. Remember to push also this file in version control.

If you use version control from command line, you can push the document file as any other file. If you use version control from Qt, you can add the document file into Qt project as follows. On the left from the edit window of Qt, you can a list of the files included in the project. On top of this list, you can see the project name. Click it with the right button of the mouse and from the opening menu, select Add Existing Files ... (if the file instructions.txt already exists) or Add New ... (if you are about to begin to write the file).

If you have implemented an additional feature, but you have not documented it in the file instructions.txt, you will not get points from the additional feature.

Valgrind + External errors

The Qt program code may cause valgrind errors, which you have no influence on. Valgrind reports these errors in the category External errors. They are counted in the total amount of errors, but by default the error messages are not visible in the valgrind report.

You don’t need care about such external erros, but of course you need to fix all other errors.

General tips

  • It is recommended to study the examples of the current round. In their code, you can find points that are useful in implementing the project.

  • When you add new widgets in the file mainwindow.ui, their relative position to widgets created in the code, might not be correct. Try to set the widgets such that final user interface is visually as good as possible.

  • Although you add widgets in Qt Designer (mainwindow.ui), adjust their properties in code. The adjustments done in Qt Designer will not necessarily shown correctly in the running program.

  • Implementing the game will most probably require you to read Qt documentation. There you can find useful functions for implementing different features.

  • You can exploit version control also in your experiments. After pushing the latest working version in Git, you can do even large modifications safely, since you know that you can return to the earlier version if needed. You can do as follows (for each modified file):

    • In Qt: Tools -> Git -> Current File -> Undo Unstaged Changes/Undo Uncommitted Changes
    • In command line: git checkout – <filename>

    See Git course on Plussa for more details.

Special requirements

If you want your assignment to pass the evaluation, you must meet these requirements:

  • The program must not have errors related to memory management. Therefore executing valgrind is recommended.
    • If you allocate memory with new, you must deallocate it with delete, unless deallocation happens via the parent-child mechanism (see round 11 at About widgets).
  • The given code template must be used, i.e. the program must be based on it. Alternatively, you can use your own code from the first project.
  • Containers only from STL library are allowed, not e.g. from Boost.

Evaluation

To end up to assistants’ evaluation, you must submit your work in Plussa, and it must pass the automated tests. (In this case, automated tests check only, if the program can be compiled.) If the automated tests give 0 points for your work, also your final points will be 0, and your work will not be evaluated by an assistant.

The assistant evaluates the latest Plussa submission that has passed the automated testing (= 1 p) and fulfilled the special requirements of the assignment before the deadline, according to the following criteria:

  • The functionality and user instructions of the program: 0-10 points
    • All the features mentioned in the list of minimal requirements have been implemented, and they are working.
    • The program does not crash.
    • The instructions inform how to use the game, and which additional features have been implemented. The instructions have been written clearly enough to enable assistants to understand them easily.
    • The game works as said in the instructions.
  • The overall principle of the solution: 0-30 points:
    • The learning goals of the exercise have been achieved.
    • The program code has been split into logical, suitably long segments using functions, classes, and/or methods.
    • If the program uses classes and objects, these have been implemented according to the basics of object-oriented programming (see from round 4 the section About programming style at Object-oriented programming). User interface is separated from the action logic of the game.
    • The data structure does not include repetitive data nor unnecessary parts. The chosen data structures have been used in a reasonable way.
    • The program code does not include unnecessary repetitions nor other unnecessary parts.
    • The program code does not include unnecessary limitations or assumptions or other forced solutions.
    • The implementations of the program’s structures are easy to understand.
    • Global variables have not been used in the program code (global constants are OK).
    • The program does not terminate with the exit function.
    • The program has no errors related to memory management (use valgrind).
  • Programming style: -20-0 points:
    • Variables and functions are named clearly and appropriately. These items have named by using only one language, not e.g. Finnish and English mixed.
    • The program uses named constants instead of magic numbers.
    • The program code is neatly formatted.
    • Each program line has at most 80 characters.
    • At the beginning of each file written/edited by yourself, there is a comment explaining the purpose of the file, your name and student number and other necessary information. (see the assignment of the first project).
    • At the beginning of each function/method (in the header file if such exists), there is a comment describing its working, return value, and parameters.
    • There are comments in the code where necessary.
    • Comments are related to the current version of the program, not to an older one.
    • All comments have written in the same language (fi/en), but comments can be written in a language different from that used in naming variables and such.
    • All the variables have been initialized.
    • The compiler does not give warnings while compiling.
  • Using the version control: 0-10 points:
    • There are enough commits.
    • The content of commit messages is clear and relevant.

From the above list, please note that in this phase of the course it is assumed that the student follows good programming style. Therefore, you will not get points from following the style guidelines, but if you do not follow them, your points will be decreased. So, it is recommended to revisit the material about programming style on rounds 4 and 10.

Final note

After the final submission, check from the web user interface of GitLab that the submission is really in your central repository. Assistants will evaluate the version of your program that corresponds to the latest Plussa submission made before the deadline.

If you get one point from your Plussa submission, your program will be evaluated by an assistant. The assistant gives 0-50 points to your submission after completing their evaluation. The maximum amount of points is 50 (it is not possible to get 51 points).

Bonus points will be added in the later section on this round.

A+ presents the exercise submission form here.