Step 4: Making a Game Class

You will need to make a Game class. Yours can look a lot like the one that comes with SampleGame called T2Game.py

In this entry we will dissect the example given game class, T2Game.py, in order to better understand what’s required in a SkeletonGame’s main class. Before we get too deep, it’s worth noting that a familiarity with Object Oriented concepts is very valuable here, as is some experience with Python. You can pick up everything you need from a few nights going through the Python tracks on Code Academy.

If you investigate the SampleGame folder you will see two files: config.yaml (discussed in a previous entry) and T2Game.py –the latter defines the “main” class of the Sample Game, and is the place to start in understanding how this game works and what is expected in your own game. Some good additional Python resources are this wikibook, and this overview of object orientation in Python.

Imports

The first few lines are imports; they include code written by others for use into your program. Some are included with python (e.g., logging) and others are part of the PyProcGame/PyProcGameHD/SkeletonGame framework (e.g., anything starting with procgame)

Nothing is wildly special in the above. In the next block, you’ll find the imports of python modules that define “Modes” –Modes are important, but let’s table that until we get through this file.

The above imports do a few things: the first imports my_modes which is a folder under SampleGame, and ultimately a package in Python lingo. In Python, the execution of this line causes Python to look a definition of a module of that name, and that search starts from the current folder, looking for a file of that name, or a package of that name. What python finds is a folder, so within that folder, Python is looking for a file called __init__.py which will be executed when that package is imported. That file can include seperate import lines to define “All” the files in that sub-folder, but importing all the files in that folder is not automatic.

The next line imports two specific classes from my_modes –those examples will be the ones we dissect in the next entry.

The next two lines give examples of how to import a new Mode that you create if you do not wish to modify the __init__.py; the general for there is:

from <folder>.<file> import <class_name>

Reading the Python docs about modules and packages should shed more light here, if you are so inclined.

Logging

The next line sets up the logging level and format.

Logging level INFO produces a considerable amount of output to the console, but actually not as verbose as is possible. The levels are listed here, and a good tutorial on using Logging (which is worlds better than just using print is availble here).

The curr_file_path line simply lets the SkeletonGame code know where in the system the current file is located for relative path loading.

The Game Class

Now we get to the meat of things. The Game class is the main game object. It “owns” all the attributes of the physical machine (.coils, .lamps, .switches) and can communicate with these components via the P-ROC interface. In addition the Game class owns the state of the active game, including (among other things) the “Player” (.current_player()), the list of players (.players), the ball number (.ball), and the Mode Queue (.modes). The Game class also is the home of the display controller (which we typically don’t access directly), and the sound controller (.sound),

Some understanding of Object Orientation goes a long way. Our game is a sub-class of SkeletonGame, which means it includes all the fields (i.e., variables) and methods (i.e., functions) of the SkeletonGame class. SkeletonGame is a subclass of BasicGame, which is in turn a sub-class of GameController.

In the code above, the __init__(self): method is defined, which is the T2Game class constructor –this is the function that gets called when a new instance of the T2Game class is created. That means, typically, this function is run once, when your game is executed. If you “peek ahead” to the bottom of the file, you will see where your game is constructed.

The rest of the constructor defines the switches that will start out as “automatically closed”, and invokes the __init__() method of the super-class (that is, calls the __init__ method defined in SkeletonGame); that code sets up a lot of stuff for us, and it’s nice that you don’t have to write that code. 🙂

The next few lines instantiate the Modes that manage the behavior of the game. When you add a new mode, you’ll need to add a line like the following:

If you’d like to add any global helpers, notice that the leftTargetLamps is defined just to be helpful, creating an array of the lamps corresponding to the left five targets, accessible through the game instance.

The last thing the game __init__() needs to do is call .reset(); the definition of reset immediately follows.

The .do_ball_search() method, shown below, is called by the framework when a ball search is required. Your methods should actually pulse coils in order to release stuck balls. This example is far from ideal since it doesn’t have any delay

Last, and certainly not least, at the bottom of the file:

That is what is actually run when you type python T2Game.py, and it passes the class into the run_proc_game() function (defined in SkeletonGame) to create an instance of your game and run it.