<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="gl">
	<id>https://gl.doc.boardgamearena.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Coin-coin+le+canapin</id>
	<title>Board Game Arena - Contribucións do/a usuario/a [gl]</title>
	<link rel="self" type="application/atom+xml" href="https://gl.doc.boardgamearena.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Coin-coin+le+canapin"/>
	<link rel="alternate" type="text/html" href="https://gl.doc.boardgamearena.com/Especial:Contribuci%C3%B3ns/Coin-coin_le_canapin"/>
	<updated>2026-10-16T06:22:56Z</updated>
	<subtitle>Contribucións do/a usuario/a</subtitle>
	<generator>MediaWiki 1.39.0</generator>
	<entry>
		<id>https://gl.doc.boardgamearena.com/index.php?title=Your_game_state_machine:_states.inc.php&amp;diff=1597</id>
		<title>Your game state machine: states.inc.php</title>
		<link rel="alternate" type="text/html" href="https://gl.doc.boardgamearena.com/index.php?title=Your_game_state_machine:_states.inc.php&amp;diff=1597"/>
		<updated>2015-08-20T14:52:30Z</updated>

		<summary type="html">&lt;p&gt;Coin-coin le canapin: /* id */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This file describes the game states machine of your game (all the game states properties, and the transitions to get from one state to another).&lt;br /&gt;
&lt;br /&gt;
Important: to understand the game state machine, the best is to read this presentation first:&lt;br /&gt;
&lt;br /&gt;
[http://www.slideshare.net/boardgamearena/bga-studio-focus-on-bga-game-state-machine Focus on BGA game state machine]&lt;br /&gt;
&lt;br /&gt;
== Overall structure ==&lt;br /&gt;
&lt;br /&gt;
The machine states is described by a PHP associative array.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$machinestates = array(&lt;br /&gt;
&lt;br /&gt;
    // The initial state. Please do not modify.&lt;br /&gt;
    1 =&amp;gt; array(&lt;br /&gt;
        &amp;quot;name&amp;quot; =&amp;gt; &amp;quot;gameSetup&amp;quot;,&lt;br /&gt;
        &amp;quot;description&amp;quot; =&amp;gt; clienttranslate(&amp;quot;Game setup&amp;quot;),&lt;br /&gt;
        &amp;quot;type&amp;quot; =&amp;gt; &amp;quot;manager&amp;quot;,&lt;br /&gt;
        &amp;quot;action&amp;quot; =&amp;gt; &amp;quot;stGameSetup&amp;quot;,&lt;br /&gt;
        &amp;quot;transitions&amp;quot; =&amp;gt; array( &amp;quot;&amp;quot; =&amp;gt; 2 )&lt;br /&gt;
    ),&lt;br /&gt;
    &lt;br /&gt;
    // Note: ID=2 =&amp;gt; your first state&lt;br /&gt;
&lt;br /&gt;
    2 =&amp;gt; array(&lt;br /&gt;
    		&amp;quot;name&amp;quot; =&amp;gt; &amp;quot;playerTurn&amp;quot;,&lt;br /&gt;
    		&amp;quot;description&amp;quot; =&amp;gt; clienttranslate(&#039;${actplayer} must play a card or pass&#039;),&lt;br /&gt;
    		&amp;quot;descriptionmyturn&amp;quot; =&amp;gt; clienttranslate(&#039;${you} must play a card or pass&#039;),&lt;br /&gt;
    		&amp;quot;type&amp;quot; =&amp;gt; &amp;quot;activeplayer&amp;quot;,&lt;br /&gt;
    		&amp;quot;possibleactions&amp;quot; =&amp;gt; array( &amp;quot;playCard&amp;quot;, &amp;quot;pass&amp;quot; ),&lt;br /&gt;
    		&amp;quot;transitions&amp;quot; =&amp;gt; array( &amp;quot;playCard&amp;quot; =&amp;gt; 2, &amp;quot;pass&amp;quot; =&amp;gt; 2 )&lt;br /&gt;
    ),&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Syntax ==&lt;br /&gt;
&lt;br /&gt;
=== id ===&lt;br /&gt;
&lt;br /&gt;
The keys determine game states IDs (in the example above: 1 and 2).&lt;br /&gt;
&lt;br /&gt;
IDs must be positive integers.&lt;br /&gt;
&lt;br /&gt;
ID=1 is reserved for the first game state and should not be used (and you must not modify it).&lt;br /&gt;
&lt;br /&gt;
ID=99 is reserved for the last game state of the game (end of the game) (and you must not modify it).&lt;br /&gt;
&lt;br /&gt;
Note: you may use any ID, even ID greater than 100. But you cannot use 1 and 99.&lt;br /&gt;
&lt;br /&gt;
Note²: You can&#039;t of course use the same ID twice.&lt;br /&gt;
&lt;br /&gt;
Note³: When a game is in prod and you change the ID of a state, all active games (including many turn based) will behave unpredictably.&lt;br /&gt;
&lt;br /&gt;
=== name ===&lt;br /&gt;
&lt;br /&gt;
(mandatory)&lt;br /&gt;
&lt;br /&gt;
The name of a game state is used to identify it in your game logic.&lt;br /&gt;
&lt;br /&gt;
Several game states can share the same name, however this is not recommended.&lt;br /&gt;
&lt;br /&gt;
PHP example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Get current game state&lt;br /&gt;
$state = $this-&amp;gt;gamestate-&amp;gt;state();&lt;br /&gt;
if( $state[&#039;name&#039;] == &#039;myGameState&#039; )&lt;br /&gt;
{&lt;br /&gt;
...&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
JS example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        onEnteringState: function( stateName, args )&lt;br /&gt;
        {&lt;br /&gt;
            console.log( &#039;Entering state: &#039;+stateName );&lt;br /&gt;
            &lt;br /&gt;
            switch( stateName )&lt;br /&gt;
            case &#039;myGameState&#039;:&lt;br /&gt;
            &lt;br /&gt;
                // Do some stuff at the beginning at this game state&lt;br /&gt;
                ....&lt;br /&gt;
                &lt;br /&gt;
                break;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== type ===&lt;br /&gt;
&lt;br /&gt;
(mandatory)&lt;br /&gt;
&lt;br /&gt;
You can use 3 types of game states:&lt;br /&gt;
* activeplayer (1 player is active and must play)&lt;br /&gt;
* multipleactiveplayer (1..N players can be active and must play)&lt;br /&gt;
* game (no player is active. This is a transitional state to do something automatic specified by game rules)&lt;br /&gt;
&lt;br /&gt;
=== description ===&lt;br /&gt;
&lt;br /&gt;
(mandatory)&lt;br /&gt;
&lt;br /&gt;
The description is the string that is displayed in the main action bar (top of the screen) when the state is active.&lt;br /&gt;
&lt;br /&gt;
When a string is specified as a description, you must use &amp;quot;clienttranslate&amp;quot; in order the string can be translate on the client side:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 		&amp;quot;description&amp;quot; =&amp;gt; clienttranslate(&#039;${actplayer} must play a card or pass&#039;),&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the description string, you can use ${actplayer} to refer to the active player.&lt;br /&gt;
&lt;br /&gt;
You can also use custom arguments in your description. These custom arguments correspond to values returned by your &amp;quot;args&amp;quot; PHP method (see below &amp;quot;args&amp;quot; field).&lt;br /&gt;
&lt;br /&gt;
Example of custom field:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In states.inc.php:&lt;br /&gt;
        &amp;quot;description&amp;quot; =&amp;gt; clienttranslate(&#039;${actplayer} must choose ${nbr} identical energies&#039;),&lt;br /&gt;
        &amp;quot;args&amp;quot; =&amp;gt; &amp;quot;argMyArgumentMethod&amp;quot;&lt;br /&gt;
&lt;br /&gt;
In mygame.game.php:&lt;br /&gt;
    function argMyArgumentMethod()&lt;br /&gt;
    {&lt;br /&gt;
        return array(&lt;br /&gt;
            &#039;nbr&#039; =&amp;gt; 2  // In this case ${nbr} in the description will be replaced by &amp;quot;2&amp;quot;&lt;br /&gt;
        );    &lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: You may specify an empty string (&amp;quot;&amp;quot;) here if it never happens that the game remains in this state (ie: if this state immediately jump to another state when activated).&lt;br /&gt;
&lt;br /&gt;
Note²: Usually, you specify a string for &amp;quot;activeplayer&amp;quot; and &amp;quot;multipleactiveplayer&amp;quot; game states, and you specify an empty string for &amp;quot;game&amp;quot; game states. BUT, if you are using synchronous notifications, the client can remains few seconds on a &amp;quot;game&amp;quot; type game state, and in this case this may be useful to display a description in the status bar during this state.&lt;br /&gt;
&lt;br /&gt;
=== descriptionmyturn ===&lt;br /&gt;
&lt;br /&gt;
(mandatory for &amp;quot;activeplayer&amp;quot; and &amp;quot;multipleactiveplayer&amp;quot; game states type)&lt;br /&gt;
&lt;br /&gt;
&amp;quot;descriptionmyturn&amp;quot; has exactly the same role and properties than &amp;quot;description&amp;quot;, except that this value is displayed to the current active player - or to all active players in case of a multipleactiveplayer game state.&lt;br /&gt;
&lt;br /&gt;
In general, we have this situation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        &amp;quot;description&amp;quot; =&amp;gt; clienttranslate(&#039;${actplayer} can take some actions&#039;),&lt;br /&gt;
        &amp;quot;descriptionmyturn&amp;quot; =&amp;gt; clienttranslate(&#039;${you} can take some actions&#039;),&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: you can use ${you} in description my turn in order the description can display &amp;quot;You&amp;quot; instead of the name of the player.&lt;br /&gt;
&lt;br /&gt;
=== action ===&lt;br /&gt;
&lt;br /&gt;
(mandatory for &amp;quot;game&amp;quot; game state type)&lt;br /&gt;
&lt;br /&gt;
&amp;quot;action&amp;quot; specify a PHP method to call when entering into this game state.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
In states.inc.php:&lt;br /&gt;
    28 =&amp;gt; array(&lt;br /&gt;
        &amp;quot;name&amp;quot; =&amp;gt; &amp;quot;startPlayerTurn&amp;quot;,&lt;br /&gt;
        &amp;quot;description&amp;quot; =&amp;gt; &#039;&#039;,&lt;br /&gt;
        &amp;quot;type&amp;quot; =&amp;gt; &amp;quot;game&amp;quot;,&lt;br /&gt;
        &amp;quot;action&amp;quot; =&amp;gt; &amp;quot;stStartPlayerTurn&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
In mygame.game.php:&lt;br /&gt;
    function stStartPlayerTurn()&lt;br /&gt;
    {   &lt;br /&gt;
        // ... do something at the beginning of this game state&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Usually, for &amp;quot;game&amp;quot; game state type, the action method is used to do some automatic stuff specified by the rules (ex: check victory conditions, deal cards for a new round, go to the next player...) and then jump to another game state.&lt;br /&gt;
&lt;br /&gt;
Note: a BGA convention specify that PHP method called with &amp;quot;action&amp;quot; are prefixed by &amp;quot;st&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== transitions ===&lt;br /&gt;
&lt;br /&gt;
(mandatory)&lt;br /&gt;
&lt;br /&gt;
With &amp;quot;transition&amp;quot; you specify in which game state you can jump from a given game state.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    25 =&amp;gt; array(&lt;br /&gt;
        &amp;quot;name&amp;quot; =&amp;gt; &amp;quot;myGameState&amp;quot;,&lt;br /&gt;
        &amp;quot;transitions&amp;quot; =&amp;gt; array( &amp;quot;nextPlayer&amp;quot; =&amp;gt; 27, &amp;quot;endRound&amp;quot; =&amp;gt; 39 ),&lt;br /&gt;
        ....&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the example above, if &amp;quot;myGameState&amp;quot; is the current active game state, I can jump to game state with ID 27, or game state with ID 39.&lt;br /&gt;
&lt;br /&gt;
Example to jump to ID 27:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
In mygame.game.php:&lt;br /&gt;
    $this-&amp;gt;gamestate-&amp;gt;nextState( &amp;quot;nextPlayer&amp;quot; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Important: &amp;quot;nextPlayer&amp;quot; is the name of the transition, and NOT the name of the target game state. Several transitions can lead to the same game state.&lt;br /&gt;
&lt;br /&gt;
Note: if you have only 1 transition, you may give it an empty name.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
In states.inc.php:&lt;br /&gt;
    &amp;quot;transitions&amp;quot; =&amp;gt; array( &amp;quot;&amp;quot; =&amp;gt; 27 ),&lt;br /&gt;
&lt;br /&gt;
In mygame.game.php:&lt;br /&gt;
    $this-&amp;gt;gamestate-&amp;gt;nextState(  );     // We don&#039;t need to specify a transition as there is only one here&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== possibleactions ===&lt;br /&gt;
&lt;br /&gt;
(mandatory for &amp;quot;activeplayer&amp;quot; and &amp;quot;multipleactiveplayer&amp;quot; game states)&lt;br /&gt;
&lt;br /&gt;
&amp;quot;possibleactions&amp;quot; defines the actions possible by the players at this game state.&lt;br /&gt;
&lt;br /&gt;
By defining &amp;quot;possibleactions&amp;quot;, you make sure players can&#039;t do actions that they are not allowed to do at this game states.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
In states.game.php:&lt;br /&gt;
       	&amp;quot;possibleactions&amp;quot; =&amp;gt; array( &amp;quot;playCard&amp;quot;, &amp;quot;pass&amp;quot; ),&lt;br /&gt;
&lt;br /&gt;
In mygame.game.php:&lt;br /&gt;
        function playCard( ...)&lt;br /&gt;
        {&lt;br /&gt;
             self::checkAction( &amp;quot;playCard&amp;quot; );    // Will failed if &amp;quot;playCard&amp;quot; is not specified in &amp;quot;possibleactions&amp;quot; in current game state.&lt;br /&gt;
&lt;br /&gt;
            ....&lt;br /&gt;
&lt;br /&gt;
In mygame.js:&lt;br /&gt;
        playCard: function( ... )&lt;br /&gt;
        {&lt;br /&gt;
            if( this.checkAction( &amp;quot;playCard&amp;quot; ) ) // Will failed if &amp;quot;playCard&amp;quot; is not specified in &amp;quot;possibleactions&amp;quot; in current game state.&lt;br /&gt;
            {  return ;   }&lt;br /&gt;
&lt;br /&gt;
            ....&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== args ===&lt;br /&gt;
&lt;br /&gt;
(optional)&lt;br /&gt;
&lt;br /&gt;
From time to time, it happens that you need some information on the client side (ie : for your game interface) only for a specific game state.&lt;br /&gt;
&lt;br /&gt;
Example 1 : for Reversi, the list of possible moves during playerTurn state.&lt;br /&gt;
Example 2 : in Caylus, the number of remaining king&#039;s favor to choose in the state where the player is choosing a favor.&lt;br /&gt;
Example 3 : in Can&#039;t stop, the list of possible die combination to be displayed to the active player in order he can choose among them.&lt;br /&gt;
&lt;br /&gt;
In such a situation, you can specify a method name as the « args » argument for your game state. This method must get some piece of information about the game (ex : for Reversi, the possible moves) and return them.&lt;br /&gt;
&lt;br /&gt;
Thus, this data can be transmitted to the clients and used by the clients to display it. It should always be an associative array.&lt;br /&gt;
&lt;br /&gt;
Let&#039;s see a complete example using args with « Reversi » game :&lt;br /&gt;
&lt;br /&gt;
In states.inc.php, we specify some « args » argument for gamestate « playerTurn » :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    10 =&amp;gt; array(&lt;br /&gt;
        &amp;quot;name&amp;quot; =&amp;gt; &amp;quot;playerTurn&amp;quot;,&lt;br /&gt;
		&amp;quot;description&amp;quot; =&amp;gt; clienttranslate(&#039;${actplayer} must play a disc&#039;),&lt;br /&gt;
		&amp;quot;descriptionmyturn&amp;quot; =&amp;gt; clienttranslate(&#039;${you} must play a disc&#039;),&lt;br /&gt;
        &amp;quot;type&amp;quot; =&amp;gt; &amp;quot;activeplayer&amp;quot;,&lt;br /&gt;
        &amp;quot;args&amp;quot; =&amp;gt; &amp;quot;argPlayerTurn&amp;quot;,    &amp;lt;================================== HERE&lt;br /&gt;
        &amp;quot;possibleactions&amp;quot; =&amp;gt; array( &#039;playDisc&#039; ),&lt;br /&gt;
        &amp;quot;transitions&amp;quot; =&amp;gt; array( &amp;quot;playDisc&amp;quot; =&amp;gt; 11, &amp;quot;zombiePass&amp;quot; =&amp;gt; 11 )&lt;br /&gt;
    ),&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It corresponds to a « argPlayerTurn » method in our PHP code (reversi.game.php):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    function argPlayerTurn()&lt;br /&gt;
    {&lt;br /&gt;
        return array(&lt;br /&gt;
            &#039;possibleMoves&#039; =&amp;gt; self::getPossibleMoves()&lt;br /&gt;
        );&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then, when we enter into « playerTurn » game state on the client side, we can highlight the possible moves on the board using information returned by argPlayerTurn :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        onEnteringState: function( stateName, args )&lt;br /&gt;
        {&lt;br /&gt;
           console.log( &#039;Entering state: &#039;+stateName );&lt;br /&gt;
            &lt;br /&gt;
            switch( stateName )&lt;br /&gt;
            {&lt;br /&gt;
            case &#039;playerTurn&#039;:&lt;br /&gt;
                this.updatePossibleMoves( args.args.possibleMoves );&lt;br /&gt;
                break;&lt;br /&gt;
            }&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: you can also use values returned by your &amp;quot;args&amp;quot; method to have some custom values in your &amp;quot;description&amp;quot;/&amp;quot;descriptionmyturn&amp;quot; (see above).&lt;br /&gt;
&lt;br /&gt;
Note: as a BGA convention, PHP methods called with &amp;quot;args&amp;quot; are prefixed by &amp;quot;arg&amp;quot; (ex: argPlayerTurn).&lt;br /&gt;
&lt;br /&gt;
Warning: the &amp;quot;args&amp;quot; method can be called before the &amp;quot;action&amp;quot; method so don&#039;t expect data modifications by the &amp;quot;action&amp;quot; method to be available in the &amp;quot;args&amp;quot; method!&lt;br /&gt;
&lt;br /&gt;
==== Private infos in args ====&lt;br /&gt;
&lt;br /&gt;
By default, all data provided through this method are PUBLIC TO ALL PLAYERS. Please do not send any private data with this method, as a cheater could see it even it is not used explicitly by the game interface logic.&lt;br /&gt;
&lt;br /&gt;
This is although possible to specify that some data should be sent to some specific players only:&lt;br /&gt;
&lt;br /&gt;
Example 1: send an information to active player(s) only:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    function argPlayerTurn()&lt;br /&gt;
    {&lt;br /&gt;
        return array(&lt;br /&gt;
            &#039;_private&#039; =&amp;gt; array(          // Using &amp;quot;_private&amp;quot; keyword, all data inside this array will be made private&lt;br /&gt;
&lt;br /&gt;
                &#039;active&#039; =&amp;gt; array(       // Using &amp;quot;active&amp;quot; keyword inside &amp;quot;_private&amp;quot;, you select active player(s)&lt;br /&gt;
                    &#039;somePrivateData&#039; =&amp;gt; self::getSomePrivateData()   // will be send only to active player(s)&lt;br /&gt;
                )&lt;br /&gt;
            ),&lt;br /&gt;
&lt;br /&gt;
            &#039;possibleMoves&#039; =&amp;gt; self::getPossibleMoves()          // will be send to all players&lt;br /&gt;
        );&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inside the js file, these variables will be available through `args._private`. (e.g. `args._private.somePrivateData` -- it is not `args._private.active.somePrivateData` nor is it `args.somePrivateData`)&lt;br /&gt;
&lt;br /&gt;
Example 2: send an information to a specific player (&amp;lt;specific_player_id&amp;gt;) only:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    function argPlayerTurn()&lt;br /&gt;
    {&lt;br /&gt;
        return array(&lt;br /&gt;
            &#039;_private&#039; =&amp;gt; array(          // Using &amp;quot;_private&amp;quot; keyword, all data inside this array will be made private&lt;br /&gt;
&lt;br /&gt;
                &amp;lt;specific_player_id&amp;gt; =&amp;gt; array(       // you select one specific player with its id&lt;br /&gt;
                    &#039;somePrivateData&#039; =&amp;gt; self::getSomePrivateData()   // will be send only to &amp;lt;specific_player_id&amp;gt;&lt;br /&gt;
                )&lt;br /&gt;
            ),&lt;br /&gt;
&lt;br /&gt;
            &#039;possibleMoves&#039; =&amp;gt; self::getPossibleMoves()          // will be send to all players&lt;br /&gt;
        );&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
IMPORTANT: in certain situation (ex: multipleactiveplayer game state) these &amp;quot;private data&amp;quot; features can have a big performance impact. Please do not use if not needed.&lt;br /&gt;
&lt;br /&gt;
=== updateGameProgression ===&lt;br /&gt;
&lt;br /&gt;
(optional)&lt;br /&gt;
&lt;br /&gt;
IF you specify &amp;quot;updateGameProgression =&amp;gt; true&amp;quot; in a game state, your &amp;quot;getGameProgression&amp;quot; PHP method will be called at the beginning of this game state - and thus the game progression of the game will be updated.&lt;br /&gt;
&lt;br /&gt;
At least one of your game state (any of them) must specify updateGameProgression=&amp;gt;true.&lt;/div&gt;</summary>
		<author><name>Coin-coin le canapin</name></author>
	</entry>
	<entry>
		<id>https://gl.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=1580</id>
		<title>Tutorial gomoku</title>
		<link rel="alternate" type="text/html" href="https://gl.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=1580"/>
		<updated>2015-07-21T11:43:08Z</updated>

		<summary type="html">&lt;p&gt;Coin-coin le canapin: /* You will start from our &amp;#039;emtpy game&amp;#039; template */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This tutorial will guide you through the basics of creating a simple game on BGA Studio, through the example of [http://en.wikipedia.org/wiki/Gomoku &#039;&#039;&#039;Gomoku&#039;&#039;&#039;] (also known as Gobang or Five in a Row).&lt;br /&gt;
&lt;br /&gt;
== You will start from our &#039;empty game&#039; template ==&lt;br /&gt;
&lt;br /&gt;
Here is how your games looks by default when it has just been created:&lt;br /&gt;
&lt;br /&gt;
[[File:Gomoku tuto1.png]]&lt;br /&gt;
&lt;br /&gt;
== Setup the board ==&lt;br /&gt;
&lt;br /&gt;
Gather useful images for the game and edit them as needed. Upload them in the &#039;img&#039; folder of your SFTP access.&lt;br /&gt;
&lt;br /&gt;
Edit .tpl to add some divs for the board in the HTML. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;gmk_game_area&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;div id=&amp;quot;gmk_background&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;div id=&amp;quot;gmk_goban&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;/div&amp;gt;&lt;br /&gt;
	&amp;lt;/div&amp;gt;	&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Edit .css to set the div sizes and positions and show the image of the board as background.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#gmk_game_area {&lt;br /&gt;
	text-align: center;&lt;br /&gt;
	position: relative;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#gmk_background {&lt;br /&gt;
	width: 620px;&lt;br /&gt;
	height: 620px;	&lt;br /&gt;
	position: relative;&lt;br /&gt;
	display: inline-block;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#gmk_goban {	&lt;br /&gt;
	background-image: url( &#039;img/goban.jpg&#039;);&lt;br /&gt;
	width: 620px;&lt;br /&gt;
	height: 620px;&lt;br /&gt;
	position: absolute;	&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Gomoku tuto2.png]]&lt;br /&gt;
&lt;br /&gt;
== Setup the backbone of your game ==&lt;br /&gt;
&lt;br /&gt;
Edit dbmodel.sql to create a table for intersections. We need coordinates for each intersection and a field to store the color of the stone on this intersection (if any).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE TABLE IF NOT EXISTS `intersection` (&lt;br /&gt;
   `id` int(10) unsigned NOT NULL AUTO_INCREMENT,&lt;br /&gt;
   `coord_x` tinyint(2) unsigned NOT NULL,&lt;br /&gt;
   `coord_y` tinyint(2) unsigned NOT NULL,&lt;br /&gt;
   `stone_color` varchar(8) NULL,&lt;br /&gt;
   PRIMARY KEY (`id`)&lt;br /&gt;
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Edit .game.php-&amp;gt;setupNewGame() to insert the empty intersections (19x19) with coordinates into the database.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        // Insert (empty) intersections into database&lt;br /&gt;
        $sql = &amp;quot;INSERT INTO intersection (coord_x, coord_y) VALUES &amp;quot;;&lt;br /&gt;
        $values = array();&lt;br /&gt;
        for ($x = 0; $x &amp;lt; 19; $x++) {&lt;br /&gt;
            for ($y = 0; $y &amp;lt; 19; $y++) {&lt;br /&gt;
        	&lt;br /&gt;
            	$values[] = &amp;quot;($x, $y)&amp;quot;;   	&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        $sql .= implode( $values, &#039;,&#039; );&lt;br /&gt;
        self::DbQuery( $sql );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Edit .game.php-&amp;gt;getAllDatas() to retrieve the state of the intersections from the database.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        // Intersections&lt;br /&gt;
        $sql = &amp;quot;SELECT id, coord_x, coord_y, stone_color FROM intersection &amp;quot;;&lt;br /&gt;
        $result[&#039;intersections&#039;] = self::getCollectionFromDb( $sql );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Edit .tpl to create a template for intersections.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
var jstpl_intersection=&#039;&amp;lt;div class=&amp;quot;gmk_intersection ${stone_type}&amp;quot; id=&amp;quot;intersection_${x}_${y}&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Define the styles for the intersection divs.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.gmk_intersection {&lt;br /&gt;
    width: 30px;&lt;br /&gt;
    height: 30px;&lt;br /&gt;
    position: relative;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Edit .js-&amp;gt;setup() to setup the intersections layer that will be used to get click events and to display the stones. The data you returned in $result[&#039;intersections&#039;] in .game.php-&amp;gt;getAllDatas() is now available in your .js-&amp;gt;setup() in gamedatas.intersections.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
            // Setup intersections&lt;br /&gt;
            for( var id in gamedatas.intersections )&lt;br /&gt;
            {&lt;br /&gt;
                var intersection = gamedatas.intersections[id];&lt;br /&gt;
&lt;br /&gt;
                dojo.place( this.format_block(&#039;jstpl_intersection&#039;, {&lt;br /&gt;
                    x:intersection.coord_x,&lt;br /&gt;
                    y:intersection.coord_y,&lt;br /&gt;
                    stone_type:(intersection.stone_color == null ? &amp;quot;no_stone&amp;quot; : &#039;stone_&#039; + intersection.stone_color)&lt;br /&gt;
                } ), $ ( &#039;gmk_background&#039; ) );&lt;br /&gt;
&lt;br /&gt;
                var x_pix = this.getXPixelCoordinates(intersection.coord_x);&lt;br /&gt;
                var y_pix = this.getYPixelCoordinates(intersection.coord_y);&lt;br /&gt;
                &lt;br /&gt;
                this.slideToObjectPos( $(&#039;intersection_&#039;+intersection.coord_x+&#039;_&#039;+intersection.coord_y), $(&#039;gmk_background&#039;), x_pix, y_pix, 10 ).play();&lt;br /&gt;
&lt;br /&gt;
                if (intersection.stone_color != null) {&lt;br /&gt;
                    // This intersection is taken, it shouldn&#039;t appear as clickable anymore&lt;br /&gt;
                    dojo.removeClass( &#039;intersection_&#039; + intersection.coord_x + &#039;_&#039; + intersection.coord_y, &#039;clickable&#039; );&lt;br /&gt;
                }&lt;br /&gt;
            } &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use some temporary css border-color or background-color and opacity to see the divs and make sure you have them positioned right. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.gmk_intersection {&lt;br /&gt;
    width: 30px;&lt;br /&gt;
    height: 30px;&lt;br /&gt;
    position: relative;&lt;br /&gt;
    background-color: blue;&lt;br /&gt;
    opacity: 0.3;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can declare some constants in material.inc.php and pass them to your .js for easy repositioning (modify constant, refresh). This is especially useful if the same constants have to be used on the server and on the client.&lt;br /&gt;
&lt;br /&gt;
* Declare your constants in material.inc.php (this will be automatically included in your .game.php)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$this-&amp;gt;gameConstants = array(&lt;br /&gt;
		&amp;quot;INTERSECTION_WIDTH&amp;quot; =&amp;gt; 30,&lt;br /&gt;
		&amp;quot;INTERSECTION_HEIGHT&amp;quot; =&amp;gt; 30,		&lt;br /&gt;
		&amp;quot;INTERSECTION_X_SPACER&amp;quot; =&amp;gt; 2.8, // Float&lt;br /&gt;
		&amp;quot;INTERSECTION_Y_SPACER&amp;quot; =&amp;gt; 2.8, // Float&lt;br /&gt;
		&amp;quot;X_ORIGIN&amp;quot; =&amp;gt; 0,&lt;br /&gt;
		&amp;quot;Y_ORIGIN&amp;quot; =&amp;gt; 0,&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* In .game.php-&amp;gt;getAllDatas(), add the constants to the result array&lt;br /&gt;
&lt;br /&gt;
        // Constants&lt;br /&gt;
        $result[&#039;constants&#039;] = $this-&amp;gt;gameConstants;&lt;br /&gt;
&lt;br /&gt;
* In .js constructor, define a class variable for constants&lt;br /&gt;
&lt;br /&gt;
        // Game constants&lt;br /&gt;
      	this.gameConstants = null;&lt;br /&gt;
&lt;br /&gt;
* In .js-&amp;gt;setup() assign the constants to this variable&lt;br /&gt;
&lt;br /&gt;
        this.gameConstants = gamedatas.constants;&lt;br /&gt;
&lt;br /&gt;
* Then use it in your getXPixelCoordinates and getYPixelCoordinates functions&lt;br /&gt;
&lt;br /&gt;
        getXPixelCoordinates: function( intersection_x )&lt;br /&gt;
        {&lt;br /&gt;
        	return this.gameConstants[&#039;X_ORIGIN&#039;] + intersection_x * (this.gameConstants[&#039;INTERSECTION_WIDTH&#039;] + this.gameConstants[&#039;INTERSECTION_X_SPACER&#039;]); &lt;br /&gt;
        },&lt;br /&gt;
        &lt;br /&gt;
        getYPixelCoordinates: function( intersection_y )&lt;br /&gt;
        {&lt;br /&gt;
        	return this.gameConstants[&#039;Y_ORIGIN&#039;] + intersection_y * (this.gameConstants[&#039;INTERSECTION_HEIGHT&#039;] + this.gameConstants[&#039;INTERSECTION_Y_SPACER&#039;]); &lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
Here is what you should get:&lt;br /&gt;
&lt;br /&gt;
[[File:Gomoku tuto3.png]]&lt;br /&gt;
&lt;br /&gt;
== Manage states and events ==&lt;br /&gt;
&lt;br /&gt;
Define your game states in states.inc.php. For gomoku we will use 3 states in addition of the predefined states 1 (gameSetup) and 99 (gameEnd). One to play, one to check the end game condition, one to give his turn to the other player if the game is not over.&lt;br /&gt;
&lt;br /&gt;
The first state requires an action from the player, so its type is &#039;activeplayer&#039;.&lt;br /&gt;
&lt;br /&gt;
The two others are automatic actions for the game, so their type is &#039;game&#039;.&lt;br /&gt;
&lt;br /&gt;
We will update the progression while checking for the end of the game, so for this state we set the &#039;updateGameProgression&#039; flag to true.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    2 =&amp;gt; array(&lt;br /&gt;
        &amp;quot;name&amp;quot; =&amp;gt; &amp;quot;playerTurn&amp;quot;,&lt;br /&gt;
        &amp;quot;description&amp;quot; =&amp;gt; clienttranslate(&#039;${actplayer} must play a stone&#039;),&lt;br /&gt;
        &amp;quot;descriptionmyturn&amp;quot; =&amp;gt; clienttranslate(&#039;${you} must play a stone&#039;),&lt;br /&gt;
        &amp;quot;type&amp;quot; =&amp;gt; &amp;quot;activeplayer&amp;quot;,&lt;br /&gt;
        &amp;quot;possibleactions&amp;quot; =&amp;gt; array( &amp;quot;playStone&amp;quot; ),&lt;br /&gt;
        &amp;quot;transitions&amp;quot; =&amp;gt; array( &amp;quot;stonePlayed&amp;quot; =&amp;gt; 3, &amp;quot;zombiePass&amp;quot; =&amp;gt; 3 )&lt;br /&gt;
    ),&lt;br /&gt;
&lt;br /&gt;
    3 =&amp;gt; array(&lt;br /&gt;
        &amp;quot;name&amp;quot; =&amp;gt; &amp;quot;checkEndOfGame&amp;quot;,&lt;br /&gt;
        &amp;quot;description&amp;quot; =&amp;gt; &#039;&#039;,&lt;br /&gt;
        &amp;quot;type&amp;quot; =&amp;gt; &amp;quot;game&amp;quot;,&lt;br /&gt;
        &amp;quot;action&amp;quot; =&amp;gt; &amp;quot;stCheckEndOfGame&amp;quot;,&lt;br /&gt;
        &amp;quot;updateGameProgression&amp;quot; =&amp;gt; true,&lt;br /&gt;
        &amp;quot;transitions&amp;quot; =&amp;gt; array( &amp;quot;gameEnded&amp;quot; =&amp;gt; 99, &amp;quot;notEndedYet&amp;quot; =&amp;gt; 4 )&lt;br /&gt;
    ),&lt;br /&gt;
&lt;br /&gt;
    4 =&amp;gt; array(&lt;br /&gt;
        &amp;quot;name&amp;quot; =&amp;gt; &amp;quot;nextPlayer&amp;quot;,&lt;br /&gt;
        &amp;quot;description&amp;quot; =&amp;gt; &#039;&#039;,&lt;br /&gt;
        &amp;quot;type&amp;quot; =&amp;gt; &amp;quot;game&amp;quot;,&lt;br /&gt;
        &amp;quot;action&amp;quot; =&amp;gt; &amp;quot;stNextPlayer&amp;quot;,&lt;br /&gt;
        &amp;quot;transitions&amp;quot; =&amp;gt; array( &amp;quot;&amp;quot; =&amp;gt; 2 )&lt;br /&gt;
    ),&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Implement the &#039;stNextPlayer()&#039; function in .game.php to manage turn rotation. Except if there are special rules for the game turn depending on context, this is really easy:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    function stNextPlayer()&lt;br /&gt;
    {&lt;br /&gt;
    	self::trace( &amp;quot;stNextPlayer&amp;quot; );&lt;br /&gt;
    	 &lt;br /&gt;
    	// Go to next player&lt;br /&gt;
    	$active_player = self::activeNextPlayer();&lt;br /&gt;
    	self::giveExtraTime( $active_player );    &lt;br /&gt;
    	 &lt;br /&gt;
    	$this-&amp;gt;gamestate-&amp;gt;nextState();&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add onclick events on intersections in .js-&amp;gt;setup()&lt;br /&gt;
&lt;br /&gt;
            // Add events on active elements (the third parameter is the method that will be called when the event defined by the second parameter happens - this method must be declared beforehand)&lt;br /&gt;
            this.addEventToClass( &amp;quot;gmk_intersection&amp;quot;, &amp;quot;onclick&amp;quot;, &amp;quot;onClickIntersection&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
Declare the corresponding .js-&amp;gt;onClickIntersection() function, which calls an action function on the server with appropriate parameters&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        onClickIntersection: function( evt )&lt;br /&gt;
        {&lt;br /&gt;
            console.log( &#039;$$$$ Event : onClickIntersection&#039; );&lt;br /&gt;
            dojo.stopEvent( evt );&lt;br /&gt;
&lt;br /&gt;
            if( ! this.checkAction( &#039;playStone&#039; ) )&lt;br /&gt;
            { return; }&lt;br /&gt;
&lt;br /&gt;
            var node = evt.currentTarget.id;&lt;br /&gt;
            var coord_x = node.split(&#039;_&#039;)[1];&lt;br /&gt;
            var coord_y = node.split(&#039;_&#039;)[2];&lt;br /&gt;
            &lt;br /&gt;
            console.log( &#039;$$$$ Selected intersection : (&#039; + coord_x + &#039;, &#039; + coord_y + &#039;)&#039; );&lt;br /&gt;
            &lt;br /&gt;
            if ( this.isCurrentPlayerActive() ) {&lt;br /&gt;
                this.ajaxcall( &amp;quot;/gomoku/gomoku/playStone.html&amp;quot;, { lock: true, coord_x: coord_x, coord_y: coord_y }, this, function( result ) {}, function( is_error ) {} );&lt;br /&gt;
            }&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add this action function in .action.php, retrieving parameters and calling the appropriate game action&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    public function playStone()&lt;br /&gt;
    {&lt;br /&gt;
        self::setAjaxMode();     &lt;br /&gt;
&lt;br /&gt;
        // Retrieve arguments&lt;br /&gt;
        // Note: these arguments correspond to what has been sent through the javascript &amp;quot;ajaxcall&amp;quot; method&lt;br /&gt;
        $coord_x = self::getArg( &amp;quot;coord_x&amp;quot;, AT_posint, true );&lt;br /&gt;
        $coord_y = self::getArg( &amp;quot;coord_y&amp;quot;, AT_posint, true );&lt;br /&gt;
&lt;br /&gt;
        // Then, call the appropriate method in your game logic, like &amp;quot;playCard&amp;quot; or &amp;quot;myAction&amp;quot;&lt;br /&gt;
        $this-&amp;gt;game-&amp;gt;playStone( $coord_x, $coord_y );&lt;br /&gt;
&lt;br /&gt;
        self::ajaxResponse( );&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add game action in .game.php to update the database, send a notification to the client providing the event notified (‘stonePlayed’) and its parameters, and proceed to the next state.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    function playStone( $coord_x, $coord_y )&lt;br /&gt;
    {&lt;br /&gt;
        // Check that this is player&#039;s turn and that it is a &amp;quot;possible action&amp;quot; at this game state (see states.inc.php)&lt;br /&gt;
        self::checkAction( &#039;playStone&#039; ); &lt;br /&gt;
        &lt;br /&gt;
        $player_id = self::getActivePlayerId();&lt;br /&gt;
        &lt;br /&gt;
        // Check that this intersection is free&lt;br /&gt;
        $sql = &amp;quot;SELECT&lt;br /&gt;
                    id, coord_x, coord_y, stone_color&lt;br /&gt;
                FROM&lt;br /&gt;
                    intersection &lt;br /&gt;
                WHERE &lt;br /&gt;
                    coord_x = $coord_x &lt;br /&gt;
                    AND coord_y = $coord_y&lt;br /&gt;
                    AND stone_color is null&lt;br /&gt;
               &amp;quot;;&lt;br /&gt;
        $intersection = self::getObjectFromDb( $sql );&lt;br /&gt;
&lt;br /&gt;
        if ($intersection == null) {&lt;br /&gt;
            throw new BgaUserException( self::_(&amp;quot;There is already a stone on this intersection, you can&#039;t play there&amp;quot;) );&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Get player color&lt;br /&gt;
        $sql = &amp;quot;SELECT&lt;br /&gt;
                    player_id, player_color&lt;br /&gt;
                FROM&lt;br /&gt;
                    player &lt;br /&gt;
                WHERE &lt;br /&gt;
                    player_id = $player_id&lt;br /&gt;
               &amp;quot;;&lt;br /&gt;
        $player = self::getNonEmptyObjectFromDb( $sql );&lt;br /&gt;
        $color = ($player[&#039;player_color&#039;] == &#039;ffffff&#039; ? &#039;white&#039; : &#039;black&#039;);&lt;br /&gt;
&lt;br /&gt;
        // Update the intersection with a stone of the appropriate color&lt;br /&gt;
        $intersection_id = $intersection[&#039;id&#039;];&lt;br /&gt;
        $sql = &amp;quot;UPDATE&lt;br /&gt;
                    intersection&lt;br /&gt;
                SET&lt;br /&gt;
                    stone_color = &#039;$color&#039;&lt;br /&gt;
                WHERE &lt;br /&gt;
                    id = $intersection_id&lt;br /&gt;
               &amp;quot;;&lt;br /&gt;
        self::DbQuery($sql);&lt;br /&gt;
        &lt;br /&gt;
        // Notify all players&lt;br /&gt;
        self::notifyAllPlayers( &amp;quot;stonePlayed&amp;quot;, clienttranslate( &#039;${player_name} dropped a stone on ${coord_x},${coord_y}&#039; ), array(&lt;br /&gt;
            &#039;player_id&#039; =&amp;gt; $player_id,&lt;br /&gt;
            &#039;player_name&#039; =&amp;gt; self::getActivePlayerName(),&lt;br /&gt;
            &#039;coord_x&#039; =&amp;gt; $coord_x,&lt;br /&gt;
            &#039;coord_y&#039; =&amp;gt; $coord_y,&lt;br /&gt;
            &#039;color&#039; =&amp;gt; $color&lt;br /&gt;
        ) );&lt;br /&gt;
&lt;br /&gt;
        // Go to next game state&lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;nextState( &amp;quot;stonePlayed&amp;quot; );&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Catch the notification in .js-&amp;gt;setupNotifications() and link it to a javascript function to execute when the notification is received.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        setupNotifications: function()&lt;br /&gt;
        {&lt;br /&gt;
            console.log( &#039;notifications subscriptions setup&#039; );&lt;br /&gt;
        &lt;br /&gt;
            dojo.subscribe( &#039;stonePlayed&#039;, this, &amp;quot;notif_stonePlayed&amp;quot; );&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Implement this function in javascript to update the intersection to show the stone, and register it inside the setNotifications function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        notif_stonePlayed: function( notif )&lt;br /&gt;
        {&lt;br /&gt;
	    console.log( &#039;**** Notification : stonePlayed&#039; );&lt;br /&gt;
            console.log( notif );&lt;br /&gt;
&lt;br /&gt;
            // Create a stone&lt;br /&gt;
            dojo.place( this.format_block(&#039;jstpl_stone&#039;, {&lt;br /&gt;
                    stone_type:&#039;stone_&#039; + notif.args.color,&lt;br /&gt;
                    x:notif.args.coord_x,&lt;br /&gt;
                    y:notif.args.coord_y&lt;br /&gt;
                } ), $( &#039;intersection_&#039; + notif.args.coord_x + &#039;_&#039; + notif.args.coord_y ) );&lt;br /&gt;
&lt;br /&gt;
            // Place it on the player panel&lt;br /&gt;
            this.placeOnObject( $( &#039;stone_&#039; + notif.args.coord_x + &#039;_&#039; + notif.args.coord_y ), $( &#039;player_board_&#039; + notif.args.player_id ) );&lt;br /&gt;
&lt;br /&gt;
            // Animate a slide from the player panel to the intersection&lt;br /&gt;
            dojo.style( &#039;stone_&#039; + notif.args.coord_x + &#039;_&#039; + notif.args.coord_y, &#039;zIndex&#039;, 1 );&lt;br /&gt;
            var slide = this.slideToObject( $( &#039;stone_&#039; + notif.args.coord_x + &#039;_&#039; + notif.args.coord_y ), $( &#039;intersection_&#039; + notif.args.coord_x + &#039;_&#039; + notif.args.coord_y ), 1000 );&lt;br /&gt;
            dojo.connect( slide, &#039;onEnd&#039;, this, dojo.hitch( this, function() {&lt;br /&gt;
                        // At the end of the slide, update the intersection &lt;br /&gt;
                        dojo.removeClass( &#039;intersection_&#039; + notif.args.coord_x + &#039;_&#039; + notif.args.coord_y, &#039;no_stone&#039; );&lt;br /&gt;
                        dojo.addClass( &#039;intersection_&#039; + notif.args.coord_x + &#039;_&#039; + notif.args.coord_y, &#039;stone_&#039;  + notif.args.color );&lt;br /&gt;
                        dojo.removeClass( &#039;intersection_&#039; + notif.args.coord_x + &#039;_&#039; + notif.args.coord_y, &#039;clickable&#039; );&lt;br /&gt;
        			&lt;br /&gt;
                        // We can now destroy the stone since it is now visible through the change in style of the intersection&lt;br /&gt;
                        dojo.destroy( &#039;stone_&#039; + notif.args.coord_x + &#039;_&#039; + notif.args.coord_y );&lt;br /&gt;
       	    }));&lt;br /&gt;
            slide.play();&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For this function to work properly, you also need: &lt;br /&gt;
&lt;br /&gt;
* to declare a stone javascript template in your .tpl file.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
var jstpl_stone=&#039;&amp;lt;div class=&amp;quot;gmk_stone ${stone_type}&amp;quot; id=&amp;quot;stone_${x}_${y}&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* to define the css styles for the stones&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.gmk_intersection {&lt;br /&gt;
    width: 30px;&lt;br /&gt;
    height: 30px;&lt;br /&gt;
    position: relative;&lt;br /&gt;
    background-image: url( &#039;img/stones.png&#039; );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.gmk_stone {&lt;br /&gt;
    width: 30px;&lt;br /&gt;
    height: 30px;&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    background-image: url( &#039;img/stones.png&#039; );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.no_stone { background-position: -60px 0px; }&lt;br /&gt;
&lt;br /&gt;
.stone_black {  background-position: 0px 0px; }&lt;br /&gt;
.stone_white { 	background-position: -30px 0px; }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These styles rely on an PNG image (with transparent background) of both the white and black stones, and positions the background appropriately to show only the part of the background image matching the appropriate stone (or the transparent space if there is no stone). Here is what the image looks like:&lt;br /&gt;
&lt;br /&gt;
[[File:Gomoku stones.png]]&lt;br /&gt;
&lt;br /&gt;
The red circle is used to highlight intersections where you can drop a stone when the player&#039;s cursor hovers over them (we also change the cursor to a hand). To do this:&lt;br /&gt;
&lt;br /&gt;
* we define in the css file the &#039;clickable&#039; css class&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.clickable {&lt;br /&gt;
	cursor: pointer;&lt;br /&gt;
}&lt;br /&gt;
.clickable:hover { background-position: -90px 0px; }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* in .js, when we enter the &#039;playerTurn&#039; state, we add the &#039;clickable&#039; style to the intersections where there is no stone&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        onEnteringState: function( stateName, args )&lt;br /&gt;
        {&lt;br /&gt;
            console.log( &#039;Entering state: &#039;+stateName );&lt;br /&gt;
            &lt;br /&gt;
            switch( stateName )&lt;br /&gt;
            {&lt;br /&gt;
            &lt;br /&gt;
                case &#039;playerTurn&#039;:&lt;br /&gt;
                    if( this.isCurrentPlayerActive() )&lt;br /&gt;
                    {&lt;br /&gt;
                        var queueEntries = dojo.query( &#039;.no_stone&#039; );&lt;br /&gt;
	                    for(var i=0; i&amp;lt;queueEntries.length; i++) {	            	   &lt;br /&gt;
	                	   dojo.addClass( queueEntries[i], &#039;clickable&#039; );&lt;br /&gt;
	                    }&lt;br /&gt;
                    }            &lt;br /&gt;
            }&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, make sure to modify the default colors for players to white and black&lt;br /&gt;
&lt;br /&gt;
          $default_colors = array( &amp;quot;000000&amp;quot;, &amp;quot;ffffff&amp;quot;, );&lt;br /&gt;
&lt;br /&gt;
The basic game turn is implemented: you can now drop some stones!&lt;br /&gt;
&lt;br /&gt;
[[File:Gomoku tuto4.png]]&lt;br /&gt;
&lt;br /&gt;
== Cleanup your styles ==&lt;br /&gt;
&lt;br /&gt;
Remove temporary css visualisation helpers : looks good!&lt;br /&gt;
&lt;br /&gt;
[[File:Gomoku tuto5.png]]&lt;br /&gt;
&lt;br /&gt;
== Implement rules and end of game conditions ==&lt;br /&gt;
&lt;br /&gt;
Implement specific rules for the game. For example in Gomoku, black plays first. So in .game.php-&amp;gt;setupNewGame(), at the end of the setup make the black player active:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        // Black plays first&lt;br /&gt;
        $sql = &amp;quot;SELECT player_id, player_name FROM player WHERE player_color = &#039;000000&#039; &amp;quot;;&lt;br /&gt;
        $black_player = self::getNonEmptyObjectFromDb( $sql );&lt;br /&gt;
&lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;changeActivePlayer( $black_player[&#039;player_id&#039;] );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Implement rule for computing game progression in .game.php-&amp;gt;getGameProgression(). For Gomoku we will use the rate of occupied intersections over the total number of intersections. This will often be wildly inaccurate as the game can end pretty quickly, but it&#039;s about the best we can do (the game can drag to a stalemate with all intersections occupied and no winner).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    function getGameProgression()&lt;br /&gt;
    {&lt;br /&gt;
        // Compute and return the game progression&lt;br /&gt;
&lt;br /&gt;
        // Number of stones laid down on the goban over the total number of intersections * 100&lt;br /&gt;
        $sql = &amp;quot;&lt;br /&gt;
	    	SELECT round(100 * count(id) / (19*19) ) as value from intersection WHERE stone_color is not null&lt;br /&gt;
    	&amp;quot;;&lt;br /&gt;
    	$counter = self::getNonEmptyObjectFromDB( $sql );&lt;br /&gt;
&lt;br /&gt;
        return $counter[&#039;value&#039;];&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Implement end of game detection and update the score according to who is the winner. It is easier to check for a win directly after setting the stone, so: &lt;br /&gt;
&lt;br /&gt;
* declare a global &#039;end_of_game&#039; variable in .game.php-&amp;gt;Gomoku()&lt;br /&gt;
&lt;br /&gt;
        self::initGameStateLabels( array(&lt;br /&gt;
                  &amp;quot;end_of_game&amp;quot; =&amp;gt; 10,&lt;br /&gt;
        ) );&lt;br /&gt;
&lt;br /&gt;
* init that global variable to 0 in .game.php-&amp;gt;setupNewGame()&lt;br /&gt;
&lt;br /&gt;
        self::setGameStateInitialValue( &#039;end_of_game&#039;, 0 );&lt;br /&gt;
&lt;br /&gt;
* add the appropriate code in .game.php before proceeding to the next state, using a checkForWin() function implemented separately for clarity. If the game has been won, we set the score, send a score update notification to the client side, and set the &#039;end_of_game&#039; global variable to 1 as a flag signaling that the game has ended.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        // Check if end of game has been met&lt;br /&gt;
        if ($this-&amp;gt;checkForWin( $coord_x, $coord_y, $color )) {&lt;br /&gt;
&lt;br /&gt;
            // Set active player score to 1 (he is the winner)&lt;br /&gt;
            $sql = &amp;quot;UPDATE player SET player_score = 1 WHERE player_id = $player_id&amp;quot;;&lt;br /&gt;
            self::DbQuery($sql);&lt;br /&gt;
&lt;br /&gt;
            // Notify final score&lt;br /&gt;
            $this-&amp;gt;notifyAllPlayers( &amp;quot;finalScore&amp;quot;,&lt;br /&gt;
    					clienttranslate( &#039;${player_name} wins the game!&#039; ),&lt;br /&gt;
    					array(&lt;br /&gt;
    							&amp;quot;player_name&amp;quot; =&amp;gt; self::getActivePlayerName(),&lt;br /&gt;
    							&amp;quot;player_id&amp;quot; =&amp;gt; $player_id,&lt;br /&gt;
    							&amp;quot;score_delta&amp;quot; =&amp;gt; 1,&lt;br /&gt;
    					)&lt;br /&gt;
   			);&lt;br /&gt;
&lt;br /&gt;
            // Set global variable flag to pass on the information that the game has ended&lt;br /&gt;
            self::setGameStateValue(&#039;end_of_game&#039;, 1);&lt;br /&gt;
&lt;br /&gt;
            // End of game message&lt;br /&gt;
            $this-&amp;gt;notifyAllPlayers( &amp;quot;message&amp;quot;,&lt;br /&gt;
    				clienttranslate(&#039;Thanks for playing!&#039;),&lt;br /&gt;
    				array(&lt;br /&gt;
    				)&lt;br /&gt;
    		);&lt;br /&gt;
&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Then in the gomoku-&amp;gt;stCheckEndOfGame() function which is called when your state machine goes to the &#039;checkEndOfGame&#039; state, check for this variable and for other possible &#039;end of game&#039; conditions (draw).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    function stCheckEndOfGame()&lt;br /&gt;
    {&lt;br /&gt;
        self::trace( &amp;quot;stCheckEndOfGame&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
        $transition = &amp;quot;notEndedYet&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        // If there is no more free intersections, the game ends&lt;br /&gt;
        $sql = &amp;quot;SELECT id, coord_x, coord_y, stone_color FROM intersection WHERE stone_color is null&amp;quot;;&lt;br /&gt;
        $free = self::getCollectionFromDb( $sql );&lt;br /&gt;
&lt;br /&gt;
        if (count($free) == 0) {&lt;br /&gt;
            $transition = &amp;quot;gameEnded&amp;quot;;&lt;br /&gt;
        }        &lt;br /&gt;
&lt;br /&gt;
        // If the &#039;end of game&#039; flag has been set, end the game&lt;br /&gt;
        if (self::getGameStateValue(&#039;end_of_game&#039;) == 1) {&lt;br /&gt;
            $transition = &amp;quot;gameEnded&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
                &lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;nextState( $transition );&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Catch the score notification on the client side in .js-&amp;gt;setupNotifications(). It is advised to set up a small delay after that so that end of game popup doesn&#039;t show too quickly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                dojo.subscribe( &#039;finalScore&#039;, this, &amp;quot;notif_finalScore&amp;quot; );&lt;br /&gt;
	        this.notifqueue.setSynchronous( &#039;finalScore&#039;, 1500 );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Implement the function declared to handle the notification.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
            notif_finalScore: function( notif )&lt;br /&gt;
	    {&lt;br /&gt;
	        console.log( &#039;**** Notification : finalScore&#039; );&lt;br /&gt;
	        console.log( notif );&lt;br /&gt;
	      &lt;br /&gt;
                // Update score&lt;br /&gt;
                this.scoreCtrl[ notif.args.player_id ].incValue( notif.args.score_delta );&lt;br /&gt;
	    },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Test everything thoroughly... you are done!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[File:Gomoku tuto6.png]]&lt;/div&gt;</summary>
		<author><name>Coin-coin le canapin</name></author>
	</entry>
</feed>