<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="hu">
	<id>https://hu.doc.boardgamearena.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Een</id>
	<title>Board Game Arena - Felhasználó közreműködései [hu]</title>
	<link rel="self" type="application/atom+xml" href="https://hu.doc.boardgamearena.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Een"/>
	<link rel="alternate" type="text/html" href="https://hu.doc.boardgamearena.com/Speci%C3%A1lis:Szerkeszt%C5%91_k%C3%B6zrem%C5%B1k%C3%B6d%C3%A9sei/Een"/>
	<updated>2026-10-18T07:31:55Z</updated>
	<subtitle>Felhasználó közreműködései</subtitle>
	<generator>MediaWiki 1.39.0</generator>
	<entry>
		<id>https://hu.doc.boardgamearena.com/index.php?title=S%C3%BAg%C3%B3&amp;diff=507</id>
		<title>Súgó</title>
		<link rel="alternate" type="text/html" href="https://hu.doc.boardgamearena.com/index.php?title=S%C3%BAg%C3%B3&amp;diff=507"/>
		<updated>2013-01-11T16:02:09Z</updated>

		<summary type="html">&lt;p&gt;Een: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;An issue? A question?&lt;br /&gt;
&lt;br /&gt;
* [[Faq|Frequently asked questions]] could probably help you.&lt;br /&gt;
&lt;br /&gt;
* [http://forum.boardgamearena.com Forums] are also helpful to get information.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Help contents ==&lt;br /&gt;
&lt;br /&gt;
* [[Faq|Frequently asked questions]]&lt;br /&gt;
* [[About Board Game Arena|About Board Game Arena]]&lt;br /&gt;
** [[About us|About us]]&lt;br /&gt;
** [[Club Board Game Arena|Club Board Game Arena]]&lt;br /&gt;
** [[Contact us|Contact us]]&lt;br /&gt;
&lt;br /&gt;
=== Detailed help ===&lt;br /&gt;
&lt;br /&gt;
* [[Getting started|Getting started]]&lt;br /&gt;
* [[Referral|Referral]]&lt;br /&gt;
* [[Browser support|Browser support]]&lt;br /&gt;
* [[Moderation and grades|Moderation and grades]]&lt;br /&gt;
* [[Game clock|Game clock]]&lt;br /&gt;
* [[Rating|Rating]]&lt;br /&gt;
* [[Reputation|Reputation]]&lt;br /&gt;
* [[Translation guidelines|Translation guidelines]]&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://hu.doc.boardgamearena.com/index.php?title=T%C3%A1mogatott_b%C3%B6ng%C3%A9sz%C5%91k&amp;diff=426</id>
		<title>Támogatott böngészők</title>
		<link rel="alternate" type="text/html" href="https://hu.doc.boardgamearena.com/index.php?title=T%C3%A1mogatott_b%C3%B6ng%C3%A9sz%C5%91k&amp;diff=426"/>
		<updated>2013-01-03T16:00:30Z</updated>

		<summary type="html">&lt;p&gt;Een: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Help]]&lt;br /&gt;
&amp;lt;h3&amp;gt;For the best experience, we recommend:&amp;lt;/h3&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Google Chrome 10+&#039;&#039;&#039; [http://www.google.com/chrome Windows] [http://www.google.com/chrome?platform=mac Mac] [http://www.google.com/chrome?platform=linux Linux]&lt;br /&gt;
* &#039;&#039;&#039;Mozilla Firefox 4+&#039;&#039;&#039; [http://www.mozilla.org/products/firefox/ Windows] [http://www.mozilla.org/products/firefox/ Mac] [http://www.mozilla.org/products/firefox/ Linux]&lt;br /&gt;
&lt;br /&gt;
Board Game Arena takes advantage of the most recent web technology to make it possible for you to play without installing anything on your computer: no software to download or update, no plugins to install, etc. &lt;br /&gt;
Consequently, to play you need to use a modern web browser. Generally speaking, the more recent your web browser is, the more pleasant your game experience on Board Game Arena will be. &lt;br /&gt;
&lt;br /&gt;
This website makes intensive use of Javascript and your browser&#039;s graphics capabilities. Thus, if you want to have the best gaming experience with Board Game Arena, you should use one of the browsers listed above. However, we officially support the following browsers:&lt;br /&gt;
&lt;br /&gt;
* Google Chrome 4+&lt;br /&gt;
* Mozilla Firefox 3.5+&lt;br /&gt;
* Internet Explorer 9+&lt;br /&gt;
* Safari 4+&lt;br /&gt;
&lt;br /&gt;
(Note: We do NOT support playing on iPads or similar tablets.)&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://hu.doc.boardgamearena.com/index.php?title=Gamehelpgomoku&amp;diff=422</id>
		<title>Gamehelpgomoku</title>
		<link rel="alternate" type="text/html" href="https://hu.doc.boardgamearena.com/index.php?title=Gamehelpgomoku&amp;diff=422"/>
		<updated>2012-12-24T12:55:06Z</updated>

		<summary type="html">&lt;p&gt;Een: Created page with &amp;quot; == Goal ==   Create an unbroken row of exactly five stones of your color horizontally, vertically, or diagonally.  Overlines (rows of 6 stones or more) do not count.  == Vari...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Goal == &lt;br /&gt;
&lt;br /&gt;
Create an unbroken row of exactly five stones of your color horizontally, vertically, or diagonally.&lt;br /&gt;
&lt;br /&gt;
Overlines (rows of 6 stones or more) do not count.&lt;br /&gt;
&lt;br /&gt;
== Variant == &lt;br /&gt;
&lt;br /&gt;
In Gomoku+ (also named Caro) in order to win your row of five stones must be free at both ends. &lt;br /&gt;
&lt;br /&gt;
This balances the game differently and gives more defensive power to the white player.&lt;br /&gt;
&lt;br /&gt;
== Openings ==&lt;br /&gt;
&lt;br /&gt;
Black always play first.&lt;br /&gt;
&lt;br /&gt;
With the &#039;standard&#039; (free) opening, black has got a distinct advantage over white who is directly put &#039;under attack&#039;.&lt;br /&gt;
&lt;br /&gt;
The &#039;tournament&#039; opening aims to even the odds between the black and white players:&lt;br /&gt;
* black lays the first stone at the center of the board&lt;br /&gt;
* white lays the second stone in one of the spaces adjoining to the center of the board (horizontally, vertically or diagonally)&lt;br /&gt;
* black lays the third stone at least three spaces away from the center of the board.&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://hu.doc.boardgamearena.com/index.php?title=Studio_FAQ&amp;diff=421</id>
		<title>Studio FAQ</title>
		<link rel="alternate" type="text/html" href="https://hu.doc.boardgamearena.com/index.php?title=Studio_FAQ&amp;diff=421"/>
		<updated>2012-12-23T17:18:00Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Some frequent errors */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a place where we will collect and answer frequently asked questions.&lt;br /&gt;
&lt;br /&gt;
== What should I use to access the files through SFTP? ==&lt;br /&gt;
&lt;br /&gt;
There is a lot of tools to do that. Use the one you are the most comfortable with.&lt;br /&gt;
&lt;br /&gt;
On Linux, you can for example use the &#039;Connect to server&#039; function of the Nautilus file management system, or use sshfs.&lt;br /&gt;
&lt;br /&gt;
On Windows, there is for example the WinSCP client.&lt;br /&gt;
&lt;br /&gt;
== I can&#039;t access the Studio back-office, I get a &#039;Not authorized&#039; error message? ==&lt;br /&gt;
&lt;br /&gt;
You should first connect to the Studio website (with any of your &amp;lt;developer name&amp;gt;&amp;lt;number&amp;gt; accounts). As the authentication is shared with the back-office, then you will be able to access it.&lt;br /&gt;
&lt;br /&gt;
== I don&#039;t know the name to use to commit my game, what name should I use? ==&lt;br /&gt;
&lt;br /&gt;
The game name for committing is the name of the game in lower case and without spaces or special characters (ex: puertorico).&lt;br /&gt;
It is the same name as the name used for the game folder in your SFTP access.&lt;br /&gt;
&lt;br /&gt;
== It&#039;s pretty annoying to log in with multiple users to start a game. Is there some easier way? ==&lt;br /&gt;
&lt;br /&gt;
You can use the &#039;Express start&#039; function. It will automatically make the specified number of players join the game (using the first of your ten player accounts available) and start the game.&lt;br /&gt;
&lt;br /&gt;
During the game, there is a red arrow on the right of each player name, that you can use to open a tab from this player&#039;s perspective.&lt;br /&gt;
&lt;br /&gt;
You can also end the game in two clicks by clicking the &#039;End game&#039; button then selecting &#039;Express game stop&#039; in the popup.&lt;br /&gt;
&lt;br /&gt;
== What is the working language on BGA studio? ==&lt;br /&gt;
&lt;br /&gt;
Working language is &#039;&#039;&#039;English&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Variables and functions must be named with English words.&lt;br /&gt;
&lt;br /&gt;
Comments must be written in English.&lt;br /&gt;
&lt;br /&gt;
Game interface strings and game logs must be written in English.&lt;br /&gt;
&lt;br /&gt;
== How can I provide translation in my language? == &lt;br /&gt;
&lt;br /&gt;
BGA administrators will translate the game in French before the game release.&lt;br /&gt;
&lt;br /&gt;
After the game release, the collaborative translation interface can be used to translate into other languages.&lt;br /&gt;
&lt;br /&gt;
== Is there a special way to declare the strings that must be translated? == &lt;br /&gt;
&lt;br /&gt;
Yes. This declaration is made through transparent functions, that depend on the context.&lt;br /&gt;
&lt;br /&gt;
In javascript files, you should use _( &#039;My string to translate&#039; ).&lt;br /&gt;
&lt;br /&gt;
In php files, you should use self::_( &#039;My string to translate&#039; ) when the string can be translated on the server side (ex: title included in the game layout) and clienttranslate( &#039;My string to translate&#039; ) when the string must be translated on the client side (ex: message for the game log).&lt;br /&gt;
&lt;br /&gt;
== I updated the images in the &#039;img&#039; folder of my game, but they don&#039;t show? ==&lt;br /&gt;
&lt;br /&gt;
On BGA Studio, there is the gameserver you are developing on, and the main site server that is used to launch the games. The game icon, box and the publisher logo are hosted on the main site server, so they are not immediately available when you modify them on the gameserver. To deploy them on the main site, you have to use the [[Studio back-office]] to do a commit.&lt;br /&gt;
&lt;br /&gt;
If the images still don&#039;t show after that, please try emptying your browser cache and reloading the page.&lt;br /&gt;
&lt;br /&gt;
== I added some game options / some game statistics, but they don&#039;t show? ==&lt;br /&gt;
&lt;br /&gt;
An extra deployment action from the BGA administrators is needed to activate new game options and statistics. Please contact us.&lt;br /&gt;
&lt;br /&gt;
== Is there a quick way to access the database for my current table? ==&lt;br /&gt;
&lt;br /&gt;
Yes! While playing a game on studio, you have a &amp;quot;Go to game database&amp;quot; link at the bottom of your game. This link will bring you directly to the database for the current table.&lt;br /&gt;
&lt;br /&gt;
== What is the best way to debug? ==&lt;br /&gt;
&lt;br /&gt;
On the server side (PHP), you can use one of these:&lt;br /&gt;
* die(var_dump( $variable_to_inspect );&lt;br /&gt;
* throw new BgaUserException(var_dump( $variable_to_inspect );&lt;br /&gt;
&lt;br /&gt;
On the client side (Javascript), we recommand installing Firebug for Firefox (or using the &#039;Developer tools&#039; with Chrome that have about the same functionalities), then:&lt;br /&gt;
* console.log( variable_to_inspect ); will give you the object structure of the variable in the Firebug console, without blocking the execution. It&#039;s often a good idea to precede this call with a console.log( &#039;### HERE ###&#039; ); to find more easily the appropriate line in the console log.&lt;br /&gt;
* alert( variable_to_inspect ); will popup what you wish and pause the execution until you click ok. This won&#039;t be useful for complex structures, only native types will get plainly displayed. But this is sometimes useful just with messages to make sure which way the execution goes.&lt;br /&gt;
&lt;br /&gt;
In general for debugging, think of using the &#039;Save &amp;amp; restore state&#039; functionality. It enables you to save the state of your game just before the issue you are investigating, then come back to that point with one click as many times as needed to understand what is going wrong. You can save up to 3 different states.&lt;br /&gt;
&lt;br /&gt;
=== Some frequent errors ===&lt;br /&gt;
&lt;br /&gt;
; The following error occurs when launching the game &amp;quot;Fatal error during creation of database ebd_quoridor_389 Not logged.&amp;quot;&lt;br /&gt;
: Check that you didn&#039;t use $g_user or getCurrentPlayerId() in setupNewGame() function or in an &amp;quot;args&amp;quot; function of your state. As these functions are not consequences of a user action, there is no current player defined. As a general rule, you should use getActivePlayerId() and not getCurrentPlayerId(). See the [http://www.slideshare.net/boardgamearena/bga-studio-focus-on-bga-game-state-machine presentation on the game state machine] for more information.&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://hu.doc.boardgamearena.com/index.php?title=Studio_FAQ&amp;diff=420</id>
		<title>Studio FAQ</title>
		<link rel="alternate" type="text/html" href="https://hu.doc.boardgamearena.com/index.php?title=Studio_FAQ&amp;diff=420"/>
		<updated>2012-12-23T17:17:40Z</updated>

		<summary type="html">&lt;p&gt;Een: /* What is the best way to debug? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a place where we will collect and answer frequently asked questions.&lt;br /&gt;
&lt;br /&gt;
== What should I use to access the files through SFTP? ==&lt;br /&gt;
&lt;br /&gt;
There is a lot of tools to do that. Use the one you are the most comfortable with.&lt;br /&gt;
&lt;br /&gt;
On Linux, you can for example use the &#039;Connect to server&#039; function of the Nautilus file management system, or use sshfs.&lt;br /&gt;
&lt;br /&gt;
On Windows, there is for example the WinSCP client.&lt;br /&gt;
&lt;br /&gt;
== I can&#039;t access the Studio back-office, I get a &#039;Not authorized&#039; error message? ==&lt;br /&gt;
&lt;br /&gt;
You should first connect to the Studio website (with any of your &amp;lt;developer name&amp;gt;&amp;lt;number&amp;gt; accounts). As the authentication is shared with the back-office, then you will be able to access it.&lt;br /&gt;
&lt;br /&gt;
== I don&#039;t know the name to use to commit my game, what name should I use? ==&lt;br /&gt;
&lt;br /&gt;
The game name for committing is the name of the game in lower case and without spaces or special characters (ex: puertorico).&lt;br /&gt;
It is the same name as the name used for the game folder in your SFTP access.&lt;br /&gt;
&lt;br /&gt;
== It&#039;s pretty annoying to log in with multiple users to start a game. Is there some easier way? ==&lt;br /&gt;
&lt;br /&gt;
You can use the &#039;Express start&#039; function. It will automatically make the specified number of players join the game (using the first of your ten player accounts available) and start the game.&lt;br /&gt;
&lt;br /&gt;
During the game, there is a red arrow on the right of each player name, that you can use to open a tab from this player&#039;s perspective.&lt;br /&gt;
&lt;br /&gt;
You can also end the game in two clicks by clicking the &#039;End game&#039; button then selecting &#039;Express game stop&#039; in the popup.&lt;br /&gt;
&lt;br /&gt;
== What is the working language on BGA studio? ==&lt;br /&gt;
&lt;br /&gt;
Working language is &#039;&#039;&#039;English&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Variables and functions must be named with English words.&lt;br /&gt;
&lt;br /&gt;
Comments must be written in English.&lt;br /&gt;
&lt;br /&gt;
Game interface strings and game logs must be written in English.&lt;br /&gt;
&lt;br /&gt;
== How can I provide translation in my language? == &lt;br /&gt;
&lt;br /&gt;
BGA administrators will translate the game in French before the game release.&lt;br /&gt;
&lt;br /&gt;
After the game release, the collaborative translation interface can be used to translate into other languages.&lt;br /&gt;
&lt;br /&gt;
== Is there a special way to declare the strings that must be translated? == &lt;br /&gt;
&lt;br /&gt;
Yes. This declaration is made through transparent functions, that depend on the context.&lt;br /&gt;
&lt;br /&gt;
In javascript files, you should use _( &#039;My string to translate&#039; ).&lt;br /&gt;
&lt;br /&gt;
In php files, you should use self::_( &#039;My string to translate&#039; ) when the string can be translated on the server side (ex: title included in the game layout) and clienttranslate( &#039;My string to translate&#039; ) when the string must be translated on the client side (ex: message for the game log).&lt;br /&gt;
&lt;br /&gt;
== I updated the images in the &#039;img&#039; folder of my game, but they don&#039;t show? ==&lt;br /&gt;
&lt;br /&gt;
On BGA Studio, there is the gameserver you are developing on, and the main site server that is used to launch the games. The game icon, box and the publisher logo are hosted on the main site server, so they are not immediately available when you modify them on the gameserver. To deploy them on the main site, you have to use the [[Studio back-office]] to do a commit.&lt;br /&gt;
&lt;br /&gt;
If the images still don&#039;t show after that, please try emptying your browser cache and reloading the page.&lt;br /&gt;
&lt;br /&gt;
== I added some game options / some game statistics, but they don&#039;t show? ==&lt;br /&gt;
&lt;br /&gt;
An extra deployment action from the BGA administrators is needed to activate new game options and statistics. Please contact us.&lt;br /&gt;
&lt;br /&gt;
== Is there a quick way to access the database for my current table? ==&lt;br /&gt;
&lt;br /&gt;
Yes! While playing a game on studio, you have a &amp;quot;Go to game database&amp;quot; link at the bottom of your game. This link will bring you directly to the database for the current table.&lt;br /&gt;
&lt;br /&gt;
== What is the best way to debug? ==&lt;br /&gt;
&lt;br /&gt;
On the server side (PHP), you can use one of these:&lt;br /&gt;
* die(var_dump( $variable_to_inspect );&lt;br /&gt;
* throw new BgaUserException(var_dump( $variable_to_inspect );&lt;br /&gt;
&lt;br /&gt;
On the client side (Javascript), we recommand installing Firebug for Firefox (or using the &#039;Developer tools&#039; with Chrome that have about the same functionalities), then:&lt;br /&gt;
* console.log( variable_to_inspect ); will give you the object structure of the variable in the Firebug console, without blocking the execution. It&#039;s often a good idea to precede this call with a console.log( &#039;### HERE ###&#039; ); to find more easily the appropriate line in the console log.&lt;br /&gt;
* alert( variable_to_inspect ); will popup what you wish and pause the execution until you click ok. This won&#039;t be useful for complex structures, only native types will get plainly displayed. But this is sometimes useful just with messages to make sure which way the execution goes.&lt;br /&gt;
&lt;br /&gt;
In general for debugging, think of using the &#039;Save &amp;amp; restore state&#039; functionality. It enables you to save the state of your game just before the issue you are investigating, then come back to that point with one click as many times as needed to understand what is going wrong. You can save up to 3 different states.&lt;br /&gt;
&lt;br /&gt;
=== Some frequent errors ===&lt;br /&gt;
&lt;br /&gt;
; The following error occurs when launching the game &amp;quot;Fatal error during creation of database ebd_quoridor_389: Not logged.&amp;quot;&lt;br /&gt;
: Check that you didn&#039;t use $g_user or getCurrentPlayerId() in setupNewGame() function or in an &amp;quot;args&amp;quot; function of your state. As these functions are not consequences of a user action, there is no current player defined. As a general rule, you should use getActivePlayerId() and not getCurrentPlayerId(). See the [http://www.slideshare.net/boardgamearena/bga-studio-focus-on-bga-game-state-machine presentation on the game state machine] for more information.&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://hu.doc.boardgamearena.com/index.php?title=Studio&amp;diff=414</id>
		<title>Studio</title>
		<link rel="alternate" type="text/html" href="https://hu.doc.boardgamearena.com/index.php?title=Studio&amp;diff=414"/>
		<updated>2012-12-11T14:48:31Z</updated>

		<summary type="html">&lt;p&gt;Een: /* How do I register? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Bga_studio_small.jpg]]&lt;br /&gt;
&lt;br /&gt;
Note: Please DO NOT translate Studio Documentation, so that there can be one place where you can find the last information available.&lt;br /&gt;
&lt;br /&gt;
== What is this? ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Board Game Arena Studio&#039;&#039;&#039; is a platform to build online board game adaptation using the Board Game Arena platform.&lt;br /&gt;
&lt;br /&gt;
It is open to any gamer with development skills :)&lt;br /&gt;
&lt;br /&gt;
See announcement here:&lt;br /&gt;
http://forum.boardgamearena.com/viewtopic.php?f=10&amp;amp;t=1973&lt;br /&gt;
&lt;br /&gt;
== How can I develop a board game on BGA Studio? ==&lt;br /&gt;
&lt;br /&gt;
Check these presentations first:&lt;br /&gt;
&lt;br /&gt;
* [http://www.slideshare.net/boardgamearena/5-reasons-why-you-should-use-bga-studio-for-your-online-board-game 5 reasons why you should use BGA Studio for your online board game]&lt;br /&gt;
* [http://www.slideshare.net/boardgamearena/the-8-steps-to-create-a-board-game-on-board-game-arena The 8 steps to create a board game on Board Game Arena]&lt;br /&gt;
* [http://www.slideshare.net/boardgamearena/the-bga-framework-at-a-glance The BGA Framework at a glance]&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;
* [http://www.slideshare.net/boardgamearena/bga-studio-guidelines BGA developers guidelines]&lt;br /&gt;
&lt;br /&gt;
== How do I register? ==&lt;br /&gt;
&lt;br /&gt;
Registering is done by e-mail at &#039;&#039;&#039;studio(at)boardgamearena.com&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Please provide the following information:&lt;br /&gt;
* your player user name on BGA&lt;br /&gt;
* your developer user name to be used on “BGA Studio” (for technical reasons, no space, number or special character);&lt;br /&gt;
* your real name;&lt;br /&gt;
* your e-mail address;&lt;br /&gt;
* your postal address.&lt;br /&gt;
&lt;br /&gt;
We also drafted a quick [http://en.doc.boardgamearena.com/images/0/02/BGA_TC_Dev_en.pdf &#039;terms &amp;amp; conditions&#039; document]. It&#039;s very light, so as to get to the fun part faster.&lt;br /&gt;
&lt;br /&gt;
To be valid, the registration e-mail must contain this document as an attachment, with the following sentence in the mail body: &#039;I agree with the terms &amp;amp; conditions for developers on BGA Studio joined as an attachment&#039;.&lt;br /&gt;
&lt;br /&gt;
And of course, we also encourage you to tell us about which games you would love to develop on BGA!&lt;br /&gt;
&lt;br /&gt;
== Ok, I registered, what do I get? ==&lt;br /&gt;
&lt;br /&gt;
First, from time to time you will get by e-mail the names of some of the games we have an agreement to develop, so that you can tell us &#039;Hey, this game is great! I want to develop it!&#039; (please keep these names confidential, or it would ruin our tradition to make players guess the name of the next game on the forum)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;NB: during the BETA pĥase, to smooth things up and make sure that everything is working correctly, &lt;br /&gt;
we will work only with 3 fearless developers on 3 simple games.&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Second, once we have discussed together and are fixed on a game you&#039;ll take charge of, we&#039;ll create your studio account and you will get:&lt;br /&gt;
* one login / password to access files through SFTP&lt;br /&gt;
* ten logins with numeric suffixes from 0 to 9 and a common simple password to test games on the studio website while developing.&lt;br /&gt;
&lt;br /&gt;
Once logged in to your SFTP root folder, you will find:&lt;br /&gt;
* a &#039;resources.html&#039; file with the URLs to use and some extra connection information&lt;br /&gt;
* three folders containing the three simple games provided as examples&lt;br /&gt;
* a folder for the game you will be developing initialized after our &#039;EmptyGame&#039; template, providing the game structure (and comments! and examples!)&lt;br /&gt;
&lt;br /&gt;
Then... that&#039;s all, you can start!&lt;br /&gt;
&lt;br /&gt;
== Great, I&#039;m in! ... How should I start? ==&lt;br /&gt;
&lt;br /&gt;
If you didn&#039;t already, check the presentations at the top of this page to get the basics.&lt;br /&gt;
&lt;br /&gt;
After that, we would advise you to take a peek at one or both of these two game creation tutorials:&lt;br /&gt;
* [[Tutorial reversi]]&lt;br /&gt;
* [[Tutorial gomoku]]&lt;br /&gt;
&lt;br /&gt;
Then start editing files and see what happens! ;)&lt;br /&gt;
&lt;br /&gt;
If you have any questions, please ask them on the [http://forum.boardgamearena.com/viewforum.php?f=12 development forum].&lt;br /&gt;
&lt;br /&gt;
== Other resources ==&lt;br /&gt;
&lt;br /&gt;
[[Studio FAQ]]&lt;br /&gt;
&lt;br /&gt;
[[Studio file reference]]&lt;br /&gt;
&lt;br /&gt;
[[Studio function reference]]&lt;br /&gt;
&lt;br /&gt;
[[Studio back-office]]&lt;br /&gt;
&lt;br /&gt;
[http://forum.boardgamearena.com/viewforum.php?f=12 Development forum]&lt;br /&gt;
&lt;br /&gt;
[http://forum.boardgamearena.com/viewforum.php?f=4 Bugs forum]&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://hu.doc.boardgamearena.com/index.php?title=Studio_FAQ&amp;diff=413</id>
		<title>Studio FAQ</title>
		<link rel="alternate" type="text/html" href="https://hu.doc.boardgamearena.com/index.php?title=Studio_FAQ&amp;diff=413"/>
		<updated>2012-12-09T20:46:36Z</updated>

		<summary type="html">&lt;p&gt;Een: /* What is the best way to debug? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a place where we will collect and answer frequently asked questions.&lt;br /&gt;
&lt;br /&gt;
== What should I use to access the files through SFTP? ==&lt;br /&gt;
&lt;br /&gt;
There is a lot of tools to do that. Use the one you are the most comfortable with.&lt;br /&gt;
&lt;br /&gt;
On Linux, you can for example use the &#039;Connect to server&#039; function of the Nautilus file management system, or use sshfs.&lt;br /&gt;
&lt;br /&gt;
On Windows, there is for example the WinSCP client.&lt;br /&gt;
&lt;br /&gt;
== I can&#039;t access the Studio back-office, I get a &#039;Not authorized&#039; error message? ==&lt;br /&gt;
&lt;br /&gt;
You should first connect to the Studio website (with any of your &amp;lt;developer name&amp;gt;&amp;lt;number&amp;gt; accounts). As the authentication is shared with the back-office, then you will be able to access it.&lt;br /&gt;
&lt;br /&gt;
== I don&#039;t know the name to use to commit my game, what name should I use? ==&lt;br /&gt;
&lt;br /&gt;
The game name for committing is the name of the game in lower case and without spaces or special characters (ex: puertorico).&lt;br /&gt;
It is the same name as the name used for the game folder in your SFTP access.&lt;br /&gt;
&lt;br /&gt;
== It&#039;s pretty annoying to log in with multiple users to start a game. Is there some easier way? ==&lt;br /&gt;
&lt;br /&gt;
You can use the &#039;Express start&#039; function. It will automatically make the specified number of players join the game (using the first of your ten player accounts available) and start the game.&lt;br /&gt;
&lt;br /&gt;
During the game, there is a red arrow on the right of each player name, that you can use to open a tab from this player&#039;s perspective.&lt;br /&gt;
&lt;br /&gt;
You can also end the game in two clicks by clicking the &#039;End game&#039; button then selecting &#039;Express game stop&#039; in the popup.&lt;br /&gt;
&lt;br /&gt;
== What is the working language on BGA studio? ==&lt;br /&gt;
&lt;br /&gt;
Working language is &#039;&#039;&#039;English&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Variables and functions must be named with English words.&lt;br /&gt;
&lt;br /&gt;
Comments must be written in English.&lt;br /&gt;
&lt;br /&gt;
Game interface strings and game logs must be written in English.&lt;br /&gt;
&lt;br /&gt;
== How can I provide translation in my language? == &lt;br /&gt;
&lt;br /&gt;
BGA administrators will translate the game in French before the game release.&lt;br /&gt;
&lt;br /&gt;
After the game release, the collaborative translation interface can be used to translate into other languages.&lt;br /&gt;
&lt;br /&gt;
== Is there a special way to declare the strings that must be translated? == &lt;br /&gt;
&lt;br /&gt;
Yes. This declaration is made through transparent functions, that depend on the context.&lt;br /&gt;
&lt;br /&gt;
In javascript files, you should use _( &#039;My string to translate&#039; ).&lt;br /&gt;
&lt;br /&gt;
In php files, you should use self::_( &#039;My string to translate&#039; ) when the string can be translated on the server side (ex: title included in the game layout) and clienttranslate( &#039;My string to translate&#039; ) when the string must be translated on the client side (ex: message for the game log).&lt;br /&gt;
&lt;br /&gt;
== I updated the images in the &#039;img&#039; folder of my game, but they don&#039;t show? ==&lt;br /&gt;
&lt;br /&gt;
On BGA Studio, there is the gameserver you are developing on, and the main site server that is used to launch the games. The game icon, box and the publisher logo are hosted on the main site server, so they are not immediately available when you modify them on the gameserver. To deploy them on the main site, you have to use the [[Studio back-office]] to do a commit.&lt;br /&gt;
&lt;br /&gt;
If the images still don&#039;t show after that, please try emptying your browser cache and reloading the page.&lt;br /&gt;
&lt;br /&gt;
== I added some game options / some game statistics, but they don&#039;t show? ==&lt;br /&gt;
&lt;br /&gt;
An extra deployment action from the BGA administrators is needed to activate new game options and statistics. Please contact us.&lt;br /&gt;
&lt;br /&gt;
== Is there a quick way to access the database for my current table? ==&lt;br /&gt;
&lt;br /&gt;
Yes! While playing a game on studio, you have a &amp;quot;Go to game database&amp;quot; link at the bottom of your game. This link will bring you directly to the database for the current table.&lt;br /&gt;
&lt;br /&gt;
== What is the best way to debug? ==&lt;br /&gt;
&lt;br /&gt;
On the server side (PHP), you can use one of these:&lt;br /&gt;
* die(var_dump( $variable_to_inspect );&lt;br /&gt;
* throw new BgaUserException(var_dump( $variable_to_inspect );&lt;br /&gt;
&lt;br /&gt;
On the client side (Javascript), we recommand installing Firebug for Firefox (or using the &#039;Developer tools&#039; with Chrome that have about the same functionalities), then:&lt;br /&gt;
* console.log( variable_to_inspect ); will give you the object structure of the variable in the Firebug console, without blocking the execution. It&#039;s often a good idea to precede this call with a console.log( &#039;### HERE ###&#039; ); to find more easily the appropriate line in the console log.&lt;br /&gt;
* alert( variable_to_inspect ); will popup what you wish and pause the execution until you click ok. This won&#039;t be useful for complex structures, only native types will get plainly displayed. But this is sometimes useful just with messages to make sure which way the execution goes.&lt;br /&gt;
&lt;br /&gt;
In general for debugging, think of using the &#039;Save &amp;amp; restore state&#039; functionality. It enables you to save the state of your game just before the issue you are investigating, then come back to that point with one click as many times as needed to understand what is going wrong. You can save up to 3 different states.&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://hu.doc.boardgamearena.com/index.php?title=Studio_FAQ&amp;diff=412</id>
		<title>Studio FAQ</title>
		<link rel="alternate" type="text/html" href="https://hu.doc.boardgamearena.com/index.php?title=Studio_FAQ&amp;diff=412"/>
		<updated>2012-12-09T20:42:02Z</updated>

		<summary type="html">&lt;p&gt;Een: /* What is the best way to debug? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a place where we will collect and answer frequently asked questions.&lt;br /&gt;
&lt;br /&gt;
== What should I use to access the files through SFTP? ==&lt;br /&gt;
&lt;br /&gt;
There is a lot of tools to do that. Use the one you are the most comfortable with.&lt;br /&gt;
&lt;br /&gt;
On Linux, you can for example use the &#039;Connect to server&#039; function of the Nautilus file management system, or use sshfs.&lt;br /&gt;
&lt;br /&gt;
On Windows, there is for example the WinSCP client.&lt;br /&gt;
&lt;br /&gt;
== I can&#039;t access the Studio back-office, I get a &#039;Not authorized&#039; error message? ==&lt;br /&gt;
&lt;br /&gt;
You should first connect to the Studio website (with any of your &amp;lt;developer name&amp;gt;&amp;lt;number&amp;gt; accounts). As the authentication is shared with the back-office, then you will be able to access it.&lt;br /&gt;
&lt;br /&gt;
== I don&#039;t know the name to use to commit my game, what name should I use? ==&lt;br /&gt;
&lt;br /&gt;
The game name for committing is the name of the game in lower case and without spaces or special characters (ex: puertorico).&lt;br /&gt;
It is the same name as the name used for the game folder in your SFTP access.&lt;br /&gt;
&lt;br /&gt;
== It&#039;s pretty annoying to log in with multiple users to start a game. Is there some easier way? ==&lt;br /&gt;
&lt;br /&gt;
You can use the &#039;Express start&#039; function. It will automatically make the specified number of players join the game (using the first of your ten player accounts available) and start the game.&lt;br /&gt;
&lt;br /&gt;
During the game, there is a red arrow on the right of each player name, that you can use to open a tab from this player&#039;s perspective.&lt;br /&gt;
&lt;br /&gt;
You can also end the game in two clicks by clicking the &#039;End game&#039; button then selecting &#039;Express game stop&#039; in the popup.&lt;br /&gt;
&lt;br /&gt;
== What is the working language on BGA studio? ==&lt;br /&gt;
&lt;br /&gt;
Working language is &#039;&#039;&#039;English&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Variables and functions must be named with English words.&lt;br /&gt;
&lt;br /&gt;
Comments must be written in English.&lt;br /&gt;
&lt;br /&gt;
Game interface strings and game logs must be written in English.&lt;br /&gt;
&lt;br /&gt;
== How can I provide translation in my language? == &lt;br /&gt;
&lt;br /&gt;
BGA administrators will translate the game in French before the game release.&lt;br /&gt;
&lt;br /&gt;
After the game release, the collaborative translation interface can be used to translate into other languages.&lt;br /&gt;
&lt;br /&gt;
== Is there a special way to declare the strings that must be translated? == &lt;br /&gt;
&lt;br /&gt;
Yes. This declaration is made through transparent functions, that depend on the context.&lt;br /&gt;
&lt;br /&gt;
In javascript files, you should use _( &#039;My string to translate&#039; ).&lt;br /&gt;
&lt;br /&gt;
In php files, you should use self::_( &#039;My string to translate&#039; ) when the string can be translated on the server side (ex: title included in the game layout) and clienttranslate( &#039;My string to translate&#039; ) when the string must be translated on the client side (ex: message for the game log).&lt;br /&gt;
&lt;br /&gt;
== I updated the images in the &#039;img&#039; folder of my game, but they don&#039;t show? ==&lt;br /&gt;
&lt;br /&gt;
On BGA Studio, there is the gameserver you are developing on, and the main site server that is used to launch the games. The game icon, box and the publisher logo are hosted on the main site server, so they are not immediately available when you modify them on the gameserver. To deploy them on the main site, you have to use the [[Studio back-office]] to do a commit.&lt;br /&gt;
&lt;br /&gt;
If the images still don&#039;t show after that, please try emptying your browser cache and reloading the page.&lt;br /&gt;
&lt;br /&gt;
== I added some game options / some game statistics, but they don&#039;t show? ==&lt;br /&gt;
&lt;br /&gt;
An extra deployment action from the BGA administrators is needed to activate new game options and statistics. Please contact us.&lt;br /&gt;
&lt;br /&gt;
== Is there a quick way to access the database for my current table? ==&lt;br /&gt;
&lt;br /&gt;
Yes! While playing a game on studio, you have a &amp;quot;Go to game database&amp;quot; link at the bottom of your game. This link will bring you directly to the database for the current table.&lt;br /&gt;
&lt;br /&gt;
== What is the best way to debug? ==&lt;br /&gt;
&lt;br /&gt;
On the server side (PHP), you can use one of these:&lt;br /&gt;
* die(var_dump( $variable_to_inspect );&lt;br /&gt;
* throw new BgaUserException(var_dump( $variable_to_inspect );&lt;br /&gt;
&lt;br /&gt;
On the client side (Javascript), we recommand installing Firebug for Firefox (or using the Developer tools with Chrome which has about the same functionalities), then:&lt;br /&gt;
* console.log( variable_to_inspect ); will give you the object structure of the variable in the Firebug console, without blocking the execution. It&#039;s often a good idea to precede this call with a console.log( &#039;### HERE ###&#039; ); to find more easily the appropriate line in the console log.&lt;br /&gt;
* alert( variable_to_inspect ); will popup what you wish and pause the execution until you click ok. This won&#039;t be useful for complex structures, only native types will get plainly displayed. But this is sometimes useful just with messages to make sure which way the execution goes.&lt;br /&gt;
&lt;br /&gt;
In general for debugging, think of using the &#039;Save &amp;amp; restore state&#039; functionality. It enables you to save the state of your game just before the issue you are investigating, then come back to that point with one click as many times as needed to understand what is going wrong. You can save up to 3 different states.&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://hu.doc.boardgamearena.com/index.php?title=Studio_FAQ&amp;diff=411</id>
		<title>Studio FAQ</title>
		<link rel="alternate" type="text/html" href="https://hu.doc.boardgamearena.com/index.php?title=Studio_FAQ&amp;diff=411"/>
		<updated>2012-12-09T20:21:23Z</updated>

		<summary type="html">&lt;p&gt;Een: /* What is the best way to debug? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a place where we will collect and answer frequently asked questions.&lt;br /&gt;
&lt;br /&gt;
== What should I use to access the files through SFTP? ==&lt;br /&gt;
&lt;br /&gt;
There is a lot of tools to do that. Use the one you are the most comfortable with.&lt;br /&gt;
&lt;br /&gt;
On Linux, you can for example use the &#039;Connect to server&#039; function of the Nautilus file management system, or use sshfs.&lt;br /&gt;
&lt;br /&gt;
On Windows, there is for example the WinSCP client.&lt;br /&gt;
&lt;br /&gt;
== I can&#039;t access the Studio back-office, I get a &#039;Not authorized&#039; error message? ==&lt;br /&gt;
&lt;br /&gt;
You should first connect to the Studio website (with any of your &amp;lt;developer name&amp;gt;&amp;lt;number&amp;gt; accounts). As the authentication is shared with the back-office, then you will be able to access it.&lt;br /&gt;
&lt;br /&gt;
== I don&#039;t know the name to use to commit my game, what name should I use? ==&lt;br /&gt;
&lt;br /&gt;
The game name for committing is the name of the game in lower case and without spaces or special characters (ex: puertorico).&lt;br /&gt;
It is the same name as the name used for the game folder in your SFTP access.&lt;br /&gt;
&lt;br /&gt;
== It&#039;s pretty annoying to log in with multiple users to start a game. Is there some easier way? ==&lt;br /&gt;
&lt;br /&gt;
You can use the &#039;Express start&#039; function. It will automatically make the specified number of players join the game (using the first of your ten player accounts available) and start the game.&lt;br /&gt;
&lt;br /&gt;
During the game, there is a red arrow on the right of each player name, that you can use to open a tab from this player&#039;s perspective.&lt;br /&gt;
&lt;br /&gt;
You can also end the game in two clicks by clicking the &#039;End game&#039; button then selecting &#039;Express game stop&#039; in the popup.&lt;br /&gt;
&lt;br /&gt;
== What is the working language on BGA studio? ==&lt;br /&gt;
&lt;br /&gt;
Working language is &#039;&#039;&#039;English&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Variables and functions must be named with English words.&lt;br /&gt;
&lt;br /&gt;
Comments must be written in English.&lt;br /&gt;
&lt;br /&gt;
Game interface strings and game logs must be written in English.&lt;br /&gt;
&lt;br /&gt;
== How can I provide translation in my language? == &lt;br /&gt;
&lt;br /&gt;
BGA administrators will translate the game in French before the game release.&lt;br /&gt;
&lt;br /&gt;
After the game release, the collaborative translation interface can be used to translate into other languages.&lt;br /&gt;
&lt;br /&gt;
== Is there a special way to declare the strings that must be translated? == &lt;br /&gt;
&lt;br /&gt;
Yes. This declaration is made through transparent functions, that depend on the context.&lt;br /&gt;
&lt;br /&gt;
In javascript files, you should use _( &#039;My string to translate&#039; ).&lt;br /&gt;
&lt;br /&gt;
In php files, you should use self::_( &#039;My string to translate&#039; ) when the string can be translated on the server side (ex: title included in the game layout) and clienttranslate( &#039;My string to translate&#039; ) when the string must be translated on the client side (ex: message for the game log).&lt;br /&gt;
&lt;br /&gt;
== I updated the images in the &#039;img&#039; folder of my game, but they don&#039;t show? ==&lt;br /&gt;
&lt;br /&gt;
On BGA Studio, there is the gameserver you are developing on, and the main site server that is used to launch the games. The game icon, box and the publisher logo are hosted on the main site server, so they are not immediately available when you modify them on the gameserver. To deploy them on the main site, you have to use the [[Studio back-office]] to do a commit.&lt;br /&gt;
&lt;br /&gt;
If the images still don&#039;t show after that, please try emptying your browser cache and reloading the page.&lt;br /&gt;
&lt;br /&gt;
== I added some game options / some game statistics, but they don&#039;t show? ==&lt;br /&gt;
&lt;br /&gt;
An extra deployment action from the BGA administrators is needed to activate new game options and statistics. Please contact us.&lt;br /&gt;
&lt;br /&gt;
== Is there a quick way to access the database for my current table? ==&lt;br /&gt;
&lt;br /&gt;
Yes! While playing a game on studio, you have a &amp;quot;Go to game database&amp;quot; link at the bottom of your game. This link will bring you directly to the database for the current table.&lt;br /&gt;
&lt;br /&gt;
== What is the best way to debug? ==&lt;br /&gt;
&lt;br /&gt;
On the server side (PHP), you can use one of these:&lt;br /&gt;
* die(var_dump( $variable_to_inspect );&lt;br /&gt;
* throw new BgaUserException(var_dump( $variable_to_inspect );&lt;br /&gt;
&lt;br /&gt;
On the client side (Javascript), we recommand installing Firebug for Firefox (or using the Developer tools with Chrome which has about the same functionalities), then:&lt;br /&gt;
* console.log( variable_to_inspect ); will give you the object structure of the variable in the Firebug console, without blocking the execution. It&#039;s often a good idea to precede this call with a console.log( &#039;### HERE ###&#039; ); to find more easily the appropriate line in the console log.&lt;br /&gt;
* alert( variable_to_inspect ); will popup what you wish and pause the execution until you click ok. This won&#039;t be useful for complex structures, only native types will get plainly displayed. But this is sometimes useful just with messages to make sure which way the execution goes.&lt;br /&gt;
&lt;br /&gt;
In general for debugging, think of using the &#039;Save &amp;amp; restore state&#039; functionality (NB: currently non functional, will be ok with the next studio update). It enables you to save the state of your game just before the issue you are investigating, then come back to that point with one click as many times as needed to understand what is going wrong. You can save up to 3 different states.&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://hu.doc.boardgamearena.com/index.php?title=Studio_FAQ&amp;diff=410</id>
		<title>Studio FAQ</title>
		<link rel="alternate" type="text/html" href="https://hu.doc.boardgamearena.com/index.php?title=Studio_FAQ&amp;diff=410"/>
		<updated>2012-12-09T20:19:37Z</updated>

		<summary type="html">&lt;p&gt;Een: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a place where we will collect and answer frequently asked questions.&lt;br /&gt;
&lt;br /&gt;
== What should I use to access the files through SFTP? ==&lt;br /&gt;
&lt;br /&gt;
There is a lot of tools to do that. Use the one you are the most comfortable with.&lt;br /&gt;
&lt;br /&gt;
On Linux, you can for example use the &#039;Connect to server&#039; function of the Nautilus file management system, or use sshfs.&lt;br /&gt;
&lt;br /&gt;
On Windows, there is for example the WinSCP client.&lt;br /&gt;
&lt;br /&gt;
== I can&#039;t access the Studio back-office, I get a &#039;Not authorized&#039; error message? ==&lt;br /&gt;
&lt;br /&gt;
You should first connect to the Studio website (with any of your &amp;lt;developer name&amp;gt;&amp;lt;number&amp;gt; accounts). As the authentication is shared with the back-office, then you will be able to access it.&lt;br /&gt;
&lt;br /&gt;
== I don&#039;t know the name to use to commit my game, what name should I use? ==&lt;br /&gt;
&lt;br /&gt;
The game name for committing is the name of the game in lower case and without spaces or special characters (ex: puertorico).&lt;br /&gt;
It is the same name as the name used for the game folder in your SFTP access.&lt;br /&gt;
&lt;br /&gt;
== It&#039;s pretty annoying to log in with multiple users to start a game. Is there some easier way? ==&lt;br /&gt;
&lt;br /&gt;
You can use the &#039;Express start&#039; function. It will automatically make the specified number of players join the game (using the first of your ten player accounts available) and start the game.&lt;br /&gt;
&lt;br /&gt;
During the game, there is a red arrow on the right of each player name, that you can use to open a tab from this player&#039;s perspective.&lt;br /&gt;
&lt;br /&gt;
You can also end the game in two clicks by clicking the &#039;End game&#039; button then selecting &#039;Express game stop&#039; in the popup.&lt;br /&gt;
&lt;br /&gt;
== What is the working language on BGA studio? ==&lt;br /&gt;
&lt;br /&gt;
Working language is &#039;&#039;&#039;English&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Variables and functions must be named with English words.&lt;br /&gt;
&lt;br /&gt;
Comments must be written in English.&lt;br /&gt;
&lt;br /&gt;
Game interface strings and game logs must be written in English.&lt;br /&gt;
&lt;br /&gt;
== How can I provide translation in my language? == &lt;br /&gt;
&lt;br /&gt;
BGA administrators will translate the game in French before the game release.&lt;br /&gt;
&lt;br /&gt;
After the game release, the collaborative translation interface can be used to translate into other languages.&lt;br /&gt;
&lt;br /&gt;
== Is there a special way to declare the strings that must be translated? == &lt;br /&gt;
&lt;br /&gt;
Yes. This declaration is made through transparent functions, that depend on the context.&lt;br /&gt;
&lt;br /&gt;
In javascript files, you should use _( &#039;My string to translate&#039; ).&lt;br /&gt;
&lt;br /&gt;
In php files, you should use self::_( &#039;My string to translate&#039; ) when the string can be translated on the server side (ex: title included in the game layout) and clienttranslate( &#039;My string to translate&#039; ) when the string must be translated on the client side (ex: message for the game log).&lt;br /&gt;
&lt;br /&gt;
== I updated the images in the &#039;img&#039; folder of my game, but they don&#039;t show? ==&lt;br /&gt;
&lt;br /&gt;
On BGA Studio, there is the gameserver you are developing on, and the main site server that is used to launch the games. The game icon, box and the publisher logo are hosted on the main site server, so they are not immediately available when you modify them on the gameserver. To deploy them on the main site, you have to use the [[Studio back-office]] to do a commit.&lt;br /&gt;
&lt;br /&gt;
If the images still don&#039;t show after that, please try emptying your browser cache and reloading the page.&lt;br /&gt;
&lt;br /&gt;
== I added some game options / some game statistics, but they don&#039;t show? ==&lt;br /&gt;
&lt;br /&gt;
An extra deployment action from the BGA administrators is needed to activate new game options and statistics. Please contact us.&lt;br /&gt;
&lt;br /&gt;
== Is there a quick way to access the database for my current table? ==&lt;br /&gt;
&lt;br /&gt;
Yes! While playing a game on studio, you have a &amp;quot;Go to game database&amp;quot; link at the bottom of your game. This link will bring you directly to the database for the current table.&lt;br /&gt;
&lt;br /&gt;
== What is the best way to debug? ==&lt;br /&gt;
&lt;br /&gt;
On the server side (PHP), you can use one of these:&lt;br /&gt;
* die(var_dump( $variable_to_inspect );&lt;br /&gt;
* throw new BgaUserException(var_dump( $variable_to_inspect );&lt;br /&gt;
&lt;br /&gt;
On the client side (Javascript), we recommand installing Firebug for Firefox (or using the Developer tools with Chrome which has about the same functionalities), then:&lt;br /&gt;
* console.log( variable_to_inspect ); will give you the object structure of the variable in the Firebug console, without blocking the execution. It&#039;s often a good idea to precede this call with a console.log( &#039;### HERE ###&#039; ); to find more easily the appropriate line in the console log.&lt;br /&gt;
* alert( variable_to_inspect ); will popup what you wish and pause the execution until you click ok. This won&#039;t be useful for complex structures, only native types will get plainly displayed. But this is sometimes useful just with messages to make sure which way the execution goes.&lt;br /&gt;
&lt;br /&gt;
In general for debugging, think of using the save/restore functionality (NB: currently non functional, will be ok with the next studio update). It enable you to save the state of your game just before the issue you are investigating, then come back to that point with one click as many times as needed to understand what is going wrong.&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://hu.doc.boardgamearena.com/index.php?title=Studio&amp;diff=408</id>
		<title>Studio</title>
		<link rel="alternate" type="text/html" href="https://hu.doc.boardgamearena.com/index.php?title=Studio&amp;diff=408"/>
		<updated>2012-12-06T22:29:11Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Great, I&amp;#039;m in! ... How should I start? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Bga_studio_small.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== What is this? ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Board Game Arena Studio&#039;&#039;&#039; is a platform to build online board game adaptation using the Board Game Arena platform.&lt;br /&gt;
&lt;br /&gt;
It is open to any gamer with development skills :)&lt;br /&gt;
&lt;br /&gt;
See announcement here:&lt;br /&gt;
http://forum.boardgamearena.com/viewtopic.php?f=10&amp;amp;t=1973&lt;br /&gt;
&lt;br /&gt;
== How can I develop a board game on BGA Studio? ==&lt;br /&gt;
&lt;br /&gt;
Check these presentations first:&lt;br /&gt;
&lt;br /&gt;
* [http://www.slideshare.net/boardgamearena/5-reasons-why-you-should-use-bga-studio-for-your-online-board-game 5 reasons why you should use BGA Studio for your online board game]&lt;br /&gt;
* [http://www.slideshare.net/boardgamearena/the-8-steps-to-create-a-board-game-on-board-game-arena The 8 steps to create a board game on Board Game Arena]&lt;br /&gt;
* [http://www.slideshare.net/boardgamearena/the-bga-framework-at-a-glance The BGA Framework at a glance]&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;
* [http://www.slideshare.net/boardgamearena/bga-studio-guidelines BGA developers guidelines]&lt;br /&gt;
&lt;br /&gt;
== How do I register? ==&lt;br /&gt;
&lt;br /&gt;
Registering is done by e-mail at &#039;&#039;&#039;studio(at)boardgamearena.com&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Please provide the following information:&lt;br /&gt;
* your developer user name to be used on “BGA Studio” (for technical reasons, no space, number or special character);&lt;br /&gt;
* your real name;&lt;br /&gt;
* your e-mail address;&lt;br /&gt;
* your postal address.&lt;br /&gt;
&lt;br /&gt;
We also drafted a quick [http://en.doc.boardgamearena.com/images/0/02/BGA_TC_Dev_en.pdf &#039;terms &amp;amp; conditions&#039; document]. It&#039;s very light, so as to get to the fun part faster.&lt;br /&gt;
&lt;br /&gt;
To be valid, the registration e-mail must contain this document as an attachment, with the following sentence in the mail body: &#039;I agree with the terms &amp;amp; conditions for developers on BGA Studio joined as an attachment&#039;.&lt;br /&gt;
&lt;br /&gt;
And of course, we also encourage you to tell us about which games you would love to develop on BGA!&lt;br /&gt;
&lt;br /&gt;
== Ok, I registered, what do I get? ==&lt;br /&gt;
&lt;br /&gt;
First, from time to time you will get by e-mail the names of some of the games we have an agreement to develop, so that you can tell us &#039;Hey, this game is great! I want to develop it!&#039; (please keep these names confidential, or it would ruin our tradition to make players guess the name of the next game on the forum)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;NB: during the BETA pĥase, to smooth things up and make sure that everything is working correctly, &lt;br /&gt;
we will work only with 3 fearless developers on 3 simple games.&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Second, once we have discussed together and are fixed on a game you&#039;ll take charge of, we&#039;ll create your studio account and you will get:&lt;br /&gt;
* one login / password to access files through SFTP&lt;br /&gt;
* ten logins with numeric suffixes from 0 to 9 and a common simple password to test games on the studio website while developing.&lt;br /&gt;
&lt;br /&gt;
Once logged in to your SFTP root folder, you will find:&lt;br /&gt;
* a &#039;resources.html&#039; file with the URLs to use and some extra connection information&lt;br /&gt;
* three folders containing the three simple games provided as examples&lt;br /&gt;
* a folder for the game you will be developing initialized after our &#039;EmptyGame&#039; template, providing the game structure (and comments! and examples!)&lt;br /&gt;
&lt;br /&gt;
Then... that&#039;s all, you can start!&lt;br /&gt;
&lt;br /&gt;
== Great, I&#039;m in! ... How should I start? ==&lt;br /&gt;
&lt;br /&gt;
If you didn&#039;t already, check the presentations at the top of this page to get the basics.&lt;br /&gt;
&lt;br /&gt;
After that, we would advise you to take a peek at one or both of these two game creation tutorials:&lt;br /&gt;
* [[Tutorial reversi]]&lt;br /&gt;
* [[Tutorial gomoku]]&lt;br /&gt;
&lt;br /&gt;
Then start editing files and see what happens! ;)&lt;br /&gt;
&lt;br /&gt;
If you have any questions, please ask them on the [http://forum.boardgamearena.com/viewforum.php?f=12 development forum].&lt;br /&gt;
&lt;br /&gt;
== Other resources ==&lt;br /&gt;
&lt;br /&gt;
[[Studio FAQ]]&lt;br /&gt;
&lt;br /&gt;
[[Studio file reference]]&lt;br /&gt;
&lt;br /&gt;
[[Studio function reference]]&lt;br /&gt;
&lt;br /&gt;
[[Studio back-office]]&lt;br /&gt;
&lt;br /&gt;
[http://forum.boardgamearena.com/viewforum.php?f=12 Development forum]&lt;br /&gt;
&lt;br /&gt;
[http://forum.boardgamearena.com/viewforum.php?f=4 Bugs forum]&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=407</id>
		<title>Tutorial gomoku</title>
		<link rel="alternate" type="text/html" href="https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=407"/>
		<updated>2012-12-06T22:27:38Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Implement rules and end of game conditions */&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;emtpy 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/gomoku/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 ${coordinates}&#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;coordinates&#039; =&amp;gt; $this-&amp;gt;getFormattedCoordinates($coord_x, $coord_y),&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;, 1000 );&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;
        			dojo.style( &#039;stone_&#039; + notif.args.coord_x + &#039;_&#039; + notif.args.coord_y, &#039;zIndex&#039;, &#039;auto&#039; );&lt;br /&gt;
       		}));&lt;br /&gt;
            slide.play();&lt;br /&gt;
           &lt;br /&gt;
            // This intersection is taken, it shouldn&#039;t appear as clickable anymore&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;
&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_stone {&lt;br /&gt;
	width: 30px;&lt;br /&gt;
	height: 30px;&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    background-image: url( &#039;../../img/gomoku/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;
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(): &lt;br /&gt;
&lt;br /&gt;
* 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;
* and 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>Een</name></author>
	</entry>
	<entry>
		<id>https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=406</id>
		<title>Tutorial gomoku</title>
		<link rel="alternate" type="text/html" href="https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=406"/>
		<updated>2012-12-06T22:26:48Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Implement rules and end of game conditions */&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;emtpy 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/gomoku/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 ${coordinates}&#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;coordinates&#039; =&amp;gt; $this-&amp;gt;getFormattedCoordinates($coord_x, $coord_y),&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;, 1000 );&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;
        			dojo.style( &#039;stone_&#039; + notif.args.coord_x + &#039;_&#039; + notif.args.coord_y, &#039;zIndex&#039;, &#039;auto&#039; );&lt;br /&gt;
       		}));&lt;br /&gt;
            slide.play();&lt;br /&gt;
           &lt;br /&gt;
            // This intersection is taken, it shouldn&#039;t appear as clickable anymore&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;
&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_stone {&lt;br /&gt;
	width: 30px;&lt;br /&gt;
	height: 30px;&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    background-image: url( &#039;../../img/gomoku/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;
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(): &lt;br /&gt;
&lt;br /&gt;
* 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;
* and 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, notify it to update the score on 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>Een</name></author>
	</entry>
	<entry>
		<id>https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=405</id>
		<title>Tutorial gomoku</title>
		<link rel="alternate" type="text/html" href="https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=405"/>
		<updated>2012-12-06T22:24:28Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Manage states and events */&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;emtpy 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/gomoku/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 ${coordinates}&#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;coordinates&#039; =&amp;gt; $this-&amp;gt;getFormattedCoordinates($coord_x, $coord_y),&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;, 1000 );&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;
        			dojo.style( &#039;stone_&#039; + notif.args.coord_x + &#039;_&#039; + notif.args.coord_y, &#039;zIndex&#039;, &#039;auto&#039; );&lt;br /&gt;
       		}));&lt;br /&gt;
            slide.play();&lt;br /&gt;
           &lt;br /&gt;
            // This intersection is taken, it shouldn&#039;t appear as clickable anymore&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;
&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_stone {&lt;br /&gt;
	width: 30px;&lt;br /&gt;
	height: 30px;&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    background-image: url( &#039;../../img/gomoku/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;
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(): &lt;br /&gt;
&lt;br /&gt;
* 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;
* and 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;
* we 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, notify it to update the score on 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>Een</name></author>
	</entry>
	<entry>
		<id>https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=404</id>
		<title>Tutorial gomoku</title>
		<link rel="alternate" type="text/html" href="https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=404"/>
		<updated>2012-12-06T22:23:06Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Setup the backbone of your game */&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;emtpy 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/gomoku/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. 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 ${coordinates}&#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;coordinates&#039; =&amp;gt; $this-&amp;gt;getFormattedCoordinates($coord_x, $coord_y),&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;, 1000 );&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;
        			dojo.style( &#039;stone_&#039; + notif.args.coord_x + &#039;_&#039; + notif.args.coord_y, &#039;zIndex&#039;, &#039;auto&#039; );&lt;br /&gt;
       		}));&lt;br /&gt;
            slide.play();&lt;br /&gt;
           &lt;br /&gt;
            // This intersection is taken, it shouldn&#039;t appear as clickable anymore&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;
&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_stone {&lt;br /&gt;
	width: 30px;&lt;br /&gt;
	height: 30px;&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    background-image: url( &#039;../../img/gomoku/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;
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(): &lt;br /&gt;
&lt;br /&gt;
* 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;
* and 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;
* we 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, notify it to update the score on 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>Een</name></author>
	</entry>
	<entry>
		<id>https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=403</id>
		<title>Tutorial gomoku</title>
		<link rel="alternate" type="text/html" href="https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=403"/>
		<updated>2012-12-06T22:22:43Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Setup the backbone of your game */&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;emtpy 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/gomoku/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 after some tweaks and refresh:&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. 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 ${coordinates}&#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;coordinates&#039; =&amp;gt; $this-&amp;gt;getFormattedCoordinates($coord_x, $coord_y),&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;, 1000 );&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;
        			dojo.style( &#039;stone_&#039; + notif.args.coord_x + &#039;_&#039; + notif.args.coord_y, &#039;zIndex&#039;, &#039;auto&#039; );&lt;br /&gt;
       		}));&lt;br /&gt;
            slide.play();&lt;br /&gt;
           &lt;br /&gt;
            // This intersection is taken, it shouldn&#039;t appear as clickable anymore&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;
&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_stone {&lt;br /&gt;
	width: 30px;&lt;br /&gt;
	height: 30px;&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    background-image: url( &#039;../../img/gomoku/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;
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(): &lt;br /&gt;
&lt;br /&gt;
* 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;
* and 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;
* we 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, notify it to update the score on 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>Een</name></author>
	</entry>
	<entry>
		<id>https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=402</id>
		<title>Tutorial gomoku</title>
		<link rel="alternate" type="text/html" href="https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=402"/>
		<updated>2012-12-06T22:21:47Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Setup the backbone of your game */&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;emtpy 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/gomoku/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. 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 ${coordinates}&#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;coordinates&#039; =&amp;gt; $this-&amp;gt;getFormattedCoordinates($coord_x, $coord_y),&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;, 1000 );&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;
        			dojo.style( &#039;stone_&#039; + notif.args.coord_x + &#039;_&#039; + notif.args.coord_y, &#039;zIndex&#039;, &#039;auto&#039; );&lt;br /&gt;
       		}));&lt;br /&gt;
            slide.play();&lt;br /&gt;
           &lt;br /&gt;
            // This intersection is taken, it shouldn&#039;t appear as clickable anymore&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;
&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_stone {&lt;br /&gt;
	width: 30px;&lt;br /&gt;
	height: 30px;&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    background-image: url( &#039;../../img/gomoku/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;
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(): &lt;br /&gt;
&lt;br /&gt;
* 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;
* and 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;
* we 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, notify it to update the score on 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>Een</name></author>
	</entry>
	<entry>
		<id>https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=401</id>
		<title>Tutorial gomoku</title>
		<link rel="alternate" type="text/html" href="https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=401"/>
		<updated>2012-12-06T22:19:41Z</updated>

		<summary type="html">&lt;p&gt;Een: /* 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;emtpy 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/gomoku/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;
* 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. 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 ${coordinates}&#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;coordinates&#039; =&amp;gt; $this-&amp;gt;getFormattedCoordinates($coord_x, $coord_y),&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;, 1000 );&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;
        			dojo.style( &#039;stone_&#039; + notif.args.coord_x + &#039;_&#039; + notif.args.coord_y, &#039;zIndex&#039;, &#039;auto&#039; );&lt;br /&gt;
       		}));&lt;br /&gt;
            slide.play();&lt;br /&gt;
           &lt;br /&gt;
            // This intersection is taken, it shouldn&#039;t appear as clickable anymore&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;
&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_stone {&lt;br /&gt;
	width: 30px;&lt;br /&gt;
	height: 30px;&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    background-image: url( &#039;../../img/gomoku/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;
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(): &lt;br /&gt;
&lt;br /&gt;
* 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;
* and 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;
* we 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, notify it to update the score on 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>Een</name></author>
	</entry>
	<entry>
		<id>https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=400</id>
		<title>Tutorial gomoku</title>
		<link rel="alternate" type="text/html" href="https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=400"/>
		<updated>2012-12-06T22:19:30Z</updated>

		<summary type="html">&lt;p&gt;Een: &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;emtpy 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/gomoku/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;
* 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. 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 ${coordinates}&#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;coordinates&#039; =&amp;gt; $this-&amp;gt;getFormattedCoordinates($coord_x, $coord_y),&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;, 1000 );&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;
        			dojo.style( &#039;stone_&#039; + notif.args.coord_x + &#039;_&#039; + notif.args.coord_y, &#039;zIndex&#039;, &#039;auto&#039; );&lt;br /&gt;
       		}));&lt;br /&gt;
            slide.play();&lt;br /&gt;
           &lt;br /&gt;
            // This intersection is taken, it shouldn&#039;t appear as clickable anymore&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;
&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_stone {&lt;br /&gt;
	width: 30px;&lt;br /&gt;
	height: 30px;&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    background-image: url( &#039;../../img/gomoku/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;
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(): &lt;br /&gt;
&lt;br /&gt;
* 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;
* and 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;
* we 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, notify it to update the score on 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>Een</name></author>
	</entry>
	<entry>
		<id>https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=399</id>
		<title>Tutorial gomoku</title>
		<link rel="alternate" type="text/html" href="https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=399"/>
		<updated>2012-12-06T22:17:16Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Setup the backbone of your game */&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;emtpy 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/gomoku/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 gomoku.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 gomoku.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 gomoku.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 gomoku.game.php-&amp;gt;getAllDatas() is now available in your gomoku.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 gomoku.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 gomoku.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 gomoku.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 gomoku.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;
* 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. 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 gomoku.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 gomoku.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 gomoku.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 gomoku.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 gomoku.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 ${coordinates}&#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;coordinates&#039; =&amp;gt; $this-&amp;gt;getFormattedCoordinates($coord_x, $coord_y),&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 gomoku.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;, 1000 );&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;
        			dojo.style( &#039;stone_&#039; + notif.args.coord_x + &#039;_&#039; + notif.args.coord_y, &#039;zIndex&#039;, &#039;auto&#039; );&lt;br /&gt;
       		}));&lt;br /&gt;
            slide.play();&lt;br /&gt;
           &lt;br /&gt;
            // This intersection is taken, it shouldn&#039;t appear as clickable anymore&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;
&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_stone {&lt;br /&gt;
	width: 30px;&lt;br /&gt;
	height: 30px;&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    background-image: url( &#039;../../img/gomoku/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 gomoku.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;
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 gomoku.game.php-&amp;gt;setupNewGame(): &lt;br /&gt;
&lt;br /&gt;
* 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;
* and 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 gomoku.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 gomoku.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;
* we init that global variable to 0 in gomoku.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 gomoku.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, notify it to update the score on 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 gomoku.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>Een</name></author>
	</entry>
	<entry>
		<id>https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=398</id>
		<title>Tutorial gomoku</title>
		<link rel="alternate" type="text/html" href="https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=398"/>
		<updated>2012-12-06T22:16:01Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Setup the board */&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;emtpy 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/gomoku/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 gomoku.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 gomoku.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 (jstpl_intersection).&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 gomoku.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 gomoku.game.php-&amp;gt;getAllDatas() is now available in your gomoku.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 gomoku.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 gomoku.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 gomoku.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 gomoku.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;
* 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. 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 gomoku.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 gomoku.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 gomoku.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 gomoku.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 gomoku.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 ${coordinates}&#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;coordinates&#039; =&amp;gt; $this-&amp;gt;getFormattedCoordinates($coord_x, $coord_y),&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 gomoku.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;, 1000 );&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;
        			dojo.style( &#039;stone_&#039; + notif.args.coord_x + &#039;_&#039; + notif.args.coord_y, &#039;zIndex&#039;, &#039;auto&#039; );&lt;br /&gt;
       		}));&lt;br /&gt;
            slide.play();&lt;br /&gt;
           &lt;br /&gt;
            // This intersection is taken, it shouldn&#039;t appear as clickable anymore&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;
&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_stone {&lt;br /&gt;
	width: 30px;&lt;br /&gt;
	height: 30px;&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    background-image: url( &#039;../../img/gomoku/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 gomoku.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;
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 gomoku.game.php-&amp;gt;setupNewGame(): &lt;br /&gt;
&lt;br /&gt;
* 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;
* and 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 gomoku.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 gomoku.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;
* we init that global variable to 0 in gomoku.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 gomoku.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, notify it to update the score on 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 gomoku.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>Een</name></author>
	</entry>
	<entry>
		<id>https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=397</id>
		<title>Tutorial gomoku</title>
		<link rel="alternate" type="text/html" href="https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=397"/>
		<updated>2012-12-06T22:15:10Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Manage states and events */&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;emtpy 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.&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/gomoku/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 gomoku.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 gomoku.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 (jstpl_intersection).&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 gomoku.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 gomoku.game.php-&amp;gt;getAllDatas() is now available in your gomoku.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 gomoku.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 gomoku.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 gomoku.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 gomoku.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;
* 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. 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 gomoku.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 gomoku.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 gomoku.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 gomoku.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 gomoku.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 ${coordinates}&#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;coordinates&#039; =&amp;gt; $this-&amp;gt;getFormattedCoordinates($coord_x, $coord_y),&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 gomoku.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;, 1000 );&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;
        			dojo.style( &#039;stone_&#039; + notif.args.coord_x + &#039;_&#039; + notif.args.coord_y, &#039;zIndex&#039;, &#039;auto&#039; );&lt;br /&gt;
       		}));&lt;br /&gt;
            slide.play();&lt;br /&gt;
           &lt;br /&gt;
            // This intersection is taken, it shouldn&#039;t appear as clickable anymore&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;
&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_stone {&lt;br /&gt;
	width: 30px;&lt;br /&gt;
	height: 30px;&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    background-image: url( &#039;../../img/gomoku/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 gomoku.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;
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 gomoku.game.php-&amp;gt;setupNewGame(): &lt;br /&gt;
&lt;br /&gt;
* 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;
* and 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 gomoku.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 gomoku.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;
* we init that global variable to 0 in gomoku.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 gomoku.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, notify it to update the score on 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 gomoku.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>Een</name></author>
	</entry>
	<entry>
		<id>https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=396</id>
		<title>Tutorial gomoku</title>
		<link rel="alternate" type="text/html" href="https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=396"/>
		<updated>2012-12-06T22:12:25Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Implement rules and end of game conditions */&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;emtpy 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.&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/gomoku/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 gomoku.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 gomoku.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 (jstpl_intersection).&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 gomoku.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 gomoku.game.php-&amp;gt;getAllDatas() is now available in your gomoku.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 gomoku.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 gomoku.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 gomoku.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 gomoku.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;
* 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. 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;
Add onclick events on intersections in gomoku.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 gomoku.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 gomoku.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 gomoku.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 ${coordinates}&#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;coordinates&#039; =&amp;gt; $this-&amp;gt;getFormattedCoordinates($coord_x, $coord_y),&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 gomoku.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;, 1000 );&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;
        			dojo.style( &#039;stone_&#039; + notif.args.coord_x + &#039;_&#039; + notif.args.coord_y, &#039;zIndex&#039;, &#039;auto&#039; );&lt;br /&gt;
       		}));&lt;br /&gt;
            slide.play();&lt;br /&gt;
           &lt;br /&gt;
            // This intersection is taken, it shouldn&#039;t appear as clickable anymore&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;
&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_stone {&lt;br /&gt;
	width: 30px;&lt;br /&gt;
	height: 30px;&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    background-image: url( &#039;../../img/gomoku/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 gomoku.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;
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 gomoku.game.php-&amp;gt;setupNewGame(): &lt;br /&gt;
&lt;br /&gt;
* 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;
* and 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 gomoku.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 gomoku.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;
* we init that global variable to 0 in gomoku.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 gomoku.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, notify it to update the score on 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 gomoku.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>Een</name></author>
	</entry>
	<entry>
		<id>https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=395</id>
		<title>Tutorial gomoku</title>
		<link rel="alternate" type="text/html" href="https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=395"/>
		<updated>2012-12-06T22:10:32Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Implement rules and end of game conditions */&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;emtpy 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.&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/gomoku/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 gomoku.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 gomoku.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 (jstpl_intersection).&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 gomoku.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 gomoku.game.php-&amp;gt;getAllDatas() is now available in your gomoku.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 gomoku.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 gomoku.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 gomoku.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 gomoku.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;
* 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. 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;
Add onclick events on intersections in gomoku.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 gomoku.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 gomoku.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 gomoku.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 ${coordinates}&#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;coordinates&#039; =&amp;gt; $this-&amp;gt;getFormattedCoordinates($coord_x, $coord_y),&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 gomoku.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;, 1000 );&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;
        			dojo.style( &#039;stone_&#039; + notif.args.coord_x + &#039;_&#039; + notif.args.coord_y, &#039;zIndex&#039;, &#039;auto&#039; );&lt;br /&gt;
       		}));&lt;br /&gt;
            slide.play();&lt;br /&gt;
           &lt;br /&gt;
            // This intersection is taken, it shouldn&#039;t appear as clickable anymore&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;
&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_stone {&lt;br /&gt;
	width: 30px;&lt;br /&gt;
	height: 30px;&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    background-image: url( &#039;../../img/gomoku/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 gomoku.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;
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 gomoku.game.php-&amp;gt;setupNewGame(): &lt;br /&gt;
&lt;br /&gt;
* 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;
* and 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 gomoku.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;
* we declare a global &#039;end_of_game&#039; variable in gomoku.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;
* we init that global variable to 0 in gomoku.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;
* we add the appropriate code in gomoku.game.php before proceeding to the next state, using a checkForWin() function that we implement separately for clarity. If the game has been won, we set the score, notify it to update the score on 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, you 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;
* We catch the score notification on the client side in gomoku.js-&amp;gt;setupNotifications() and we 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;
* We implement the function declared to handle the notification.&lt;br /&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;
&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>Een</name></author>
	</entry>
	<entry>
		<id>https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=394</id>
		<title>Tutorial gomoku</title>
		<link rel="alternate" type="text/html" href="https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=394"/>
		<updated>2012-12-06T22:09:13Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Implement rules and end of game conditions */&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;emtpy 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.&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/gomoku/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 gomoku.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 gomoku.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 (jstpl_intersection).&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 gomoku.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 gomoku.game.php-&amp;gt;getAllDatas() is now available in your gomoku.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 gomoku.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 gomoku.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 gomoku.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 gomoku.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;
* 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. 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;
Add onclick events on intersections in gomoku.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 gomoku.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 gomoku.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 gomoku.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 ${coordinates}&#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;coordinates&#039; =&amp;gt; $this-&amp;gt;getFormattedCoordinates($coord_x, $coord_y),&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 gomoku.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;, 1000 );&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;
        			dojo.style( &#039;stone_&#039; + notif.args.coord_x + &#039;_&#039; + notif.args.coord_y, &#039;zIndex&#039;, &#039;auto&#039; );&lt;br /&gt;
       		}));&lt;br /&gt;
            slide.play();&lt;br /&gt;
           &lt;br /&gt;
            // This intersection is taken, it shouldn&#039;t appear as clickable anymore&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;
&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_stone {&lt;br /&gt;
	width: 30px;&lt;br /&gt;
	height: 30px;&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    background-image: url( &#039;../../img/gomoku/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 gomoku.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;
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 gomoku.game.php-&amp;gt;setupNewGame(): &lt;br /&gt;
&lt;br /&gt;
* 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;
* and 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 gomoku.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;
* we declare a global &#039;end_of_game&#039; variable in gomoku.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;
* we init that global variable to 0 in gomoku.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;
* we add the appropriate code in gomoku.game.php before proceeding to the next state, using a checkForWin() function that we implement separately for clarity. If the game has been won, we set the score, notify it to update the score on 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() which is called when your state machine goes to the &#039;checkEndOfGame&#039; state, you check for this variable and for other &#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;
* We catch the score notification on the client side in gomoku.js-&amp;gt;setupNotifications() and we 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;
* We implement the function declared to handle the notification.&lt;br /&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;
&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>Een</name></author>
	</entry>
	<entry>
		<id>https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=393</id>
		<title>Tutorial gomoku</title>
		<link rel="alternate" type="text/html" href="https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=393"/>
		<updated>2012-12-06T22:07:37Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Implement rules and end of game conditions */&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;emtpy 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.&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/gomoku/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 gomoku.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 gomoku.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 (jstpl_intersection).&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 gomoku.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 gomoku.game.php-&amp;gt;getAllDatas() is now available in your gomoku.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 gomoku.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 gomoku.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 gomoku.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 gomoku.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;
* 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. 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;
Add onclick events on intersections in gomoku.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 gomoku.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 gomoku.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 gomoku.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 ${coordinates}&#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;coordinates&#039; =&amp;gt; $this-&amp;gt;getFormattedCoordinates($coord_x, $coord_y),&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 gomoku.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;, 1000 );&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;
        			dojo.style( &#039;stone_&#039; + notif.args.coord_x + &#039;_&#039; + notif.args.coord_y, &#039;zIndex&#039;, &#039;auto&#039; );&lt;br /&gt;
       		}));&lt;br /&gt;
            slide.play();&lt;br /&gt;
           &lt;br /&gt;
            // This intersection is taken, it shouldn&#039;t appear as clickable anymore&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;
&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_stone {&lt;br /&gt;
	width: 30px;&lt;br /&gt;
	height: 30px;&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    background-image: url( &#039;../../img/gomoku/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 gomoku.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;
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 gomoku.game.php-&amp;gt;setupNewGame(): &lt;br /&gt;
&lt;br /&gt;
* 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;
* and 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 gomoku.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 in gomoku.game.php-&amp;gt;stCheckEndOfGame()&lt;br /&gt;
&lt;br /&gt;
* It is easier to check for a win directly after setting the stone, so: &lt;br /&gt;
** we declare a global &#039;end_of_game&#039; variable in gomoku.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;
** we init that global variable to 0 in gomoku.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;
** we add the appropriate code in gomoku.game.php before proceeding to the next state, using a checkForWin() function that we implement separately for clarity. If the game has been won, we set the score, notify it to update the score on 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() which is called when your state machine goes to the &#039;checkEndOfGame&#039; state, you check for this variable and for other &#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;
* We catch the score notification on the client side in gomoku.js-&amp;gt;setupNotifications() and we 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;
* We implement the function declared to handle the notification.&lt;br /&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;
&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>Een</name></author>
	</entry>
	<entry>
		<id>https://hu.doc.boardgamearena.com/index.php?title=Studio_function_reference&amp;diff=392</id>
		<title>Studio function reference</title>
		<link rel="alternate" type="text/html" href="https://hu.doc.boardgamearena.com/index.php?title=Studio_function_reference&amp;diff=392"/>
		<updated>2012-12-06T22:06:45Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Client side (Javascript functions) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page references useful server side and client side functions (and some interesting class variables), so that nobody needs to reinvent the wheel (unless he wants to).&lt;br /&gt;
&lt;br /&gt;
This list is not exhaustive, in particular functions already well described by comments in the &#039;EmptyGame&#039; game template may not be described again below.&lt;br /&gt;
&lt;br /&gt;
== Server side (PHP functions) ==&lt;br /&gt;
&lt;br /&gt;
=== APP_GameAction class (&amp;lt;gamename&amp;gt;.action.php) ===&lt;br /&gt;
&lt;br /&gt;
; function isArg( $argName )&lt;br /&gt;
: Is this argument filled ?&lt;br /&gt;
; function getArg( $argName, $argType, $mandatory=false, $default=NULL, $argTypeDetails=array(), $bCanFail=false  )&lt;br /&gt;
: Get script argument with the correct type&lt;br /&gt;
: bCanFail means than a validation failure is possible (user input)&lt;br /&gt;
: The main argType values are as follows.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
define( &#039;AT_int&#039;, 0 );        //  an integer&lt;br /&gt;
define( &#039;AT_posint&#039;, 1 );     //  a positive integer &lt;br /&gt;
define( &#039;AT_float&#039;, 2 );      //  a float&lt;br /&gt;
define( &#039;AT_email&#039;, 3 );      //  an email  &lt;br /&gt;
define( &#039;AT_url&#039;, 4 );        //  a URL&lt;br /&gt;
define( &#039;AT_bool&#039;, 5 );       //  1/0/true/false&lt;br /&gt;
define( &#039;AT_enum&#039;, 6 );       //  argTypeDetails list the possible values&lt;br /&gt;
define( &#039;AT_alphanum&#039;, 7 );   //  only 0-9a-zA-Z_ and space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Table class (&amp;lt;gamename&amp;gt;.game.php) ===&lt;br /&gt;
&lt;br /&gt;
; function _( $text )&lt;br /&gt;
: Transparent function, used to mark strings to be translated on the server side (ex: error message)&lt;br /&gt;
; function clienttranslate( $string )&lt;br /&gt;
: Transparent function: used to mark string to be translated on client side (ex: notification message)&lt;br /&gt;
; function getPlayersNumber()&lt;br /&gt;
: Returns the number of players playing at the table&lt;br /&gt;
; function checkAction( $actionName, $bThrowException=true )&lt;br /&gt;
: Check if action is valid regarding current game state (exception if fails)&lt;br /&gt;
: if &amp;quot;bThrowException&amp;quot; is set to &amp;quot;false&amp;quot;, the function return false in case of failure instead of throwing and exception&lt;br /&gt;
; function getActivePlayerId()&lt;br /&gt;
: Get the &amp;quot;active_player&amp;quot;, whatever what is the current state type&lt;br /&gt;
: Note: it does NOT mean that this player is active right now, because state type could be &amp;quot;game&amp;quot; or &amp;quot;multiplayer&amp;quot;&lt;br /&gt;
; function getActivePlayerName()&lt;br /&gt;
: Get the &amp;quot;active_player&amp;quot; name&lt;br /&gt;
; function getCurrentPlayerId()&lt;br /&gt;
: Get the &amp;quot;current_player&amp;quot;. The current player is the one from which the action originated. It is not always the active player.&lt;br /&gt;
; function getCurrentPlayerName()&lt;br /&gt;
: Get the &amp;quot;current_player&amp;quot; name&lt;br /&gt;
; function getCurrentPlayerColor()&lt;br /&gt;
: Get the &amp;quot;current_player&amp;quot; color&lt;br /&gt;
; function isCurrentPlayerZombie()&lt;br /&gt;
: Check the &amp;quot;current_player&amp;quot; zombie status&lt;br /&gt;
; function activeNextPlayer()&lt;br /&gt;
: Make the next player active&lt;br /&gt;
; function activePrevPlayer()&lt;br /&gt;
: Make the previous player active&lt;br /&gt;
; function giveExtraTime( $player_id, $specific_time=null )&lt;br /&gt;
: Give standard extra time to this player (standard extra time is a game option)&lt;br /&gt;
; function initStat( $table_or_player, $name, $value, $player_id=null )&lt;br /&gt;
: Create a statistic entry for the specified statistics with a default value&lt;br /&gt;
: In case of a &amp;quot;player&amp;quot; entry, if player_id is not specified, all players are set to the same value&lt;br /&gt;
; function setStat( $value, $name, $player_id = null )&lt;br /&gt;
: Set statistic value&lt;br /&gt;
; function incStat( $delta, $name, $player_id = null )&lt;br /&gt;
: Increment (or decrement) specified value&lt;br /&gt;
; function DbQuery( $sql )&lt;br /&gt;
: Executes sql query on the database&lt;br /&gt;
; function getCollectionFromDB( $sql, $bSingleValue=false )&lt;br /&gt;
: Returns an associative array of rows for the sql query. First column must be a primary or alternate key. The resulting collection can be empty.&lt;br /&gt;
; protected function getNonEmptyCollectionFromDB( $sql )&lt;br /&gt;
: Idem, but raise an exception if the collection is empty&lt;br /&gt;
; function getUniqueValueFromDB( $sql )&lt;br /&gt;
: Returns a unique value from DB or null if no value is found&lt;br /&gt;
: Raise an exception if more than 1 row is returned&lt;br /&gt;
; function getObjectFromDB( $sql )&lt;br /&gt;
: Returns one row for the sql query as an associative array or null if there is no result&lt;br /&gt;
: Raise an exception if the query return more than one row&lt;br /&gt;
; function getNonEmptyObjectFromDB( $sql )&lt;br /&gt;
: Idem, but raise an exception if the query doesn&#039;t return exactly one row&lt;br /&gt;
&lt;br /&gt;
=== Exceptions you can throw ===&lt;br /&gt;
&lt;br /&gt;
; throw new BgaUserException ( $error_message)&lt;br /&gt;
: Base class to notify a user error&lt;br /&gt;
; throw new BgaSystemException ( $error_message)&lt;br /&gt;
: Base class to notify a system exception. The message will be hidden from the user, but show in the logs. Use this if the message contains technical information.&lt;br /&gt;
; throw new BgaSystemVisibleException ( $error_message)&lt;br /&gt;
: Same as previous, except that the message is visible by the user. You can use this if the message is understandable by the user.&lt;br /&gt;
&lt;br /&gt;
== Client side (Javascript functions) ==&lt;br /&gt;
&lt;br /&gt;
; this.player_id&lt;br /&gt;
: Id of the player on whose browser the code is running.&lt;br /&gt;
&lt;br /&gt;
; this.isSpectator&lt;br /&gt;
: Flag set to true if the user at the table is a spectator (not a player).&lt;br /&gt;
&lt;br /&gt;
; this.gamedatas&lt;br /&gt;
: Contains your initial set of datas to init the game, created at game start or game refresh (F5)&lt;br /&gt;
: You can update it as needed to keep an up to date reference of the game on the client side.&lt;br /&gt;
&lt;br /&gt;
; slideToObject: function( mobile_obj, target_obj, duration, delay )&lt;br /&gt;
: Return an dojo.fx animation that is sliding a DOM object from its current position over another one&lt;br /&gt;
: Animate a slide of the DOM object referred to by domNodeToSlide from its current position to the xpos, ypos relative to the object referred to by domNodeToSlideTo.&lt;br /&gt;
&lt;br /&gt;
; slideToObjectPos: function( mobile_obj, target_obj, target_x, target_y, duration, delay )&lt;br /&gt;
: Return an dojo.fx animation that is sliding a DOM object from its current position over another one at the given coordinates relative to the target object.&lt;br /&gt;
&lt;br /&gt;
; updateCounters(counters)&lt;br /&gt;
: Useful for updating game counters in the player panel (such as resources). &lt;br /&gt;
: &#039;counters&#039; arg is an associative array [counter_name_value =&amp;gt; [ &#039;counter_name&#039; =&amp;gt; counter_name_value, &#039;counter_value&#039; =&amp;gt; counter_value_value], ... ]&lt;br /&gt;
: All counters must be referenced in this.gamedatas.counters and will be updated.&lt;br /&gt;
: DOM objects referenced by &#039;counter_name&#039; will have their innerHTML updated with &#039;counter_value&#039;.&lt;br /&gt;
&lt;br /&gt;
; addTooltip( node, _( helpString ), _( actionString ), delay );&lt;br /&gt;
: Add a simple text tooltip to the DOM node. Only one of &#039;helpString&#039; or &#039;actionString&#039; must be used. _() must be used for the text to be marked for translation.&lt;br /&gt;
&lt;br /&gt;
; addTooltipHtml( node, html, delay );&lt;br /&gt;
: Add an HTML tooltip to the DOM node (for more elaborate content such as presenting a bigger version of a card).&lt;br /&gt;
&lt;br /&gt;
; addTooltipToClass( cssClass, _( helpString ), _( actionString ), delay );&lt;br /&gt;
: Add a simple text tooltip to all the DOM nodes set with this cssClass. Only one of &#039;helpString&#039; or &#039;actionString&#039; must be used. _() must be used for the text to be marked for translation.&lt;br /&gt;
: NB: all concerned nodes must have IDs to get tooltips&lt;br /&gt;
&lt;br /&gt;
; addTooltipHtmlToClass( cssClass, html, delay );&lt;br /&gt;
: Add an HTML tooltip to to all the DOM nodes set with this cssClass (for more elaborate content such as presenting a bigger version of a card).&lt;br /&gt;
: NB: all concerned nodes must have IDs to get tooltips&lt;br /&gt;
&lt;br /&gt;
; addEventToClass: function( cssClassName, eventName, functionName )&lt;br /&gt;
: Same as dojo.connect(), but for all the nodes set with the specified cssClassName&lt;br /&gt;
&lt;br /&gt;
; addStyleToClass: function( cssClassName, cssProperty, propertyValue )&lt;br /&gt;
: Same as dojo.style(), but for all the nodes set with the specified cssClassName&lt;br /&gt;
&lt;br /&gt;
; isCurrentPlayerActive()&lt;br /&gt;
: Returns true if the player on whose browser the code is running is currently active (it&#039;s his turn to play)&lt;br /&gt;
&lt;br /&gt;
; checkAction: function( action, nomessage )&lt;br /&gt;
: Check if player can do the specified action by taking into account:  _ current game state &amp;amp; _ interface locking&lt;br /&gt;
: return true if action is authorized&lt;br /&gt;
: return false and display an error message if not (display no message if nomessage is specified)&lt;br /&gt;
&lt;br /&gt;
; showMessage: function( msg, type )&lt;br /&gt;
: Show an information message during a few seconds at the top of the page&lt;br /&gt;
: Type can be &#039;error&#039; or &#039;info&#039;&lt;br /&gt;
&lt;br /&gt;
; this.scoreCtrl[ player_id ].incValue( score_delta );&lt;br /&gt;
: Adds score_delta (positive or negative integer) to the current score value for player&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://hu.doc.boardgamearena.com/index.php?title=Studio_back-office&amp;diff=391</id>
		<title>Studio back-office</title>
		<link rel="alternate" type="text/html" href="https://hu.doc.boardgamearena.com/index.php?title=Studio_back-office&amp;diff=391"/>
		<updated>2012-12-06T21:43:49Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Sources */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;You will find the URL to the Studio back-office in the &#039;resources.html&#039; file at the root of your SFTP access.&lt;br /&gt;
&lt;br /&gt;
Here is a list and description of the links and functions in this back-office.&lt;br /&gt;
&lt;br /&gt;
Click on a menu to display its content.&lt;br /&gt;
&lt;br /&gt;
=== Documentation ===&lt;br /&gt;
&lt;br /&gt;
Contains links to this wiki, the development forum and the bugs forum.&lt;br /&gt;
&lt;br /&gt;
=== Database ===&lt;br /&gt;
&lt;br /&gt;
Contains a link to the Studio database administration tool (PHPMyAdmin).&lt;br /&gt;
&lt;br /&gt;
Your login / password for this tool is the same as for your SFTP access.&lt;br /&gt;
&lt;br /&gt;
=== Sources ===&lt;br /&gt;
&lt;br /&gt;
Contains a form for committing your sources to the BGA repository.&lt;br /&gt;
* Game name field should contain the name of your game (lower case, no space). Ex: puertorico&lt;br /&gt;
* Comment field should contain your commit comment describing changes to the code since your last commit.&lt;br /&gt;
&lt;br /&gt;
You should commit from time to time when you hit some landmarks in your development. This is an extra assurance not to lose your code, and to have the possibility (by asking BGA administrators) to get a previous version of your code if you need to backtrack.&lt;br /&gt;
&lt;br /&gt;
=== Logs ===&lt;br /&gt;
&lt;br /&gt;
Gives you a web based access to the studio server logs.&lt;br /&gt;
&lt;br /&gt;
; Current table error log&lt;br /&gt;
: main log of interest to you while developing, it contains the error happening at the table you are currently playing at.&lt;br /&gt;
; Current table request logs&lt;br /&gt;
: this log traces all the actions happening at the table you are currently playing at.&lt;br /&gt;
; Javascript error log&lt;br /&gt;
: this log traces all the Javascript errors happening on the client side. Errors are also briefly displayed in your browser, but in this log it&#039;s better formatted and you can look a it quietly.&lt;br /&gt;
; Gameserver error log&lt;br /&gt;
: this log traces all errors happening on the gameserver. It should mainly be useful if your game setup crashes (ie before your table is ready, so before errors are collected in the current table error log), for example if there is a syntax error in your &#039;dbmodel.sql&#039; file.&lt;br /&gt;
; HTTP error log&lt;br /&gt;
: this log traces the web server errors. This is useful to look at PHP syntax errors and warnings. &lt;br /&gt;
&lt;br /&gt;
Please note that the three last logs are common to all games being developed on the platform, so there may be some noise in the data you are interested in.&lt;br /&gt;
&lt;br /&gt;
You can open the log links in a different tab and just hit F5 when you need to refresh. The URL you will get for the new tab has a &amp;quot;?n=100&amp;quot; parameter that gives the number of lines to display: you can modify it in the URL if you need more.&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://hu.doc.boardgamearena.com/index.php?title=Studio_FAQ&amp;diff=390</id>
		<title>Studio FAQ</title>
		<link rel="alternate" type="text/html" href="https://hu.doc.boardgamearena.com/index.php?title=Studio_FAQ&amp;diff=390"/>
		<updated>2012-12-06T21:43:08Z</updated>

		<summary type="html">&lt;p&gt;Een: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a place where we will collect and answer frequently asked questions.&lt;br /&gt;
&lt;br /&gt;
== What should I use to access the files through SFTP? ==&lt;br /&gt;
&lt;br /&gt;
There is a lot of tools to do that. Use the one you are the most comfortable with.&lt;br /&gt;
&lt;br /&gt;
On Linux, you can for example use the &#039;Connect to server&#039; function of the Nautilus file management system, or use sshfs.&lt;br /&gt;
&lt;br /&gt;
On Windows, there is for example the WinSCP client.&lt;br /&gt;
&lt;br /&gt;
== I can&#039;t access the Studio back-office, I get a &#039;Not authorized&#039; error message? ==&lt;br /&gt;
&lt;br /&gt;
You should first connect to the Studio website (with any of your &amp;lt;developer name&amp;gt;&amp;lt;number&amp;gt; accounts). As the authentication is shared with the back-office, then you will be able to access it.&lt;br /&gt;
&lt;br /&gt;
== I don&#039;t know the name to use to commit my game, what name should I use? ==&lt;br /&gt;
&lt;br /&gt;
The game name for committing is the name of the game in lower case and without spaces or special characters (ex: puertorico).&lt;br /&gt;
It is the same name as the name used for the game folder in your SFTP access.&lt;br /&gt;
&lt;br /&gt;
== It&#039;s pretty annoying to log in with multiple users to start a game. Is there some easier way? ==&lt;br /&gt;
&lt;br /&gt;
You can use the &#039;Express start&#039; function. It will automatically make the specified number of players join the game (using the first of your ten player accounts available) and start the game.&lt;br /&gt;
&lt;br /&gt;
During the game, there is a red arrow on the right of each player name, that you can use to open a tab from this player&#039;s perspective.&lt;br /&gt;
&lt;br /&gt;
You can also end the game in two clicks by clicking the &#039;End game&#039; button then selecting &#039;Express game stop&#039; in the popup.&lt;br /&gt;
&lt;br /&gt;
== What is the working language on BGA studio? ==&lt;br /&gt;
&lt;br /&gt;
Working language is &#039;&#039;&#039;English&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Variables and functions must be named with English words.&lt;br /&gt;
&lt;br /&gt;
Comments must be written in English.&lt;br /&gt;
&lt;br /&gt;
Game interface strings and game logs must be written in English.&lt;br /&gt;
&lt;br /&gt;
== How can I provide translation in my language? == &lt;br /&gt;
&lt;br /&gt;
BGA administrators will translate the game in French before the game release.&lt;br /&gt;
&lt;br /&gt;
After the game release, the collaborative translation interface can be used to translate into other languages.&lt;br /&gt;
&lt;br /&gt;
== Is there a special way to declare the strings that must be translated? == &lt;br /&gt;
&lt;br /&gt;
Yes. This declaration is made through transparent functions, that depend on the context.&lt;br /&gt;
&lt;br /&gt;
In javascript files, you should use _( &#039;My string to translate&#039; ).&lt;br /&gt;
&lt;br /&gt;
In php files, you should use self::_( &#039;My string to translate&#039; ) when the string can be translated on the server side (ex: title included in the game layout) and clienttranslate( &#039;My string to translate&#039; ) when the string must be translated on the client side (ex: message for the game log).&lt;br /&gt;
&lt;br /&gt;
== I updated the images in the &#039;img&#039; folder of my game, but they don&#039;t show? ==&lt;br /&gt;
&lt;br /&gt;
On BGA Studio, there is the gameserver you are developing on, and the main site server that is used to launch the games. The game icon, box and the publisher logo are hosted on the main site server, so they are not immediately available when you modify them on the gameserver. To deploy them on the main site, you have to use the [[Studio back-office]] to do a commit.&lt;br /&gt;
&lt;br /&gt;
If the images still don&#039;t show after that, please try emptying your browser cache and reloading the page.&lt;br /&gt;
&lt;br /&gt;
== I added some game options / some game statistics, but they don&#039;t show? ==&lt;br /&gt;
&lt;br /&gt;
An extra deployment action from the BGA administrators is needed to activate new game options and statistics. Please contact us.&lt;br /&gt;
&lt;br /&gt;
== Is there a quick way to access the database for my current table? ==&lt;br /&gt;
&lt;br /&gt;
Yes! While playing a game on studio, you have a &amp;quot;Go to game database&amp;quot; link at the bottom of your game. This link will bring you directly to the database for the current table.&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=377</id>
		<title>Tutorial gomoku</title>
		<link rel="alternate" type="text/html" href="https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=377"/>
		<updated>2012-12-05T23:06:25Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Implement rules and end of game conditions */&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;emtpy 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.&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/gomoku/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 gomoku.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 gomoku.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 (jstpl_intersection).&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 gomoku.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 gomoku.game.php-&amp;gt;getAllDatas() is now available in your gomoku.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 gomoku.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 gomoku.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 gomoku.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 gomoku.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;
* 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. 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;
Add onclick events on intersections in gomoku.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 gomoku.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 gomoku.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 gomoku.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 ${coordinates}&#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;coordinates&#039; =&amp;gt; $this-&amp;gt;getFormattedCoordinates($coord_x, $coord_y),&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 gomoku.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;, 1000 );&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;
        			dojo.style( &#039;stone_&#039; + notif.args.coord_x + &#039;_&#039; + notif.args.coord_y, &#039;zIndex&#039;, &#039;auto&#039; );&lt;br /&gt;
       		}));&lt;br /&gt;
            slide.play();&lt;br /&gt;
           &lt;br /&gt;
            // This intersection is taken, it shouldn&#039;t appear as clickable anymore&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;
&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_stone {&lt;br /&gt;
	width: 30px;&lt;br /&gt;
	height: 30px;&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    background-image: url( &#039;../../img/gomoku/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 gomoku.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;
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 gomoku.game.php-&amp;gt;setupNewGame(): &lt;br /&gt;
&lt;br /&gt;
* 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;
* and 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 gomoku.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 in .game.php-&amp;gt;stCheckEndOfGame()&lt;br /&gt;
&lt;br /&gt;
Notify the score and implement the corresponding interface update in .js&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>Een</name></author>
	</entry>
	<entry>
		<id>https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=375</id>
		<title>Tutorial gomoku</title>
		<link rel="alternate" type="text/html" href="https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=375"/>
		<updated>2012-12-05T22:55:18Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Manage states and events */&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;emtpy 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.&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/gomoku/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 gomoku.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 gomoku.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 (jstpl_intersection).&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 gomoku.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 gomoku.game.php-&amp;gt;getAllDatas() is now available in your gomoku.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 gomoku.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 gomoku.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 gomoku.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 gomoku.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;
* 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. 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;
Add onclick events on intersections in gomoku.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 gomoku.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 gomoku.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 gomoku.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 ${coordinates}&#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;coordinates&#039; =&amp;gt; $this-&amp;gt;getFormattedCoordinates($coord_x, $coord_y),&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 gomoku.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;, 1000 );&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;
        			dojo.style( &#039;stone_&#039; + notif.args.coord_x + &#039;_&#039; + notif.args.coord_y, &#039;zIndex&#039;, &#039;auto&#039; );&lt;br /&gt;
       		}));&lt;br /&gt;
            slide.play();&lt;br /&gt;
           &lt;br /&gt;
            // This intersection is taken, it shouldn&#039;t appear as clickable anymore&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;
&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_stone {&lt;br /&gt;
	width: 30px;&lt;br /&gt;
	height: 30px;&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    background-image: url( &#039;../../img/gomoku/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 gomoku.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;
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 (if any)&lt;br /&gt;
&lt;br /&gt;
  Nothing special for Gomoku&lt;br /&gt;
&lt;br /&gt;
Implement rule for computing game progression in .game.php-&amp;gt;getGameProgression()&lt;br /&gt;
&lt;br /&gt;
Implement end of game detection and update the score according to who is the winner in .game.php-&amp;gt;stCheckEndOfGame()&lt;br /&gt;
&lt;br /&gt;
Notify the score and implement the corresponding interface update in .js&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>Een</name></author>
	</entry>
	<entry>
		<id>https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=374</id>
		<title>Tutorial gomoku</title>
		<link rel="alternate" type="text/html" href="https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=374"/>
		<updated>2012-12-05T22:48:00Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Manage states and events */&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;emtpy 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.&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/gomoku/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 gomoku.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 gomoku.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 (jstpl_intersection).&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 gomoku.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 gomoku.game.php-&amp;gt;getAllDatas() is now available in your gomoku.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 gomoku.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 gomoku.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 gomoku.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 gomoku.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;
* 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. 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;
Add onclick events on intersections in gomoku.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 gomoku.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 gomoku.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 gomoku.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 ${coordinates}&#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;coordinates&#039; =&amp;gt; $this-&amp;gt;getFormattedCoordinates($coord_x, $coord_y),&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 gomoku.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;, 1000 );&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;
        			dojo.style( &#039;stone_&#039; + notif.args.coord_x + &#039;_&#039; + notif.args.coord_y, &#039;zIndex&#039;, &#039;auto&#039; );&lt;br /&gt;
       		}));&lt;br /&gt;
            slide.play();&lt;br /&gt;
           &lt;br /&gt;
            // This intersection is taken, it shouldn&#039;t appear as clickable anymore&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;
&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_stone {&lt;br /&gt;
	width: 30px;&lt;br /&gt;
	height: 30px;&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    background-image: url( &#039;../../img/gomoku/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 (we will use the red circle later on):&lt;br /&gt;
&lt;br /&gt;
[[File:Gomoku stones.png]]&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 (if any)&lt;br /&gt;
&lt;br /&gt;
  Nothing special for Gomoku&lt;br /&gt;
&lt;br /&gt;
Implement rule for computing game progression in .game.php-&amp;gt;getGameProgression()&lt;br /&gt;
&lt;br /&gt;
Implement end of game detection and update the score according to who is the winner in .game.php-&amp;gt;stCheckEndOfGame()&lt;br /&gt;
&lt;br /&gt;
Notify the score and implement the corresponding interface update in .js&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>Een</name></author>
	</entry>
	<entry>
		<id>https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=373</id>
		<title>Tutorial gomoku</title>
		<link rel="alternate" type="text/html" href="https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=373"/>
		<updated>2012-12-05T22:45:13Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Manage states and events */&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;emtpy 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.&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/gomoku/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 gomoku.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 gomoku.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 (jstpl_intersection).&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 gomoku.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 gomoku.game.php-&amp;gt;getAllDatas() is now available in your gomoku.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 gomoku.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 gomoku.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 gomoku.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 gomoku.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;
* 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. 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;
Add onclick events on intersections in gomoku.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 gomoku.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 gomoku.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 gomoku.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 ${coordinates}&#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;coordinates&#039; =&amp;gt; $this-&amp;gt;getFormattedCoordinates($coord_x, $coord_y),&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 gomoku.js-&amp;gt;setupNotifications() and link it to a javascript function to execute&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;, 1000 );&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;
        			dojo.style( &#039;stone_&#039; + notif.args.coord_x + &#039;_&#039; + notif.args.coord_y, &#039;zIndex&#039;, &#039;auto&#039; );&lt;br /&gt;
       		}));&lt;br /&gt;
            slide.play();&lt;br /&gt;
           &lt;br /&gt;
            // This intersection is taken, it shouldn&#039;t appear as clickable anymore&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;
&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_stone {&lt;br /&gt;
	width: 30px;&lt;br /&gt;
	height: 30px;&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    background-image: url( &#039;../../img/gomoku/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 image of both the white and black stones, and position the background appropriately to show only the part of the background image matching the appropriate stone or the white space if there is no stone. Here is what the image looks like (we will use the red circle later on):&lt;br /&gt;
&lt;br /&gt;
[[File:Gomoku stones.png]]&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 (if any)&lt;br /&gt;
&lt;br /&gt;
  Nothing special for Gomoku&lt;br /&gt;
&lt;br /&gt;
Implement rule for computing game progression in .game.php-&amp;gt;getGameProgression()&lt;br /&gt;
&lt;br /&gt;
Implement end of game detection and update the score according to who is the winner in .game.php-&amp;gt;stCheckEndOfGame()&lt;br /&gt;
&lt;br /&gt;
Notify the score and implement the corresponding interface update in .js&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>Een</name></author>
	</entry>
	<entry>
		<id>https://hu.doc.boardgamearena.com/index.php?title=F%C3%A1jl:Gomoku_stones.png&amp;diff=372</id>
		<title>Fájl:Gomoku stones.png</title>
		<link rel="alternate" type="text/html" href="https://hu.doc.boardgamearena.com/index.php?title=F%C3%A1jl:Gomoku_stones.png&amp;diff=372"/>
		<updated>2012-12-05T22:45:06Z</updated>

		<summary type="html">&lt;p&gt;Een: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=371</id>
		<title>Tutorial gomoku</title>
		<link rel="alternate" type="text/html" href="https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=371"/>
		<updated>2012-12-05T22:40:51Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Manage states and events */&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;emtpy 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.&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/gomoku/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 gomoku.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 gomoku.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 (jstpl_intersection).&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 gomoku.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 gomoku.game.php-&amp;gt;getAllDatas() is now available in your gomoku.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 gomoku.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 gomoku.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 gomoku.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 gomoku.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;
* 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. 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;
Add onclick events on intersections in gomoku.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 gomoku.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 gomoku.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 gomoku.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 ${coordinates}&#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;coordinates&#039; =&amp;gt; $this-&amp;gt;getFormattedCoordinates($coord_x, $coord_y),&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 gomoku.js-&amp;gt;setupNotifications() and link it to a javascript function to execute&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;, 1000 );&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;
        			dojo.style( &#039;stone_&#039; + notif.args.coord_x + &#039;_&#039; + notif.args.coord_y, &#039;zIndex&#039;, &#039;auto&#039; );&lt;br /&gt;
       		}));&lt;br /&gt;
            slide.play();&lt;br /&gt;
           &lt;br /&gt;
            // This intersection is taken, it shouldn&#039;t appear as clickable anymore&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;
&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;
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;
&lt;br /&gt;
* to define the css styles for the stones&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/gomoku/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;
&lt;br /&gt;
These styles rely on an image of both the white and black stones, and position the background appropriately to show only the part of the background image matching the appropriate stone.&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 (if any)&lt;br /&gt;
&lt;br /&gt;
  Nothing special for Gomoku&lt;br /&gt;
&lt;br /&gt;
Implement rule for computing game progression in .game.php-&amp;gt;getGameProgression()&lt;br /&gt;
&lt;br /&gt;
Implement end of game detection and update the score according to who is the winner in .game.php-&amp;gt;stCheckEndOfGame()&lt;br /&gt;
&lt;br /&gt;
Notify the score and implement the corresponding interface update in .js&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>Een</name></author>
	</entry>
	<entry>
		<id>https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=370</id>
		<title>Tutorial gomoku</title>
		<link rel="alternate" type="text/html" href="https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=370"/>
		<updated>2012-12-05T22:36:37Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Manage states and events */&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;emtpy 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.&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/gomoku/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 gomoku.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 gomoku.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 (jstpl_intersection).&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 gomoku.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 gomoku.game.php-&amp;gt;getAllDatas() is now available in your gomoku.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 gomoku.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 gomoku.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 gomoku.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 gomoku.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;
* 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. 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;
Add onclick events on intersections in gomoku.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 gomoku.js-&amp;gt;onClickIntersection() function, which calls an action function on the server with appropriate parameters&lt;br /&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;
&lt;br /&gt;
Add this action function in gomoku.action.php, retrieving parameters and calling the appropriate game action&lt;br /&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;
&lt;br /&gt;
Add game action in gomoku.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;
    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 ${coordinates}&#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;coordinates&#039; =&amp;gt; $this-&amp;gt;getFormattedCoordinates($coord_x, $coord_y),&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;
&lt;br /&gt;
Catch the notification in gomoku.js-&amp;gt;setupNotifications() and link it to a javascript function to execute&lt;br /&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;
&lt;br /&gt;
Implement this method in javascript to update the intersection to show the stone, and register it inside the setNotifications function.&lt;br /&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;, 1000 );&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;
        			dojo.style( &#039;stone_&#039; + notif.args.coord_x + &#039;_&#039; + notif.args.coord_y, &#039;zIndex&#039;, &#039;auto&#039; );&lt;br /&gt;
       		}));&lt;br /&gt;
            slide.play();&lt;br /&gt;
           &lt;br /&gt;
            // This intersection is taken, it shouldn&#039;t appear as clickable anymore&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;
&lt;br /&gt;
For this function, you need to declare a stone javascript template in your .tpl file&lt;br /&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;
&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 (if any)&lt;br /&gt;
&lt;br /&gt;
  Nothing special for Gomoku&lt;br /&gt;
&lt;br /&gt;
Implement rule for computing game progression in .game.php-&amp;gt;getGameProgression()&lt;br /&gt;
&lt;br /&gt;
Implement end of game detection and update the score according to who is the winner in .game.php-&amp;gt;stCheckEndOfGame()&lt;br /&gt;
&lt;br /&gt;
Notify the score and implement the corresponding interface update in .js&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>Een</name></author>
	</entry>
	<entry>
		<id>https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=369</id>
		<title>Tutorial gomoku</title>
		<link rel="alternate" type="text/html" href="https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=369"/>
		<updated>2012-12-05T22:21:30Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Setup the backbone of your game */&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;emtpy 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.&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/gomoku/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 gomoku.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 gomoku.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 (jstpl_intersection).&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 gomoku.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 gomoku.game.php-&amp;gt;getAllDatas() is now available in your gomoku.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 gomoku.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 gomoku.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 gomoku.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 gomoku.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;
* 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&lt;br /&gt;
&lt;br /&gt;
Add onclick events on intersections in .js, calling an action with appropriate parameters&lt;br /&gt;
&lt;br /&gt;
Add action in .action.php, retrieving parameters and calling the appropriate game action&lt;br /&gt;
&lt;br /&gt;
Add game action in .game.php to update the database, then notify the client using a method ‘stonePlayed’&lt;br /&gt;
&lt;br /&gt;
Implement this method in javascript to update the intersection to show the stone, and register it inside the setNotifications function.&lt;br /&gt;
&lt;br /&gt;
The basic game turn is implemented: you can 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 (if any)&lt;br /&gt;
&lt;br /&gt;
  Nothing special for Gomoku&lt;br /&gt;
&lt;br /&gt;
Implement rule for computing game progression in .game.php-&amp;gt;getGameProgression()&lt;br /&gt;
&lt;br /&gt;
Implement end of game detection and update the score according to who is the winner in .game.php-&amp;gt;stCheckEndOfGame()&lt;br /&gt;
&lt;br /&gt;
Notify the score and implement the corresponding interface update in .js&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>Een</name></author>
	</entry>
	<entry>
		<id>https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=368</id>
		<title>Tutorial gomoku</title>
		<link rel="alternate" type="text/html" href="https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=368"/>
		<updated>2012-12-05T22:20:55Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Setup the backbone of your game */&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;emtpy 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.&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/gomoku/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 gomoku.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 gomoku.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 (jstpl_intersection).&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 gomoku.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 gomoku.game.php-&amp;gt;getAllDatas() is now available in your gomoku.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 gomoku.js for easy repositioning (modify constant, refresh). This is especially useful if the same constant values 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 gomoku.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 gomoku.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 gomoku.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;
* 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&lt;br /&gt;
&lt;br /&gt;
Add onclick events on intersections in .js, calling an action with appropriate parameters&lt;br /&gt;
&lt;br /&gt;
Add action in .action.php, retrieving parameters and calling the appropriate game action&lt;br /&gt;
&lt;br /&gt;
Add game action in .game.php to update the database, then notify the client using a method ‘stonePlayed’&lt;br /&gt;
&lt;br /&gt;
Implement this method in javascript to update the intersection to show the stone, and register it inside the setNotifications function.&lt;br /&gt;
&lt;br /&gt;
The basic game turn is implemented: you can 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 (if any)&lt;br /&gt;
&lt;br /&gt;
  Nothing special for Gomoku&lt;br /&gt;
&lt;br /&gt;
Implement rule for computing game progression in .game.php-&amp;gt;getGameProgression()&lt;br /&gt;
&lt;br /&gt;
Implement end of game detection and update the score according to who is the winner in .game.php-&amp;gt;stCheckEndOfGame()&lt;br /&gt;
&lt;br /&gt;
Notify the score and implement the corresponding interface update in .js&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>Een</name></author>
	</entry>
	<entry>
		<id>https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=367</id>
		<title>Tutorial gomoku</title>
		<link rel="alternate" type="text/html" href="https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=367"/>
		<updated>2012-12-05T22:18:34Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Setup the backbone of your game */&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;emtpy 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.&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/gomoku/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 gomoku.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 gomoku.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 (jstpl_intersection).&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 gomoku.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 gomoku.game.php-&amp;gt;getAllDatas() is now available in your gomoku.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 &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;
And pass them to your gomoku.js for easy repositioning (modify constant, refresh).&lt;br /&gt;
&lt;br /&gt;
* In gomoku.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 gomoku.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;
* 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&lt;br /&gt;
&lt;br /&gt;
Add onclick events on intersections in .js, calling an action with appropriate parameters&lt;br /&gt;
&lt;br /&gt;
Add action in .action.php, retrieving parameters and calling the appropriate game action&lt;br /&gt;
&lt;br /&gt;
Add game action in .game.php to update the database, then notify the client using a method ‘stonePlayed’&lt;br /&gt;
&lt;br /&gt;
Implement this method in javascript to update the intersection to show the stone, and register it inside the setNotifications function.&lt;br /&gt;
&lt;br /&gt;
The basic game turn is implemented: you can 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 (if any)&lt;br /&gt;
&lt;br /&gt;
  Nothing special for Gomoku&lt;br /&gt;
&lt;br /&gt;
Implement rule for computing game progression in .game.php-&amp;gt;getGameProgression()&lt;br /&gt;
&lt;br /&gt;
Implement end of game detection and update the score according to who is the winner in .game.php-&amp;gt;stCheckEndOfGame()&lt;br /&gt;
&lt;br /&gt;
Notify the score and implement the corresponding interface update in .js&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>Een</name></author>
	</entry>
	<entry>
		<id>https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=366</id>
		<title>Tutorial gomoku</title>
		<link rel="alternate" type="text/html" href="https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=366"/>
		<updated>2012-12-05T22:13:56Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Setup the backbone of your game */&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;emtpy 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.&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/gomoku/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 gomoku.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 gomoku.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 (jstpl_intersection).&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 gomoku.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 gomoku.game.php-&amp;gt;getAllDatas() is now available in your gomoku.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 &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;
And pass them to your gomoku.js through gomoku.game.php-&amp;gt;getAllDatas() for easy repositioning (modify constant, refresh).&lt;br /&gt;
&lt;br /&gt;
        // Constants&lt;br /&gt;
        $result[&#039;constants&#039;] = $this-&amp;gt;gameConstants;&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&lt;br /&gt;
&lt;br /&gt;
Add onclick events on intersections in .js, calling an action with appropriate parameters&lt;br /&gt;
&lt;br /&gt;
Add action in .action.php, retrieving parameters and calling the appropriate game action&lt;br /&gt;
&lt;br /&gt;
Add game action in .game.php to update the database, then notify the client using a method ‘stonePlayed’&lt;br /&gt;
&lt;br /&gt;
Implement this method in javascript to update the intersection to show the stone, and register it inside the setNotifications function.&lt;br /&gt;
&lt;br /&gt;
The basic game turn is implemented: you can 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 (if any)&lt;br /&gt;
&lt;br /&gt;
  Nothing special for Gomoku&lt;br /&gt;
&lt;br /&gt;
Implement rule for computing game progression in .game.php-&amp;gt;getGameProgression()&lt;br /&gt;
&lt;br /&gt;
Implement end of game detection and update the score according to who is the winner in .game.php-&amp;gt;stCheckEndOfGame()&lt;br /&gt;
&lt;br /&gt;
Notify the score and implement the corresponding interface update in .js&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>Een</name></author>
	</entry>
	<entry>
		<id>https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=365</id>
		<title>Tutorial gomoku</title>
		<link rel="alternate" type="text/html" href="https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=365"/>
		<updated>2012-12-05T22:13:33Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Setup the backbone of your game */&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;emtpy 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.&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/gomoku/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 .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 gomoku.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 gomoku.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 (jstpl_intersection).&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 gomoku.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 gomoku.game.php-&amp;gt;getAllDatas() is now available in your gomoku.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 &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;
And pass them to your gomoku.js through gomoku.game.php-&amp;gt;getAllDatas() for easy repositioning (modify constant, refresh).&lt;br /&gt;
&lt;br /&gt;
        // Constants&lt;br /&gt;
        $result[&#039;constants&#039;] = $this-&amp;gt;gameConstants;&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&lt;br /&gt;
&lt;br /&gt;
Add onclick events on intersections in .js, calling an action with appropriate parameters&lt;br /&gt;
&lt;br /&gt;
Add action in .action.php, retrieving parameters and calling the appropriate game action&lt;br /&gt;
&lt;br /&gt;
Add game action in .game.php to update the database, then notify the client using a method ‘stonePlayed’&lt;br /&gt;
&lt;br /&gt;
Implement this method in javascript to update the intersection to show the stone, and register it inside the setNotifications function.&lt;br /&gt;
&lt;br /&gt;
The basic game turn is implemented: you can 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 (if any)&lt;br /&gt;
&lt;br /&gt;
  Nothing special for Gomoku&lt;br /&gt;
&lt;br /&gt;
Implement rule for computing game progression in .game.php-&amp;gt;getGameProgression()&lt;br /&gt;
&lt;br /&gt;
Implement end of game detection and update the score according to who is the winner in .game.php-&amp;gt;stCheckEndOfGame()&lt;br /&gt;
&lt;br /&gt;
Notify the score and implement the corresponding interface update in .js&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>Een</name></author>
	</entry>
	<entry>
		<id>https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=364</id>
		<title>Tutorial gomoku</title>
		<link rel="alternate" type="text/html" href="https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=364"/>
		<updated>2012-12-05T21:58:44Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Setup the board */&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;emtpy 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.&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/gomoku/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 .sql to create a table for intersections.&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;
Edit .game.php-&amp;gt;getAllDatas to retrieve the state of the intersections from the database.&lt;br /&gt;
&lt;br /&gt;
Edit .tpl to create a template for intersections (jstpl_intersection).&lt;br /&gt;
&lt;br /&gt;
Edit .js to setup the intersections layer that will be used to get click events and to display the stones. Use some temporary css colors on borders or background+opacity to make sure they are positioned right. You can declare some constants in &lt;br /&gt;
material.inc.php and pass them to your .js through .game.php-&amp;gt;getAllDatas for easy repositioning.&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&lt;br /&gt;
&lt;br /&gt;
Add onclick events on intersections in .js, calling an action with appropriate parameters&lt;br /&gt;
&lt;br /&gt;
Add action in .action.php, retrieving parameters and calling the appropriate game action&lt;br /&gt;
&lt;br /&gt;
Add game action in .game.php to update the database, then notify the client using a method ‘stonePlayed’&lt;br /&gt;
&lt;br /&gt;
Implement this method in javascript to update the intersection to show the stone, and register it inside the setNotifications function.&lt;br /&gt;
&lt;br /&gt;
The basic game turn is implemented: you can 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 (if any)&lt;br /&gt;
&lt;br /&gt;
  Nothing special for Gomoku&lt;br /&gt;
&lt;br /&gt;
Implement rule for computing game progression in .game.php-&amp;gt;getGameProgression()&lt;br /&gt;
&lt;br /&gt;
Implement end of game detection and update the score according to who is the winner in .game.php-&amp;gt;stCheckEndOfGame()&lt;br /&gt;
&lt;br /&gt;
Notify the score and implement the corresponding interface update in .js&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>Een</name></author>
	</entry>
	<entry>
		<id>https://hu.doc.boardgamearena.com/index.php?title=Studio_FAQ&amp;diff=363</id>
		<title>Studio FAQ</title>
		<link rel="alternate" type="text/html" href="https://hu.doc.boardgamearena.com/index.php?title=Studio_FAQ&amp;diff=363"/>
		<updated>2012-12-05T21:45:22Z</updated>

		<summary type="html">&lt;p&gt;Een: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a place where we will collect and answer frequently asked questions.&lt;br /&gt;
&lt;br /&gt;
== What should I use to access the files through SFTP? ==&lt;br /&gt;
&lt;br /&gt;
There is a lot of tools to do that. Use the one you are the most comfortable with.&lt;br /&gt;
&lt;br /&gt;
On Linux, you can for example use the &#039;Connect to server&#039; function of the Nautilus file management system, or use sshfs.&lt;br /&gt;
&lt;br /&gt;
On Windows, there is for example the WinSCP client.&lt;br /&gt;
&lt;br /&gt;
== I can&#039;t access the Studio back-office, I get a &#039;Not authorized&#039; error message? ==&lt;br /&gt;
&lt;br /&gt;
You should first connect to the Studio website (with any of your &amp;lt;developer name&amp;gt;&amp;lt;number&amp;gt; accounts). As the authentication is shared with the back-office, then you will be able to access it.&lt;br /&gt;
&lt;br /&gt;
== It&#039;s pretty annoying to log in with multiple users to start a game. Is there some easier way? ==&lt;br /&gt;
&lt;br /&gt;
You can use the &#039;Express start&#039; function. It will automatically make the specified number of players join the game (using the first of your ten player accounts available) and start the game.&lt;br /&gt;
&lt;br /&gt;
During the game, there is a red arrow on the right of each player name, that you can use to open a tab from this player&#039;s perspective.&lt;br /&gt;
&lt;br /&gt;
You can also end the game in two clicks by clicking the &#039;End game&#039; button then selecting &#039;Express game stop&#039; in the popup.&lt;br /&gt;
&lt;br /&gt;
== What is the working language on BGA studio? ==&lt;br /&gt;
&lt;br /&gt;
Working language is &#039;&#039;&#039;English&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Variables and functions must be named with English words.&lt;br /&gt;
&lt;br /&gt;
Comments must be written in English.&lt;br /&gt;
&lt;br /&gt;
Game interface strings and game logs must be written in English.&lt;br /&gt;
&lt;br /&gt;
== How can I provide translation in my language? == &lt;br /&gt;
&lt;br /&gt;
BGA administrators will translate the game in French before the game release.&lt;br /&gt;
&lt;br /&gt;
After the game release, the collaborative translation interface can be used to translate into other languages.&lt;br /&gt;
&lt;br /&gt;
== Is there a special way to declare the strings that must be translated? == &lt;br /&gt;
&lt;br /&gt;
Yes. This declaration is made through transparent functions, that depend on the context.&lt;br /&gt;
&lt;br /&gt;
In javascript files, you should use _( &#039;My string to translate&#039; ).&lt;br /&gt;
&lt;br /&gt;
In php files, you should use self::_( &#039;My string to translate&#039; ) when the string can be translated on the server side (ex: title included in the game layout) and clienttranslate( &#039;My string to translate&#039; ) when the string must be translated on the client side (ex: message for the game log).&lt;br /&gt;
&lt;br /&gt;
== I updated the images in the &#039;img&#039; folder of my game, but they don&#039;t show? ==&lt;br /&gt;
&lt;br /&gt;
On BGA Studio, there is the gameserver you are developing on, and the main site server that is used to launch the games. The game icon, box and the publisher logo are hosted on the main site server, so they are not immediately available when you modify them on the gameserver. To deploy them on the main site, you have to use the [[Studio back-office]] to do a commit.&lt;br /&gt;
&lt;br /&gt;
If the images still don&#039;t show after that, please try emptying your browser cache and reloading the page.&lt;br /&gt;
&lt;br /&gt;
== I added some game options / some game statistics, but they don&#039;t show? ==&lt;br /&gt;
&lt;br /&gt;
An extra deployment action from the BGA administrators is needed to activate new game options and statistics. Please contact us.&lt;br /&gt;
&lt;br /&gt;
== Is there a quick way to access the database for my current table? ==&lt;br /&gt;
&lt;br /&gt;
Yes! While playing a game on studio, you have a &amp;quot;Go to game database&amp;quot; link at the bottom of your game. This link will bring you directly to the database for the current table.&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=362</id>
		<title>Tutorial gomoku</title>
		<link rel="alternate" type="text/html" href="https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=362"/>
		<updated>2012-12-05T21:26:20Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Implement rules and end of game condition(s) */&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;emtpy 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 div for the board in the HTML.&lt;br /&gt;
&lt;br /&gt;
Edit .css to show the image of the board as background.&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 .sql to create a table for intersections.&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;
Edit .game.php-&amp;gt;getAllDatas to retrieve the state of the intersections from the database.&lt;br /&gt;
&lt;br /&gt;
Edit .tpl to create a template for intersections (jstpl_intersection).&lt;br /&gt;
&lt;br /&gt;
Edit .js to setup the intersections layer that will be used to get click events and to display the stones. Use some temporary css colors on borders or background+opacity to make sure they are positioned right. You can declare some constants in &lt;br /&gt;
material.inc.php and pass them to your .js through .game.php-&amp;gt;getAllDatas for easy repositioning.&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&lt;br /&gt;
&lt;br /&gt;
Add onclick events on intersections in .js, calling an action with appropriate parameters&lt;br /&gt;
&lt;br /&gt;
Add action in .action.php, retrieving parameters and calling the appropriate game action&lt;br /&gt;
&lt;br /&gt;
Add game action in .game.php to update the database, then notify the client using a method ‘stonePlayed’&lt;br /&gt;
&lt;br /&gt;
Implement this method in javascript to update the intersection to show the stone, and register it inside the setNotifications function.&lt;br /&gt;
&lt;br /&gt;
The basic game turn is implemented: you can 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 (if any)&lt;br /&gt;
&lt;br /&gt;
  Nothing special for Gomoku&lt;br /&gt;
&lt;br /&gt;
Implement rule for computing game progression in .game.php-&amp;gt;getGameProgression()&lt;br /&gt;
&lt;br /&gt;
Implement end of game detection and update the score according to who is the winner in .game.php-&amp;gt;stCheckEndOfGame()&lt;br /&gt;
&lt;br /&gt;
Notify the score and implement the corresponding interface update in .js&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>Een</name></author>
	</entry>
	<entry>
		<id>https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=361</id>
		<title>Tutorial gomoku</title>
		<link rel="alternate" type="text/html" href="https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=361"/>
		<updated>2012-12-05T21:26:10Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Cleanup */&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;emtpy 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 div for the board in the HTML.&lt;br /&gt;
&lt;br /&gt;
Edit .css to show the image of the board as background.&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 .sql to create a table for intersections.&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;
Edit .game.php-&amp;gt;getAllDatas to retrieve the state of the intersections from the database.&lt;br /&gt;
&lt;br /&gt;
Edit .tpl to create a template for intersections (jstpl_intersection).&lt;br /&gt;
&lt;br /&gt;
Edit .js to setup the intersections layer that will be used to get click events and to display the stones. Use some temporary css colors on borders or background+opacity to make sure they are positioned right. You can declare some constants in &lt;br /&gt;
material.inc.php and pass them to your .js through .game.php-&amp;gt;getAllDatas for easy repositioning.&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&lt;br /&gt;
&lt;br /&gt;
Add onclick events on intersections in .js, calling an action with appropriate parameters&lt;br /&gt;
&lt;br /&gt;
Add action in .action.php, retrieving parameters and calling the appropriate game action&lt;br /&gt;
&lt;br /&gt;
Add game action in .game.php to update the database, then notify the client using a method ‘stonePlayed’&lt;br /&gt;
&lt;br /&gt;
Implement this method in javascript to update the intersection to show the stone, and register it inside the setNotifications function.&lt;br /&gt;
&lt;br /&gt;
The basic game turn is implemented: you can 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 condition(s) ==&lt;br /&gt;
&lt;br /&gt;
Implement specific rules for the game (if any)&lt;br /&gt;
&lt;br /&gt;
  Nothing special for Gomoku&lt;br /&gt;
&lt;br /&gt;
Implement rule for computing game progression in .game.php-&amp;gt;getGameProgression()&lt;br /&gt;
&lt;br /&gt;
Implement end of game detection and update the score according to who is the winner in .game.php-&amp;gt;stCheckEndOfGame()&lt;br /&gt;
&lt;br /&gt;
Notify the score and implement the corresponding interface update in .js&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>Een</name></author>
	</entry>
	<entry>
		<id>https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=360</id>
		<title>Tutorial gomoku</title>
		<link rel="alternate" type="text/html" href="https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=360"/>
		<updated>2012-12-05T21:25:33Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Start from the emtpy game 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;emtpy 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 div for the board in the HTML.&lt;br /&gt;
&lt;br /&gt;
Edit .css to show the image of the board as background.&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 .sql to create a table for intersections.&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;
Edit .game.php-&amp;gt;getAllDatas to retrieve the state of the intersections from the database.&lt;br /&gt;
&lt;br /&gt;
Edit .tpl to create a template for intersections (jstpl_intersection).&lt;br /&gt;
&lt;br /&gt;
Edit .js to setup the intersections layer that will be used to get click events and to display the stones. Use some temporary css colors on borders or background+opacity to make sure they are positioned right. You can declare some constants in &lt;br /&gt;
material.inc.php and pass them to your .js through .game.php-&amp;gt;getAllDatas for easy repositioning.&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&lt;br /&gt;
&lt;br /&gt;
Add onclick events on intersections in .js, calling an action with appropriate parameters&lt;br /&gt;
&lt;br /&gt;
Add action in .action.php, retrieving parameters and calling the appropriate game action&lt;br /&gt;
&lt;br /&gt;
Add game action in .game.php to update the database, then notify the client using a method ‘stonePlayed’&lt;br /&gt;
&lt;br /&gt;
Implement this method in javascript to update the intersection to show the stone, and register it inside the setNotifications function.&lt;br /&gt;
&lt;br /&gt;
The basic game turn is implemented: you can drop some stones!&lt;br /&gt;
&lt;br /&gt;
[[File:Gomoku tuto4.png]]&lt;br /&gt;
&lt;br /&gt;
== Cleanup ==&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 condition(s) ==&lt;br /&gt;
&lt;br /&gt;
Implement specific rules for the game (if any)&lt;br /&gt;
&lt;br /&gt;
  Nothing special for Gomoku&lt;br /&gt;
&lt;br /&gt;
Implement rule for computing game progression in .game.php-&amp;gt;getGameProgression()&lt;br /&gt;
&lt;br /&gt;
Implement end of game detection and update the score according to who is the winner in .game.php-&amp;gt;stCheckEndOfGame()&lt;br /&gt;
&lt;br /&gt;
Notify the score and implement the corresponding interface update in .js&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>Een</name></author>
	</entry>
	<entry>
		<id>https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=359</id>
		<title>Tutorial gomoku</title>
		<link rel="alternate" type="text/html" href="https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=359"/>
		<updated>2012-12-05T21:24:48Z</updated>

		<summary type="html">&lt;p&gt;Een: &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;
== Start from the emtpy game 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 div for the board in the HTML.&lt;br /&gt;
&lt;br /&gt;
Edit .css to show the image of the board as background.&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 .sql to create a table for intersections.&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;
Edit .game.php-&amp;gt;getAllDatas to retrieve the state of the intersections from the database.&lt;br /&gt;
&lt;br /&gt;
Edit .tpl to create a template for intersections (jstpl_intersection).&lt;br /&gt;
&lt;br /&gt;
Edit .js to setup the intersections layer that will be used to get click events and to display the stones. Use some temporary css colors on borders or background+opacity to make sure they are positioned right. You can declare some constants in &lt;br /&gt;
material.inc.php and pass them to your .js through .game.php-&amp;gt;getAllDatas for easy repositioning.&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&lt;br /&gt;
&lt;br /&gt;
Add onclick events on intersections in .js, calling an action with appropriate parameters&lt;br /&gt;
&lt;br /&gt;
Add action in .action.php, retrieving parameters and calling the appropriate game action&lt;br /&gt;
&lt;br /&gt;
Add game action in .game.php to update the database, then notify the client using a method ‘stonePlayed’&lt;br /&gt;
&lt;br /&gt;
Implement this method in javascript to update the intersection to show the stone, and register it inside the setNotifications function.&lt;br /&gt;
&lt;br /&gt;
The basic game turn is implemented: you can drop some stones!&lt;br /&gt;
&lt;br /&gt;
[[File:Gomoku tuto4.png]]&lt;br /&gt;
&lt;br /&gt;
== Cleanup ==&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 condition(s) ==&lt;br /&gt;
&lt;br /&gt;
Implement specific rules for the game (if any)&lt;br /&gt;
&lt;br /&gt;
  Nothing special for Gomoku&lt;br /&gt;
&lt;br /&gt;
Implement rule for computing game progression in .game.php-&amp;gt;getGameProgression()&lt;br /&gt;
&lt;br /&gt;
Implement end of game detection and update the score according to who is the winner in .game.php-&amp;gt;stCheckEndOfGame()&lt;br /&gt;
&lt;br /&gt;
Notify the score and implement the corresponding interface update in .js&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>Een</name></author>
	</entry>
	<entry>
		<id>https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=358</id>
		<title>Tutorial gomoku</title>
		<link rel="alternate" type="text/html" href="https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=358"/>
		<updated>2012-12-05T21:18:27Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Setup the board */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Start from the emtpy game 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 div for the board in the HTML.&lt;br /&gt;
&lt;br /&gt;
Edit .css to show the image of the board as background.&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 .sql to create a table for intersections.&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;
Edit .game.php-&amp;gt;getAllDatas to retrieve the state of the intersections from the database.&lt;br /&gt;
&lt;br /&gt;
Edit .tpl to create a template for intersections (jstpl_intersection).&lt;br /&gt;
&lt;br /&gt;
Edit .js to setup the intersections layer that will be used to get click events and to display the stones. Use some temporary css colors on borders or background+opacity to make sure they are positioned right. You can declare some constants in &lt;br /&gt;
material.inc.php and pass them to your .js through .game.php-&amp;gt;getAllDatas for easy repositioning.&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&lt;br /&gt;
&lt;br /&gt;
Add onclick events on intersections in .js, calling an action with appropriate parameters&lt;br /&gt;
&lt;br /&gt;
Add action in .action.php, retrieving parameters and calling the appropriate game action&lt;br /&gt;
&lt;br /&gt;
Add game action in .game.php to update the database, then notify the client using a method ‘stonePlayed’&lt;br /&gt;
&lt;br /&gt;
Implement this method in javascript to update the intersection to show the stone, and register it inside the setNotifications function.&lt;br /&gt;
&lt;br /&gt;
The basic game turn is implemented: you can drop some stones!&lt;br /&gt;
&lt;br /&gt;
[[File:Gomoku tuto4.png]]&lt;br /&gt;
&lt;br /&gt;
== Cleanup ==&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 condition(s) ==&lt;br /&gt;
&lt;br /&gt;
Implement specific rules for the game (if any)&lt;br /&gt;
&lt;br /&gt;
  Nothing special for Gomoku&lt;br /&gt;
&lt;br /&gt;
Implement rule for computing game progression in .game.php-&amp;gt;getGameProgression()&lt;br /&gt;
&lt;br /&gt;
Implement end of game detection and update the score according to who is the winner in .game.php-&amp;gt;stCheckEndOfGame()&lt;br /&gt;
&lt;br /&gt;
Notify the score and implement the corresponding interface update in .js&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>Een</name></author>
	</entry>
	<entry>
		<id>https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=357</id>
		<title>Tutorial gomoku</title>
		<link rel="alternate" type="text/html" href="https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=357"/>
		<updated>2012-12-05T21:17:54Z</updated>

		<summary type="html">&lt;p&gt;Een: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Start from the emtpy game 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.&lt;br /&gt;
&lt;br /&gt;
Edit .tpl to add some div for the board in the HTML.&lt;br /&gt;
&lt;br /&gt;
Edit .css to show the image of the board as background.&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 .sql to create a table for intersections.&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;
Edit .game.php-&amp;gt;getAllDatas to retrieve the state of the intersections from the database.&lt;br /&gt;
&lt;br /&gt;
Edit .tpl to create a template for intersections (jstpl_intersection).&lt;br /&gt;
&lt;br /&gt;
Edit .js to setup the intersections layer that will be used to get click events and to display the stones. Use some temporary css colors on borders or background+opacity to make sure they are positioned right. You can declare some constants in &lt;br /&gt;
material.inc.php and pass them to your .js through .game.php-&amp;gt;getAllDatas for easy repositioning.&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&lt;br /&gt;
&lt;br /&gt;
Add onclick events on intersections in .js, calling an action with appropriate parameters&lt;br /&gt;
&lt;br /&gt;
Add action in .action.php, retrieving parameters and calling the appropriate game action&lt;br /&gt;
&lt;br /&gt;
Add game action in .game.php to update the database, then notify the client using a method ‘stonePlayed’&lt;br /&gt;
&lt;br /&gt;
Implement this method in javascript to update the intersection to show the stone, and register it inside the setNotifications function.&lt;br /&gt;
&lt;br /&gt;
The basic game turn is implemented: you can drop some stones!&lt;br /&gt;
&lt;br /&gt;
[[File:Gomoku tuto4.png]]&lt;br /&gt;
&lt;br /&gt;
== Cleanup ==&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 condition(s) ==&lt;br /&gt;
&lt;br /&gt;
Implement specific rules for the game (if any)&lt;br /&gt;
&lt;br /&gt;
  Nothing special for Gomoku&lt;br /&gt;
&lt;br /&gt;
Implement rule for computing game progression in .game.php-&amp;gt;getGameProgression()&lt;br /&gt;
&lt;br /&gt;
Implement end of game detection and update the score according to who is the winner in .game.php-&amp;gt;stCheckEndOfGame()&lt;br /&gt;
&lt;br /&gt;
Notify the score and implement the corresponding interface update in .js&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>Een</name></author>
	</entry>
	<entry>
		<id>https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=356</id>
		<title>Tutorial gomoku</title>
		<link rel="alternate" type="text/html" href="https://hu.doc.boardgamearena.com/index.php?title=Tutorial_gomoku&amp;diff=356"/>
		<updated>2012-12-05T21:14:15Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Start from the emtpy game template */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Start from the emtpy game 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.&lt;br /&gt;
Edit .tpl &amp;amp; .css to add the board :&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 .sql to create a table for intersections.&lt;br /&gt;
Edit .game.php-&amp;gt;setupNewGame to insert the empty intersections (19x19) with coordinates into the database.&lt;br /&gt;
Edit .game.php-&amp;gt;getAllDatas to retrieve the state of the intersections from the database.&lt;br /&gt;
Edit .tpl to create a template for intersections (jstpl_intersection).&lt;br /&gt;
Edit .js to setup the intersections layer that will be used to get click events and to display the stones. Use some temporary css colors on borders or background+opacity to make sure they are positioned right. You can declare some constants in material.inc.php and pass them to your .js through .game.php-&amp;gt;getAllDatas for easy repositioning.&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&lt;br /&gt;
Add onclick events on intersections in .js, calling an action with appropriate parameters&lt;br /&gt;
Add action in .action.php, retrieving parameters and calling the appropriate game action.&lt;br /&gt;
Add game action in .game.php to update the database, then notify the client using a method ‘stonePlayed’&lt;br /&gt;
Implement this method in javascript to update the intersection to show the stone, and register it inside the setNotifications function.&lt;br /&gt;
The basic game turn is implemented: you can drop some stones!&lt;br /&gt;
&lt;br /&gt;
[[File:Gomoku tuto4.png]]&lt;br /&gt;
&lt;br /&gt;
== Cleanup ==&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 condition(s) ==&lt;br /&gt;
&lt;br /&gt;
Implement specific rules for the game (if any)&lt;br /&gt;
Implement rule for computing game progression in .game.php-&amp;gt;getGameProgression()&lt;br /&gt;
Implement end of game detection and update the score according to who is the winner in .game.php-&amp;gt;stCheckEndOfGame()&lt;br /&gt;
Notify the score and implement the corresponding interface update in .js&lt;br /&gt;
&lt;br /&gt;
Test everything thoroughly... you are done!&lt;br /&gt;
&lt;br /&gt;
[[File:Gomoku tuto6.png]]&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
</feed>