• Dear Cerberus X User!

    As we prepare to transition the forum ownership from Mike to Phil (TripleHead GmbH), we need your explicit consent to transfer your user data in accordance with our amended Terms and Rules in order to be compliant with data protection laws.

    Important: If you accept the amended Terms and Rules, you agree to the transfer of your user data to the future forum owner!

    Please read the new Terms and Rules below, check the box to agree, and click "Accept" to continue enjoying your Cerberus X Forum experience. The deadline for consent is April 5, 2024.

    Do not accept the amended Terms and Rules if you do not wish your personal data to be transferred to the future forum owner!

    Accepting ensures:

    - Continued access to your account with a short break for the actual transfer.

    - Retention of your data under the same terms.

    Without consent:

    - You don't have further access to your forum user account.

    - Your account and personal data will be deleted after April 5, 2024.

    - Public posts remain, but usernames indicating real identity will be anonymized. If you disagree with a fictitious name you have the option to contact us so we can find a name that is acceptable to you.

    We hope to keep you in our community and see you on the forum soon!

    All the best

    Your Cerberus X Team

Different variants of the same game. Best practice?

Phil7

Moderator
CX Code Contributor
3rd Party Tool Dev
Joined
Jun 26, 2017
Messages
886
I am making a math game and I am using the same game mechanics for different exercises like addition or multiplication.
Untill now I was using the same code for each game modifying it with a global variable called appType and two or three select blocks to have different behaviour.
Then I have an abstract class for the handling of the exercises, which is extended by each exercise class.
Now I wonder if there is a better solution. Maybe have the code that is used in every game separated in some Modules that are imported in each game.

How are you solving these problems? I think it is the same with bigger testing environments?!
 
Unless the scale of the game is huge, it's really a matter of what works best for you. The perfect is often the enemy of the good, and all programs are a little bit messy in some way! My thoughts...

If I understand you correctly, the games are separate classes of the same parent, and they have common code that is *almost* the same but not quite?

Ideally I guess you would have the common code in the form of functions to which you would pass parameters rather than access global variables, or else as methods of a separate support class which could have its fields set to what you use global variables for now. That way you could mix and match the different functions and classes freely in your game type classes, or create separate instances of the support classes for use in different game types. (That would allow you to access different variants within the same game too, without having to switch global variables first.)
 
Thanks a lot for your reply.
It seems that understanding my explanation of the problem is as hard as understanding your explanation of a solution to it... ;)
I got a few new thoughts out of it and maybe I can come up with some pseudo code to show where I am coming from.
If I understand you correctly, the games are separate classes of the same parent
At the moment no, there is only one game in one class and you choose by setting appType which variant is built. For now only one part of the game (generating and handling of the exercises list) is chosen by instantiating different child classes (through appType again).
 
Maybe it is helpful to know where I need variation of the code to make each game work with the exercises:
  1. All exercises of one type have to be generated before I put them in a list. Like 1+1=2, 1+2=3, ... compared to 1x1=1, 1x2=4
  2. The rendering of the exercise and the solution is different, especially if I want to visualize numbers as sets of elements.
 
Here is some pseudo code of the different options I see:
1. This is how it was:
Code:
Const MULTIPL = 1
Const ADDIT = 2
Global AppType = MULTIPL 'Here I can switch, which one is built.


Class ExercHandling Abstract
    Method generateExercises() Abstract

End Class

Class ExercHandlingMultipl Extends ExercHandling
    Method generateExercises()
        'generate Exercises for Multiplication
    End
End Class


'...somewhere in the setup
Select AppType
    Case MULTIPL
        exercises = New ExercHandlingMultipl()
    Case ADDIT
        exercises = New ExercHandlingAddit()
End

'...somewhere in the rendering
Select AppType
    Case MULTIPL
        DrawStuffMultipl()
    Case ADDIT
        DrawStuffAddit()
End

2. How I plan to do it now (Thanks to @Gerry Quinn):
Code:
Import CommonClasses

Class MultiplSpecific 'maybe Extdends a commonClass
    Method generateExercises()
    End
    Method RenderStuff()
    End
End Class

Class AddSpecific 'maybe Extdends a commonClass
    Method generateExercises()
    End
    Method RenderStuff()
    End
End Class

'...somewhere in the setup
exercises = New MultiplSpecific 'Here I can switch, which one is built.
'exercises = New AdditSpecific

'...somewhere in the rendering
exercises.RenderStuff

I was also thinking about having different starting points i.e. files with the Main function in it, but then I have to have a .data folder for each of them with a lot of duplicates in it.
Any thoughts?
 
but then I have to have a .data folder for each of them with a lot of duplicates in it.
Any thoughts?

Not necessarily. You can have all your data in a shared folder called data (or anything else) and make them accessible by writing
Code:
Import "data/myfile.png"
 
Ah right, I didn't have that in mind. That way I could have all shared data in one directory and still have the specific data in the normal .data folders. This option is quite interesting because then I have seperate build folders.
 
So you really want to make different games with some common code? It might be simplest to just use common modules as much as possible. You could also use preprocessor #IF...#END directives rather than Select statements .

Or you could have a base class with some common functionality that is extended in different exercise classes:
Code:
Class Exercise Abstract

    ' Common fields
    Field dataFolder:String
   
    ' Common methods, functions etc. - can be extended anyway if you need to
    DrawBackground:Void()
        ' Code
    End
   
    ' Methods that will definitely be different for every class
    Method CheckAnswer:Bool( exerciseNumber:Int, answer:String ) Abstract
    Method DrawAll:Void() Abstract
End

Class AdditionExercise Extends Exercise

Class MultiplyExercise Extends Exercise
 
Back
Top Bottom