Tic-Tac-Toe Example (Python extension and state machine animations)

I’m going to teach a multi-day beginner TouchDesigner workshop in a few days. Towards the end, I want to give an impression of the power of Python extensions and parent shortcuts. So in preparation for this, I made Tic Tac Toe. I’d like to get feedback from anyone on what you think of the implementation. Maybe try implementing it yourself before looking at what I did? If you do, try to implement these features:

  • You play by clicking in a 3x3 grid. Clicking instantly adds the correct letter to the empty cell.
  • When the game is over, a game over screen fades in saying who won or if it was a tie.
  • Clicking on the game over screen restarts the game.
  • When playing, there’s a button for instructions that fades in an instructions screen. Clicking it instantly dismisses it.
  • When playing, there’s an indicator saying whose turn it is.

Secondary to this Tic Tac Toe demo, I tried implementing Model-View-Controller with a Python extension but keeping the state entirely in a timer CHOP (using segments). This was a throwback to how I learned MVC from iOS programming: UIViewController | Apple Developer Documentation What do you think of this design? I thought about merging this MVC design into the TicTacToe example, but it seems overkill.
tic_tac_toe_example.tox (110.3 KB)

Hi @DavidBraun,

very interesting to dive into. Because of recent conversations just also wanted to bring this to attention of @alphamoonbase and @mickeyvanolst

cheers
Markus

This thread already was on my radar this morning and I am interrested in also creating a TTT-Game as a little challange.

Regarding MVC: I am certainly an MVC-Stan. All components I released in the last year/s do follow these schema, but also in projects I try to follow this paradigm as it increases maintenability my a huge margin!

1 Like

Thanks! There was a typo in the tox. I meant to say “Remember to avoid doing any kind of state logic inside CHOP Execute DATs and haphazard scripts.”

I’m thinking that the next step for the MVC example is to add a second Python extension that is meant to handling transitions between states, unrelated to visibility of the entire container. This is where I’m headed thinking with ChatGPT but I think I’m out of time programming for today…

Here is my interpretation. Missin the “How to Play” Part but otherwise it does work. You can also select your player icon :slight_smile:

It hinges heavily on two components I built: BanaMash as a finite statemachine with transitions and the sceneCompositor for the UI.
I am not 100% happy with the current state as I have the feeling command structure could be better bundled in the GameController.

There are some inconsistent behaviours in how I do handle data and where they are.
Some Parameters of the datastore do refferences inside the sbcomponents or to attriutes, while other do get set from inside of subcomponents via scripts.I am not happy with this disconnect and need to think about a better/clear approach.

Should the datastore be a target of modification from the subcomponents or should it only reflect the state of the subcomponents?

@alphamoonbase Your TicTacToe is great and probably warrants an entire workshop. Adding an idle mode is such a valid use case.

I’m adding a new version of the MVC thing.
multistate_container.tox (111.2 KB)

I split the concept of state into two dimensions. The first dimension is related to the visibility of the container. This “ContainerState” dimension takes one of six values:
0: Will Appear
1: Appearing
2: Visible
3: Will Disappear
4: Disappearing
5: Invisible

The ContainerState value at any moment is inferred from the timer_container CHOP. The Python extension for the Controller does not hold this value in storage.

The second dimension of state refers to the scene. When subclassing the Python extension, it is up to the user to define the scenes and the allowed transitions between the scenes.

In this specific example, we have scenes A, B, and C. When the container appears we’re always in A. From A we can go to B or C. B and C can go to each other but not A. However, when the container disappear, we can instantly cut to A so that the next time the container appears, we’re in A.

When moving between Scenes, the “TransitionState” is either HOLD, WILL_TRANSITION, or TRANSITIONING.