Connect a stand-alone game model with a Qt-based user interface

I created a simple console game Scrabble using Python. I tried to encapsulate the game model from I / O as much as possible, that is, I created several classes to describe the game with my rules and current state. I basically came up with these classes:

  • LetterSet : describe the tiles in the game (score, total, etc.).
  • Board : introducing the board with its tiles and auxiliary functions
  • Player : a virtual class for a subclass of real classes such as Human or Bot, got one play() method, which should return the movement of players.
  • Game : Well ...

Everything works fine using a simple linear and synchronous stream with my console application.

But it turns out that it is not so easy to transfer this concept to Qt. I created all the necessary widgets, such as the Dragable board, general visual elements that describe the state of the game, and simple buttons, such as "Pass", "Continue", "Exchange".

The problem is that I'm not sure how to handle the play() method, which can use the Qt interface that I created to generate the actual move. This is not a problem for Bot though, which is simply looking for movement without any interaction.

My current idea is to create a local event loop described here and wait for the buttons to be pressed in my play() method defined in Human(Bot) . This is pretty ugly, so I'm wondering if there is a better way to do this.

I would like the main logic to be the same, for example, the Player class maintains the play() method, which generates a move and returns it. Thus, it should be possible to create any type of Player , for example, network players or bots. This is a synchronous way to do this. It doesn’t work very well with Qt based on signals / slots in a way to do things. Hope someone has a clear idea to solve my problem.

Summarized: How to generate a Player move inside its play() method and return it as a simple call to move = player.play(game) ?

Edit: Snapshot to understand what I'm talking about: snapshot http://reaktor42.de/~b52/shots/2011-06-26-235749_972x729_scrot.png

Edit2: This is quite old, and I successfully completed the task two years ago. However, I thought it might be useful to others if I post the results via github .

Thanks in advance, Oli

+6
source share
3 answers

What you can do in the Player play function:

  • Turn on the buttons and connect them to the slots (one for each action)
  • Wait for the player’s engine to be checked (or any other reason to exit)
  • Disable signals in the slot when a player is moved, has been received (or checked)

This is one way, but you must change it to fit your game model.

+2
source

My current idea is to create a local event loop described here and wait for the buttons to click in my play () method defined in Human (Bot). This is pretty ugly, so I'm wondering if there is a better way to do this.

I don’t understand why you think this is ugly. Almost any GUI program works this way: initialize a set of controls (buttons, etc.). Wait for the user to interact with the controls, respond to the interaction and repeat.

I would recommend that you have a button for the player to submit his move. They click on it, the event fires, the event handler tells your Player object that the movement has been made, and it passes it to the game logic event handler. The game logic checks whether the movement is legal (you must put the code here, and not in the GUI classes), and transfers control to the next Player object, if this movement was legal.

+1
source

I think you're right that there is some difference between the event-based model in the GUI environment and your original application design. Using a console application, you write an event loop, but in a GUI application in any of the frameworks, which, as I know, have one of them.

I would have a Player object that would pass it on a signal to the game object. You will need to structure your base Player class around this design. Not everything is so difficult to do, since you already have real logic, you just redo it a little.

Please note that the objects of your Player are actually only the interfaces between the game and the actual player, which can be someone pushing buttons in the user interface or a remote player over a network connection. Only in the case of a bot can a player actually become a player, and even then you may be better off having separate objects from the strategy engine. Thinking of it this way can help capture the design.

You don’t have to do that. You can get around this, for example. as described above, but I would not want to mess with my own event loops inside an application that has its own GUI event loop. This is a struggle with the graphical interface, and not work with it. This is not just Qt, like this, you will have a problem like this in any graphical environment. This is another way to think about structuring the application, and I would recommend covering it.

+1
source

Source: https://habr.com/ru/post/891394/


All Articles