Test Setup Failed
Push — master ( 3fdbae...4eb8b5 )
by Michael
18:46
created
include/install.inc.php 1 patch
Indentation   +156 added lines, -156 removed lines patch added patch discarded remove patch
@@ -49,74 +49,74 @@  discard block
 block discarded – undo
49 49
  */
50 50
 function xoops_module_pre_update_chess($module, $oldversion)
51 51
 {
52
-    global $xoopsDB;
53
-
54
-    // For downward-compatiblity, in case this function doesn't get called by the module handler.
55
-    $GLOBALS['chess_module_pre_update_called'] = true;
56
-
57
-    if ($oldversion < 102) { // old version < 1.02: direct update not supported.
58
-
59
-        $docfile = XOOPS_ROOT_PATH . '/modules/chess/docs/INSTALL.TXT';
60
-        chess_set_message($module, sprintf(_MI_CHESS_OLD_VERSION, (string)$oldversion, $docfile), true);
61
-        return false;
62
-    } elseif ($oldversion >= 107) { // old version >= 1.07:  no action needed.
63
-
64
-        return true;
65
-    }
66
-
67
-    // 1.02 <= old version < 1.07: perform update.
68
-
69
-    $ratings_table    = $xoopsDB->prefix('chess_ratings');
70
-    $challenges_table = $xoopsDB->prefix('chess_challenges');
71
-    $games_table      = $xoopsDB->prefix('chess_games');
72
-
73
-    // Check that ratings table does not already exist.
74
-    chess_set_message($module, sprintf(_MI_CHESS_RATINGS_TABLE_1, $ratings_table));
75
-    $result = $xoopsDB->query("SHOW TABLES LIKE '$ratings_table'");
76
-    if (!$result) {
77
-        $mysql_errno = $xoopsDB->errno();
78
-        $mysql_error = $xoopsDB->error();
79
-        chess_set_message($module, sprintf(_MI_CHESS_RATINGS_TABLE_2, $ratings_table, (string)$mysql_errno, $mysql_error), true);
80
-        return false;
81
-    }
82
-    if ($xoopsDB->getRowsNum($result) > 0) {
83
-        chess_set_message($module, sprintf(_MI_CHESS_RATINGS_TABLE_3, $ratings_table), true);
84
-        return false;
85
-    }
86
-    $xoopsDB->freeRecordSet($result);
87
-    chess_set_message($module, _MI_CHESS_OK);
88
-
89
-    // Check database tables.
90
-    chess_set_message($module, _MI_CHESS_CHK_DB_TABLES);
91
-    $table_check_messages = chess_check_tables([$challenges_table, $games_table]);
92
-    if (!empty($table_check_messages)) {
93
-        foreach ($table_check_messages as $message) {
94
-            chess_set_message($module, $message, true);
95
-        }
96
-        return false;
97
-    }
98
-    chess_set_message($module, _MI_CHESS_OK);
99
-
100
-    // Check that values in column pgn_result of games table are in range.
101
-    $pgn_result_values = "'*','1-0','0-1','1/2-1/2'";
102
-    chess_set_message($module, sprintf(_MI_CHESS_GAMES_TABLE_1, $games_table));
103
-    $result = $xoopsDB->query("SELECT COUNT(*) FROM `$games_table` WHERE `pgn_result` NOT IN ($pgn_result_values)");
104
-    if (!$result) {
105
-        $mysql_errno = $xoopsDB->errno();
106
-        $mysql_error = $xoopsDB->error();
107
-        chess_set_message($module, sprintf(_MI_CHESS_GAMES_TABLE_2, $games_table, (string)$mysql_errno, $mysql_error), true);
108
-        return false;
109
-    }
110
-    [$count] = $xoopsDB->fetchRow($result);
111
-    if ($count > 0) {
112
-        chess_set_message($module, sprintf(_MI_CHESS_GAMES_TABLE_3, 'pgn_result', $games_table, $pgn_result_values), true);
113
-        chess_set_message($module, _MI_CHESS_GAMES_TABLE_4, true);
114
-        return false;
115
-    }
116
-    $xoopsDB->freeRecordSet($result);
117
-    chess_set_message($module, _MI_CHESS_OK);
118
-
119
-    return true; // successful
52
+	global $xoopsDB;
53
+
54
+	// For downward-compatiblity, in case this function doesn't get called by the module handler.
55
+	$GLOBALS['chess_module_pre_update_called'] = true;
56
+
57
+	if ($oldversion < 102) { // old version < 1.02: direct update not supported.
58
+
59
+		$docfile = XOOPS_ROOT_PATH . '/modules/chess/docs/INSTALL.TXT';
60
+		chess_set_message($module, sprintf(_MI_CHESS_OLD_VERSION, (string)$oldversion, $docfile), true);
61
+		return false;
62
+	} elseif ($oldversion >= 107) { // old version >= 1.07:  no action needed.
63
+
64
+		return true;
65
+	}
66
+
67
+	// 1.02 <= old version < 1.07: perform update.
68
+
69
+	$ratings_table    = $xoopsDB->prefix('chess_ratings');
70
+	$challenges_table = $xoopsDB->prefix('chess_challenges');
71
+	$games_table      = $xoopsDB->prefix('chess_games');
72
+
73
+	// Check that ratings table does not already exist.
74
+	chess_set_message($module, sprintf(_MI_CHESS_RATINGS_TABLE_1, $ratings_table));
75
+	$result = $xoopsDB->query("SHOW TABLES LIKE '$ratings_table'");
76
+	if (!$result) {
77
+		$mysql_errno = $xoopsDB->errno();
78
+		$mysql_error = $xoopsDB->error();
79
+		chess_set_message($module, sprintf(_MI_CHESS_RATINGS_TABLE_2, $ratings_table, (string)$mysql_errno, $mysql_error), true);
80
+		return false;
81
+	}
82
+	if ($xoopsDB->getRowsNum($result) > 0) {
83
+		chess_set_message($module, sprintf(_MI_CHESS_RATINGS_TABLE_3, $ratings_table), true);
84
+		return false;
85
+	}
86
+	$xoopsDB->freeRecordSet($result);
87
+	chess_set_message($module, _MI_CHESS_OK);
88
+
89
+	// Check database tables.
90
+	chess_set_message($module, _MI_CHESS_CHK_DB_TABLES);
91
+	$table_check_messages = chess_check_tables([$challenges_table, $games_table]);
92
+	if (!empty($table_check_messages)) {
93
+		foreach ($table_check_messages as $message) {
94
+			chess_set_message($module, $message, true);
95
+		}
96
+		return false;
97
+	}
98
+	chess_set_message($module, _MI_CHESS_OK);
99
+
100
+	// Check that values in column pgn_result of games table are in range.
101
+	$pgn_result_values = "'*','1-0','0-1','1/2-1/2'";
102
+	chess_set_message($module, sprintf(_MI_CHESS_GAMES_TABLE_1, $games_table));
103
+	$result = $xoopsDB->query("SELECT COUNT(*) FROM `$games_table` WHERE `pgn_result` NOT IN ($pgn_result_values)");
104
+	if (!$result) {
105
+		$mysql_errno = $xoopsDB->errno();
106
+		$mysql_error = $xoopsDB->error();
107
+		chess_set_message($module, sprintf(_MI_CHESS_GAMES_TABLE_2, $games_table, (string)$mysql_errno, $mysql_error), true);
108
+		return false;
109
+	}
110
+	[$count] = $xoopsDB->fetchRow($result);
111
+	if ($count > 0) {
112
+		chess_set_message($module, sprintf(_MI_CHESS_GAMES_TABLE_3, 'pgn_result', $games_table, $pgn_result_values), true);
113
+		chess_set_message($module, _MI_CHESS_GAMES_TABLE_4, true);
114
+		return false;
115
+	}
116
+	$xoopsDB->freeRecordSet($result);
117
+	chess_set_message($module, _MI_CHESS_OK);
118
+
119
+	return true; // successful
120 120
 }
121 121
 
122 122
 /**
@@ -128,25 +128,25 @@  discard block
 block discarded – undo
128 128
  */
129 129
 function xoops_module_update_chess($module, $oldversion)
130 130
 {
131
-    global $xoopsDB;
131
+	global $xoopsDB;
132 132
 
133
-    // Before proceeding, ensure that pre-update processing has been done, and that all the checks pass.
134
-    // For downward-compatiblity, in case the "pre_update" function doesn't get called by the module handler.
135
-    if (!@$GLOBALS['chess_module_pre_update_called'] && !xoops_module_pre_update_chess($module, $oldversion)) {
136
-        return false;
137
-    }
133
+	// Before proceeding, ensure that pre-update processing has been done, and that all the checks pass.
134
+	// For downward-compatiblity, in case the "pre_update" function doesn't get called by the module handler.
135
+	if (!@$GLOBALS['chess_module_pre_update_called'] && !xoops_module_pre_update_chess($module, $oldversion)) {
136
+		return false;
137
+	}
138 138
 
139
-    if ($oldversion >= 107) { // old version >= 1.07:  no action needed.
140
-        return true;
141
-    }
139
+	if ($oldversion >= 107) { // old version >= 1.07:  no action needed.
140
+		return true;
141
+	}
142 142
 
143
-    $ratings_table    = $xoopsDB->prefix('chess_ratings');
144
-    $challenges_table = $xoopsDB->prefix('chess_challenges');
145
-    $games_table      = $xoopsDB->prefix('chess_games');
143
+	$ratings_table    = $xoopsDB->prefix('chess_ratings');
144
+	$challenges_table = $xoopsDB->prefix('chess_challenges');
145
+	$games_table      = $xoopsDB->prefix('chess_games');
146 146
 
147
-    $queries = [
147
+	$queries = [
148 148
 
149
-        "CREATE TABLE `$ratings_table` (
149
+		"CREATE TABLE `$ratings_table` (
150 150
             `player_uid` mediumint(8) unsigned NOT NULL default '0',
151 151
             `rating` smallint(6) unsigned NOT NULL default '1200',
152 152
             `games_won` smallint(6) unsigned NOT NULL default '0',
@@ -157,40 +157,40 @@  discard block
 block discarded – undo
157 157
             KEY `games` (`games_won`,`games_lost`,`games_drawn`)
158 158
             ) TYPE=MyISAM",
159 159
 
160
-        "ALTER TABLE `$challenges_table` ADD `is_rated` ENUM('1','0') DEFAULT '1' NOT NULL",
161
-        "ALTER TABLE `$challenges_table` ADD INDEX `game_type` (`game_type`)",
162
-        "ALTER TABLE `$challenges_table` ADD INDEX `player1_uid` (`player1_uid`)",
163
-        "ALTER TABLE `$challenges_table` ADD INDEX `player2_uid` (`player2_uid`)",
164
-        "ALTER TABLE `$challenges_table` ADD INDEX `create_date` (`create_date`)",
165
-        "ALTER TABLE `$challenges_table` ADD INDEX `is_rated` (`is_rated`)",
166
-
167
-        "ALTER TABLE `$games_table` CHANGE `pgn_result` `pgn_result` ENUM('*','0-1','1-0','1/2-1/2') DEFAULT '*' NOT NULL",
168
-        "ALTER TABLE `$games_table` ADD `is_rated` ENUM('1','0') DEFAULT '1' NOT NULL",
169
-        "ALTER TABLE `$games_table` ADD INDEX `white_uid` (`white_uid`)",
170
-        "ALTER TABLE `$games_table` ADD INDEX `black_uid` (`black_uid`)",
171
-        "ALTER TABLE `$games_table` ADD INDEX `date` (`create_date`,`start_date`,`last_date`)",
172
-        "ALTER TABLE `$games_table` ADD INDEX `pgn_result` (`pgn_result`)",
173
-        "ALTER TABLE `$games_table` ADD INDEX `suspended_date` (`suspended`(19))",
174
-        "ALTER TABLE `$games_table` ADD INDEX `is_rated` (`is_rated`)",
175
-
176
-        "UPDATE `$games_table` SET `is_rated` = '0' WHERE `white_uid` = `black_uid`",
177
-    ];
178
-
179
-    // Update database tables.
180
-    chess_set_message($module, _MI_CHESS_UPDATING_DATABASE);
181
-    foreach ($queries as $query) {
182
-        chess_set_message($module, "> $query");
183
-        $result = $xoopsDB->query($query);
184
-        if (!$result) {
185
-            $mysql_errno = $xoopsDB->errno();
186
-            $mysql_error = $xoopsDB->error();
187
-            chess_set_message($module, " ... ($mysql_errno) $mysql_error");
188
-            return false;
189
-        }
190
-        chess_set_message($module, _MI_CHESS_OK);
191
-    }
192
-
193
-    /***
160
+		"ALTER TABLE `$challenges_table` ADD `is_rated` ENUM('1','0') DEFAULT '1' NOT NULL",
161
+		"ALTER TABLE `$challenges_table` ADD INDEX `game_type` (`game_type`)",
162
+		"ALTER TABLE `$challenges_table` ADD INDEX `player1_uid` (`player1_uid`)",
163
+		"ALTER TABLE `$challenges_table` ADD INDEX `player2_uid` (`player2_uid`)",
164
+		"ALTER TABLE `$challenges_table` ADD INDEX `create_date` (`create_date`)",
165
+		"ALTER TABLE `$challenges_table` ADD INDEX `is_rated` (`is_rated`)",
166
+
167
+		"ALTER TABLE `$games_table` CHANGE `pgn_result` `pgn_result` ENUM('*','0-1','1-0','1/2-1/2') DEFAULT '*' NOT NULL",
168
+		"ALTER TABLE `$games_table` ADD `is_rated` ENUM('1','0') DEFAULT '1' NOT NULL",
169
+		"ALTER TABLE `$games_table` ADD INDEX `white_uid` (`white_uid`)",
170
+		"ALTER TABLE `$games_table` ADD INDEX `black_uid` (`black_uid`)",
171
+		"ALTER TABLE `$games_table` ADD INDEX `date` (`create_date`,`start_date`,`last_date`)",
172
+		"ALTER TABLE `$games_table` ADD INDEX `pgn_result` (`pgn_result`)",
173
+		"ALTER TABLE `$games_table` ADD INDEX `suspended_date` (`suspended`(19))",
174
+		"ALTER TABLE `$games_table` ADD INDEX `is_rated` (`is_rated`)",
175
+
176
+		"UPDATE `$games_table` SET `is_rated` = '0' WHERE `white_uid` = `black_uid`",
177
+	];
178
+
179
+	// Update database tables.
180
+	chess_set_message($module, _MI_CHESS_UPDATING_DATABASE);
181
+	foreach ($queries as $query) {
182
+		chess_set_message($module, "> $query");
183
+		$result = $xoopsDB->query($query);
184
+		if (!$result) {
185
+			$mysql_errno = $xoopsDB->errno();
186
+			$mysql_error = $xoopsDB->error();
187
+			chess_set_message($module, " ... ($mysql_errno) $mysql_error");
188
+			return false;
189
+		}
190
+		chess_set_message($module, _MI_CHESS_OK);
191
+	}
192
+
193
+	/***
194 194
      * #*#TODO# - Leave this here for now, in case I think of a way to get it to work.
195 195
      * # This causes an error about the rating_system module configuration parameter not being defined,
196 196
      * # so I added a note in INSTALL.TXT about manually recalculating the ratings after install.
@@ -201,9 +201,9 @@  discard block
 block discarded – undo
201 201
      * chess_recalc_ratings();
202 202
      ***/
203 203
 
204
-    chess_set_message($module, _MI_CHESS_UPDATE_SUCCESSFUL);
204
+	chess_set_message($module, _MI_CHESS_UPDATE_SUCCESSFUL);
205 205
 
206
-    return true; // successful
206
+	return true; // successful
207 207
 }
208 208
 
209 209
 /**
@@ -214,37 +214,37 @@  discard block
 block discarded – undo
214 214
  */
215 215
 function chess_check_tables($table_names)
216 216
 {
217
-    global $xoopsDB;
217
+	global $xoopsDB;
218 218
 
219
-    $messages = [];
219
+	$messages = [];
220 220
 
221
-    foreach ($table_names as $table_name) {
222
-        $query  = "CHECK TABLE `$table_name`";
223
-        $result = $xoopsDB->query($query);
224
-        if (!$result) {
225
-            $mysql_errno = $xoopsDB->errno();
226
-            $mysql_error = $xoopsDB->error();
227
-            $messages[]  = $query;
228
-            $messages[]  = " ... ($mysql_errno) $mysql_error";
229
-            continue;
230
-        }
221
+	foreach ($table_names as $table_name) {
222
+		$query  = "CHECK TABLE `$table_name`";
223
+		$result = $xoopsDB->query($query);
224
+		if (!$result) {
225
+			$mysql_errno = $xoopsDB->errno();
226
+			$mysql_error = $xoopsDB->error();
227
+			$messages[]  = $query;
228
+			$messages[]  = " ... ($mysql_errno) $mysql_error";
229
+			continue;
230
+		}
231 231
 
232
-        // Initialize, in case the real table status fails to get retrieved.
233
-        $table_status = '*** STATUS UNKNOWN ***';
232
+		// Initialize, in case the real table status fails to get retrieved.
233
+		$table_status = '*** STATUS UNKNOWN ***';
234 234
 
235
-        // The query may return multiple rows.  Only the last row is normally of interest, so only that row is saved.
236
-        while ($row = $xoopsDB->fetchArray($result)) {
237
-            $table_status = $row['Msg_text'];
238
-        }
235
+		// The query may return multiple rows.  Only the last row is normally of interest, so only that row is saved.
236
+		while ($row = $xoopsDB->fetchArray($result)) {
237
+			$table_status = $row['Msg_text'];
238
+		}
239 239
 
240
-        $xoopsDB->freeRecordSet($result);
240
+		$xoopsDB->freeRecordSet($result);
241 241
 
242
-        if ('OK' != $table_status) {
243
-            $messages[] = " ... $table_name: $table_status";
244
-        }
245
-    }
242
+		if ('OK' != $table_status) {
243
+			$messages[] = " ... $table_name: $table_status";
244
+		}
245
+	}
246 246
 
247
-    return $messages;
247
+	return $messages;
248 248
 }
249 249
 
250 250
 /**
@@ -259,12 +259,12 @@  discard block
 block discarded – undo
259 259
  */
260 260
 function chess_load_lang_file($filename, $module = '', $default = 'english')
261 261
 {
262
-    $lang = $GLOBALS['xoopsConfig']['language'];
263
-    $path = XOOPS_ROOT_PATH . (empty($module) ? '/' : "/modules/$module/") . 'language';
264
-    if (!($ret = @include_once("$path/$lang/$filename.php"))) {
265
-        $ret = include_once("$path/$default/$filename.php");
266
-    }
267
-    return $ret;
262
+	$lang = $GLOBALS['xoopsConfig']['language'];
263
+	$path = XOOPS_ROOT_PATH . (empty($module) ? '/' : "/modules/$module/") . 'language';
264
+	if (!($ret = @include_once("$path/$lang/$filename.php"))) {
265
+		$ret = include_once("$path/$default/$filename.php");
266
+	}
267
+	return $ret;
268 268
 }
269 269
 
270 270
 /**
@@ -276,14 +276,14 @@  discard block
 block discarded – undo
276 276
  */
277 277
 function chess_set_message($module, $text = '', $error = false)
278 278
 {
279
-    $text = $error ? "<span style='color:#ff0000;background-color:#ffffff;font-weight:bold;'>$text</span>" : $text;
280
-
281
-    // For downward compatibility with XOOPS versions that don't have the method XoopsModule::setMessage.
282
-    if (is_object($module) && method_exists($module, 'setMessage')) {
283
-        $module->setMessage($text);
284
-    } else {
285
-        echo "<code>$text</code><br />\n";
286
-    }
279
+	$text = $error ? "<span style='color:#ff0000;background-color:#ffffff;font-weight:bold;'>$text</span>" : $text;
280
+
281
+	// For downward compatibility with XOOPS versions that don't have the method XoopsModule::setMessage.
282
+	if (is_object($module) && method_exists($module, 'setMessage')) {
283
+		$module->setMessage($text);
284
+	} else {
285
+		echo "<code>$text</code><br />\n";
286
+	}
287 287
 }
288 288
 
289 289
 ?>
Please login to merge, or discard this patch.
class/ChessGame.php 2 patches
Indentation   +1978 added lines, -1978 removed lines patch added patch discarded remove patch
@@ -54,986 +54,986 @@  discard block
 block discarded – undo
54 54
  */
55 55
 class ChessGame
56 56
 {
57
-    /**
58
-     * Indicates whether object is valid.
59
-     *
60
-     * If empty string (''), indicates this is a valid object; otherwise contains an error message.
61
-     * Should be checked after creating an instance of this class.
62
-     *
63
-     * @var string  $error
64
-     */
65
-
66
-    public $error;
67
-    /**
68
-     * gamestate
69
-     *
70
-     * The game state is represented as an array with the following elements:
71
-     *
72
-     *  - 'fen_piece_placement'
73
-     *  - 'fen_active_color'
74
-     *  - 'fen_castling_availability'
75
-     *  - 'fen_en_passant_target_square'
76
-     *  - 'fen_halfmove_clock'
77
-     *  - 'fen_fullmove_number'
78
-     *  - 'pgn_result'
79
-     *  - 'pgn_fen'
80
-     *  - 'pgn_movetext'
81
-     *
82
-     * The elements prefixed with 'fen_' are standard Forsyth-Edwards Notation (FEN) elements,
83
-     * and the elements prefixed with 'pgn_' are standard Portable Game Notation (PGN) elements.
84
-     *
85
-     * Each element is a string.
86
-     *
87
-     * @var array $gamestate
88
-     */
89
-
90
-    public $gamestate;
91
-    /**
92
-     * board
93
-     *
94
-     * A 64-element array, constructed from fen_piece_placement, is used for handling moves.
95
-     * Its indices are related to the standard tile coordinates as follows:
96
-     *
97
-     * <pre>
98
-     * 8 | 56 57 58 59 60 61 62 63
99
-     * 7 | 48 49 50 51 52 53 54 55
100
-     * 6 | 40 41 42 43 44 45 46 47
101
-     * 5 | 32 33 34 35 36 37 38 39
102
-     * 4 | 24 25 26 27 28 29 30 31
103
-     * 3 | 16 17 18 19 20 21 22 23
104
-     * 2 |  8  9 10 11 12 13 14 15
105
-     * 1 |  0  1  2  3  4  5  6  7
106
-     *    ------------------------
107
-     *      a  b  c  d  e  f  g  h
108
-     * </pre>
109
-     *
110
-     * For example, $board[17] is tile b3 and $board[55] is tile h7.
111
-     *
112
-     * @var array $board
113
-     */
114
-
115
-    public $board;
116
-    /**
117
-     * for auto-completion of moves
118
-     * @var string $ac_move
119
-     */
120
-
121
-    public $ac_move;
122
-    /**
123
-     * array of white's pieces
124
-     * @var array $w_figures
125
-     */
126
-
127
-    public $w_figures;
128
-    /**
129
-     * array of black's pieces
130
-     * @var array $b_figures
131
-     */
132
-
133
-    public $b_figures;
134
-    /**
135
-     * updated by handleMove, not used now but might be used in future
136
-     * @var string $last_move
137
-     */
138
-
139
-    public $last_move;
140
-    /**
141
-     * updated by handleMove, not used now but might be used in future
142
-     * @var string $captured_piece
143
-     */
144
-
145
-    public $captured_piece;
146
-    // --------------
147
-
148
-    // PUBLIC METHODS
149
-
150
-    // --------------
151
-
152
-    /**
153
-     * constructor
154
-     *
155
-     * If a failure occurs, $this->error is set to a string containing an error message;
156
-     * otherwise $this->error is set to an empty string.
157
-     *
158
-     * Example:
159
-     * <pre>
160
-     *    $chessgame = new ChessGame($fen);
161
-     *    if (!empty($chessgame->error)) {
162
-     *      echo "'$fen' invalid: $chessgame->error\n";
163
-     *    }
164
-     * </pre>
165
-     *
166
-     * @param mixed $param If $param is an array, an existing game is loaded using $param as the nine-element gamestate array described above.
167
-     *                     If $param is a non-empty string, a new game is created using $param as a FEN setup position.
168
-     *                     Otherwise, a new game is created using the standard starting position.
169
-     */
170
-    public function __construct($param = null)
171
-    {
172
-        // for now
173
-
174
-        $this->browsing_mode = 0;
175
-
176
-        if (\is_array($param)) {
177
-            $this->gamestate = $param;
178
-
179
-            $this->error = '';
180
-        } elseif (\is_string($param) && !empty($param)) {
181
-            $this->error = $this->init_gamestate($param);
182
-        } else {
183
-            $this->init_gamestate();
184
-
185
-            $this->error = '';
186
-        }
187
-    }
188
-
189
-    /**
190
-     * Handle a move.
191
-     *
192
-     * @param string $move
193
-     * @return array A two-element array:
194
-     *  - $move_performed: true if the move was performed and the game state has been updated, false otherwise
195
-     *  - $move_result_text: text message
196
-     */
197
-    public function move($move)
198
-    {
199
-        empty($this->error) or \trigger_error(_MD_CHESS_ERROR, \E_USER_ERROR);
200
-
201
-        return $this->handleMove($move);
202
-    }
203
-
204
-    /**
205
-     * get game state
206
-     *
207
-     * @return array
208
-     */
209
-    public function gamestate()
210
-    {
211
-        empty($this->error) or \trigger_error(_MD_CHESS_ERROR, \E_USER_ERROR);
212
-
213
-        return $this->gamestate;
214
-    }
215
-
216
-    // ----------------------------------------------------------------
217
-
218
-    // PRIVATE METHODS - intended for use only by methods of this class
219
-
220
-    // ----------------------------------------------------------------
221
-
222
-    /**
223
-     * Initialize gamestate for a new game.
224
-     *
225
-     * If a non-empty string $fen is provided, the game is initialized using $fen as a FEN setup position.
226
-     * Otherwise the game is initialized using the standard starting position.
227
-     *
228
-     * @param string $fen
229
-     * @return string  empty string on success, or error message on failure
230
-     *
231
-     * @access private
232
-     */
233
-    public function init_gamestate($fen = null)
234
-    {
235
-        $this->gamestate = [];
236
-
237
-        if (!empty($fen)) {
238
-            $setup = true;
239
-        } else {
240
-            $setup = false;
241
-
242
-            $fen = 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1';
243
-        }
244
-
245
-        // check that data is not unreasonably short or long
246
-
247
-        if (\mb_strlen($fen) < 23 || \mb_strlen($fen) > 100) {
248
-            return _MD_CHESS_FENBAD_LENGTH; // invalid length
249
-        }
250
-
251
-        $fen_data = \explode(' ', $fen);
252
-
253
-        if (6 != \count($fen_data)) {
254
-            return _MD_CHESS_FENBAD_FIELD_COUNT; // wrong number of fields
255
-        }
256
-
257
-        $this->gamestate['fen_piece_placement'] = $fen_data[0];
258
-
259
-        $this->gamestate['fen_active_color'] = $fen_data[1];
260
-
261
-        $this->gamestate['fen_castling_availability'] = $fen_data[2];
262
-
263
-        $this->gamestate['fen_en_passant_target_square'] = $fen_data[3];
264
-
265
-        $this->gamestate['fen_halfmove_clock'] = $fen_data[4];
266
-
267
-        $this->gamestate['fen_fullmove_number'] = $fen_data[5];
268
-
269
-        $this->gamestate['pgn_fen'] = $setup ? $fen : null;
270
-
271
-        $this->gamestate['pgn_result'] = '*';
272
-
273
-        $this->gamestate['pgn_movetext'] = '*';
274
-
275
-        if (!$this->fen_piece_placement_to_board()) {
276
-            return _MD_CHESS_FENBAD_PP_INVALID; // piece_placement invalid
277
-        } elseif ('w' != $this->gamestate['fen_active_color'] && 'b' != $this->gamestate['fen_active_color']) {
278
-            return _MD_CHESS_FENBAD_AC_INVALID; // active_color invalid
279
-        } // Since fen_piece_placement_to_board() checked $fen for the correct number of fields above, $castling_availability is non-empty.
280
-
281
-        elseif ('-' != $this->gamestate['fen_castling_availability'] && !\preg_match('/^K?Q?k?q?$/', $this->gamestate['fen_castling_availability'])) {
282
-            return _MD_CHESS_FENBAD_CA_INVALID; // castling_availability invalid
283
-        } elseif ('-' != $this->gamestate['fen_en_passant_target_square'] && !\preg_match('/^[a-h][36]$/', $this->gamestate['fen_en_passant_target_square'])) {
284
-            return _MD_CHESS_FENBAD_EP_INVALID; // en_passant_target_square invalid
285
-        } elseif (!\preg_match('/^\d{0,4}$/', $this->gamestate['fen_halfmove_clock'])) {
286
-            return _MD_CHESS_FENBAD_HC_INVALID; // halfmove_clock invalid
287
-        } elseif (!\preg_match('/^\d{0,4}$/', $this->gamestate['fen_fullmove_number']) || $this->gamestate['fen_fullmove_number'] < 1) {
288
-            return _MD_CHESS_FENBAD_FN_INVALID; // fullmove_number invalid
289
-        } elseif ($this->insufficient_mating_material()) {
290
-            return _MD_CHESS_FENBAD_MATERIAL; // insufficient mating material
291
-        } elseif (('w' == $this->gamestate['fen_active_color'] && $this->kingIsUnderAttack('b', 'w'))
292
-                  || ('b' == $this->gamestate['fen_active_color'] && $this->kingIsUnderAttack('w', 'b'))) {
293
-            return _MD_CHESS_FENBAD_IN_CHECK; // player to move cannot have opponent in check
294
-        } elseif ((\mb_strstr($this->gamestate['fen_castling_availability'], 'K') && ('wK' != $this->board[4] || 'wR' != $this->board[7]))
295
-                  || (\mb_strstr($this->gamestate['fen_castling_availability'], 'Q') && ('wK' != $this->board[4] || 'wR' != $this->board[0]))
296
-                  || (\mb_strstr($this->gamestate['fen_castling_availability'], 'k') && ('bK' != $this->board[60] || 'bR' != $this->board[63]))
297
-                  || (\mb_strstr($this->gamestate['fen_castling_availability'], 'q') && ('bK' != $this->board[60] || 'bR' != $this->board[56]))) {
298
-            return _MD_CHESS_FENBAD_CA_INCONSISTENT; // castling availability inconsistent with piece placement
299
-        } elseif (('-' != $this->gamestate['fen_en_passant_target_square'] && 3 == $this->gamestate['fen_en_passant_target_square'][1] && 'b' != $this->gamestate['fen_active_color'])
300
-                  || ('-' != $this->gamestate['fen_en_passant_target_square'] && 6 == $this->gamestate['fen_en_passant_target_square'][1] && 'w' != $this->gamestate['fen_active_color'])) {
301
-            return _MD_CHESS_FENBAD_EP_COLOR; // en passant target square wrong color
302
-        } elseif ('-' != $this->gamestate['fen_en_passant_target_square'] && 3 == $this->gamestate['fen_en_passant_target_square'][1]
303
-                  && 'wP' != $this->board[$this->boardCoordToIndex($this->gamestate['fen_en_passant_target_square'][0] . '4')]) {
304
-            return _MD_CHESS_FENBAD_EP_NO_PAWN; // en passant target square for nonexistent pawn
305
-        } elseif ('-' != $this->gamestate['fen_en_passant_target_square'] && 6 == $this->gamestate['fen_en_passant_target_square'][1]
306
-                  && 'bP' != $this->board[$this->boardCoordToIndex($this->gamestate['fen_en_passant_target_square'][0] . '5')]) {
307
-            return _MD_CHESS_FENBAD_EP_NO_PAWN; // en passant target square for nonexistent pawn
308
-        }
309
-
310
-        #echo "In " . __CLASS__ . '::' . __FUNCTION__ . "\n";#*#DEBUG#
311
-
312
-        #var_dump('gamestate', $this->gamestate);#*#DEBUG#
313
-
314
-        return ''; // successful
315
-    }
316
-
317
-    /**
318
-     * Check whether a path is blocked.
319
-     *
320
-     * check a series of tiles given a start, an end tile
321
-     * which is not included to the check and a position
322
-     * change for each iteration. return true if not blocked.
323
-     * all values are given for 1dim board.
324
-     *
325
-     * @param int $start
326
-     * @param int $end
327
-     * @param int $change
328
-     * @return bool
329
-     *
330
-     * @access private
331
-     */
332
-    public function pathIsNotBlocked($start, $end, $change)
333
-    {
334
-        for ($pos = $start; $pos != $end; $pos += $change) {
335
-            #echo "path: $pos: '$this->board[$pos]' "; #*#DEBUG#
336
-
337
-            if (!$this->is_empty_tile($pos)) {
338
-                return 0;
339
-            }
340
-        }
341
-
342
-        return 1;
343
-    }
344
-
345
-    /**
346
-     * Get path.
347
-     *
348
-     * get the empty tiles between start and end as an 1dim array.
349
-     * whether the path is clear is not checked.
350
-     *
351
-     * @param int $start
352
-     * @param int $end
353
-     * @param int $change
354
-     * @return array
355
-     *
356
-     * @access private
357
-     */
358
-    public function getPath($start, $end, $change)
359
-    {
360
-        $path = [];
361
-
362
-        for ($pos = $start; $pos != $end; $pos += $change) {
363
-            $path[] = $pos;
364
-        }
365
-
366
-        return $path;
367
-    }
368
-
369
-    /**
370
-     * get path change
371
-     *
372
-     * get the change value that must be added to create
373
-     * the 1dim path for figure moving from fig_pos to
374
-     * dest_pos. it is assumed that the movement is valid!
375
-     * no additional checks as in tileIsReachable are
376
-     * performed. rook, queen and bishop are the only
377
-     * units that can have empty tiles in between.
378
-     *
379
-     * @param string $fig
380
-     * @param int    $fig_pos
381
-     * @param int    $dest_pos
382
-     * @return int
383
-     *
384
-     * @access private
385
-     */
386
-    public function getPathChange($fig, $fig_pos, $dest_pos)
387
-    {
388
-        $change = 0;
389
-
390
-        $fy = \floor($fig_pos / 8);
391
-
392
-        $fx = $fig_pos % 8;
393
-
394
-        $dx = $dest_pos % 8;
395
-
396
-        $dy = \floor($dest_pos / 8);
397
-
398
-        switch ($fig) {
399
-            /* bishop */ case 'B':
400
-            $change = $dy < $fy ? -8 : 8;
401
-            $change += $dx < $fx ? -1 : 1;
402
-            break;
403
-            /* rook */ case 'R':
404
-            if ($fx == $dx) {
405
-                $change = $dy < $fy ? -8 : 8;
406
-            } else {
407
-                $change = $dx < $fx ? -1 : 1;
408
-            }
409
-            break;
410
-            /* queen */ case 'Q':
411
-            if (\abs($fx - $dx) == \abs($fy - $dy)) {
412
-                $change = $dy < $fy ? -8 : 8;
413
-
414
-                $change += $dx < $fx ? -1 : 1;
415
-            } elseif ($fx == $dx) {
416
-                $change = $dy < $fy ? -8 : 8;
417
-            } else {
418
-                $change = $dx < $fx ? -1 : 1;
419
-            }
420
-            break;
421
-        }
422
-
423
-        return $change;
424
-    }
425
-
426
-    /**
427
-     * Check whether a tile is reachable.
428
-     *
429
-     * check whether dest_pos is in reach for unit of fig_type
430
-     * at tile fig_pos. it is not checked whether the tile
431
-     * itself is occupied but only the tiles in between.
432
-     * this function does not check pawns.
433
-     *
434
-     * @param string $fig
435
-     * @param int    $fig_pos
436
-     * @param int    $dest_pos
437
-     * @return bool
438
-     *
439
-     * @access private
440
-     */
441
-    public function tileIsReachable($fig, $fig_pos, $dest_pos)
442
-    {
443
-        if ($fig_pos == $dest_pos) {
444
-            return;
445
-        }
446
-
447
-        $result = 0;
448
-
449
-        $fy = \floor($fig_pos / 8);
450
-
451
-        $fx = $fig_pos % 8;
452
-
453
-        $dy = \floor($dest_pos / 8);
454
-
455
-        $dx = $dest_pos % 8;
456
-
457
-        /* DEBUG:  echo "$fx,$fy --> $dx,$dy: "; */
458
-
459
-        switch ($fig) {
460
-            /* knight */ case 'N':
461
-            if (1 == \abs($fx - $dx) && 2 == \abs($fy - $dy)) {
462
-                $result = 1;
463
-            }
464
-            if (1 == \abs($fy - $dy) && 2 == \abs($fx - $dx)) {
465
-                $result = 1;
466
-            }
467
-            break;
468
-            /* bishop */ case 'B':
469
-            if (\abs($fx - $dx) != \abs($fy - $dy)) {
470
-                break;
471
-            }
472
-            if ($dy < $fy) {
473
-                $change = -8;
474
-            } else {
475
-                $change = 8;
476
-            }
477
-            if ($dx < $fx) {
478
-                --$change;
479
-            } else {
480
-                ++$change;
481
-            }
482
-            if ($this->pathIsNotBlocked($fig_pos + $change, $dest_pos, $change)) {
483
-                $result = 1;
484
-            }
485
-            break;
486
-            /* rook */ case 'R':
487
-            if ($fx != $dx && $fy != $dy) {
488
-                break;
489
-            }
490
-            if ($fx == $dx) {
491
-                if ($dy < $fy) {
492
-                    $change = -8;
493
-                } else {
494
-                    $change = 8;
495
-                }
496
-            } else {
497
-                if ($dx < $fx) {
498
-                    $change = -1;
499
-                } else {
500
-                    $change = 1;
501
-                }
502
-            }
503
-            if ($this->pathIsNotBlocked($fig_pos + $change, $dest_pos, $change)) {
504
-                $result = 1;
505
-            }
506
-            break;
507
-            /* queen */ case 'Q':
508
-            if (\abs($fx - $dx) != \abs($fy - $dy) && $fx != $dx && $fy != $dy) {
509
-                break;
510
-            }
511
-            if (\abs($fx - $dx) == \abs($fy - $dy)) {
512
-                if ($dy < $fy) {
513
-                    $change = -8;
514
-                } else {
515
-                    $change = 8;
516
-                }
517
-
518
-                if ($dx < $fx) {
519
-                    --$change;
520
-                } else {
521
-                    ++$change;
522
-                }
523
-            } elseif ($fx == $dx) {
524
-                if ($dy < $fy) {
525
-                    $change = -8;
526
-                } else {
527
-                    $change = 8;
528
-                }
529
-            } else {
530
-                if ($dx < $fx) {
531
-                    $change = -1;
532
-                } else {
533
-                    $change = 1;
534
-                }
535
-            }
536
-            if ($this->pathIsNotBlocked($fig_pos + $change, $dest_pos, $change)) {
537
-                $result = 1;
538
-            }
539
-            break;
540
-            /* king */ case 'K':
541
-            if (\abs($fx - $dx) > 1 || \abs($fy - $dy) > 1) {
542
-                break;
543
-            }
544
-            $kings     = 0;
545
-            $adj_tiles = $this->getAdjTiles($dest_pos);
546
-            foreach ($adj_tiles as $tile) {
547
-                if ('K' == $this->board[$tile][1]) {
548
-                    $kings++;
549
-                }
550
-            }
551
-            if (2 == $kings) {
552
-                break;
553
-            }
554
-            $result = 1;
555
-            break;
556
-        }
557
-
558
-        /* DEBUG: echo " $result<br>"; */
559
-
560
-        return $result;
561
-    }
562
-
563
-    /**
564
-     * Check whether a pawn can attack a tile.
565
-     *
566
-     * @param int $fig_pos  Position of pawn
567
-     * @param int $dest_pos Tile to check
568
-     * @return bool True if pawn can attack
569
-     *
570
-     * @access private
571
-     */
572
-    public function checkPawnAttack($fig_pos, $dest_pos)
573
-    {
574
-        if ('w' == $this->board[$fig_pos][0]) {
575
-            if ($fig_pos % 8 > 0 && $dest_pos == $fig_pos + 7) {
576
-                return 1;
577
-            }
578
-
579
-            if ($fig_pos % 8 < 7 && $dest_pos == $fig_pos + 9) {
580
-                return 1;
581
-            }
582
-        } elseif ('b' == $this->board[$fig_pos][0]) {
583
-            if ($fig_pos % 8 < 7 && $dest_pos == $fig_pos - 7) {
584
-                return 1;
585
-            }
586
-
587
-            if ($fig_pos % 8 > 0 && $dest_pos == $fig_pos - 9) {
588
-                return 1;
589
-            }
590
-        }
591
-
592
-        return 0;
593
-    }
594
-
595
-    /**
596
-     * Check whether a pawn move is legal.
597
-     *
598
-     * check whether pawn at figpos may move to destpos.
599
-     * first move may be two tiles instead of just one.
600
-     * again the last tile is not checked but just the path
601
-     * in between.
602
-     *
603
-     * @param int $fig_pos  Position of pawn.
604
-     * @param int $dest_pos Destination tile.
605
-     * @return bool True if move is legal
606
-     *
607
-     * @access private
608
-     */
609
-    public function checkPawnMove($fig_pos, $dest_pos)
610
-    {
611
-        $first_move = 0;
612
-
613
-        if ('w' == $this->board[$fig_pos][0]) {
614
-            if ($fig_pos >= 8 && $fig_pos <= 15) {
615
-                $first_move = 1;
616
-            }
617
-
618
-            if ($dest_pos == $fig_pos + 8) {
619
-                return 1;
620
-            }
621
-
622
-            if ($first_move && ($dest_pos == $fig_pos + 16)) {
623
-                if ($this->is_empty_tile($fig_pos + 8)) {
624
-                    return 1;
625
-                }
626
-            }
627
-        } elseif ('b' == $this->board[$fig_pos][0]) {
628
-            if ($fig_pos >= 48 && $fig_pos <= 55) {
629
-                $first_move = 1;
630
-            }
631
-
632
-            if ($dest_pos == $fig_pos - 8) {
633
-                return 1;
634
-            }
635
-
636
-            if ($first_move && ($dest_pos == $fig_pos - 16)) {
637
-                if ($this->is_empty_tile($fig_pos - 8)) {
638
-                    return 1;
639
-                }
640
-            }
641
-        }
642
-
643
-        return 0;
644
-    }
645
-
646
-    /**
647
-     * Check whether a tile is under attack by the specified player.
648
-     *
649
-     * @param string $opp      Attacking color ('w' or 'b')
650
-     * @param int    $dest_pos Tile to check
651
-     * @return bool
652
-     *
653
-     * @access private
654
-     */
655
-    public function tileIsUnderAttack($opp, $dest_pos)
656
-    {
657
-        #var_dump('tileIsUnderAttack, opp', $opp, 'dest_pos', $dest_pos, 'board', $board);#*#DEBUG#
658
-
659
-        for ($i = 0; $i < 64; $i++) {
660
-            if ($this->board[$i][0] == $opp) {
661
-                if (('P' == $this->board[$i][1] && $this->checkPawnAttack($i, $dest_pos))
662
-                    || ('P' != $this->board[$i][1]
663
-                        && $this->tileIsReachable($this->board[$i][1], $i, $dest_pos))) {
664
-                    /*DEBUG: echo "attack test: $i: ",$opp,"P<br>"; */
665
-
666
-                    return 1;
667
-                }
668
-            }
669
-        }
670
-
671
-        return 0;
672
-    }
673
-
674
-    /**
675
-     * Check whether a player's king can be attacked by his opponent.
676
-     *
677
-     * @param string $player Player's color ('w' or 'b')
678
-     * @param string $opp    Opponent's color ('w' or 'b')
679
-     * @return bool
680
-     *
681
-     * @access private
682
-     */
683
-    public function kingIsUnderAttack($player, $opp)
684
-    {
685
-        #var_dump('kingIsUnderAttack, player', $player, 'opp', $opp, 'board', $board);#*#DEBUG#
686
-
687
-        for ($i = 0; $i < 64; $i++) {
688
-            if ($this->board[$i][0] == $player && 'K' == $this->board[$i][1]) {
689
-                $king_pos = $i;
690
-
691
-                break;
692
-            }
693
-        }
694
-
695
-        /*DEBUG: echo "$player king is at $king_pos<br>"; */
696
-
697
-        return $this->tileIsUnderAttack($opp, $king_pos);
698
-    }
699
-
700
-    /**
701
-     * Check whether player's king is checkmated by his opponent.
702
-     *
703
-     * @param string $player Player's color ('w' or 'b')
704
-     * @param string $opp    Opponent's color ('w' or 'b')
705
-     * @return bool
706
-     *
707
-     * @access private
708
-     */
709
-    public function isCheckMate($player, $opp)
710
-    {
711
-        for ($i = 0; $i < 64; $i++) {
712
-            if ($this->board[$i][0] == $player && 'K' == $this->board[$i][1]) {
713
-                $king_pos = $i;
714
-
715
-                $king_x = $i % 8;
716
-
717
-                $king_y = \floor($i / 8);
718
-
719
-                break;
720
-            }
721
-        }
722
-
723
-        /* test adjacent tiles while king is temporarly removed */
724
-
725
-        $adj_tiles = $this->getAdjTiles($king_pos);
726
-
727
-        $contents = $this->board[$king_pos];
728
-
729
-        $this->clear_tile($king_pos);
730
-
731
-        foreach ($adj_tiles as $dest_pos) {
732
-            if ($this->board[$dest_pos][0] == $player) {
733
-                continue;
734
-            }
735
-
736
-            if ($this->tileIsUnderAttack($opp, $dest_pos)) {
737
-                continue;
738
-            }
739
-
740
-            $this->board[$king_pos] = $contents;
741
-
742
-            return 0;
743
-        }
744
-
745
-        $this->board[$king_pos] = $contents;
746
-
747
-        /* DEBUG:  echo "King cannot escape by itself! "; */
748
-
749
-        /* get all figures that attack the king */
750
-
751
-        $attackers = [];
752
-
753
-        $count = 0;
754
-
755
-        for ($i = 0; $i < 64; $i++) {
756
-            if ($this->board[$i][0] == $opp) {
757
-                if (('P' == $this->board[$i][1] && $this->checkPawnAttack($i, $king_pos))
758
-                    || ('P' != $this->board[$i][1]
759
-                        && $this->tileIsReachable($this->board[$i][1], $i, $king_pos))) {
760
-                    $attackers[$count++] = $i;
761
-                }
762
-            }
763
-        }
57
+	/**
58
+	 * Indicates whether object is valid.
59
+	 *
60
+	 * If empty string (''), indicates this is a valid object; otherwise contains an error message.
61
+	 * Should be checked after creating an instance of this class.
62
+	 *
63
+	 * @var string  $error
64
+	 */
65
+
66
+	public $error;
67
+	/**
68
+	 * gamestate
69
+	 *
70
+	 * The game state is represented as an array with the following elements:
71
+	 *
72
+	 *  - 'fen_piece_placement'
73
+	 *  - 'fen_active_color'
74
+	 *  - 'fen_castling_availability'
75
+	 *  - 'fen_en_passant_target_square'
76
+	 *  - 'fen_halfmove_clock'
77
+	 *  - 'fen_fullmove_number'
78
+	 *  - 'pgn_result'
79
+	 *  - 'pgn_fen'
80
+	 *  - 'pgn_movetext'
81
+	 *
82
+	 * The elements prefixed with 'fen_' are standard Forsyth-Edwards Notation (FEN) elements,
83
+	 * and the elements prefixed with 'pgn_' are standard Portable Game Notation (PGN) elements.
84
+	 *
85
+	 * Each element is a string.
86
+	 *
87
+	 * @var array $gamestate
88
+	 */
89
+
90
+	public $gamestate;
91
+	/**
92
+	 * board
93
+	 *
94
+	 * A 64-element array, constructed from fen_piece_placement, is used for handling moves.
95
+	 * Its indices are related to the standard tile coordinates as follows:
96
+	 *
97
+	 * <pre>
98
+	 * 8 | 56 57 58 59 60 61 62 63
99
+	 * 7 | 48 49 50 51 52 53 54 55
100
+	 * 6 | 40 41 42 43 44 45 46 47
101
+	 * 5 | 32 33 34 35 36 37 38 39
102
+	 * 4 | 24 25 26 27 28 29 30 31
103
+	 * 3 | 16 17 18 19 20 21 22 23
104
+	 * 2 |  8  9 10 11 12 13 14 15
105
+	 * 1 |  0  1  2  3  4  5  6  7
106
+	 *    ------------------------
107
+	 *      a  b  c  d  e  f  g  h
108
+	 * </pre>
109
+	 *
110
+	 * For example, $board[17] is tile b3 and $board[55] is tile h7.
111
+	 *
112
+	 * @var array $board
113
+	 */
114
+
115
+	public $board;
116
+	/**
117
+	 * for auto-completion of moves
118
+	 * @var string $ac_move
119
+	 */
120
+
121
+	public $ac_move;
122
+	/**
123
+	 * array of white's pieces
124
+	 * @var array $w_figures
125
+	 */
126
+
127
+	public $w_figures;
128
+	/**
129
+	 * array of black's pieces
130
+	 * @var array $b_figures
131
+	 */
132
+
133
+	public $b_figures;
134
+	/**
135
+	 * updated by handleMove, not used now but might be used in future
136
+	 * @var string $last_move
137
+	 */
138
+
139
+	public $last_move;
140
+	/**
141
+	 * updated by handleMove, not used now but might be used in future
142
+	 * @var string $captured_piece
143
+	 */
144
+
145
+	public $captured_piece;
146
+	// --------------
147
+
148
+	// PUBLIC METHODS
149
+
150
+	// --------------
151
+
152
+	/**
153
+	 * constructor
154
+	 *
155
+	 * If a failure occurs, $this->error is set to a string containing an error message;
156
+	 * otherwise $this->error is set to an empty string.
157
+	 *
158
+	 * Example:
159
+	 * <pre>
160
+	 *    $chessgame = new ChessGame($fen);
161
+	 *    if (!empty($chessgame->error)) {
162
+	 *      echo "'$fen' invalid: $chessgame->error\n";
163
+	 *    }
164
+	 * </pre>
165
+	 *
166
+	 * @param mixed $param If $param is an array, an existing game is loaded using $param as the nine-element gamestate array described above.
167
+	 *                     If $param is a non-empty string, a new game is created using $param as a FEN setup position.
168
+	 *                     Otherwise, a new game is created using the standard starting position.
169
+	 */
170
+	public function __construct($param = null)
171
+	{
172
+		// for now
173
+
174
+		$this->browsing_mode = 0;
175
+
176
+		if (\is_array($param)) {
177
+			$this->gamestate = $param;
178
+
179
+			$this->error = '';
180
+		} elseif (\is_string($param) && !empty($param)) {
181
+			$this->error = $this->init_gamestate($param);
182
+		} else {
183
+			$this->init_gamestate();
184
+
185
+			$this->error = '';
186
+		}
187
+	}
188
+
189
+	/**
190
+	 * Handle a move.
191
+	 *
192
+	 * @param string $move
193
+	 * @return array A two-element array:
194
+	 *  - $move_performed: true if the move was performed and the game state has been updated, false otherwise
195
+	 *  - $move_result_text: text message
196
+	 */
197
+	public function move($move)
198
+	{
199
+		empty($this->error) or \trigger_error(_MD_CHESS_ERROR, \E_USER_ERROR);
200
+
201
+		return $this->handleMove($move);
202
+	}
203
+
204
+	/**
205
+	 * get game state
206
+	 *
207
+	 * @return array
208
+	 */
209
+	public function gamestate()
210
+	{
211
+		empty($this->error) or \trigger_error(_MD_CHESS_ERROR, \E_USER_ERROR);
212
+
213
+		return $this->gamestate;
214
+	}
215
+
216
+	// ----------------------------------------------------------------
217
+
218
+	// PRIVATE METHODS - intended for use only by methods of this class
219
+
220
+	// ----------------------------------------------------------------
221
+
222
+	/**
223
+	 * Initialize gamestate for a new game.
224
+	 *
225
+	 * If a non-empty string $fen is provided, the game is initialized using $fen as a FEN setup position.
226
+	 * Otherwise the game is initialized using the standard starting position.
227
+	 *
228
+	 * @param string $fen
229
+	 * @return string  empty string on success, or error message on failure
230
+	 *
231
+	 * @access private
232
+	 */
233
+	public function init_gamestate($fen = null)
234
+	{
235
+		$this->gamestate = [];
236
+
237
+		if (!empty($fen)) {
238
+			$setup = true;
239
+		} else {
240
+			$setup = false;
241
+
242
+			$fen = 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1';
243
+		}
244
+
245
+		// check that data is not unreasonably short or long
246
+
247
+		if (\mb_strlen($fen) < 23 || \mb_strlen($fen) > 100) {
248
+			return _MD_CHESS_FENBAD_LENGTH; // invalid length
249
+		}
250
+
251
+		$fen_data = \explode(' ', $fen);
252
+
253
+		if (6 != \count($fen_data)) {
254
+			return _MD_CHESS_FENBAD_FIELD_COUNT; // wrong number of fields
255
+		}
256
+
257
+		$this->gamestate['fen_piece_placement'] = $fen_data[0];
258
+
259
+		$this->gamestate['fen_active_color'] = $fen_data[1];
260
+
261
+		$this->gamestate['fen_castling_availability'] = $fen_data[2];
262
+
263
+		$this->gamestate['fen_en_passant_target_square'] = $fen_data[3];
264
+
265
+		$this->gamestate['fen_halfmove_clock'] = $fen_data[4];
266
+
267
+		$this->gamestate['fen_fullmove_number'] = $fen_data[5];
268
+
269
+		$this->gamestate['pgn_fen'] = $setup ? $fen : null;
270
+
271
+		$this->gamestate['pgn_result'] = '*';
272
+
273
+		$this->gamestate['pgn_movetext'] = '*';
274
+
275
+		if (!$this->fen_piece_placement_to_board()) {
276
+			return _MD_CHESS_FENBAD_PP_INVALID; // piece_placement invalid
277
+		} elseif ('w' != $this->gamestate['fen_active_color'] && 'b' != $this->gamestate['fen_active_color']) {
278
+			return _MD_CHESS_FENBAD_AC_INVALID; // active_color invalid
279
+		} // Since fen_piece_placement_to_board() checked $fen for the correct number of fields above, $castling_availability is non-empty.
280
+
281
+		elseif ('-' != $this->gamestate['fen_castling_availability'] && !\preg_match('/^K?Q?k?q?$/', $this->gamestate['fen_castling_availability'])) {
282
+			return _MD_CHESS_FENBAD_CA_INVALID; // castling_availability invalid
283
+		} elseif ('-' != $this->gamestate['fen_en_passant_target_square'] && !\preg_match('/^[a-h][36]$/', $this->gamestate['fen_en_passant_target_square'])) {
284
+			return _MD_CHESS_FENBAD_EP_INVALID; // en_passant_target_square invalid
285
+		} elseif (!\preg_match('/^\d{0,4}$/', $this->gamestate['fen_halfmove_clock'])) {
286
+			return _MD_CHESS_FENBAD_HC_INVALID; // halfmove_clock invalid
287
+		} elseif (!\preg_match('/^\d{0,4}$/', $this->gamestate['fen_fullmove_number']) || $this->gamestate['fen_fullmove_number'] < 1) {
288
+			return _MD_CHESS_FENBAD_FN_INVALID; // fullmove_number invalid
289
+		} elseif ($this->insufficient_mating_material()) {
290
+			return _MD_CHESS_FENBAD_MATERIAL; // insufficient mating material
291
+		} elseif (('w' == $this->gamestate['fen_active_color'] && $this->kingIsUnderAttack('b', 'w'))
292
+				  || ('b' == $this->gamestate['fen_active_color'] && $this->kingIsUnderAttack('w', 'b'))) {
293
+			return _MD_CHESS_FENBAD_IN_CHECK; // player to move cannot have opponent in check
294
+		} elseif ((\mb_strstr($this->gamestate['fen_castling_availability'], 'K') && ('wK' != $this->board[4] || 'wR' != $this->board[7]))
295
+				  || (\mb_strstr($this->gamestate['fen_castling_availability'], 'Q') && ('wK' != $this->board[4] || 'wR' != $this->board[0]))
296
+				  || (\mb_strstr($this->gamestate['fen_castling_availability'], 'k') && ('bK' != $this->board[60] || 'bR' != $this->board[63]))
297
+				  || (\mb_strstr($this->gamestate['fen_castling_availability'], 'q') && ('bK' != $this->board[60] || 'bR' != $this->board[56]))) {
298
+			return _MD_CHESS_FENBAD_CA_INCONSISTENT; // castling availability inconsistent with piece placement
299
+		} elseif (('-' != $this->gamestate['fen_en_passant_target_square'] && 3 == $this->gamestate['fen_en_passant_target_square'][1] && 'b' != $this->gamestate['fen_active_color'])
300
+				  || ('-' != $this->gamestate['fen_en_passant_target_square'] && 6 == $this->gamestate['fen_en_passant_target_square'][1] && 'w' != $this->gamestate['fen_active_color'])) {
301
+			return _MD_CHESS_FENBAD_EP_COLOR; // en passant target square wrong color
302
+		} elseif ('-' != $this->gamestate['fen_en_passant_target_square'] && 3 == $this->gamestate['fen_en_passant_target_square'][1]
303
+				  && 'wP' != $this->board[$this->boardCoordToIndex($this->gamestate['fen_en_passant_target_square'][0] . '4')]) {
304
+			return _MD_CHESS_FENBAD_EP_NO_PAWN; // en passant target square for nonexistent pawn
305
+		} elseif ('-' != $this->gamestate['fen_en_passant_target_square'] && 6 == $this->gamestate['fen_en_passant_target_square'][1]
306
+				  && 'bP' != $this->board[$this->boardCoordToIndex($this->gamestate['fen_en_passant_target_square'][0] . '5')]) {
307
+			return _MD_CHESS_FENBAD_EP_NO_PAWN; // en passant target square for nonexistent pawn
308
+		}
309
+
310
+		#echo "In " . __CLASS__ . '::' . __FUNCTION__ . "\n";#*#DEBUG#
311
+
312
+		#var_dump('gamestate', $this->gamestate);#*#DEBUG#
313
+
314
+		return ''; // successful
315
+	}
316
+
317
+	/**
318
+	 * Check whether a path is blocked.
319
+	 *
320
+	 * check a series of tiles given a start, an end tile
321
+	 * which is not included to the check and a position
322
+	 * change for each iteration. return true if not blocked.
323
+	 * all values are given for 1dim board.
324
+	 *
325
+	 * @param int $start
326
+	 * @param int $end
327
+	 * @param int $change
328
+	 * @return bool
329
+	 *
330
+	 * @access private
331
+	 */
332
+	public function pathIsNotBlocked($start, $end, $change)
333
+	{
334
+		for ($pos = $start; $pos != $end; $pos += $change) {
335
+			#echo "path: $pos: '$this->board[$pos]' "; #*#DEBUG#
336
+
337
+			if (!$this->is_empty_tile($pos)) {
338
+				return 0;
339
+			}
340
+		}
341
+
342
+		return 1;
343
+	}
344
+
345
+	/**
346
+	 * Get path.
347
+	 *
348
+	 * get the empty tiles between start and end as an 1dim array.
349
+	 * whether the path is clear is not checked.
350
+	 *
351
+	 * @param int $start
352
+	 * @param int $end
353
+	 * @param int $change
354
+	 * @return array
355
+	 *
356
+	 * @access private
357
+	 */
358
+	public function getPath($start, $end, $change)
359
+	{
360
+		$path = [];
361
+
362
+		for ($pos = $start; $pos != $end; $pos += $change) {
363
+			$path[] = $pos;
364
+		}
365
+
366
+		return $path;
367
+	}
368
+
369
+	/**
370
+	 * get path change
371
+	 *
372
+	 * get the change value that must be added to create
373
+	 * the 1dim path for figure moving from fig_pos to
374
+	 * dest_pos. it is assumed that the movement is valid!
375
+	 * no additional checks as in tileIsReachable are
376
+	 * performed. rook, queen and bishop are the only
377
+	 * units that can have empty tiles in between.
378
+	 *
379
+	 * @param string $fig
380
+	 * @param int    $fig_pos
381
+	 * @param int    $dest_pos
382
+	 * @return int
383
+	 *
384
+	 * @access private
385
+	 */
386
+	public function getPathChange($fig, $fig_pos, $dest_pos)
387
+	{
388
+		$change = 0;
389
+
390
+		$fy = \floor($fig_pos / 8);
391
+
392
+		$fx = $fig_pos % 8;
393
+
394
+		$dx = $dest_pos % 8;
395
+
396
+		$dy = \floor($dest_pos / 8);
397
+
398
+		switch ($fig) {
399
+			/* bishop */ case 'B':
400
+			$change = $dy < $fy ? -8 : 8;
401
+			$change += $dx < $fx ? -1 : 1;
402
+			break;
403
+			/* rook */ case 'R':
404
+			if ($fx == $dx) {
405
+				$change = $dy < $fy ? -8 : 8;
406
+			} else {
407
+				$change = $dx < $fx ? -1 : 1;
408
+			}
409
+			break;
410
+			/* queen */ case 'Q':
411
+			if (\abs($fx - $dx) == \abs($fy - $dy)) {
412
+				$change = $dy < $fy ? -8 : 8;
413
+
414
+				$change += $dx < $fx ? -1 : 1;
415
+			} elseif ($fx == $dx) {
416
+				$change = $dy < $fy ? -8 : 8;
417
+			} else {
418
+				$change = $dx < $fx ? -1 : 1;
419
+			}
420
+			break;
421
+		}
422
+
423
+		return $change;
424
+	}
425
+
426
+	/**
427
+	 * Check whether a tile is reachable.
428
+	 *
429
+	 * check whether dest_pos is in reach for unit of fig_type
430
+	 * at tile fig_pos. it is not checked whether the tile
431
+	 * itself is occupied but only the tiles in between.
432
+	 * this function does not check pawns.
433
+	 *
434
+	 * @param string $fig
435
+	 * @param int    $fig_pos
436
+	 * @param int    $dest_pos
437
+	 * @return bool
438
+	 *
439
+	 * @access private
440
+	 */
441
+	public function tileIsReachable($fig, $fig_pos, $dest_pos)
442
+	{
443
+		if ($fig_pos == $dest_pos) {
444
+			return;
445
+		}
446
+
447
+		$result = 0;
448
+
449
+		$fy = \floor($fig_pos / 8);
450
+
451
+		$fx = $fig_pos % 8;
452
+
453
+		$dy = \floor($dest_pos / 8);
454
+
455
+		$dx = $dest_pos % 8;
456
+
457
+		/* DEBUG:  echo "$fx,$fy --> $dx,$dy: "; */
458
+
459
+		switch ($fig) {
460
+			/* knight */ case 'N':
461
+			if (1 == \abs($fx - $dx) && 2 == \abs($fy - $dy)) {
462
+				$result = 1;
463
+			}
464
+			if (1 == \abs($fy - $dy) && 2 == \abs($fx - $dx)) {
465
+				$result = 1;
466
+			}
467
+			break;
468
+			/* bishop */ case 'B':
469
+			if (\abs($fx - $dx) != \abs($fy - $dy)) {
470
+				break;
471
+			}
472
+			if ($dy < $fy) {
473
+				$change = -8;
474
+			} else {
475
+				$change = 8;
476
+			}
477
+			if ($dx < $fx) {
478
+				--$change;
479
+			} else {
480
+				++$change;
481
+			}
482
+			if ($this->pathIsNotBlocked($fig_pos + $change, $dest_pos, $change)) {
483
+				$result = 1;
484
+			}
485
+			break;
486
+			/* rook */ case 'R':
487
+			if ($fx != $dx && $fy != $dy) {
488
+				break;
489
+			}
490
+			if ($fx == $dx) {
491
+				if ($dy < $fy) {
492
+					$change = -8;
493
+				} else {
494
+					$change = 8;
495
+				}
496
+			} else {
497
+				if ($dx < $fx) {
498
+					$change = -1;
499
+				} else {
500
+					$change = 1;
501
+				}
502
+			}
503
+			if ($this->pathIsNotBlocked($fig_pos + $change, $dest_pos, $change)) {
504
+				$result = 1;
505
+			}
506
+			break;
507
+			/* queen */ case 'Q':
508
+			if (\abs($fx - $dx) != \abs($fy - $dy) && $fx != $dx && $fy != $dy) {
509
+				break;
510
+			}
511
+			if (\abs($fx - $dx) == \abs($fy - $dy)) {
512
+				if ($dy < $fy) {
513
+					$change = -8;
514
+				} else {
515
+					$change = 8;
516
+				}
517
+
518
+				if ($dx < $fx) {
519
+					--$change;
520
+				} else {
521
+					++$change;
522
+				}
523
+			} elseif ($fx == $dx) {
524
+				if ($dy < $fy) {
525
+					$change = -8;
526
+				} else {
527
+					$change = 8;
528
+				}
529
+			} else {
530
+				if ($dx < $fx) {
531
+					$change = -1;
532
+				} else {
533
+					$change = 1;
534
+				}
535
+			}
536
+			if ($this->pathIsNotBlocked($fig_pos + $change, $dest_pos, $change)) {
537
+				$result = 1;
538
+			}
539
+			break;
540
+			/* king */ case 'K':
541
+			if (\abs($fx - $dx) > 1 || \abs($fy - $dy) > 1) {
542
+				break;
543
+			}
544
+			$kings     = 0;
545
+			$adj_tiles = $this->getAdjTiles($dest_pos);
546
+			foreach ($adj_tiles as $tile) {
547
+				if ('K' == $this->board[$tile][1]) {
548
+					$kings++;
549
+				}
550
+			}
551
+			if (2 == $kings) {
552
+				break;
553
+			}
554
+			$result = 1;
555
+			break;
556
+		}
557
+
558
+		/* DEBUG: echo " $result<br>"; */
559
+
560
+		return $result;
561
+	}
562
+
563
+	/**
564
+	 * Check whether a pawn can attack a tile.
565
+	 *
566
+	 * @param int $fig_pos  Position of pawn
567
+	 * @param int $dest_pos Tile to check
568
+	 * @return bool True if pawn can attack
569
+	 *
570
+	 * @access private
571
+	 */
572
+	public function checkPawnAttack($fig_pos, $dest_pos)
573
+	{
574
+		if ('w' == $this->board[$fig_pos][0]) {
575
+			if ($fig_pos % 8 > 0 && $dest_pos == $fig_pos + 7) {
576
+				return 1;
577
+			}
578
+
579
+			if ($fig_pos % 8 < 7 && $dest_pos == $fig_pos + 9) {
580
+				return 1;
581
+			}
582
+		} elseif ('b' == $this->board[$fig_pos][0]) {
583
+			if ($fig_pos % 8 < 7 && $dest_pos == $fig_pos - 7) {
584
+				return 1;
585
+			}
586
+
587
+			if ($fig_pos % 8 > 0 && $dest_pos == $fig_pos - 9) {
588
+				return 1;
589
+			}
590
+		}
591
+
592
+		return 0;
593
+	}
594
+
595
+	/**
596
+	 * Check whether a pawn move is legal.
597
+	 *
598
+	 * check whether pawn at figpos may move to destpos.
599
+	 * first move may be two tiles instead of just one.
600
+	 * again the last tile is not checked but just the path
601
+	 * in between.
602
+	 *
603
+	 * @param int $fig_pos  Position of pawn.
604
+	 * @param int $dest_pos Destination tile.
605
+	 * @return bool True if move is legal
606
+	 *
607
+	 * @access private
608
+	 */
609
+	public function checkPawnMove($fig_pos, $dest_pos)
610
+	{
611
+		$first_move = 0;
612
+
613
+		if ('w' == $this->board[$fig_pos][0]) {
614
+			if ($fig_pos >= 8 && $fig_pos <= 15) {
615
+				$first_move = 1;
616
+			}
617
+
618
+			if ($dest_pos == $fig_pos + 8) {
619
+				return 1;
620
+			}
621
+
622
+			if ($first_move && ($dest_pos == $fig_pos + 16)) {
623
+				if ($this->is_empty_tile($fig_pos + 8)) {
624
+					return 1;
625
+				}
626
+			}
627
+		} elseif ('b' == $this->board[$fig_pos][0]) {
628
+			if ($fig_pos >= 48 && $fig_pos <= 55) {
629
+				$first_move = 1;
630
+			}
631
+
632
+			if ($dest_pos == $fig_pos - 8) {
633
+				return 1;
634
+			}
635
+
636
+			if ($first_move && ($dest_pos == $fig_pos - 16)) {
637
+				if ($this->is_empty_tile($fig_pos - 8)) {
638
+					return 1;
639
+				}
640
+			}
641
+		}
642
+
643
+		return 0;
644
+	}
645
+
646
+	/**
647
+	 * Check whether a tile is under attack by the specified player.
648
+	 *
649
+	 * @param string $opp      Attacking color ('w' or 'b')
650
+	 * @param int    $dest_pos Tile to check
651
+	 * @return bool
652
+	 *
653
+	 * @access private
654
+	 */
655
+	public function tileIsUnderAttack($opp, $dest_pos)
656
+	{
657
+		#var_dump('tileIsUnderAttack, opp', $opp, 'dest_pos', $dest_pos, 'board', $board);#*#DEBUG#
658
+
659
+		for ($i = 0; $i < 64; $i++) {
660
+			if ($this->board[$i][0] == $opp) {
661
+				if (('P' == $this->board[$i][1] && $this->checkPawnAttack($i, $dest_pos))
662
+					|| ('P' != $this->board[$i][1]
663
+						&& $this->tileIsReachable($this->board[$i][1], $i, $dest_pos))) {
664
+					/*DEBUG: echo "attack test: $i: ",$opp,"P<br>"; */
665
+
666
+					return 1;
667
+				}
668
+			}
669
+		}
670
+
671
+		return 0;
672
+	}
673
+
674
+	/**
675
+	 * Check whether a player's king can be attacked by his opponent.
676
+	 *
677
+	 * @param string $player Player's color ('w' or 'b')
678
+	 * @param string $opp    Opponent's color ('w' or 'b')
679
+	 * @return bool
680
+	 *
681
+	 * @access private
682
+	 */
683
+	public function kingIsUnderAttack($player, $opp)
684
+	{
685
+		#var_dump('kingIsUnderAttack, player', $player, 'opp', $opp, 'board', $board);#*#DEBUG#
686
+
687
+		for ($i = 0; $i < 64; $i++) {
688
+			if ($this->board[$i][0] == $player && 'K' == $this->board[$i][1]) {
689
+				$king_pos = $i;
690
+
691
+				break;
692
+			}
693
+		}
694
+
695
+		/*DEBUG: echo "$player king is at $king_pos<br>"; */
696
+
697
+		return $this->tileIsUnderAttack($opp, $king_pos);
698
+	}
699
+
700
+	/**
701
+	 * Check whether player's king is checkmated by his opponent.
702
+	 *
703
+	 * @param string $player Player's color ('w' or 'b')
704
+	 * @param string $opp    Opponent's color ('w' or 'b')
705
+	 * @return bool
706
+	 *
707
+	 * @access private
708
+	 */
709
+	public function isCheckMate($player, $opp)
710
+	{
711
+		for ($i = 0; $i < 64; $i++) {
712
+			if ($this->board[$i][0] == $player && 'K' == $this->board[$i][1]) {
713
+				$king_pos = $i;
714
+
715
+				$king_x = $i % 8;
716
+
717
+				$king_y = \floor($i / 8);
718
+
719
+				break;
720
+			}
721
+		}
722
+
723
+		/* test adjacent tiles while king is temporarly removed */
724
+
725
+		$adj_tiles = $this->getAdjTiles($king_pos);
726
+
727
+		$contents = $this->board[$king_pos];
728
+
729
+		$this->clear_tile($king_pos);
730
+
731
+		foreach ($adj_tiles as $dest_pos) {
732
+			if ($this->board[$dest_pos][0] == $player) {
733
+				continue;
734
+			}
735
+
736
+			if ($this->tileIsUnderAttack($opp, $dest_pos)) {
737
+				continue;
738
+			}
739
+
740
+			$this->board[$king_pos] = $contents;
741
+
742
+			return 0;
743
+		}
744
+
745
+		$this->board[$king_pos] = $contents;
746
+
747
+		/* DEBUG:  echo "King cannot escape by itself! "; */
748
+
749
+		/* get all figures that attack the king */
750
+
751
+		$attackers = [];
752
+
753
+		$count = 0;
754
+
755
+		for ($i = 0; $i < 64; $i++) {
756
+			if ($this->board[$i][0] == $opp) {
757
+				if (('P' == $this->board[$i][1] && $this->checkPawnAttack($i, $king_pos))
758
+					|| ('P' != $this->board[$i][1]
759
+						&& $this->tileIsReachable($this->board[$i][1], $i, $king_pos))) {
760
+					$attackers[$count++] = $i;
761
+				}
762
+			}
763
+		}
764 764
 
765
-        /* DEBUG:
765
+		/* DEBUG:
766 766
         for( $i = 0; $i < $count; $i++ )
767 767
           echo "Attacker: $attackers[$i] ";
768 768
         echo "Attackercount: ",count($attackers), " "; */
769 769
 
770
-        /* if more than one there is no chance to escape */
770
+		/* if more than one there is no chance to escape */
771 771
 
772
-        if ($count > 1) {
773
-            return 1;
774
-        }
772
+		if ($count > 1) {
773
+			return 1;
774
+		}
775 775
 
776
-        /* check whether attacker can be killed by own figure */
776
+		/* check whether attacker can be killed by own figure */
777 777
 
778
-        $dest_pos = $attackers[0];
778
+		$dest_pos = $attackers[0];
779 779
 
780
-        for ($i = 0; $i < 64; $i++) {
781
-            if ($this->board[$i][0] == $player) {
782
-                if (('P' == $this->board[$i][1] && $this->checkPawnAttack($i, $dest_pos))
783
-                    || ('P' != $this->board[$i][1] && 'K' != $this->board[$i][1]
784
-                        && $this->tileIsReachable($this->board[$i][1], $i, $dest_pos))
785
-                    || ('K' == $this->board[$i][1]
786
-                        && $this->tileIsReachable($this->board[$i][1], $i, $dest_pos)
787
-                        && !$this->tileIsUnderAttack($opp, $dest_pos))) {
788
-                    /* DEBUG: echo "candidate: $i "; */
780
+		for ($i = 0; $i < 64; $i++) {
781
+			if ($this->board[$i][0] == $player) {
782
+				if (('P' == $this->board[$i][1] && $this->checkPawnAttack($i, $dest_pos))
783
+					|| ('P' != $this->board[$i][1] && 'K' != $this->board[$i][1]
784
+						&& $this->tileIsReachable($this->board[$i][1], $i, $dest_pos))
785
+					|| ('K' == $this->board[$i][1]
786
+						&& $this->tileIsReachable($this->board[$i][1], $i, $dest_pos)
787
+						&& !$this->tileIsUnderAttack($opp, $dest_pos))) {
788
+					/* DEBUG: echo "candidate: $i "; */
789 789
 
790
-                    $can_kill_atk = 0;
790
+					$can_kill_atk = 0;
791 791
 
792
-                    $contents_def = $this->board[$i];
792
+					$contents_def = $this->board[$i];
793 793
 
794
-                    $contents_atk = $this->board[$dest_pos];
794
+					$contents_atk = $this->board[$dest_pos];
795 795
 
796
-                    $this->board[$dest_pos] = $this->board[$i];
796
+					$this->board[$dest_pos] = $this->board[$i];
797 797
 
798
-                    $this->clear_tile($i);
798
+					$this->clear_tile($i);
799 799
 
800
-                    if (!$this->tileIsUnderAttack($opp, $king_pos)) {
801
-                        $can_kill_atk = 1;
802
-                    }
800
+					if (!$this->tileIsUnderAttack($opp, $king_pos)) {
801
+						$can_kill_atk = 1;
802
+					}
803 803
 
804
-                    $this->board[$i] = $contents_def;
804
+					$this->board[$i] = $contents_def;
805 805
 
806
-                    $this->board[$dest_pos] = $contents_atk;
806
+					$this->board[$dest_pos] = $contents_atk;
807 807
 
808
-                    if ($can_kill_atk) {
809
-                        /* DEBUG: echo "$i can kill attacker"; */
808
+					if ($can_kill_atk) {
809
+						/* DEBUG: echo "$i can kill attacker"; */
810 810
 
811
-                        return 0;
812
-                    }
813
-                }
814
-            }
815
-        }
811
+						return 0;
812
+					}
813
+				}
814
+			}
815
+		}
816 816
 
817
-        /* check whether own unit can block the way */
817
+		/* check whether own unit can block the way */
818 818
 
819
-        /* if attacking unit is a knight there
819
+		/* if attacking unit is a knight there
820 820
          * is no way to block the path */
821 821
 
822
-        if ('N' == $this->board[$dest_pos][1]) {
823
-            return 1;
824
-        }
822
+		if ('N' == $this->board[$dest_pos][1]) {
823
+			return 1;
824
+		}
825 825
 
826
-        /* if enemy is adjacent to king there is no
826
+		/* if enemy is adjacent to king there is no
827 827
          * way either */
828 828
 
829
-        $dest_x = $dest_pos % 8;
829
+		$dest_x = $dest_pos % 8;
830 830
 
831
-        $dest_y = \floor($dest_pos / 8);
831
+		$dest_y = \floor($dest_pos / 8);
832 832
 
833
-        if (\abs($dest_x - $king_x) <= 1 && \abs($dest_y - $king_y) <= 1) {
834
-            return 1;
835
-        }
833
+		if (\abs($dest_x - $king_x) <= 1 && \abs($dest_y - $king_y) <= 1) {
834
+			return 1;
835
+		}
836 836
 
837
-        /* get the list of tiles between king and attacking
837
+		/* get the list of tiles between king and attacking
838 838
          * unit that can be blocked to stop the attack */
839 839
 
840
-        $change = $this->getPathChange($this->board[$dest_pos][1], $dest_pos, $king_pos);
841
-
842
-        /* DEBUG:  echo "path change: $change "; */
843
-
844
-        $path = $this->getPath($dest_pos + $change, $king_pos, $change);
845
-
846
-        /* DEBUG: foreach( $path as $tile ) echo "tile: $tile "; */
847
-
848
-        foreach ($path as $pos) {
849
-            for ($i = 0; $i < 64; $i++) {
850
-                if ($this->board[$i][0] == $player) {
851
-                    if (('P' == $this->board[$i][1] && $this->checkPawnMove($i, $pos))
852
-                        || ('P' != $this->board[$i][1] && 'K' != $this->board[$i][1]
853
-                            && $this->tileIsReachable($this->board[$i][1], $i, $pos))) {
854
-                        /* DEBUG: echo "$i can block "; */
855
-
856
-                        return 0;
857
-                    }
858
-                }
859
-            }
860
-        }
861
-
862
-        return 1;
863
-    }
864
-
865
-    /**
866
-     * Check whether player is stalemated.
867
-     *
868
-     * @param string $player Color of player who has the move ('w' or 'b')
869
-     * @param string $opp    Opponent's color ('w' or 'b')
870
-     * @return bool
871
-     *
872
-     * @todo   recognize when move is not possible because of check
873
-     *
874
-     * @access private
875
-     */
876
-    public function isStaleMate($player, $opp)
877
-    {
878
-        for ($i = 0; $i < 64; $i++) {
879
-            if ($this->board[$i][0] == $player) {
880
-                switch ($this->board[$i][1]) {
881
-                    case 'K':
882
-                        $adj_tiles = $this->getAdjTiles($i);
883
-                        foreach ($adj_tiles as $pos) {
884
-                            if ($this->board[$pos][0] == $player) {
885
-                                continue;
886
-                            }
887
-
888
-                            if ($this->tileIsUnderAttack($opp, $pos)) {
889
-                                continue;
890
-                            }
891
-
892
-                            return 0;
893
-                        }
894
-                        /* DEBUG:  echo "King cannot escape by itself! "; */
895
-                        break;
896
-                    case 'P':
897
-                        if ('w' == $player) {
898
-                            if ($this->is_empty_tile($i + 8)) {
899
-                                return 0;
900
-                            }
901
-
902
-                            if ($i % 8 > 0 && $this->board[$i + 7][0] != $player) {
903
-                                return 0;
904
-                            }
905
-
906
-                            if ($i % 8 < 7 && $this->board[$i + 9][0] != $player) {
907
-                                return 0;
908
-                            }
909
-                        } else {
910
-                            if ($this->is_empty_tile($i - 8)) {
911
-                                return 0;
912
-                            }
913
-
914
-                            if ($i % 8 > 0 && $this->board[$i - 9][0] != $player) {
915
-                                return 0;
916
-                            }
917
-
918
-                            if ($i % 8 < 7 && $this->board[$i - 7][0] != $player) {
919
-                                return 0;
920
-                            }
921
-                        }
922
-                        break;
923
-                    case 'B':
924
-                        if ($i - 9 >= 0 && $this->board[$i - 9][0] != $player) {
925
-                            return 0;
926
-                        }
927
-                        if ($i - 7 >= 0 && $this->board[$i - 7][0] != $player) {
928
-                            return 0;
929
-                        }
930
-                        if ($i + 9 <= 63 && $this->board[$i + 9][0] != $player) {
931
-                            return 0;
932
-                        }
933
-                        if ($i + 7 <= 63 && $this->board[$i + 7][0] != $player) {
934
-                            return 0;
935
-                        }
936
-                        break;
937
-                    case 'R':
938
-                        if ($i - 8 >= 0 && $this->board[$i - 8][0] != $player) {
939
-                            return 0;
940
-                        }
941
-                        if ($i - 1 >= 0 && $this->board[$i - 1][0] != $player) {
942
-                            return 0;
943
-                        }
944
-                        if ($i + 8 <= 63 && $this->board[$i + 8][0] != $player) {
945
-                            return 0;
946
-                        }
947
-                        if ($i + 1 <= 63 && $this->board[$i + 1][0] != $player) {
948
-                            return 0;
949
-                        }
950
-                        break;
951
-                    case 'Q':
952
-                        $adj_tiles = $this->getAdjTiles($i);
953
-                        foreach ($adj_tiles as $pos) {
954
-                            if ($this->board[$pos][0] != $player) {
955
-                                return 0;
956
-                            }
957
-                        }
958
-                        break;
959
-                    case 'N':
960
-                        if ($i - 17 >= 0 && $this->board[$i - 17][0] != $player) {
961
-                            return 0;
962
-                        }
963
-                        if ($i - 15 >= 0 && $this->board[$i - 15][0] != $player) {
964
-                            return 0;
965
-                        }
966
-                        if ($i - 6 >= 0 && $this->board[$i - 6][0] != $player) {
967
-                            return 0;
968
-                        }
969
-                        if ($i + 10 <= 63 && $this->board[$i + 10][0] != $player) {
970
-                            return 0;
971
-                        }
972
-                        if ($i + 17 <= 63 && $this->board[$i + 17][0] != $player) {
973
-                            return 0;
974
-                        }
975
-                        if ($i + 15 <= 63 && $this->board[$i + 15][0] != $player) {
976
-                            return 0;
977
-                        }
978
-                        if ($i + 6 <= 63 && $this->board[$i + 6][0] != $player) {
979
-                            return 0;
980
-                        }
981
-                        if ($i - 10 >= 0 && $this->board[$i - 10][0] != $player) {
982
-                            return 0;
983
-                        }
984
-                        break;
985
-                }
986
-            }
987
-        }
988
-
989
-        return 1;
990
-    }
991
-
992
-    /**
993
-     * Generate informational text message with parameters.
994
-     *
995
-     * Example:
996
-     * <pre>
997
-     *   echo move_msg('cannot find {$param[1]} pawn in column {$param[2]}', 'b', 'e');
998
-     *    - prints: "cannot find b pawn in column e"
999
-     * </pre>
1000
-     *
1001
-     * @param string $text
1002
-     * @return string
1003
-     *
1004
-     * @access private
1005
-     */
1006
-    public function move_msg($text)
1007
-    {
1008
-        $param = \func_get_args();
1009
-
1010
-        #var_dump('move_msg, text', $text, 'param', $param);#*#DEBUG#
1011
-
1012
-        return eval("return \"$text\";");
1013
-    }
1014
-
1015
-    /**
1016
-     * Translate Standard Algebraic Notation (SAN) into a full move description.
1017
-     *
1018
-     * The completed move is placed in $this->ac_move.
1019
-     *
1020
-     * @param string $player 'w' or 'b'
1021
-     * @param string $move
1022
-     *                       <pre>
1023
-     *                       [a-h][1-8|a-h][RNBQK]              pawn move/attack
1024
-     *                       [PRNBQK][a-h][1-8]                 figure move
1025
-     *                       [PRNBQK][:x][a-h][1-8]             figure attack
1026
-     *                       [PRNBQK][1-8|a-h][a-h][1-8]        ambigous figure move
1027
-     *                       [a-h][:x][a-h][1-8][[RNBQK]        ambigous pawn attack
1028
-     *                       [PRNBQK][1-8|a-h][:x][a-h][1-8]    ambigous figure attack
1029
-     *                       </pre>
1030
-     * @return string  Empty string if successful, otherwise error message
1031
-     *
1032
-     * @access private
1033
-     */
1034
-    public function completeMove($player, $move)
1035
-    {
1036
-        /*
840
+		$change = $this->getPathChange($this->board[$dest_pos][1], $dest_pos, $king_pos);
841
+
842
+		/* DEBUG:  echo "path change: $change "; */
843
+
844
+		$path = $this->getPath($dest_pos + $change, $king_pos, $change);
845
+
846
+		/* DEBUG: foreach( $path as $tile ) echo "tile: $tile "; */
847
+
848
+		foreach ($path as $pos) {
849
+			for ($i = 0; $i < 64; $i++) {
850
+				if ($this->board[$i][0] == $player) {
851
+					if (('P' == $this->board[$i][1] && $this->checkPawnMove($i, $pos))
852
+						|| ('P' != $this->board[$i][1] && 'K' != $this->board[$i][1]
853
+							&& $this->tileIsReachable($this->board[$i][1], $i, $pos))) {
854
+						/* DEBUG: echo "$i can block "; */
855
+
856
+						return 0;
857
+					}
858
+				}
859
+			}
860
+		}
861
+
862
+		return 1;
863
+	}
864
+
865
+	/**
866
+	 * Check whether player is stalemated.
867
+	 *
868
+	 * @param string $player Color of player who has the move ('w' or 'b')
869
+	 * @param string $opp    Opponent's color ('w' or 'b')
870
+	 * @return bool
871
+	 *
872
+	 * @todo   recognize when move is not possible because of check
873
+	 *
874
+	 * @access private
875
+	 */
876
+	public function isStaleMate($player, $opp)
877
+	{
878
+		for ($i = 0; $i < 64; $i++) {
879
+			if ($this->board[$i][0] == $player) {
880
+				switch ($this->board[$i][1]) {
881
+					case 'K':
882
+						$adj_tiles = $this->getAdjTiles($i);
883
+						foreach ($adj_tiles as $pos) {
884
+							if ($this->board[$pos][0] == $player) {
885
+								continue;
886
+							}
887
+
888
+							if ($this->tileIsUnderAttack($opp, $pos)) {
889
+								continue;
890
+							}
891
+
892
+							return 0;
893
+						}
894
+						/* DEBUG:  echo "King cannot escape by itself! "; */
895
+						break;
896
+					case 'P':
897
+						if ('w' == $player) {
898
+							if ($this->is_empty_tile($i + 8)) {
899
+								return 0;
900
+							}
901
+
902
+							if ($i % 8 > 0 && $this->board[$i + 7][0] != $player) {
903
+								return 0;
904
+							}
905
+
906
+							if ($i % 8 < 7 && $this->board[$i + 9][0] != $player) {
907
+								return 0;
908
+							}
909
+						} else {
910
+							if ($this->is_empty_tile($i - 8)) {
911
+								return 0;
912
+							}
913
+
914
+							if ($i % 8 > 0 && $this->board[$i - 9][0] != $player) {
915
+								return 0;
916
+							}
917
+
918
+							if ($i % 8 < 7 && $this->board[$i - 7][0] != $player) {
919
+								return 0;
920
+							}
921
+						}
922
+						break;
923
+					case 'B':
924
+						if ($i - 9 >= 0 && $this->board[$i - 9][0] != $player) {
925
+							return 0;
926
+						}
927
+						if ($i - 7 >= 0 && $this->board[$i - 7][0] != $player) {
928
+							return 0;
929
+						}
930
+						if ($i + 9 <= 63 && $this->board[$i + 9][0] != $player) {
931
+							return 0;
932
+						}
933
+						if ($i + 7 <= 63 && $this->board[$i + 7][0] != $player) {
934
+							return 0;
935
+						}
936
+						break;
937
+					case 'R':
938
+						if ($i - 8 >= 0 && $this->board[$i - 8][0] != $player) {
939
+							return 0;
940
+						}
941
+						if ($i - 1 >= 0 && $this->board[$i - 1][0] != $player) {
942
+							return 0;
943
+						}
944
+						if ($i + 8 <= 63 && $this->board[$i + 8][0] != $player) {
945
+							return 0;
946
+						}
947
+						if ($i + 1 <= 63 && $this->board[$i + 1][0] != $player) {
948
+							return 0;
949
+						}
950
+						break;
951
+					case 'Q':
952
+						$adj_tiles = $this->getAdjTiles($i);
953
+						foreach ($adj_tiles as $pos) {
954
+							if ($this->board[$pos][0] != $player) {
955
+								return 0;
956
+							}
957
+						}
958
+						break;
959
+					case 'N':
960
+						if ($i - 17 >= 0 && $this->board[$i - 17][0] != $player) {
961
+							return 0;
962
+						}
963
+						if ($i - 15 >= 0 && $this->board[$i - 15][0] != $player) {
964
+							return 0;
965
+						}
966
+						if ($i - 6 >= 0 && $this->board[$i - 6][0] != $player) {
967
+							return 0;
968
+						}
969
+						if ($i + 10 <= 63 && $this->board[$i + 10][0] != $player) {
970
+							return 0;
971
+						}
972
+						if ($i + 17 <= 63 && $this->board[$i + 17][0] != $player) {
973
+							return 0;
974
+						}
975
+						if ($i + 15 <= 63 && $this->board[$i + 15][0] != $player) {
976
+							return 0;
977
+						}
978
+						if ($i + 6 <= 63 && $this->board[$i + 6][0] != $player) {
979
+							return 0;
980
+						}
981
+						if ($i - 10 >= 0 && $this->board[$i - 10][0] != $player) {
982
+							return 0;
983
+						}
984
+						break;
985
+				}
986
+			}
987
+		}
988
+
989
+		return 1;
990
+	}
991
+
992
+	/**
993
+	 * Generate informational text message with parameters.
994
+	 *
995
+	 * Example:
996
+	 * <pre>
997
+	 *   echo move_msg('cannot find {$param[1]} pawn in column {$param[2]}', 'b', 'e');
998
+	 *    - prints: "cannot find b pawn in column e"
999
+	 * </pre>
1000
+	 *
1001
+	 * @param string $text
1002
+	 * @return string
1003
+	 *
1004
+	 * @access private
1005
+	 */
1006
+	public function move_msg($text)
1007
+	{
1008
+		$param = \func_get_args();
1009
+
1010
+		#var_dump('move_msg, text', $text, 'param', $param);#*#DEBUG#
1011
+
1012
+		return eval("return \"$text\";");
1013
+	}
1014
+
1015
+	/**
1016
+	 * Translate Standard Algebraic Notation (SAN) into a full move description.
1017
+	 *
1018
+	 * The completed move is placed in $this->ac_move.
1019
+	 *
1020
+	 * @param string $player 'w' or 'b'
1021
+	 * @param string $move
1022
+	 *                       <pre>
1023
+	 *                       [a-h][1-8|a-h][RNBQK]              pawn move/attack
1024
+	 *                       [PRNBQK][a-h][1-8]                 figure move
1025
+	 *                       [PRNBQK][:x][a-h][1-8]             figure attack
1026
+	 *                       [PRNBQK][1-8|a-h][a-h][1-8]        ambigous figure move
1027
+	 *                       [a-h][:x][a-h][1-8][[RNBQK]        ambigous pawn attack
1028
+	 *                       [PRNBQK][1-8|a-h][:x][a-h][1-8]    ambigous figure attack
1029
+	 *                       </pre>
1030
+	 * @return string  Empty string if successful, otherwise error message
1031
+	 *
1032
+	 * @access private
1033
+	 */
1034
+	public function completeMove($player, $move)
1035
+	{
1036
+		/*
1037 1037
          * [a-h][1-8|a-h][RNBQK]              pawn move/attack
1038 1038
          * [PRNBQK][a-h][1-8]                 figure move
1039 1039
          * [PRNBQK][:x][a-h][1-8]             figure attack
@@ -1042,1298 +1042,1298 @@  discard block
 block discarded – undo
1042 1042
          * [PRNBQK][1-8|a-h][:x][a-h][1-8]    ambigous figure attack
1043 1043
          */
1044 1044
 
1045
-        $error = _MD_CHESS_MOVE_UNKNOWN; // "format is totally unknown!"
1045
+		$error = _MD_CHESS_MOVE_UNKNOWN; // "format is totally unknown!"
1046 1046
 
1047
-        $this->ac_move = $move;
1047
+		$this->ac_move = $move;
1048 1048
 
1049
-        if (\mb_strlen($move) >= 6) {
1050
-            /* full move: a pawn requires a ? in the end
1049
+		if (\mb_strlen($move) >= 6) {
1050
+			/* full move: a pawn requires a ? in the end
1051 1051
              * to automatically choose a queen on last line */
1052 1052
 
1053
-            if (0 === \strpos($move, 'P')) {
1054
-                if ($move[\mb_strlen($move) - 1] < 'A' || $move[\mb_strlen($move) - 1] > 'Z') {
1055
-                    $this->ac_move = "$move?";
1056
-                }
1057
-            }
1053
+			if (0 === \strpos($move, 'P')) {
1054
+				if ($move[\mb_strlen($move) - 1] < 'A' || $move[\mb_strlen($move) - 1] > 'Z') {
1055
+					$this->ac_move = "$move?";
1056
+				}
1057
+			}
1058 1058
 
1059
-            return '';
1060
-        }
1059
+			return '';
1060
+		}
1061 1061
 
1062
-        /* allow last letter to be a capital one indicating
1062
+		/* allow last letter to be a capital one indicating
1063 1063
          * the chessmen a pawn is supposed to transform into,
1064 1064
          * when entering the last file. we split this character
1065 1065
          * to keep the autocompletion process the same. */
1066 1066
 
1067
-        $pawn_upg = '?';
1067
+		$pawn_upg = '?';
1068 1068
 
1069
-        if ($move[\mb_strlen($move) - 1] >= 'A' && $move[\mb_strlen($move) - 1] <= 'Z') {
1070
-            $pawn_upg = $move[\mb_strlen($move) - 1];
1069
+		if ($move[\mb_strlen($move) - 1] >= 'A' && $move[\mb_strlen($move) - 1] <= 'Z') {
1070
+			$pawn_upg = $move[\mb_strlen($move) - 1];
1071 1071
 
1072
-            $move = \mb_substr($move, 0, -1);
1073
-        }
1072
+			$move = \mb_substr($move, 0, -1);
1073
+		}
1074 1074
 
1075
-        // remove trailing '=', if present
1075
+		// remove trailing '=', if present
1076 1076
 
1077
-        if ('=' == $move[mb_strlen($move) - 1]) {
1078
-            $move = \mb_substr($move, 0, -1);
1079
-        }
1077
+		if ('=' == $move[mb_strlen($move) - 1]) {
1078
+			$move = \mb_substr($move, 0, -1);
1079
+		}
1080 1080
 
1081
-        if ('P' == $pawn_upg || 'K' == $pawn_upg) {
1082
-            return _MD_CHESS_MOVE_PAWN_MAY_BECOME;
1083
-        } // "A pawn may only become either a knight, a bishop, a rook or a queen!"
1081
+		if ('P' == $pawn_upg || 'K' == $pawn_upg) {
1082
+			return _MD_CHESS_MOVE_PAWN_MAY_BECOME;
1083
+		} // "A pawn may only become either a knight, a bishop, a rook or a queen!"
1084 1084
 
1085
-        if ($move[0] >= 'a' && $move[0] <= 'h') {
1086
-            /* pawn move. either it's 2 or for characters as
1085
+		if ($move[0] >= 'a' && $move[0] <= 'h') {
1086
+			/* pawn move. either it's 2 or for characters as
1087 1087
              * listed above */
1088 1088
 
1089
-            if (4 == mb_strlen($move)) {
1090
-                if ('x' != $move[1]) {
1091
-                    return _MD_CHESS_MOVE_USE_X;
1092
-                } // "use x to indicate an attack"
1089
+			if (4 == mb_strlen($move)) {
1090
+				if ('x' != $move[1]) {
1091
+					return _MD_CHESS_MOVE_USE_X;
1092
+				} // "use x to indicate an attack"
1093 1093
 
1094
-                $dest_x = $move[2];
1094
+				$dest_x = $move[2];
1095 1095
 
1096
-                $dest_y = $move[3];
1096
+				$dest_y = $move[3];
1097 1097
 
1098
-                $src_x = $move[0];
1098
+				$src_x = $move[0];
1099 1099
 
1100
-                if ('w' == $player) {
1101
-                    $src_y = $dest_y - 1;
1102
-                } else {
1103
-                    $src_y = $dest_y + 1;
1104
-                }
1100
+				if ('w' == $player) {
1101
+					$src_y = $dest_y - 1;
1102
+				} else {
1103
+					$src_y = $dest_y + 1;
1104
+				}
1105 1105
 
1106
-                $this->ac_move = \sprintf(
1107
-                    'P%s%dx%s%d%s',
1108
-                    $src_x,
1109
-                    $src_y,
1110
-                    $dest_x,
1111
-                    $dest_y,
1112
-                    $pawn_upg
1113
-                );
1106
+				$this->ac_move = \sprintf(
1107
+					'P%s%dx%s%d%s',
1108
+					$src_x,
1109
+					$src_y,
1110
+					$dest_x,
1111
+					$dest_y,
1112
+					$pawn_upg
1113
+				);
1114 1114
 
1115
-                return '';
1116
-            } elseif (2 == mb_strlen($move)) {
1117
-                $fig = \sprintf('%sP', $player);
1115
+				return '';
1116
+			} elseif (2 == mb_strlen($move)) {
1117
+				$fig = \sprintf('%sP', $player);
1118 1118
 
1119
-                if ($move[1] >= '1' && $move[1] <= '8') {
1120
-                    /* pawn move */
1119
+				if ($move[1] >= '1' && $move[1] <= '8') {
1120
+					/* pawn move */
1121 1121
 
1122
-                    $pos = $this->boardCoordToIndex($move);
1122
+					$pos = $this->boardCoordToIndex($move);
1123 1123
 
1124
-                    if (64 == $pos) {
1125
-                        return $this->move_msg(_MD_CHESS_MOVE_COORD_INVALID, $move);
1126
-                    } // "coordinate $move is invalid"
1124
+					if (64 == $pos) {
1125
+						return $this->move_msg(_MD_CHESS_MOVE_COORD_INVALID, $move);
1126
+					} // "coordinate $move is invalid"
1127 1127
 
1128
-                    if ('w' == $player) {
1129
-                        while ($pos >= 0 && $this->board[$pos] != $fig) {
1130
-                            $pos -= 8;
1131
-                        }
1128
+					if ('w' == $player) {
1129
+						while ($pos >= 0 && $this->board[$pos] != $fig) {
1130
+							$pos -= 8;
1131
+						}
1132 1132
 
1133
-                        if ($pos < 0) {
1134
-                            $not_found = 1;
1135
-                        }
1136
-                    } else {
1137
-                        while ($pos <= 63 && $this->board[$pos] != $fig) {
1138
-                            $pos += 8;
1139
-                        }
1133
+						if ($pos < 0) {
1134
+							$not_found = 1;
1135
+						}
1136
+					} else {
1137
+						while ($pos <= 63 && $this->board[$pos] != $fig) {
1138
+							$pos += 8;
1139
+						}
1140 1140
 
1141
-                        if ($pos > 63) {
1142
-                            $not_found = 1;
1143
-                        }
1144
-                    }
1141
+						if ($pos > 63) {
1142
+							$not_found = 1;
1143
+						}
1144
+					}
1145 1145
 
1146
-                    $pos = $this->boardIndexToCoord($pos);
1146
+					$pos = $this->boardIndexToCoord($pos);
1147 1147
 
1148
-                    if ((isset($not_found) && $not_found) || '' == $pos) {
1149
-                        return $this->move_msg(_MD_CHESS_MOVE_CANNOT_FIND_PAWN, $player, $move[0]); // "cannot find $player pawn in column $move[0]"
1150
-                    }
1148
+					if ((isset($not_found) && $not_found) || '' == $pos) {
1149
+						return $this->move_msg(_MD_CHESS_MOVE_CANNOT_FIND_PAWN, $player, $move[0]); // "cannot find $player pawn in column $move[0]"
1150
+					}
1151 1151
 
1152
-                    $this->ac_move = \sprintf('P%s-%s%s', $pos, $move, $pawn_upg);
1152
+					$this->ac_move = \sprintf('P%s-%s%s', $pos, $move, $pawn_upg);
1153 1153
 
1154
-                    return '';
1155
-                }
1154
+					return '';
1155
+				}
1156 1156
 
1157
-                /* notation: [a-h][a-h] for pawn attack no longer allowed
1157
+				/* notation: [a-h][a-h] for pawn attack no longer allowed
1158 1158
                  * except for history browser */
1159 1159
 
1160
-                if (0 == $this->browsing_mode) {
1161
-                    return _MD_CHESS_MOVE_USE_NOTATION;
1162
-                } // "please use denotation [a-h]x[a-h][1-8] for pawn attacks (see help for more information)"
1160
+				if (0 == $this->browsing_mode) {
1161
+					return _MD_CHESS_MOVE_USE_NOTATION;
1162
+				} // "please use denotation [a-h]x[a-h][1-8] for pawn attacks (see help for more information)"
1163 1163
 
1164
-                /* pawn attack must be only one pawn in column! */
1164
+				/* pawn attack must be only one pawn in column! */
1165 1165
 
1166
-                $pawns = 0;
1166
+				$pawns = 0;
1167 1167
 
1168
-                $start = $this->boardCoordToIndex(\sprintf('%s1', $move[0]));
1168
+				$start = $this->boardCoordToIndex(\sprintf('%s1', $move[0]));
1169 1169
 
1170
-                if (64 == $start) {
1171
-                    return $this->move_msg(_MD_CHESS_MOVE_COORD_INVALID, $move[0]);
1172
-                } // "coordinate $move[0] is invalid"
1170
+				if (64 == $start) {
1171
+					return $this->move_msg(_MD_CHESS_MOVE_COORD_INVALID, $move[0]);
1172
+				} // "coordinate $move[0] is invalid"
1173 1173
 
1174
-                for ($i = 1; $i <= 8; $i++, $start += 8) {
1175
-                    if ($this->board[$start] == $fig) {
1176
-                        $pawns++;
1174
+				for ($i = 1; $i <= 8; $i++, $start += 8) {
1175
+					if ($this->board[$start] == $fig) {
1176
+						$pawns++;
1177 1177
 
1178
-                        $pawn_line = $i;
1179
-                    }
1180
-                }
1178
+						$pawn_line = $i;
1179
+					}
1180
+				}
1181 1181
 
1182
-                if (0 == $pawns) {
1183
-                    return $this->move_msg(_MD_CHESS_MOVE_NO_PAWN, $move[0]);
1184
-                } // "there is no pawn in column $move[0]"
1182
+				if (0 == $pawns) {
1183
+					return $this->move_msg(_MD_CHESS_MOVE_NO_PAWN, $move[0]);
1184
+				} // "there is no pawn in column $move[0]"
1185 1185
 
1186
-                elseif ($pawns > 1) {
1187
-                    return $this->move_msg(_MD_CHESS_MOVE_TWO_PAWNS, $move[0]);
1188
-                } // "there is more than one pawn in column $move[0]"
1186
+				elseif ($pawns > 1) {
1187
+					return $this->move_msg(_MD_CHESS_MOVE_TWO_PAWNS, $move[0]);
1188
+				} // "there is more than one pawn in column $move[0]"
1189 1189
 
1190
-                if ('w' == $player) {
1191
-                    $dest_line = $pawn_line + 1;
1192
-                } else {
1193
-                    $dest_line = $pawn_line - 1;
1194
-                }
1190
+				if ('w' == $player) {
1191
+					$dest_line = $pawn_line + 1;
1192
+				} else {
1193
+					$dest_line = $pawn_line - 1;
1194
+				}
1195 1195
 
1196
-                $this->ac_move = \sprintf(
1197
-                    'P%s%dx%s%d',
1198
-                    $move[0],
1199
-                    $pawn_line,
1200
-                    $move[1],
1201
-                    $dest_line
1202
-                );
1203
-
1204
-                return '';
1205
-            }
1206
-        } else {
1207
-            /* figure move */
1208
-
1209
-            $dest_coord = \mb_substr($move, \mb_strlen($move) - 2, 2);
1210
-
1211
-            $action = $move[\mb_strlen($move) - 3];
1212
-
1213
-            if ('x' != $action) {
1214
-                $action = '-';
1215
-            }
1216
-
1217
-            if ('w' == $player) {
1218
-                $figures = $this->w_figures;
1219
-            } else {
1220
-                $figures = $this->b_figures;
1221
-            }
1222
-
1223
-            $fig_count = 0;
1224
-
1225
-            foreach ($figures as $figure) {
1226
-                if ($figure[0] == $move[0]) {
1227
-                    $fig_count++;
1228
-
1229
-                    if (1 == $fig_count) {
1230
-                        $pos1 = \mb_substr($figure, 1, 2);
1231
-                    } else {
1232
-                        $pos2 = \mb_substr($figure, 1, 2);
1233
-                    }
1234
-                }
1235
-            }
1236
-
1237
-            if (0 == $fig_count) {
1238
-                return $this->move_msg(_MD_CHESS_MOVE_NO_FIGURE, $move[0], $this->getFullFigureName($move[0]));
1239
-            } // sprintf("there is no figure %s = %s", $move[0], $this->getFullFigureName($move[0]))
1240
-
1241
-            elseif (1 == $fig_count) {
1242
-                $this->ac_move = \sprintf(
1243
-                    '%s%s%s%s',
1244
-                    $move[0],
1245
-                    $pos1,
1246
-                    $action,
1247
-                    $dest_coord
1248
-                );
1249
-
1250
-                return '';
1251
-            }
1252
-
1253
-            /* two figures which may cause ambiguity */
1254
-
1255
-            $dest_pos = $this->boardCoordToIndex($dest_coord);
1256
-
1257
-            if (64 == $dest_pos) {
1258
-                return $this->move_msg(_MD_CHESS_MOVE_COORD_INVALID, $dest_coord);
1259
-            } // "coordinate $dest_coord is invalid"
1260
-
1261
-            $fig1_can_reach = $this->tileIsReachable(
1262
-                $move[0],
1263
-                $this->boardCoordToIndex($pos1),
1264
-                $dest_pos
1265
-            );
1266
-
1267
-            $fig2_can_reach = $this->tileIsReachable(
1268
-                $move[0],
1269
-                $this->boardCoordToIndex($pos2),
1270
-                $dest_pos
1271
-            );
1272
-
1273
-            if (!$fig1_can_reach && !$fig2_can_reach) {
1274
-                return $this->move_msg(_MD_CHESS_MOVE_NEITHER_CAN_REACH, $move[0], $this->getFullFigureName($move[0]), $dest_coord);
1275
-            } // sprintf("neither of the %s = %s can reach %s", $move[0], $this->getFullFigureName($move[0]), $dest_coord)
1276
-
1277
-            elseif ($fig1_can_reach && $fig2_can_reach) {
1278
-                /* ambiguity - check whether a hint is given */
1279
-
1280
-                if (('-' == $action && 4 == mb_strlen($move))
1281
-                    || ('x' == $action && 5 == mb_strlen($move))) {
1282
-                    $hint = $move[1];
1283
-                }
1284
-
1285
-                if (empty($hint)) {
1286
-                    return $this->move_msg(_MD_CHESS_MOVE_BOTH_CAN_REACH, $move[0], $this->getFullFigureName($move[0]), $dest_coord);
1287
-                } // sprintf("both of the %s = %s can reach %s", $move[0], $this->getFullFigureName($move[0]), $dest_coord)
1288
-
1289
-                $move_fig1 = 0;
1290
-
1291
-                $move_fig2 = 0;
1292
-
1293
-                if ($hint >= '1' && $hint <= '8') {
1294
-                    if ($pos1[1] == $hint && $pos2[1] != $hint) {
1295
-                        $move_fig1 = 1;
1296
-                    }
1297
-
1298
-                    if ($pos2[1] == $hint && $pos1[1] != $hint) {
1299
-                        $move_fig2 = 1;
1300
-                    }
1301
-                } else {
1302
-                    if ($pos1[0] == $hint && $pos2[0] != $hint) {
1303
-                        $move_fig1 = 1;
1304
-                    }
1305
-
1306
-                    if ($pos2[0] == $hint && $pos1[0] != $hint) {
1307
-                        $move_fig2 = 1;
1308
-                    }
1309
-                }
1310
-
1311
-                if (!$move_fig1 && !$move_fig2) {
1312
-                    return _MD_CHESS_MOVE_AMBIGUOUS;
1313
-                } // "ambiguity is not properly resolved"
1314
-
1315
-                if ($move_fig1) {
1316
-                    $this->ac_move = \sprintf(
1317
-                        '%s%s%s%s',
1318
-                        $move[0],
1319
-                        $pos1,
1320
-                        $action,
1321
-                        $dest_coord
1322
-                    );
1323
-                } else {
1324
-                    $this->ac_move = \sprintf(
1325
-                        '%s%s%s%s',
1326
-                        $move[0],
1327
-                        $pos2,
1328
-                        $action,
1329
-                        $dest_coord
1330
-                    );
1331
-                }
1332
-
1333
-                return;
1334
-            }
1335
-
1336
-            if ($fig1_can_reach) {
1337
-                $this->ac_move = \sprintf(
1338
-                    '%s%s%s%s',
1339
-                    $move[0],
1340
-                    $pos1,
1341
-                    $action,
1342
-                    $dest_coord
1343
-                );
1344
-            } else {
1345
-                $this->ac_move = \sprintf(
1346
-                    '%s%s%s%s',
1347
-                    $move[0],
1348
-                    $pos2,
1349
-                    $action,
1350
-                    $dest_coord
1351
-                );
1352
-            }
1353
-
1354
-            return '';
1355
-        }
1356
-
1357
-        return $error;
1358
-    }
1359
-
1360
-    /**
1361
-     * A hacky function that uses autocomplete to short
1362
-     * a full move. if this fails there is no warning
1363
-     * but the move is kept unchanged.
1364
-     *
1365
-     * @param string $player 'w' or 'b'
1366
-     * @param string $move
1367
-     * @return string  new move
1368
-     *
1369
-     * @access private
1370
-     */
1371
-    public function convertFullToChessNotation($player, $move)
1372
-    {
1373
-        $new_move = $move;
1374
-
1375
-        $old_ac_move = $this->ac_move; /* backup required as autocomplete
1196
+				$this->ac_move = \sprintf(
1197
+					'P%s%dx%s%d',
1198
+					$move[0],
1199
+					$pawn_line,
1200
+					$move[1],
1201
+					$dest_line
1202
+				);
1203
+
1204
+				return '';
1205
+			}
1206
+		} else {
1207
+			/* figure move */
1208
+
1209
+			$dest_coord = \mb_substr($move, \mb_strlen($move) - 2, 2);
1210
+
1211
+			$action = $move[\mb_strlen($move) - 3];
1212
+
1213
+			if ('x' != $action) {
1214
+				$action = '-';
1215
+			}
1216
+
1217
+			if ('w' == $player) {
1218
+				$figures = $this->w_figures;
1219
+			} else {
1220
+				$figures = $this->b_figures;
1221
+			}
1222
+
1223
+			$fig_count = 0;
1224
+
1225
+			foreach ($figures as $figure) {
1226
+				if ($figure[0] == $move[0]) {
1227
+					$fig_count++;
1228
+
1229
+					if (1 == $fig_count) {
1230
+						$pos1 = \mb_substr($figure, 1, 2);
1231
+					} else {
1232
+						$pos2 = \mb_substr($figure, 1, 2);
1233
+					}
1234
+				}
1235
+			}
1236
+
1237
+			if (0 == $fig_count) {
1238
+				return $this->move_msg(_MD_CHESS_MOVE_NO_FIGURE, $move[0], $this->getFullFigureName($move[0]));
1239
+			} // sprintf("there is no figure %s = %s", $move[0], $this->getFullFigureName($move[0]))
1240
+
1241
+			elseif (1 == $fig_count) {
1242
+				$this->ac_move = \sprintf(
1243
+					'%s%s%s%s',
1244
+					$move[0],
1245
+					$pos1,
1246
+					$action,
1247
+					$dest_coord
1248
+				);
1249
+
1250
+				return '';
1251
+			}
1252
+
1253
+			/* two figures which may cause ambiguity */
1254
+
1255
+			$dest_pos = $this->boardCoordToIndex($dest_coord);
1256
+
1257
+			if (64 == $dest_pos) {
1258
+				return $this->move_msg(_MD_CHESS_MOVE_COORD_INVALID, $dest_coord);
1259
+			} // "coordinate $dest_coord is invalid"
1260
+
1261
+			$fig1_can_reach = $this->tileIsReachable(
1262
+				$move[0],
1263
+				$this->boardCoordToIndex($pos1),
1264
+				$dest_pos
1265
+			);
1266
+
1267
+			$fig2_can_reach = $this->tileIsReachable(
1268
+				$move[0],
1269
+				$this->boardCoordToIndex($pos2),
1270
+				$dest_pos
1271
+			);
1272
+
1273
+			if (!$fig1_can_reach && !$fig2_can_reach) {
1274
+				return $this->move_msg(_MD_CHESS_MOVE_NEITHER_CAN_REACH, $move[0], $this->getFullFigureName($move[0]), $dest_coord);
1275
+			} // sprintf("neither of the %s = %s can reach %s", $move[0], $this->getFullFigureName($move[0]), $dest_coord)
1276
+
1277
+			elseif ($fig1_can_reach && $fig2_can_reach) {
1278
+				/* ambiguity - check whether a hint is given */
1279
+
1280
+				if (('-' == $action && 4 == mb_strlen($move))
1281
+					|| ('x' == $action && 5 == mb_strlen($move))) {
1282
+					$hint = $move[1];
1283
+				}
1284
+
1285
+				if (empty($hint)) {
1286
+					return $this->move_msg(_MD_CHESS_MOVE_BOTH_CAN_REACH, $move[0], $this->getFullFigureName($move[0]), $dest_coord);
1287
+				} // sprintf("both of the %s = %s can reach %s", $move[0], $this->getFullFigureName($move[0]), $dest_coord)
1288
+
1289
+				$move_fig1 = 0;
1290
+
1291
+				$move_fig2 = 0;
1292
+
1293
+				if ($hint >= '1' && $hint <= '8') {
1294
+					if ($pos1[1] == $hint && $pos2[1] != $hint) {
1295
+						$move_fig1 = 1;
1296
+					}
1297
+
1298
+					if ($pos2[1] == $hint && $pos1[1] != $hint) {
1299
+						$move_fig2 = 1;
1300
+					}
1301
+				} else {
1302
+					if ($pos1[0] == $hint && $pos2[0] != $hint) {
1303
+						$move_fig1 = 1;
1304
+					}
1305
+
1306
+					if ($pos2[0] == $hint && $pos1[0] != $hint) {
1307
+						$move_fig2 = 1;
1308
+					}
1309
+				}
1310
+
1311
+				if (!$move_fig1 && !$move_fig2) {
1312
+					return _MD_CHESS_MOVE_AMBIGUOUS;
1313
+				} // "ambiguity is not properly resolved"
1314
+
1315
+				if ($move_fig1) {
1316
+					$this->ac_move = \sprintf(
1317
+						'%s%s%s%s',
1318
+						$move[0],
1319
+						$pos1,
1320
+						$action,
1321
+						$dest_coord
1322
+					);
1323
+				} else {
1324
+					$this->ac_move = \sprintf(
1325
+						'%s%s%s%s',
1326
+						$move[0],
1327
+						$pos2,
1328
+						$action,
1329
+						$dest_coord
1330
+					);
1331
+				}
1332
+
1333
+				return;
1334
+			}
1335
+
1336
+			if ($fig1_can_reach) {
1337
+				$this->ac_move = \sprintf(
1338
+					'%s%s%s%s',
1339
+					$move[0],
1340
+					$pos1,
1341
+					$action,
1342
+					$dest_coord
1343
+				);
1344
+			} else {
1345
+				$this->ac_move = \sprintf(
1346
+					'%s%s%s%s',
1347
+					$move[0],
1348
+					$pos2,
1349
+					$action,
1350
+					$dest_coord
1351
+				);
1352
+			}
1353
+
1354
+			return '';
1355
+		}
1356
+
1357
+		return $error;
1358
+	}
1359
+
1360
+	/**
1361
+	 * A hacky function that uses autocomplete to short
1362
+	 * a full move. if this fails there is no warning
1363
+	 * but the move is kept unchanged.
1364
+	 *
1365
+	 * @param string $player 'w' or 'b'
1366
+	 * @param string $move
1367
+	 * @return string  new move
1368
+	 *
1369
+	 * @access private
1370
+	 */
1371
+	public function convertFullToChessNotation($player, $move)
1372
+	{
1373
+		$new_move = $move;
1374
+
1375
+		$old_ac_move = $this->ac_move; /* backup required as autocomplete
1376 1376
                               will overwrite it */
1377 1377
 
1378
-        /* valid pawn moves are always non-ambigious */
1378
+		/* valid pawn moves are always non-ambigious */
1379 1379
 
1380
-        if (0 === \strpos($move, 'P')) {
1381
-            /* skip P anycase. for attacks skip source digit
1380
+		if (0 === \strpos($move, 'P')) {
1381
+			/* skip P anycase. for attacks skip source digit
1382 1382
                and for moves skip source pos and - */
1383 1383
 
1384
-            if ('-' == $move[3]) {
1385
-                $new_move = \mb_substr($move, 4);
1386
-            } elseif ('x' == $move[3]) {
1387
-                $new_move = \sprintf('%s%s', $move[1], \mb_substr($move, 3));
1388
-            }
1389
-        } else {
1390
-            /* try to remove the source position and check whether it
1384
+			if ('-' == $move[3]) {
1385
+				$new_move = \mb_substr($move, 4);
1386
+			} elseif ('x' == $move[3]) {
1387
+				$new_move = \sprintf('%s%s', $move[1], \mb_substr($move, 3));
1388
+			}
1389
+		} else {
1390
+			/* try to remove the source position and check whether it
1391 1391
              * is a non-ambigious move. if it is add one of the components
1392 1392
              * and check again */
1393 1393
 
1394
-            if ('-' == $move[3]) {
1395
-                $dest = \mb_substr($move, 4);
1396
-            } elseif ('x' == $move[3]) {
1397
-                $dest = \mb_substr($move, 3);
1398
-            }
1394
+			if ('-' == $move[3]) {
1395
+				$dest = \mb_substr($move, 4);
1396
+			} elseif ('x' == $move[3]) {
1397
+				$dest = \mb_substr($move, 3);
1398
+			}
1399 1399
 
1400
-            $new_move = \sprintf('%s%s', $move[0], $dest);
1400
+			$new_move = \sprintf('%s%s', $move[0], $dest);
1401 1401
 
1402
-            if ('' != $this->completeMove($player, $new_move)) {
1403
-                /* add a component */
1402
+			if ('' != $this->completeMove($player, $new_move)) {
1403
+				/* add a component */
1404 1404
 
1405
-                $new_move = \sprintf('%s%s%s', $move[0], $move[1], $dest);
1405
+				$new_move = \sprintf('%s%s%s', $move[0], $move[1], $dest);
1406 1406
 
1407
-                if ('' != $this->completeMove($player, $new_move)) {
1408
-                    /* add other component */
1407
+				if ('' != $this->completeMove($player, $new_move)) {
1408
+					/* add other component */
1409 1409
 
1410
-                    $new_move = \sprintf('%s%s%s', $move[0], $move[2], $dest);
1410
+					$new_move = \sprintf('%s%s%s', $move[0], $move[2], $dest);
1411 1411
 
1412
-                    if ('' != $this->completeMove($player, $new_move)) {
1413
-                        $new_move = $move;
1414
-                    } /* give up */
1415
-                }
1416
-            }
1417
-        }
1412
+					if ('' != $this->completeMove($player, $new_move)) {
1413
+						$new_move = $move;
1414
+					} /* give up */
1415
+				}
1416
+			}
1417
+		}
1418 1418
 
1419
-        $this->ac_move = $old_ac_move;
1419
+		$this->ac_move = $old_ac_move;
1420 1420
 
1421
-        return $new_move;
1422
-    }
1421
+		return $new_move;
1422
+	}
1423 1423
 
1424
-    /**
1425
-     * Handle a move.
1426
-     *
1427
-     * check whether it is user's turn and the move is valid.
1428
-     * if the move is okay update the game file.
1429
-     *
1430
-     * @param string $move
1431
-     * @return array A two-element array:
1432
-     *  - $move_performed: true if the move was performed and the game state has been updated, false otherwise
1433
-     *  - $move_result_text: text message
1434
-     *
1435
-     * @access private
1436
-     */
1437
-    public function handleMove($move)
1438
-    {
1439
-        /* DEBUG: echo "HANDLE: $move, $comment<br>"; */
1424
+	/**
1425
+	 * Handle a move.
1426
+	 *
1427
+	 * check whether it is user's turn and the move is valid.
1428
+	 * if the move is okay update the game file.
1429
+	 *
1430
+	 * @param string $move
1431
+	 * @return array A two-element array:
1432
+	 *  - $move_performed: true if the move was performed and the game state has been updated, false otherwise
1433
+	 *  - $move_result_text: text message
1434
+	 *
1435
+	 * @access private
1436
+	 */
1437
+	public function handleMove($move)
1438
+	{
1439
+		/* DEBUG: echo "HANDLE: $move, $comment<br>"; */
1440 1440
 
1441
-        $result = _MD_CHESS_MOVE_UNDEFINED;
1441
+		$result = _MD_CHESS_MOVE_UNDEFINED;
1442 1442
 
1443
-        $move_handled = 0;
1443
+		$move_handled = 0;
1444 1444
 
1445
-        // Use $this->gamestate['fen_piece_placement'] to initialize $this->board, $this->w_figures and $this->b_figures.
1445
+		// Use $this->gamestate['fen_piece_placement'] to initialize $this->board, $this->w_figures and $this->b_figures.
1446 1446
 
1447
-        $this->fen_piece_placement_to_board() || \trigger_error('handleMove, piece_placement invalid', \E_USER_ERROR);
1447
+		$this->fen_piece_placement_to_board() || \trigger_error('handleMove, piece_placement invalid', \E_USER_ERROR);
1448 1448
 
1449
-        // get color of current player
1449
+		// get color of current player
1450 1450
 
1451
-        $cur_player = $this->gamestate['fen_active_color']; /* b or w */
1451
+		$cur_player = $this->gamestate['fen_active_color']; /* b or w */
1452 1452
 
1453
-        if ('w' != $cur_player && 'b' != $cur_player) {
1454
-            return [false, "handleMove, internal error: player='$cur_player'"];
1455
-        }
1453
+		if ('w' != $cur_player && 'b' != $cur_player) {
1454
+			return [false, "handleMove, internal error: player='$cur_player'"];
1455
+		}
1456 1456
 
1457
-        $cur_opp = 'w' == $cur_player ? 'b' : 'w';
1457
+		$cur_opp = 'w' == $cur_player ? 'b' : 'w';
1458 1458
 
1459
-        if ('*' != $this->gamestate['pgn_result']) {
1460
-            return [false, _MD_CHESS_MOVE_GAME_OVER];
1461
-        }
1459
+		if ('*' != $this->gamestate['pgn_result']) {
1460
+			return [false, _MD_CHESS_MOVE_GAME_OVER];
1461
+		}
1462 1462
 
1463
-        // get castling availability flags
1463
+		// get castling availability flags
1464 1464
 
1465
-        $white_may_castle_short = \mb_strstr($this->gamestate['fen_castling_availability'], 'K') ? true : false;
1465
+		$white_may_castle_short = \mb_strstr($this->gamestate['fen_castling_availability'], 'K') ? true : false;
1466 1466
 
1467
-        $white_may_castle_long = \mb_strstr($this->gamestate['fen_castling_availability'], 'Q') ? true : false;
1467
+		$white_may_castle_long = \mb_strstr($this->gamestate['fen_castling_availability'], 'Q') ? true : false;
1468 1468
 
1469
-        $black_may_castle_short = \mb_strstr($this->gamestate['fen_castling_availability'], 'k') ? true : false;
1469
+		$black_may_castle_short = \mb_strstr($this->gamestate['fen_castling_availability'], 'k') ? true : false;
1470 1470
 
1471
-        $black_may_castle_long = \mb_strstr($this->gamestate['fen_castling_availability'], 'q') ? true : false;
1471
+		$black_may_castle_long = \mb_strstr($this->gamestate['fen_castling_availability'], 'q') ? true : false;
1472 1472
 
1473
-        // Castling is supposed to use ohs, not zeros.  Allow zeros on input anyway.
1473
+		// Castling is supposed to use ohs, not zeros.  Allow zeros on input anyway.
1474 1474
 
1475
-        if ('0-0' == $move) {
1476
-            $move = 'O-O';
1477
-        } elseif ('0-0-0' == $move) {
1478
-            $move = 'O-O-O';
1479
-        }
1475
+		if ('0-0' == $move) {
1476
+			$move = 'O-O';
1477
+		} elseif ('0-0-0' == $move) {
1478
+			$move = 'O-O-O';
1479
+		}
1480 1480
 
1481
-        // allow two-step of king to indicate castling
1481
+		// allow two-step of king to indicate castling
1482 1482
 
1483
-        if ('w' == $cur_player && 'Ke1-g1' == $move) {
1484
-            $move = 'O-O';
1485
-        } elseif ('w' == $cur_player && 'Ke1-c1' == $move) {
1486
-            $move = 'O-O-O';
1487
-        } elseif ('b' == $cur_player && 'Ke8-g8' == $move) {
1488
-            $move = 'O-O';
1489
-        } elseif ('b' == $cur_player && 'Ke8-c8' == $move) {
1490
-            $move = 'O-O-O';
1491
-        }
1483
+		if ('w' == $cur_player && 'Ke1-g1' == $move) {
1484
+			$move = 'O-O';
1485
+		} elseif ('w' == $cur_player && 'Ke1-c1' == $move) {
1486
+			$move = 'O-O-O';
1487
+		} elseif ('b' == $cur_player && 'Ke8-g8' == $move) {
1488
+			$move = 'O-O';
1489
+		} elseif ('b' == $cur_player && 'Ke8-c8' == $move) {
1490
+			$move = 'O-O-O';
1491
+		}
1492 1492
 
1493
-        /* backup full move input for game history before
1493
+		/* backup full move input for game history before
1494 1494
          * splitting figure type apart */
1495 1495
 
1496
-        $history_move = $move;
1496
+		$history_move = $move;
1497 1497
 
1498
-        /* clear last move - won't be saved yet if anything
1498
+		/* clear last move - won't be saved yet if anything
1499 1499
            goes wrong */
1500 1500
 
1501
-        $this->last_move = 'x';
1501
+		$this->last_move = 'x';
1502 1502
 
1503
-        $this->piece_captured = 'x';
1503
+		$this->piece_captured = 'x';
1504 1504
 
1505
-        /* HANDLE MOVES:
1505
+		/* HANDLE MOVES:
1506 1506
          * ---                               surrender
1507 1507
          * O-O                               short castling
1508 1508
          * O-O-O                             long castling
1509 1509
          * [PRNBQK][a-h][1-8][-:x][a-h][1-8] unshortened move
1510 1510
          */
1511 1511
 
1512
-        if ('O-O' == $move) {
1513
-            /* short castling */
1512
+		if ('O-O' == $move) {
1513
+			/* short castling */
1514 1514
 
1515
-            if ('b' == $cur_player) {
1516
-                if (!$black_may_castle_short) {
1517
-                    return [false, _MD_CHESS_MOVE_NO_CASTLE]; // You cannot castle short any longer!
1518
-                }
1515
+			if ('b' == $cur_player) {
1516
+				if (!$black_may_castle_short) {
1517
+					return [false, _MD_CHESS_MOVE_NO_CASTLE]; // You cannot castle short any longer!
1518
+				}
1519 1519
 
1520
-                if (!$this->is_empty_tile(61) || !$this->is_empty_tile(62)) {
1521
-                    return [false, _MD_CHESS_MOVE_NO_CASTLE]; // Cannot castle short because the way is blocked!
1522
-                }
1520
+				if (!$this->is_empty_tile(61) || !$this->is_empty_tile(62)) {
1521
+					return [false, _MD_CHESS_MOVE_NO_CASTLE]; // Cannot castle short because the way is blocked!
1522
+				}
1523 1523
 
1524
-                if ($this->kingIsUnderAttack('b', 'w')) {
1525
-                    return [false, _MD_CHESS_MOVE_NO_CASTLE]; // You cannot escape check by castling!
1526
-                }
1524
+				if ($this->kingIsUnderAttack('b', 'w')) {
1525
+					return [false, _MD_CHESS_MOVE_NO_CASTLE]; // You cannot escape check by castling!
1526
+				}
1527 1527
 
1528
-                if ($this->tileIsUnderAttack('w', 62) || $this->tileIsUnderAttack('w', 61)) {
1529
-                    return [false, _MD_CHESS_MOVE_NO_CASTLE]; // A tile the king passes over or into would be under attack after short castling!
1530
-                }
1528
+				if ($this->tileIsUnderAttack('w', 62) || $this->tileIsUnderAttack('w', 61)) {
1529
+					return [false, _MD_CHESS_MOVE_NO_CASTLE]; // A tile the king passes over or into would be under attack after short castling!
1530
+				}
1531 1531
 
1532
-                $this->clear_tile(60);
1532
+				$this->clear_tile(60);
1533 1533
 
1534
-                $this->board[62] = 'bK';
1534
+				$this->board[62] = 'bK';
1535 1535
 
1536
-                $this->board[61] = 'bR';
1536
+				$this->board[61] = 'bR';
1537 1537
 
1538
-                $this->clear_tile(63);
1538
+				$this->clear_tile(63);
1539 1539
 
1540
-                $black_may_castle_short = false;
1540
+				$black_may_castle_short = false;
1541 1541
 
1542
-                $black_may_castle_long = false;
1543
-            } else {
1544
-                if (!$white_may_castle_short) {
1545
-                    return [false, _MD_CHESS_MOVE_NO_CASTLE]; // You cannot castle short any longer!
1546
-                }
1542
+				$black_may_castle_long = false;
1543
+			} else {
1544
+				if (!$white_may_castle_short) {
1545
+					return [false, _MD_CHESS_MOVE_NO_CASTLE]; // You cannot castle short any longer!
1546
+				}
1547 1547
 
1548
-                if (!$this->is_empty_tile(5) || !$this->is_empty_tile(6)) {
1549
-                    return [false, _MD_CHESS_MOVE_NO_CASTLE]; // Cannot castle short because the way is blocked!
1550
-                }
1548
+				if (!$this->is_empty_tile(5) || !$this->is_empty_tile(6)) {
1549
+					return [false, _MD_CHESS_MOVE_NO_CASTLE]; // Cannot castle short because the way is blocked!
1550
+				}
1551 1551
 
1552
-                if ($this->kingIsUnderAttack('w', 'b')) {
1553
-                    return [false, _MD_CHESS_MOVE_NO_CASTLE]; // You cannot escape check by castling!
1554
-                }
1552
+				if ($this->kingIsUnderAttack('w', 'b')) {
1553
+					return [false, _MD_CHESS_MOVE_NO_CASTLE]; // You cannot escape check by castling!
1554
+				}
1555 1555
 
1556
-                if ($this->tileIsUnderAttack('b', 5) || $this->tileIsUnderAttack('b', 6)) {
1557
-                    return [false, _MD_CHESS_MOVE_NO_CASTLE]; // A tile the king passes over or into would be under attack after short castling!
1558
-                }
1556
+				if ($this->tileIsUnderAttack('b', 5) || $this->tileIsUnderAttack('b', 6)) {
1557
+					return [false, _MD_CHESS_MOVE_NO_CASTLE]; // A tile the king passes over or into would be under attack after short castling!
1558
+				}
1559 1559
 
1560
-                $this->clear_tile(4);
1560
+				$this->clear_tile(4);
1561 1561
 
1562
-                $this->board[6] = 'wK';
1562
+				$this->board[6] = 'wK';
1563 1563
 
1564
-                $this->board[5] = 'wR';
1564
+				$this->board[5] = 'wR';
1565 1565
 
1566
-                $this->clear_tile(7);
1566
+				$this->clear_tile(7);
1567 1567
 
1568
-                $white_may_castle_short = false;
1568
+				$white_may_castle_short = false;
1569 1569
 
1570
-                $white_may_castle_long = false;
1571
-            }
1570
+				$white_may_castle_long = false;
1571
+			}
1572 1572
 
1573
-            $result = _MD_CHESS_MOVE_CASTLED_SHORT;
1573
+			$result = _MD_CHESS_MOVE_CASTLED_SHORT;
1574 1574
 
1575
-            $move_handled = 1;
1575
+			$move_handled = 1;
1576 1576
 
1577
-            $this->last_move = 'O-O';
1578
-        } elseif ('O-O-O' == $move) {
1579
-            /* long castling */
1577
+			$this->last_move = 'O-O';
1578
+		} elseif ('O-O-O' == $move) {
1579
+			/* long castling */
1580 1580
 
1581
-            if ('b' == $cur_player) {
1582
-                if (!$black_may_castle_long) {
1583
-                    return [false, _MD_CHESS_MOVE_NO_CASTLE]; // You cannot castle long any longer!
1584
-                }
1581
+			if ('b' == $cur_player) {
1582
+				if (!$black_may_castle_long) {
1583
+					return [false, _MD_CHESS_MOVE_NO_CASTLE]; // You cannot castle long any longer!
1584
+				}
1585 1585
 
1586
-                if (!$this->is_empty_tile(57) || !$this->is_empty_tile(58) || !$this->is_empty_tile(59)) {
1587
-                    return [false, _MD_CHESS_MOVE_NO_CASTLE]; // Cannot castle long because the way is blocked!
1588
-                }
1586
+				if (!$this->is_empty_tile(57) || !$this->is_empty_tile(58) || !$this->is_empty_tile(59)) {
1587
+					return [false, _MD_CHESS_MOVE_NO_CASTLE]; // Cannot castle long because the way is blocked!
1588
+				}
1589 1589
 
1590
-                if ($this->kingIsUnderAttack('b', 'w')) {
1591
-                    return [false, _MD_CHESS_MOVE_NO_CASTLE]; // You cannot escape check by castling!
1592
-                }
1590
+				if ($this->kingIsUnderAttack('b', 'w')) {
1591
+					return [false, _MD_CHESS_MOVE_NO_CASTLE]; // You cannot escape check by castling!
1592
+				}
1593 1593
 
1594
-                if ($this->tileIsUnderAttack('w', 58) || $this->tileIsUnderAttack('w', 59)) {
1595
-                    return [false, _MD_CHESS_MOVE_NO_CASTLE]; // A tile the king passes over or into would be under attack after short castling!
1596
-                }
1594
+				if ($this->tileIsUnderAttack('w', 58) || $this->tileIsUnderAttack('w', 59)) {
1595
+					return [false, _MD_CHESS_MOVE_NO_CASTLE]; // A tile the king passes over or into would be under attack after short castling!
1596
+				}
1597 1597
 
1598
-                $this->clear_tile(56);
1598
+				$this->clear_tile(56);
1599 1599
 
1600
-                $this->board[58] = 'bK';
1600
+				$this->board[58] = 'bK';
1601 1601
 
1602
-                $this->board[59] = 'bR';
1602
+				$this->board[59] = 'bR';
1603 1603
 
1604
-                $this->clear_tile(60);
1604
+				$this->clear_tile(60);
1605 1605
 
1606
-                $black_may_castle_short = false;
1606
+				$black_may_castle_short = false;
1607 1607
 
1608
-                $black_may_castle_long = false;
1609
-            } else {
1610
-                if (!$white_may_castle_long) {
1611
-                    return [false, _MD_CHESS_MOVE_NO_CASTLE]; // You cannot castle long any longer!
1612
-                }
1608
+				$black_may_castle_long = false;
1609
+			} else {
1610
+				if (!$white_may_castle_long) {
1611
+					return [false, _MD_CHESS_MOVE_NO_CASTLE]; // You cannot castle long any longer!
1612
+				}
1613 1613
 
1614
-                if (!$this->is_empty_tile(1) || !$this->is_empty_tile(2) || !$this->is_empty_tile(3)) {
1615
-                    return [false, _MD_CHESS_MOVE_NO_CASTLE]; // Cannot castle long because the way is blocked!
1616
-                }
1614
+				if (!$this->is_empty_tile(1) || !$this->is_empty_tile(2) || !$this->is_empty_tile(3)) {
1615
+					return [false, _MD_CHESS_MOVE_NO_CASTLE]; // Cannot castle long because the way is blocked!
1616
+				}
1617 1617
 
1618
-                if ($this->kingIsUnderAttack('w', 'b')) {
1619
-                    return [false, _MD_CHESS_MOVE_NO_CASTLE]; // You cannot escape check by castling!
1620
-                }
1618
+				if ($this->kingIsUnderAttack('w', 'b')) {
1619
+					return [false, _MD_CHESS_MOVE_NO_CASTLE]; // You cannot escape check by castling!
1620
+				}
1621 1621
 
1622
-                if ($this->tileIsUnderAttack('b', 2) || $this->tileIsUnderAttack('b', 3)) {
1623
-                    return [false, _MD_CHESS_MOVE_NO_CASTLE]; // A tile the king passes over or into would be under attack after short castling!
1624
-                }
1622
+				if ($this->tileIsUnderAttack('b', 2) || $this->tileIsUnderAttack('b', 3)) {
1623
+					return [false, _MD_CHESS_MOVE_NO_CASTLE]; // A tile the king passes over or into would be under attack after short castling!
1624
+				}
1625 1625
 
1626
-                $this->clear_tile(0);
1626
+				$this->clear_tile(0);
1627 1627
 
1628
-                $this->board[2] = 'wK';
1628
+				$this->board[2] = 'wK';
1629 1629
 
1630
-                $this->board[3] = 'wR';
1630
+				$this->board[3] = 'wR';
1631 1631
 
1632
-                $this->clear_tile(4);
1632
+				$this->clear_tile(4);
1633 1633
 
1634
-                $white_may_castle_short = false;
1634
+				$white_may_castle_short = false;
1635 1635
 
1636
-                $white_may_castle_long = false;
1637
-            }
1636
+				$white_may_castle_long = false;
1637
+			}
1638 1638
 
1639
-            $result = _MD_CHESS_MOVE_CASTLED_LONG;
1639
+			$result = _MD_CHESS_MOVE_CASTLED_LONG;
1640 1640
 
1641
-            $move_handled = 1;
1641
+			$move_handled = 1;
1642 1642
 
1643
-            $this->last_move = 'O-O-O';
1644
-        } else {
1645
-            /* [PRNBQK][a-h][1-8][-:x][a-h][1-8][RNBQK] full move */
1643
+			$this->last_move = 'O-O-O';
1644
+		} else {
1645
+			/* [PRNBQK][a-h][1-8][-:x][a-h][1-8][RNBQK] full move */
1646 1646
 
1647
-            /* allow short move description by autocompleting to
1647
+			/* allow short move description by autocompleting to
1648 1648
              * full description */
1649 1649
 
1650
-            $ac_error = $this->completeMove($cur_player, \trim($move));
1650
+			$ac_error = $this->completeMove($cur_player, \trim($move));
1651 1651
 
1652
-            if ('' != $ac_error) {
1653
-                return [false, $ac_error];
1654
-            } // "ERROR: autocomplete: $ac_error"
1652
+			if ('' != $ac_error) {
1653
+				return [false, $ac_error];
1654
+			} // "ERROR: autocomplete: $ac_error"
1655 1655
 
1656
-            $move = $this->ac_move;
1656
+			$move = $this->ac_move;
1657 1657
 
1658
-            $this->last_move = \str_replace('?', '', $move);
1658
+			$this->last_move = \str_replace('?', '', $move);
1659 1659
 
1660
-            /* a final captial letter may only be N,B,R,Q for the
1660
+			/* a final captial letter may only be N,B,R,Q for the
1661 1661
              * appropiate chessman */
1662 1662
 
1663
-            $c = $move[\mb_strlen($move) - 1];
1663
+			$c = $move[\mb_strlen($move) - 1];
1664 1664
 
1665
-            if ($c >= 'A' && $c <= 'Z') {
1666
-                if ('N' != $c && 'B' != $c && 'R' != $c && 'Q' != $c) {
1667
-                    return [false, _MD_CHESS_MOVE_INVALID_PIECE];
1668
-                }
1669
-            } // "ERROR: only N (knight), B (bishop), R (rook) and Q (queen) are valid chessman identifiers"
1665
+			if ($c >= 'A' && $c <= 'Z') {
1666
+				if ('N' != $c && 'B' != $c && 'R' != $c && 'Q' != $c) {
1667
+					return [false, _MD_CHESS_MOVE_INVALID_PIECE];
1668
+				}
1669
+			} // "ERROR: only N (knight), B (bishop), R (rook) and Q (queen) are valid chessman identifiers"
1670 1670
 
1671
-            /* if it is a full move, try to shorten the history move */
1671
+			/* if it is a full move, try to shorten the history move */
1672 1672
 
1673
-            if (\mb_strlen($history_move) >= 6) {
1674
-                $history_move = $this->convertFullToChessNotation($cur_player, $history_move);
1675
-            }
1673
+			if (\mb_strlen($history_move) >= 6) {
1674
+				$history_move = $this->convertFullToChessNotation($cur_player, $history_move);
1675
+			}
1676 1676
 
1677
-            /* DEBUG: echo "Move: $move ($history_move)<br>"; */
1677
+			/* DEBUG: echo "Move: $move ($history_move)<br>"; */
1678 1678
 
1679
-            /* validate figure and position */
1679
+			/* validate figure and position */
1680 1680
 
1681
-            $fig_type = $move[0];
1681
+			$fig_type = $move[0];
1682 1682
 
1683
-            $fig_name = $this->getFullFigureName($fig_type);
1683
+			$fig_name = $this->getFullFigureName($fig_type);
1684 1684
 
1685
-            if ('empty' == $fig_name) {
1686
-                return [false, $this->move_msg(_MD_CHESS_MOVE_UNKNOWN_FIGURE, $fig_type)];
1687
-            } // "ERROR: Figure $fig_type is unknown!"
1685
+			if ('empty' == $fig_name) {
1686
+				return [false, $this->move_msg(_MD_CHESS_MOVE_UNKNOWN_FIGURE, $fig_type)];
1687
+			} // "ERROR: Figure $fig_type is unknown!"
1688 1688
 
1689
-            $fig_coord = \mb_substr($move, 1, 2);
1689
+			$fig_coord = \mb_substr($move, 1, 2);
1690 1690
 
1691
-            $fig_pos = $this->boardCoordToIndex($fig_coord);
1691
+			$fig_pos = $this->boardCoordToIndex($fig_coord);
1692 1692
 
1693
-            if (64 == $fig_pos) {
1694
-                return [false, $this->move_msg(_MD_CHESS_MOVE_COORD_INVALID, $fig_coord)];
1695
-            } // "ERROR: $fig_coord is invalid!"
1693
+			if (64 == $fig_pos) {
1694
+				return [false, $this->move_msg(_MD_CHESS_MOVE_COORD_INVALID, $fig_coord)];
1695
+			} // "ERROR: $fig_coord is invalid!"
1696 1696
 
1697
-            /* DEBUG  echo "fig_type: $fig_type, fig_pos: $fig_pos<br>"; */
1697
+			/* DEBUG  echo "fig_type: $fig_type, fig_pos: $fig_pos<br>"; */
1698 1698
 
1699
-            if ($this->is_empty_tile($fig_pos)) {
1700
-                return [false, $this->move_msg(_MD_CHESS_MOVE_TILE_EMPTY, $fig_coord)];
1701
-            } // "ERROR: Tile $fig_coord is empty."
1699
+			if ($this->is_empty_tile($fig_pos)) {
1700
+				return [false, $this->move_msg(_MD_CHESS_MOVE_TILE_EMPTY, $fig_coord)];
1701
+			} // "ERROR: Tile $fig_coord is empty."
1702 1702
 
1703
-            if ($this->board[$fig_pos][0] != $cur_player) {
1704
-                return [false, _MD_CHESS_MOVE_NOT_YOUR_PIECE];
1705
-            } // "ERROR: Figure does not belong to you!"
1703
+			if ($this->board[$fig_pos][0] != $cur_player) {
1704
+				return [false, _MD_CHESS_MOVE_NOT_YOUR_PIECE];
1705
+			} // "ERROR: Figure does not belong to you!"
1706 1706
 
1707
-            if ($this->board[$fig_pos][1] != $fig_type) {
1708
-                return [false, _MD_CHESS_MOVE_NOEXIST_FIGURE];
1709
-            } // "ERROR: Figure does not exist!"
1707
+			if ($this->board[$fig_pos][1] != $fig_type) {
1708
+				return [false, _MD_CHESS_MOVE_NOEXIST_FIGURE];
1709
+			} // "ERROR: Figure does not exist!"
1710 1710
 
1711
-            /* get target index */
1711
+			/* get target index */
1712 1712
 
1713
-            $dest_coord = \mb_substr($move, 4, 2);
1713
+			$dest_coord = \mb_substr($move, 4, 2);
1714 1714
 
1715
-            $dest_pos = $this->boardCoordToIndex($dest_coord);
1715
+			$dest_pos = $this->boardCoordToIndex($dest_coord);
1716 1716
 
1717
-            if (64 == $dest_pos) {
1718
-                return [false, $this->move_msg(_MD_CHESS_MOVE_COORD_INVALID, $dest_coord)];
1719
-            } // "ERROR: $dest_coord is invalid!"
1717
+			if (64 == $dest_pos) {
1718
+				return [false, $this->move_msg(_MD_CHESS_MOVE_COORD_INVALID, $dest_coord)];
1719
+			} // "ERROR: $dest_coord is invalid!"
1720 1720
 
1721
-            if ($dest_pos == $fig_pos) {
1722
-                return [false, _MD_CHESS_MOVE_START_END_SAME];
1723
-            }
1721
+			if ($dest_pos == $fig_pos) {
1722
+				return [false, _MD_CHESS_MOVE_START_END_SAME];
1723
+			}
1724 1724
 
1725
-            /* DEBUG  echo "dest_pos: $dest_pos<br>"; */
1725
+			/* DEBUG  echo "dest_pos: $dest_pos<br>"; */
1726 1726
 
1727
-            /* get action */
1727
+			/* get action */
1728 1728
 
1729
-            $action = $move[3];
1729
+			$action = $move[3];
1730 1730
 
1731
-            if ('-' == $move[3]) {
1732
-                $action = 'M';
1733
-            } /* move */
1731
+			if ('-' == $move[3]) {
1732
+				$action = 'M';
1733
+			} /* move */
1734 1734
 
1735
-            elseif ('x' == $move[3]) {
1736
-                $action = 'A';
1737
-            } /* attack */
1735
+			elseif ('x' == $move[3]) {
1736
+				$action = 'A';
1737
+			} /* attack */
1738 1738
 
1739
-            else {
1740
-                return [false, $this->move_msg(_MD_CHESS_MOVE_UNKNOWN_ACTION, $action)];
1741
-            } // "ERROR: $action is unknown! Please use \"-\" for a move and \"x\" for an attack."
1739
+			else {
1740
+				return [false, $this->move_msg(_MD_CHESS_MOVE_UNKNOWN_ACTION, $action)];
1741
+			} // "ERROR: $action is unknown! Please use \"-\" for a move and \"x\" for an attack."
1742 1742
 
1743
-            /* if attack an enemy unit must be present on tile
1743
+			/* if attack an enemy unit must be present on tile
1744 1744
              * and if move then tile must be empty. in both cases
1745 1745
              * the king must not be checked after moving. */
1746 1746
 
1747
-            /* check whether the move is along a valid path and
1747
+			/* check whether the move is along a valid path and
1748 1748
              * whether all tiles in between are empty thus the path
1749 1749
              * is not blocked. the final destination tile is not
1750 1750
              * checked here. */
1751 1751
 
1752
-            if ('P' != $fig_type) {
1753
-                if (!$this->tileIsReachable($fig_type, $fig_pos, $dest_pos)) {
1754
-                    return [false, $this->move_msg(_MD_CHESS_MOVE_OUT_OF_RANGE, $dest_coord, $fig_name, $fig_coord)];
1755
-                } // "ERROR: Tile $dest_coord is out of moving range for $fig_name at $fig_coord!"
1756
-            } else {
1757
-                if ('M' == $action && !$this->checkPawnMove($fig_pos, $dest_pos)) {
1758
-                    return [false, $this->move_msg(_MD_CHESS_MOVE_OUT_OF_RANGE, $dest_coord, $fig_name, $fig_coord)];
1759
-                } // "ERROR: Tile $dest_coord is out of moving range for $fig_name at $fig_coord!"
1752
+			if ('P' != $fig_type) {
1753
+				if (!$this->tileIsReachable($fig_type, $fig_pos, $dest_pos)) {
1754
+					return [false, $this->move_msg(_MD_CHESS_MOVE_OUT_OF_RANGE, $dest_coord, $fig_name, $fig_coord)];
1755
+				} // "ERROR: Tile $dest_coord is out of moving range for $fig_name at $fig_coord!"
1756
+			} else {
1757
+				if ('M' == $action && !$this->checkPawnMove($fig_pos, $dest_pos)) {
1758
+					return [false, $this->move_msg(_MD_CHESS_MOVE_OUT_OF_RANGE, $dest_coord, $fig_name, $fig_coord)];
1759
+				} // "ERROR: Tile $dest_coord is out of moving range for $fig_name at $fig_coord!"
1760 1760
 
1761
-                if ('A' == $action && !$this->checkPawnAttack($fig_pos, $dest_pos)) {
1762
-                    return [false, $this->move_msg(_MD_CHESS_MOVE_OUT_OF_RANGE, $dest_coord, $fig_name, $fig_coord)];
1763
-                } // "ERROR: Tile $dest_coord is out of attacking range for $fig_name at $fig_coord!"
1764
-            }
1761
+				if ('A' == $action && !$this->checkPawnAttack($fig_pos, $dest_pos)) {
1762
+					return [false, $this->move_msg(_MD_CHESS_MOVE_OUT_OF_RANGE, $dest_coord, $fig_name, $fig_coord)];
1763
+				} // "ERROR: Tile $dest_coord is out of attacking range for $fig_name at $fig_coord!"
1764
+			}
1765 1765
 
1766
-            $en_passant_capture_performed = 0; // 1 if en passant captured occurred, else 0
1766
+			$en_passant_capture_performed = 0; // 1 if en passant captured occurred, else 0
1767 1767
 
1768
-            /* check action */
1768
+			/* check action */
1769 1769
 
1770
-            if ('M' == $action && !$this->is_empty_tile($dest_pos)) {
1771
-                return [false, $this->move_msg(_MD_CHESS_MOVE_OCCUPIED, $dest_coord)]; // "ERROR: Tile $dest_coord is occupied. You cannot move there."
1772
-            }
1770
+			if ('M' == $action && !$this->is_empty_tile($dest_pos)) {
1771
+				return [false, $this->move_msg(_MD_CHESS_MOVE_OCCUPIED, $dest_coord)]; // "ERROR: Tile $dest_coord is occupied. You cannot move there."
1772
+			}
1773 1773
 
1774
-            if ('A' == $action && $this->is_empty_tile($dest_pos)) {
1775
-                /* en passant of pawn? */
1774
+			if ('A' == $action && $this->is_empty_tile($dest_pos)) {
1775
+				/* en passant of pawn? */
1776 1776
 
1777
-                if ('P' == $fig_type) {
1778
-                    if ($this->boardIndexToCoord($dest_pos) == $this->gamestate['fen_en_passant_target_square']) {
1779
-                        $en_passant_capture_performed = 1;
1780
-                    }
1777
+				if ('P' == $fig_type) {
1778
+					if ($this->boardIndexToCoord($dest_pos) == $this->gamestate['fen_en_passant_target_square']) {
1779
+						$en_passant_capture_performed = 1;
1780
+					}
1781 1781
 
1782
-                    if (0 == $en_passant_capture_performed) {
1783
-                        return [false, _MD_CHESS_MOVE_NO_EN_PASSANT]; // "ERROR: en-passant no longer possible!"
1784
-                    }
1785
-                } else {
1786
-                    return [false, $this->move_msg(_MD_CHESS_MOVE_ATTACK_EMPTY, $dest_coord)]; // "ERROR: Tile $dest_coord is empty. You cannot attack it."
1787
-                }
1788
-            }
1782
+					if (0 == $en_passant_capture_performed) {
1783
+						return [false, _MD_CHESS_MOVE_NO_EN_PASSANT]; // "ERROR: en-passant no longer possible!"
1784
+					}
1785
+				} else {
1786
+					return [false, $this->move_msg(_MD_CHESS_MOVE_ATTACK_EMPTY, $dest_coord)]; // "ERROR: Tile $dest_coord is empty. You cannot attack it."
1787
+				}
1788
+			}
1789 1789
 
1790
-            if ('A' == $action && $this->board[$dest_pos][0] == $cur_player) {
1791
-                return [false, $this->move_msg(_MD_CHESS_MOVE_ATTACK_SELF, $dest_coord)]; // "ERROR: You cannot attack own unit at $dest_coord."
1792
-            }
1790
+			if ('A' == $action && $this->board[$dest_pos][0] == $cur_player) {
1791
+				return [false, $this->move_msg(_MD_CHESS_MOVE_ATTACK_SELF, $dest_coord)]; // "ERROR: You cannot attack own unit at $dest_coord."
1792
+			}
1793 1793
 
1794
-            /* backup affected tiles */
1794
+			/* backup affected tiles */
1795 1795
 
1796
-            $old_fig_tile = $this->board[$fig_pos];
1796
+			$old_fig_tile = $this->board[$fig_pos];
1797 1797
 
1798
-            $old_dest_tile = $this->board[$dest_pos];
1798
+			$old_dest_tile = $this->board[$dest_pos];
1799 1799
 
1800
-            /* perform move */
1800
+			/* perform move */
1801 1801
 
1802
-            $this->clear_tile($fig_pos);
1802
+			$this->clear_tile($fig_pos);
1803 1803
 
1804
-            if (!$this->is_empty_tile($dest_pos)) {
1805
-                $this->piece_captured = \sprintf('%s%s', $this->board[$dest_pos], $dest_pos);
1806
-            }
1804
+			if (!$this->is_empty_tile($dest_pos)) {
1805
+				$this->piece_captured = \sprintf('%s%s', $this->board[$dest_pos], $dest_pos);
1806
+			}
1807 1807
 
1808
-            $this->board[$dest_pos] = "$cur_player$fig_type";
1808
+			$this->board[$dest_pos] = "$cur_player$fig_type";
1809 1809
 
1810
-            if ($en_passant_capture_performed) {
1811
-                /* kill pawn */
1810
+			if ($en_passant_capture_performed) {
1811
+				/* kill pawn */
1812 1812
 
1813
-                if ('w' == $cur_player) {
1814
-                    $this->clear_tile($dest_pos - 8);
1813
+				if ('w' == $cur_player) {
1814
+					$this->clear_tile($dest_pos - 8);
1815 1815
 
1816
-                    $this->piece_captured = \sprintf('bP%s', $dest_pos - 8);
1817
-                } else {
1818
-                    $this->clear_tile($dest_pos + 8);
1816
+					$this->piece_captured = \sprintf('bP%s', $dest_pos - 8);
1817
+				} else {
1818
+					$this->clear_tile($dest_pos + 8);
1819 1819
 
1820
-                    $this->piece_captured = \sprintf('wP%s', $dest_pos + 8);
1821
-                }
1822
-            }
1820
+					$this->piece_captured = \sprintf('wP%s', $dest_pos + 8);
1821
+				}
1822
+			}
1823 1823
 
1824
-            /* check check :) */
1824
+			/* check check :) */
1825 1825
 
1826
-            if ($this->kingIsUnderAttack($cur_player, $cur_opp)) {
1827
-                $this->board[$fig_pos] = $old_fig_tile;
1826
+			if ($this->kingIsUnderAttack($cur_player, $cur_opp)) {
1827
+				$this->board[$fig_pos] = $old_fig_tile;
1828 1828
 
1829
-                $this->board[$dest_pos] = $old_dest_tile;
1829
+				$this->board[$dest_pos] = $old_dest_tile;
1830 1830
 
1831
-                if ($en_passant_capture_performed) {
1832
-                    // restore pawn that was captured above, since that move is invalid
1831
+				if ($en_passant_capture_performed) {
1832
+					// restore pawn that was captured above, since that move is invalid
1833 1833
 
1834
-                    if ('w' == $cur_player) {
1835
-                        $this->board[$dest_pos - 8] = 'bP';
1836
-                    } else {
1837
-                        $this->board[$dest_pos + 8] = 'wP';
1838
-                    }
1839
-                }
1834
+					if ('w' == $cur_player) {
1835
+						$this->board[$dest_pos - 8] = 'bP';
1836
+					} else {
1837
+						$this->board[$dest_pos + 8] = 'wP';
1838
+					}
1839
+				}
1840 1840
 
1841
-                return [false, _MD_CHESS_MOVE_IN_CHECK]; // "ERROR: Move is invalid because king would be under attack then."
1842
-            }
1841
+				return [false, _MD_CHESS_MOVE_IN_CHECK]; // "ERROR: Move is invalid because king would be under attack then."
1842
+			}
1843 1843
 
1844
-            // check whether this forbids any castling
1844
+			// check whether this forbids any castling
1845 1845
 
1846
-            if ('K' == $fig_type) {
1847
-                if ('w' == $cur_player) {
1848
-                    $white_may_castle_short = false;
1846
+			if ('K' == $fig_type) {
1847
+				if ('w' == $cur_player) {
1848
+					$white_may_castle_short = false;
1849 1849
 
1850
-                    $white_may_castle_long = false;
1851
-                } else {
1852
-                    $black_may_castle_short = false;
1850
+					$white_may_castle_long = false;
1851
+				} else {
1852
+					$black_may_castle_short = false;
1853 1853
 
1854
-                    $black_may_castle_long = false;
1855
-                }
1856
-            }
1854
+					$black_may_castle_long = false;
1855
+				}
1856
+			}
1857 1857
 
1858
-            if ('R' == $fig_type) {
1859
-                if ('w' == $cur_player) {
1860
-                    if (7 == $fig_pos) {
1861
-                        $white_may_castle_short = false;
1862
-                    } elseif (0 == $fig_pos) {
1863
-                        $white_may_castle_long = false;
1864
-                    }
1865
-                } else {
1866
-                    if (63 == $fig_pos) {
1867
-                        $black_may_castle_short = false;
1868
-                    } elseif (56 == $fig_pos) {
1869
-                        $black_may_castle_long = false;
1870
-                    }
1871
-                }
1872
-            }
1858
+			if ('R' == $fig_type) {
1859
+				if ('w' == $cur_player) {
1860
+					if (7 == $fig_pos) {
1861
+						$white_may_castle_short = false;
1862
+					} elseif (0 == $fig_pos) {
1863
+						$white_may_castle_long = false;
1864
+					}
1865
+				} else {
1866
+					if (63 == $fig_pos) {
1867
+						$black_may_castle_short = false;
1868
+					} elseif (56 == $fig_pos) {
1869
+						$black_may_castle_long = false;
1870
+					}
1871
+				}
1872
+			}
1873 1873
 
1874
-            // if a pawn moved two tiles, this will allow 'en passant' on next move
1874
+			// if a pawn moved two tiles, this will allow 'en passant' on next move
1875 1875
 
1876
-            if ('P' == $fig_type && 16 == \abs($fig_pos - $dest_pos)) {
1877
-                $file_chars = 'abcdefgh';
1876
+			if ('P' == $fig_type && 16 == \abs($fig_pos - $dest_pos)) {
1877
+				$file_chars = 'abcdefgh';
1878 1878
 
1879
-                $this->gamestate['fen_en_passant_target_square'] = $file_chars[$fig_pos % 8] . ('w' == $cur_player ? '3' : '6');
1880
-            } else {
1881
-                // clear 'en passant'
1879
+				$this->gamestate['fen_en_passant_target_square'] = $file_chars[$fig_pos % 8] . ('w' == $cur_player ? '3' : '6');
1880
+			} else {
1881
+				// clear 'en passant'
1882 1882
 
1883
-                $this->gamestate['fen_en_passant_target_square'] = '-';
1884
-            }
1883
+				$this->gamestate['fen_en_passant_target_square'] = '-';
1884
+			}
1885 1885
 
1886
-            if ('M' == $action) {
1887
-                $result = $this->move_msg(_MD_CHESS_MOVE_MOVED, $fig_name, $fig_coord, $dest_coord);
1888
-            } else {
1889
-                $result = $this->move_msg(_MD_CHESS_MOVE_CAPTURED, $fig_name, $dest_coord, $fig_coord);
1890
-            }
1886
+			if ('M' == $action) {
1887
+				$result = $this->move_msg(_MD_CHESS_MOVE_MOVED, $fig_name, $fig_coord, $dest_coord);
1888
+			} else {
1889
+				$result = $this->move_msg(_MD_CHESS_MOVE_CAPTURED, $fig_name, $dest_coord, $fig_coord);
1890
+			}
1891 1891
 
1892
-            /* if pawn reached last line convert into a queen */
1892
+			/* if pawn reached last line convert into a queen */
1893 1893
 
1894
-            if ('P' == $fig_type) {
1895
-                if (('w' == $cur_player && $dest_pos >= 56)
1896
-                    || ('b' == $cur_player && $dest_pos <= 7)) {
1897
-                    $pawn_upg = $move[\mb_strlen($move) - 1];
1894
+			if ('P' == $fig_type) {
1895
+				if (('w' == $cur_player && $dest_pos >= 56)
1896
+					|| ('b' == $cur_player && $dest_pos <= 7)) {
1897
+					$pawn_upg = $move[\mb_strlen($move) - 1];
1898 1898
 
1899
-                    if ('?' == $pawn_upg) {
1900
-                        $pawn_upg = 'Q';
1899
+					if ('?' == $pawn_upg) {
1900
+						$pawn_upg = 'Q';
1901 1901
 
1902
-                        $history_move = \sprintf('%sQ', $history_move);
1903
-                    }
1902
+						$history_move = \sprintf('%sQ', $history_move);
1903
+					}
1904 1904
 
1905
-                    $this->board[$dest_pos] = "$cur_player$pawn_upg";
1905
+					$this->board[$dest_pos] = "$cur_player$pawn_upg";
1906 1906
 
1907
-                    $result .= ' ... ' . $this->move_msg(_MD_CHESS_MOVE_PROMOTED, $this->getFullFigureName($pawn_upg));
1908
-                }
1909
-            }
1907
+					$result .= ' ... ' . $this->move_msg(_MD_CHESS_MOVE_PROMOTED, $this->getFullFigureName($pawn_upg));
1908
+				}
1909
+			}
1910 1910
 
1911
-            $move_handled = 1;
1912
-        }
1911
+			$move_handled = 1;
1912
+		}
1913 1913
 
1914
-        /* if a legal move was performed test whether you
1914
+		/* if a legal move was performed test whether you
1915 1915
          * check the opponent or even check-mate him. then
1916 1916
          * update castling and en-passant flags, select the
1917 1917
          * next player and add the move to the history. */
1918 1918
 
1919
-        if ($move_handled) {
1920
-            // Use $this->board to update $this->gamestate['fen_piece_placement'].
1919
+		if ($move_handled) {
1920
+			// Use $this->board to update $this->gamestate['fen_piece_placement'].
1921 1921
 
1922
-            $this->board_to_fen_piece_placement();
1922
+			$this->board_to_fen_piece_placement();
1923 1923
 
1924
-            // handle check, checkmate and stalemate
1924
+			// handle check, checkmate and stalemate
1925 1925
 
1926
-            $comment = '';
1926
+			$comment = '';
1927 1927
 
1928
-            if ($this->kingIsUnderAttack($cur_opp, $cur_player)) {
1929
-                // if this is check mate finish the game, otherwise if not just add a + to the move
1928
+			if ($this->kingIsUnderAttack($cur_opp, $cur_player)) {
1929
+				// if this is check mate finish the game, otherwise if not just add a + to the move
1930 1930
 
1931
-                if ($this->isCheckMate($cur_opp, $cur_player)) {
1932
-                    $this->gamestate['pgn_result'] = 'w' == $cur_player ? '1-0' : '0-1';
1931
+				if ($this->isCheckMate($cur_opp, $cur_player)) {
1932
+					$this->gamestate['pgn_result'] = 'w' == $cur_player ? '1-0' : '0-1';
1933 1933
 
1934
-                    $history_move .= '#';
1934
+					$history_move .= '#';
1935 1935
 
1936
-                    $result .= ' ... ' . _MD_CHESS_MOVE_CHECKMATE;
1937
-                } else {
1938
-                    $history_move .= '+';
1939
-                }
1940
-            } elseif ($this->isStaleMate($cur_opp, $cur_player)) {
1941
-                $this->gamestate['pgn_result'] = '1/2-1/2';
1936
+					$result .= ' ... ' . _MD_CHESS_MOVE_CHECKMATE;
1937
+				} else {
1938
+					$history_move .= '+';
1939
+				}
1940
+			} elseif ($this->isStaleMate($cur_opp, $cur_player)) {
1941
+				$this->gamestate['pgn_result'] = '1/2-1/2';
1942 1942
 
1943
-                $result .= ' ... ' . _MD_CHESS_MOVE_STALEMATE;
1943
+				$result .= ' ... ' . _MD_CHESS_MOVE_STALEMATE;
1944 1944
 
1945
-                $comment = _MD_CHESS_DRAW_STALEMATE;
1946
-            } elseif ($this->insufficient_mating_material()) {
1947
-                $this->gamestate['pgn_result'] = '1/2-1/2';
1945
+				$comment = _MD_CHESS_DRAW_STALEMATE;
1946
+			} elseif ($this->insufficient_mating_material()) {
1947
+				$this->gamestate['pgn_result'] = '1/2-1/2';
1948 1948
 
1949
-                $result .= ' ... ' . _MD_CHESS_MOVE_MATERIAL;
1949
+				$result .= ' ... ' . _MD_CHESS_MOVE_MATERIAL;
1950 1950
 
1951
-                $comment = _MD_CHESS_DRAW_NO_MATE;
1952
-            }
1951
+				$comment = _MD_CHESS_DRAW_NO_MATE;
1952
+			}
1953 1953
 
1954
-            // store possible castling-availability modification
1954
+			// store possible castling-availability modification
1955 1955
 
1956
-            $KQkq = ($white_may_castle_short ? 'K' : '') . ($white_may_castle_long ? 'Q' : '') . ($black_may_castle_short ? 'k' : '') . ($black_may_castle_long ? 'q' : '');
1956
+			$KQkq = ($white_may_castle_short ? 'K' : '') . ($white_may_castle_long ? 'Q' : '') . ($black_may_castle_short ? 'k' : '') . ($black_may_castle_long ? 'q' : '');
1957 1957
 
1958
-            $this->gamestate['fen_castling_availability'] = !empty($KQkq) ? $KQkq : '-';
1958
+			$this->gamestate['fen_castling_availability'] = !empty($KQkq) ? $KQkq : '-';
1959 1959
 
1960
-            // strip old result-string from end of movetext
1960
+			// strip old result-string from end of movetext
1961 1961
 
1962
-            // It's assumed that the movetext for a game in play is terminated by a '*', possibly preceded by whitespace.
1962
+			// It's assumed that the movetext for a game in play is terminated by a '*', possibly preceded by whitespace.
1963 1963
 
1964
-            // (The whitespace will be present unless there are no moves in the game yet.)
1964
+			// (The whitespace will be present unless there are no moves in the game yet.)
1965 1965
 
1966
-            $this->gamestate['pgn_movetext'] = \preg_replace('/\s*\*$/', '', $this->gamestate['pgn_movetext']);
1966
+			$this->gamestate['pgn_movetext'] = \preg_replace('/\s*\*$/', '', $this->gamestate['pgn_movetext']);
1967 1967
 
1968
-            // if white move, output move-number
1968
+			// if white move, output move-number
1969 1969
 
1970
-            if ('w' == $this->gamestate['fen_active_color']) {
1971
-                if (!empty($this->gamestate['pgn_movetext'])) {
1972
-                    $this->gamestate['pgn_movetext'] .= ' ';
1973
-                }
1970
+			if ('w' == $this->gamestate['fen_active_color']) {
1971
+				if (!empty($this->gamestate['pgn_movetext'])) {
1972
+					$this->gamestate['pgn_movetext'] .= ' ';
1973
+				}
1974 1974
 
1975
-                $this->gamestate['pgn_movetext'] .= $this->gamestate['fen_fullmove_number'] . '.';
1976
-                // if black move, no moves yet, and game is setup, output move number with special '...' terminator
1977
-            } elseif (empty($this->gamestate['pgn_movetext']) && !empty($this->gamestate['pgn_fen'])) {
1978
-                $this->gamestate['pgn_movetext'] .= $this->gamestate['fen_fullmove_number'] . '...';
1979
-            }
1975
+				$this->gamestate['pgn_movetext'] .= $this->gamestate['fen_fullmove_number'] . '.';
1976
+				// if black move, no moves yet, and game is setup, output move number with special '...' terminator
1977
+			} elseif (empty($this->gamestate['pgn_movetext']) && !empty($this->gamestate['pgn_fen'])) {
1978
+				$this->gamestate['pgn_movetext'] .= $this->gamestate['fen_fullmove_number'] . '...';
1979
+			}
1980 1980
 
1981
-            // update movetext
1981
+			// update movetext
1982 1982
 
1983
-            // comment is added only for a concluded game
1983
+			// comment is added only for a concluded game
1984 1984
 
1985
-            $this->gamestate['pgn_movetext'] .= ' ' . $history_move . ' ' . $this->gamestate['pgn_result'];
1986
-
1987
-            if (!empty($comment)) {
1988
-                $this->gamestate['pgn_movetext'] .= ' {' . $comment . '}';
1989
-            }
1990
-
1991
-            // if black move, increment move-number
1985
+			$this->gamestate['pgn_movetext'] .= ' ' . $history_move . ' ' . $this->gamestate['pgn_result'];
1986
+
1987
+			if (!empty($comment)) {
1988
+				$this->gamestate['pgn_movetext'] .= ' {' . $comment . '}';
1989
+			}
1990
+
1991
+			// if black move, increment move-number
1992 1992
 
1993
-            if ('b' == $this->gamestate['fen_active_color']) {
1994
-                ++$this->gamestate['fen_fullmove_number'];
1995
-            }
1993
+			if ('b' == $this->gamestate['fen_active_color']) {
1994
+				++$this->gamestate['fen_fullmove_number'];
1995
+			}
1996 1996
 
1997
-            // If pawn advance or capturing move, reset the halfmove clock. Otherwise increment it.
1997
+			// If pawn advance or capturing move, reset the halfmove clock. Otherwise increment it.
1998 1998
 
1999
-            if ('O-O' != $move && 'O-O-O' != $move && (0 === \strpos($move, 'P') || 'x' == $move[3])) {
2000
-                $this->gamestate['fen_halfmove_clock'] = 0;
2001
-            } else {
2002
-                ++$this->gamestate['fen_halfmove_clock'];
2003
-            }
1999
+			if ('O-O' != $move && 'O-O-O' != $move && (0 === \strpos($move, 'P') || 'x' == $move[3])) {
2000
+				$this->gamestate['fen_halfmove_clock'] = 0;
2001
+			} else {
2002
+				++$this->gamestate['fen_halfmove_clock'];
2003
+			}
2004 2004
 
2005
-            // set next player
2005
+			// set next player
2006 2006
 
2007
-            $this->gamestate['fen_active_color'] = 'w' == $this->gamestate['fen_active_color'] ? 'b' : 'w';
2008
-        }
2007
+			$this->gamestate['fen_active_color'] = 'w' == $this->gamestate['fen_active_color'] ? 'b' : 'w';
2008
+		}
2009 2009
 
2010
-        return [$move_handled, $result];
2011
-    }
2010
+		return [$move_handled, $result];
2011
+	}
2012 2012
 
2013
-    /**
2014
-     * Check whether a tile is empty.
2015
-     *
2016
-     * @param int $position
2017
-     * @return bool
2018
-     *
2019
-     * @access private
2020
-     */
2021
-    public function is_empty_tile($position)
2022
-    {
2023
-        return '00' == $this->board[$position];
2024
-    }
2025
-
2026
-    /**
2027
-     * Clear a tile.
2028
-     *
2029
-     * @param int $position Position of tile
2030
-     *
2031
-     * @access private
2032
-     */
2033
-    public function clear_tile($position)
2034
-    {
2035
-        $this->board[$position] = '00';
2036
-    }
2037
-
2038
-    /**
2039
-     * Convert FEN piece placement field to array.
2040
-     *
2041
-     * Use $this->gamestate['fen_piece_placement'] to initialize $this->board, $this->w_figures and $this->b_figures.
2042
-     *
2043
-     * @return bool True if piece placement is valid, otherwise false.
2044
-     *
2045
-     * @access private
2046
-     */
2047
-    public function fen_piece_placement_to_board()
2048
-    {
2049
-        if (empty($this->gamestate['fen_piece_placement']) || \mb_strlen($this->gamestate['fen_piece_placement']) > 71) {
2050
-            #trigger_error('piece placement empty or length invalid', E_USER_WARNING); #*#DEBUG#
2051
-            return false; // invalid length
2052
-        }
2053
-
2054
-        $this->board = [];
2055
-
2056
-        $piece_map = [
2057
-            'K' => 'wK',
2058
-            'Q' => 'wQ',
2059
-            'R' => 'wR',
2060
-            'B' => 'wB',
2061
-            'N' => 'wN',
2062
-            'P' => 'wP',
2063
-            'k' => 'bK',
2064
-            'q' => 'bQ',
2065
-            'r' => 'bR',
2066
-            'b' => 'bB',
2067
-            'n' => 'bN',
2068
-            'p' => 'bP',
2069
-        ];
2070
-
2071
-        $tiles = \implode('', \array_reverse(\explode('/', $this->gamestate['fen_piece_placement'])));
2072
-
2073
-        for ($i = 0, $iMax = mb_strlen($tiles); $i < $iMax; ++$i) {
2074
-            $tile = $tiles[$i];
2075
-
2076
-            if (isset($piece_map[$tile])) {
2077
-                $this->board[] = $piece_map[$tile];
2078
-            } elseif (\is_numeric($tile) && $tile >= 1 && $tile <= 8) {
2079
-                for ($j = 0; $j < $tile; ++$j) {
2080
-                    $this->board[] = '00';
2081
-                }
2082
-            } else {
2083
-                #trigger_error("tile='$tile'", E_USER_WARNING); #*#DEBUG#
2084
-                return false; // unexpected character in piece_placement
2085
-            }
2086
-        }
2087
-
2088
-        if (64 != \count($this->board)) {
2089
-            #trigger_error('count(board)=' . count($this->board), E_USER_WARNING); #*#DEBUG#
2090
-            return false; // piece_placement has incorrect number of tiles
2091
-        }
2092
-
2093
-        $this->w_figures = [];
2094
-
2095
-        $this->b_figures = [];
2096
-
2097
-        for ($i = 0; $i < 64; ++$i) {
2098
-            $tile = $this->board[$i];
2099
-
2100
-            $coordinates = $this->boardIndexToCoord($i);
2101
-
2102
-            if ('w' == $tile[0]) {
2103
-                $this->w_figures[] = $tile[1] . $coordinates;
2104
-            } elseif ('b' == $tile[0]) {
2105
-                $this->b_figures[] = $tile[1] . $coordinates;
2106
-            }
2107
-        }
2108
-
2109
-        return true;
2110
-    }
2111
-
2112
-    /**
2113
-     * Convert array to FEN piece placement field.
2114
-     *
2115
-     * Use $this->board to initialize $this->gamestate['fen_piece_placement'].
2116
-     *
2117
-     * @access private
2118
-     */
2119
-    public function board_to_fen_piece_placement()
2120
-    {
2121
-        $rows = [];
2122
-
2123
-        for ($rank = 7; $rank >= 0; --$rank) {
2124
-            $row = '';
2125
-
2126
-            for ($file = 0; $file < 8; ++$file) {
2127
-                $index = 8 * $rank + $file;
2128
-
2129
-                if (!$this->is_empty_tile($index)) {
2130
-                    $tile = $this->board[$index];
2131
-
2132
-                    $piece = 'w' == $tile[0] ? $tile[1] : \mb_strtolower($tile[1]); // 'K','Q','R','B','N' or 'P' (uppercase for white, lowercase for black)
2133
-                } else {
2134
-                    $piece = 'x'; // temporarily mark each empty tile with 'x'
2135
-                }
2136
-
2137
-                $row .= $piece; // append piece symbol to row-string
2138
-            }
2139
-
2140
-            $rows[] = $row;
2141
-        }
2142
-
2143
-        // Concatenate the eight row-strings with the separator '/'.
2144
-
2145
-        // Then replace each string of x's with the string length.
2146
-
2147
-        $this->gamestate['fen_piece_placement'] = \preg_replace_callback('/(x+)/', static function($matches) {return \strlen($matches[1]);}, \implode('/', $rows));
2148
-    }
2149
-
2150
-    /**
2151
-     * Determine whether there is insufficient material to mate.
2152
-     *
2153
-     * @return bool  True if only the following pieces remain: K vs. K, K vs. K+B or K vs. K+N; otherwise false.
2154
-     *
2155
-     * @access private
2156
-     */
2157
-    public function insufficient_mating_material()
2158
-    {
2159
-        $pieces = \mb_strtoupper($this->gamestate['fen_piece_placement']);
2160
-
2161
-        $counts = \count_chars($pieces, 1);
2162
-
2163
-        $num_queens = (int)@$counts[\ord('Q')];
2164
-
2165
-        $num_rooks = (int)@$counts[\ord('R')];
2166
-
2167
-        $num_bishops = (int)@$counts[\ord('B')];
2168
-
2169
-        $num_knights = (int)@$counts[\ord('N')];
2170
-
2171
-        $num_pawns = (int)@$counts[\ord('P')];
2172
-
2173
-        return 0 == $num_queens && 0 == $num_rooks && ($num_bishops + $num_knights) <= 1 && 0 == $num_pawns;
2174
-    }
2175
-
2176
-    // --------------------------
2177
-
2178
-    // INCIDENTAL PRIVATE METHODS
2179
-
2180
-    // --------------------------
2181
-
2182
-    // These functions don't really need to be class methods, since they don't access class properties.
2183
-
2184
-    // They're placed within the class only for name-scoping.
2185
-
2186
-    /**
2187
-     * Convert board coordinates [a-h][1-8] to board index [0..63]
2188
-     *
2189
-     * @param string $coord Example: 'b3'
2190
-     * @return int  Example: 17
2191
-     *
2192
-     * @access private
2193
-     */
2194
-    public function boardCoordToIndex($coord)
2195
-    {
2196
-        //echo $coord," --> ";
2197
-
2198
-        switch ($coord[0]) {
2199
-            case 'a':
2200
-                $x = 0;
2201
-                break;
2202
-            case 'b':
2203
-                $x = 1;
2204
-                break;
2205
-            case 'c':
2206
-                $x = 2;
2207
-                break;
2208
-            case 'd':
2209
-                $x = 3;
2210
-                break;
2211
-            case 'e':
2212
-                $x = 4;
2213
-                break;
2214
-            case 'f':
2215
-                $x = 5;
2216
-                break;
2217
-            case 'g':
2218
-                $x = 6;
2219
-                break;
2220
-            case 'h':
2221
-                $x = 7;
2222
-                break;
2223
-            default:
2224
-                return 64; /* erronous coord */
2225
-        }
2226
-
2227
-        $y = $coord[1] - 1;
2228
-
2229
-        if ($y < 0 || $y > 7) {
2230
-            return 64;
2231
-        } /* erronous coord */
2232
-
2233
-        return $y * 8 + $x;
2234
-        //echo "$index | ";
2235
-    }
2236
-
2237
-    /**
2238
-     * Convert board index [0..63] to board coordinates [a-h][1-8].
2239
-     *
2240
-     * @param int $index Example: 17
2241
-     * @return string  Example: 'b3'
2242
-     *
2243
-     * @access private
2244
-     */
2245
-    public function boardIndexToCoord($index)
2246
-    {
2247
-        //echo $index," --> ";
2248
-
2249
-        if ($index < 0 || $index > 63) {
2250
-            return '';
2251
-        }
2252
-
2253
-        $y = \floor($index / 8) + 1;
2254
-
2255
-        $x = \chr(($index % 8) + 97);
2256
-
2257
-        return "$x$y";
2258
-    }
2259
-
2260
-    /**
2261
-     * Get piece name from piece symbol.
2262
-     *
2263
-     * @param string $short Piece symbol
2264
-     * @return string        Piece name
2265
-     *
2266
-     * @access private
2267
-     */
2268
-    public function getFullFigureName($short)
2269
-    {
2270
-        static $names = [
2271
-            'K' => _MD_CHESS_MOVE_KING,
2272
-            'Q' => _MD_CHESS_MOVE_QUEEN,
2273
-            'R' => _MD_CHESS_MOVE_ROOK,
2274
-            'B' => _MD_CHESS_MOVE_BISHOP,
2275
-            'N' => _MD_CHESS_MOVE_KNIGHT,
2276
-            'P' => _MD_CHESS_MOVE_PAWN,
2277
-        ];
2278
-
2279
-        return $names[$short] ?? _MD_CHESS_MOVE_EMPTY;
2280
-    }
2281
-
2282
-    /**
2283
-     * Get tiles adjacent to specified tile.
2284
-     *
2285
-     * @param int $fig_pos
2286
-     * @return array
2287
-     *
2288
-     * @access private
2289
-     */
2290
-    public function getAdjTiles($fig_pos)
2291
-    {
2292
-        $adj_tiles = [];
2293
-
2294
-        $i = 0;
2295
-
2296
-        $x = $fig_pos % 8;
2297
-
2298
-        $y = \floor($fig_pos / 8);
2299
-
2300
-        if ($x > 0 && $y > 0) {
2301
-            $adj_tiles[$i++] = $fig_pos - 9;
2302
-        }
2303
-
2304
-        if ($y > 0) {
2305
-            $adj_tiles[$i++] = $fig_pos - 8;
2306
-        }
2307
-
2308
-        if ($x < 7 && $y > 0) {
2309
-            $adj_tiles[$i++] = $fig_pos - 7;
2310
-        }
2311
-
2312
-        if ($x < 7) {
2313
-            $adj_tiles[$i++] = $fig_pos + 1;
2314
-        }
2315
-
2316
-        if ($x < 7 && $y < 7) {
2317
-            $adj_tiles[$i++] = $fig_pos + 9;
2318
-        }
2319
-
2320
-        if ($y < 7) {
2321
-            $adj_tiles[$i++] = $fig_pos + 8;
2322
-        }
2323
-
2324
-        if ($x > 0 && $y < 7) {
2325
-            $adj_tiles[$i++] = $fig_pos + 7;
2326
-        }
2327
-
2328
-        if ($x > 0) {
2329
-            $adj_tiles[$i++] = $fig_pos - 1;
2330
-        }
2331
-
2332
-        /* DEBUG:  foreach( $adj_tiles as $tile )
2013
+	/**
2014
+	 * Check whether a tile is empty.
2015
+	 *
2016
+	 * @param int $position
2017
+	 * @return bool
2018
+	 *
2019
+	 * @access private
2020
+	 */
2021
+	public function is_empty_tile($position)
2022
+	{
2023
+		return '00' == $this->board[$position];
2024
+	}
2025
+
2026
+	/**
2027
+	 * Clear a tile.
2028
+	 *
2029
+	 * @param int $position Position of tile
2030
+	 *
2031
+	 * @access private
2032
+	 */
2033
+	public function clear_tile($position)
2034
+	{
2035
+		$this->board[$position] = '00';
2036
+	}
2037
+
2038
+	/**
2039
+	 * Convert FEN piece placement field to array.
2040
+	 *
2041
+	 * Use $this->gamestate['fen_piece_placement'] to initialize $this->board, $this->w_figures and $this->b_figures.
2042
+	 *
2043
+	 * @return bool True if piece placement is valid, otherwise false.
2044
+	 *
2045
+	 * @access private
2046
+	 */
2047
+	public function fen_piece_placement_to_board()
2048
+	{
2049
+		if (empty($this->gamestate['fen_piece_placement']) || \mb_strlen($this->gamestate['fen_piece_placement']) > 71) {
2050
+			#trigger_error('piece placement empty or length invalid', E_USER_WARNING); #*#DEBUG#
2051
+			return false; // invalid length
2052
+		}
2053
+
2054
+		$this->board = [];
2055
+
2056
+		$piece_map = [
2057
+			'K' => 'wK',
2058
+			'Q' => 'wQ',
2059
+			'R' => 'wR',
2060
+			'B' => 'wB',
2061
+			'N' => 'wN',
2062
+			'P' => 'wP',
2063
+			'k' => 'bK',
2064
+			'q' => 'bQ',
2065
+			'r' => 'bR',
2066
+			'b' => 'bB',
2067
+			'n' => 'bN',
2068
+			'p' => 'bP',
2069
+		];
2070
+
2071
+		$tiles = \implode('', \array_reverse(\explode('/', $this->gamestate['fen_piece_placement'])));
2072
+
2073
+		for ($i = 0, $iMax = mb_strlen($tiles); $i < $iMax; ++$i) {
2074
+			$tile = $tiles[$i];
2075
+
2076
+			if (isset($piece_map[$tile])) {
2077
+				$this->board[] = $piece_map[$tile];
2078
+			} elseif (\is_numeric($tile) && $tile >= 1 && $tile <= 8) {
2079
+				for ($j = 0; $j < $tile; ++$j) {
2080
+					$this->board[] = '00';
2081
+				}
2082
+			} else {
2083
+				#trigger_error("tile='$tile'", E_USER_WARNING); #*#DEBUG#
2084
+				return false; // unexpected character in piece_placement
2085
+			}
2086
+		}
2087
+
2088
+		if (64 != \count($this->board)) {
2089
+			#trigger_error('count(board)=' . count($this->board), E_USER_WARNING); #*#DEBUG#
2090
+			return false; // piece_placement has incorrect number of tiles
2091
+		}
2092
+
2093
+		$this->w_figures = [];
2094
+
2095
+		$this->b_figures = [];
2096
+
2097
+		for ($i = 0; $i < 64; ++$i) {
2098
+			$tile = $this->board[$i];
2099
+
2100
+			$coordinates = $this->boardIndexToCoord($i);
2101
+
2102
+			if ('w' == $tile[0]) {
2103
+				$this->w_figures[] = $tile[1] . $coordinates;
2104
+			} elseif ('b' == $tile[0]) {
2105
+				$this->b_figures[] = $tile[1] . $coordinates;
2106
+			}
2107
+		}
2108
+
2109
+		return true;
2110
+	}
2111
+
2112
+	/**
2113
+	 * Convert array to FEN piece placement field.
2114
+	 *
2115
+	 * Use $this->board to initialize $this->gamestate['fen_piece_placement'].
2116
+	 *
2117
+	 * @access private
2118
+	 */
2119
+	public function board_to_fen_piece_placement()
2120
+	{
2121
+		$rows = [];
2122
+
2123
+		for ($rank = 7; $rank >= 0; --$rank) {
2124
+			$row = '';
2125
+
2126
+			for ($file = 0; $file < 8; ++$file) {
2127
+				$index = 8 * $rank + $file;
2128
+
2129
+				if (!$this->is_empty_tile($index)) {
2130
+					$tile = $this->board[$index];
2131
+
2132
+					$piece = 'w' == $tile[0] ? $tile[1] : \mb_strtolower($tile[1]); // 'K','Q','R','B','N' or 'P' (uppercase for white, lowercase for black)
2133
+				} else {
2134
+					$piece = 'x'; // temporarily mark each empty tile with 'x'
2135
+				}
2136
+
2137
+				$row .= $piece; // append piece symbol to row-string
2138
+			}
2139
+
2140
+			$rows[] = $row;
2141
+		}
2142
+
2143
+		// Concatenate the eight row-strings with the separator '/'.
2144
+
2145
+		// Then replace each string of x's with the string length.
2146
+
2147
+		$this->gamestate['fen_piece_placement'] = \preg_replace_callback('/(x+)/', static function($matches) {return \strlen($matches[1]);}, \implode('/', $rows));
2148
+	}
2149
+
2150
+	/**
2151
+	 * Determine whether there is insufficient material to mate.
2152
+	 *
2153
+	 * @return bool  True if only the following pieces remain: K vs. K, K vs. K+B or K vs. K+N; otherwise false.
2154
+	 *
2155
+	 * @access private
2156
+	 */
2157
+	public function insufficient_mating_material()
2158
+	{
2159
+		$pieces = \mb_strtoupper($this->gamestate['fen_piece_placement']);
2160
+
2161
+		$counts = \count_chars($pieces, 1);
2162
+
2163
+		$num_queens = (int)@$counts[\ord('Q')];
2164
+
2165
+		$num_rooks = (int)@$counts[\ord('R')];
2166
+
2167
+		$num_bishops = (int)@$counts[\ord('B')];
2168
+
2169
+		$num_knights = (int)@$counts[\ord('N')];
2170
+
2171
+		$num_pawns = (int)@$counts[\ord('P')];
2172
+
2173
+		return 0 == $num_queens && 0 == $num_rooks && ($num_bishops + $num_knights) <= 1 && 0 == $num_pawns;
2174
+	}
2175
+
2176
+	// --------------------------
2177
+
2178
+	// INCIDENTAL PRIVATE METHODS
2179
+
2180
+	// --------------------------
2181
+
2182
+	// These functions don't really need to be class methods, since they don't access class properties.
2183
+
2184
+	// They're placed within the class only for name-scoping.
2185
+
2186
+	/**
2187
+	 * Convert board coordinates [a-h][1-8] to board index [0..63]
2188
+	 *
2189
+	 * @param string $coord Example: 'b3'
2190
+	 * @return int  Example: 17
2191
+	 *
2192
+	 * @access private
2193
+	 */
2194
+	public function boardCoordToIndex($coord)
2195
+	{
2196
+		//echo $coord," --> ";
2197
+
2198
+		switch ($coord[0]) {
2199
+			case 'a':
2200
+				$x = 0;
2201
+				break;
2202
+			case 'b':
2203
+				$x = 1;
2204
+				break;
2205
+			case 'c':
2206
+				$x = 2;
2207
+				break;
2208
+			case 'd':
2209
+				$x = 3;
2210
+				break;
2211
+			case 'e':
2212
+				$x = 4;
2213
+				break;
2214
+			case 'f':
2215
+				$x = 5;
2216
+				break;
2217
+			case 'g':
2218
+				$x = 6;
2219
+				break;
2220
+			case 'h':
2221
+				$x = 7;
2222
+				break;
2223
+			default:
2224
+				return 64; /* erronous coord */
2225
+		}
2226
+
2227
+		$y = $coord[1] - 1;
2228
+
2229
+		if ($y < 0 || $y > 7) {
2230
+			return 64;
2231
+		} /* erronous coord */
2232
+
2233
+		return $y * 8 + $x;
2234
+		//echo "$index | ";
2235
+	}
2236
+
2237
+	/**
2238
+	 * Convert board index [0..63] to board coordinates [a-h][1-8].
2239
+	 *
2240
+	 * @param int $index Example: 17
2241
+	 * @return string  Example: 'b3'
2242
+	 *
2243
+	 * @access private
2244
+	 */
2245
+	public function boardIndexToCoord($index)
2246
+	{
2247
+		//echo $index," --> ";
2248
+
2249
+		if ($index < 0 || $index > 63) {
2250
+			return '';
2251
+		}
2252
+
2253
+		$y = \floor($index / 8) + 1;
2254
+
2255
+		$x = \chr(($index % 8) + 97);
2256
+
2257
+		return "$x$y";
2258
+	}
2259
+
2260
+	/**
2261
+	 * Get piece name from piece symbol.
2262
+	 *
2263
+	 * @param string $short Piece symbol
2264
+	 * @return string        Piece name
2265
+	 *
2266
+	 * @access private
2267
+	 */
2268
+	public function getFullFigureName($short)
2269
+	{
2270
+		static $names = [
2271
+			'K' => _MD_CHESS_MOVE_KING,
2272
+			'Q' => _MD_CHESS_MOVE_QUEEN,
2273
+			'R' => _MD_CHESS_MOVE_ROOK,
2274
+			'B' => _MD_CHESS_MOVE_BISHOP,
2275
+			'N' => _MD_CHESS_MOVE_KNIGHT,
2276
+			'P' => _MD_CHESS_MOVE_PAWN,
2277
+		];
2278
+
2279
+		return $names[$short] ?? _MD_CHESS_MOVE_EMPTY;
2280
+	}
2281
+
2282
+	/**
2283
+	 * Get tiles adjacent to specified tile.
2284
+	 *
2285
+	 * @param int $fig_pos
2286
+	 * @return array
2287
+	 *
2288
+	 * @access private
2289
+	 */
2290
+	public function getAdjTiles($fig_pos)
2291
+	{
2292
+		$adj_tiles = [];
2293
+
2294
+		$i = 0;
2295
+
2296
+		$x = $fig_pos % 8;
2297
+
2298
+		$y = \floor($fig_pos / 8);
2299
+
2300
+		if ($x > 0 && $y > 0) {
2301
+			$adj_tiles[$i++] = $fig_pos - 9;
2302
+		}
2303
+
2304
+		if ($y > 0) {
2305
+			$adj_tiles[$i++] = $fig_pos - 8;
2306
+		}
2307
+
2308
+		if ($x < 7 && $y > 0) {
2309
+			$adj_tiles[$i++] = $fig_pos - 7;
2310
+		}
2311
+
2312
+		if ($x < 7) {
2313
+			$adj_tiles[$i++] = $fig_pos + 1;
2314
+		}
2315
+
2316
+		if ($x < 7 && $y < 7) {
2317
+			$adj_tiles[$i++] = $fig_pos + 9;
2318
+		}
2319
+
2320
+		if ($y < 7) {
2321
+			$adj_tiles[$i++] = $fig_pos + 8;
2322
+		}
2323
+
2324
+		if ($x > 0 && $y < 7) {
2325
+			$adj_tiles[$i++] = $fig_pos + 7;
2326
+		}
2327
+
2328
+		if ($x > 0) {
2329
+			$adj_tiles[$i++] = $fig_pos - 1;
2330
+		}
2331
+
2332
+		/* DEBUG:  foreach( $adj_tiles as $tile )
2333 2333
           echo "adj: $tile "; */
2334 2334
 
2335
-        return $adj_tiles;
2336
-    }
2335
+		return $adj_tiles;
2336
+	}
2337 2337
 } // class ChessGame
2338 2338
 
2339 2339
 ?>
Please login to merge, or discard this patch.
Spacing   +20 added lines, -20 removed lines patch added patch discarded remove patch
@@ -300,10 +300,10 @@  discard block
 block discarded – undo
300 300
                   || ('-' != $this->gamestate['fen_en_passant_target_square'] && 6 == $this->gamestate['fen_en_passant_target_square'][1] && 'w' != $this->gamestate['fen_active_color'])) {
301 301
             return _MD_CHESS_FENBAD_EP_COLOR; // en passant target square wrong color
302 302
         } elseif ('-' != $this->gamestate['fen_en_passant_target_square'] && 3 == $this->gamestate['fen_en_passant_target_square'][1]
303
-                  && 'wP' != $this->board[$this->boardCoordToIndex($this->gamestate['fen_en_passant_target_square'][0] . '4')]) {
303
+                  && 'wP' != $this->board[$this->boardCoordToIndex($this->gamestate['fen_en_passant_target_square'][0].'4')]) {
304 304
             return _MD_CHESS_FENBAD_EP_NO_PAWN; // en passant target square for nonexistent pawn
305 305
         } elseif ('-' != $this->gamestate['fen_en_passant_target_square'] && 6 == $this->gamestate['fen_en_passant_target_square'][1]
306
-                  && 'bP' != $this->board[$this->boardCoordToIndex($this->gamestate['fen_en_passant_target_square'][0] . '5')]) {
306
+                  && 'bP' != $this->board[$this->boardCoordToIndex($this->gamestate['fen_en_passant_target_square'][0].'5')]) {
307 307
             return _MD_CHESS_FENBAD_EP_NO_PAWN; // en passant target square for nonexistent pawn
308 308
         }
309 309
 
@@ -1876,7 +1876,7 @@  discard block
 block discarded – undo
1876 1876
             if ('P' == $fig_type && 16 == \abs($fig_pos - $dest_pos)) {
1877 1877
                 $file_chars = 'abcdefgh';
1878 1878
 
1879
-                $this->gamestate['fen_en_passant_target_square'] = $file_chars[$fig_pos % 8] . ('w' == $cur_player ? '3' : '6');
1879
+                $this->gamestate['fen_en_passant_target_square'] = $file_chars[$fig_pos % 8].('w' == $cur_player ? '3' : '6');
1880 1880
             } else {
1881 1881
                 // clear 'en passant'
1882 1882
 
@@ -1904,7 +1904,7 @@  discard block
 block discarded – undo
1904 1904
 
1905 1905
                     $this->board[$dest_pos] = "$cur_player$pawn_upg";
1906 1906
 
1907
-                    $result .= ' ... ' . $this->move_msg(_MD_CHESS_MOVE_PROMOTED, $this->getFullFigureName($pawn_upg));
1907
+                    $result .= ' ... '.$this->move_msg(_MD_CHESS_MOVE_PROMOTED, $this->getFullFigureName($pawn_upg));
1908 1908
                 }
1909 1909
             }
1910 1910
 
@@ -1933,27 +1933,27 @@  discard block
 block discarded – undo
1933 1933
 
1934 1934
                     $history_move .= '#';
1935 1935
 
1936
-                    $result .= ' ... ' . _MD_CHESS_MOVE_CHECKMATE;
1936
+                    $result .= ' ... '._MD_CHESS_MOVE_CHECKMATE;
1937 1937
                 } else {
1938 1938
                     $history_move .= '+';
1939 1939
                 }
1940 1940
             } elseif ($this->isStaleMate($cur_opp, $cur_player)) {
1941 1941
                 $this->gamestate['pgn_result'] = '1/2-1/2';
1942 1942
 
1943
-                $result .= ' ... ' . _MD_CHESS_MOVE_STALEMATE;
1943
+                $result .= ' ... '._MD_CHESS_MOVE_STALEMATE;
1944 1944
 
1945 1945
                 $comment = _MD_CHESS_DRAW_STALEMATE;
1946 1946
             } elseif ($this->insufficient_mating_material()) {
1947 1947
                 $this->gamestate['pgn_result'] = '1/2-1/2';
1948 1948
 
1949
-                $result .= ' ... ' . _MD_CHESS_MOVE_MATERIAL;
1949
+                $result .= ' ... '._MD_CHESS_MOVE_MATERIAL;
1950 1950
 
1951 1951
                 $comment = _MD_CHESS_DRAW_NO_MATE;
1952 1952
             }
1953 1953
 
1954 1954
             // store possible castling-availability modification
1955 1955
 
1956
-            $KQkq = ($white_may_castle_short ? 'K' : '') . ($white_may_castle_long ? 'Q' : '') . ($black_may_castle_short ? 'k' : '') . ($black_may_castle_long ? 'q' : '');
1956
+            $KQkq = ($white_may_castle_short ? 'K' : '').($white_may_castle_long ? 'Q' : '').($black_may_castle_short ? 'k' : '').($black_may_castle_long ? 'q' : '');
1957 1957
 
1958 1958
             $this->gamestate['fen_castling_availability'] = !empty($KQkq) ? $KQkq : '-';
1959 1959
 
@@ -1972,20 +1972,20 @@  discard block
 block discarded – undo
1972 1972
                     $this->gamestate['pgn_movetext'] .= ' ';
1973 1973
                 }
1974 1974
 
1975
-                $this->gamestate['pgn_movetext'] .= $this->gamestate['fen_fullmove_number'] . '.';
1975
+                $this->gamestate['pgn_movetext'] .= $this->gamestate['fen_fullmove_number'].'.';
1976 1976
                 // if black move, no moves yet, and game is setup, output move number with special '...' terminator
1977 1977
             } elseif (empty($this->gamestate['pgn_movetext']) && !empty($this->gamestate['pgn_fen'])) {
1978
-                $this->gamestate['pgn_movetext'] .= $this->gamestate['fen_fullmove_number'] . '...';
1978
+                $this->gamestate['pgn_movetext'] .= $this->gamestate['fen_fullmove_number'].'...';
1979 1979
             }
1980 1980
 
1981 1981
             // update movetext
1982 1982
 
1983 1983
             // comment is added only for a concluded game
1984 1984
 
1985
-            $this->gamestate['pgn_movetext'] .= ' ' . $history_move . ' ' . $this->gamestate['pgn_result'];
1985
+            $this->gamestate['pgn_movetext'] .= ' '.$history_move.' '.$this->gamestate['pgn_result'];
1986 1986
 
1987 1987
             if (!empty($comment)) {
1988
-                $this->gamestate['pgn_movetext'] .= ' {' . $comment . '}';
1988
+                $this->gamestate['pgn_movetext'] .= ' {'.$comment.'}';
1989 1989
             }
1990 1990
 
1991 1991
             // if black move, increment move-number
@@ -2100,9 +2100,9 @@  discard block
 block discarded – undo
2100 2100
             $coordinates = $this->boardIndexToCoord($i);
2101 2101
 
2102 2102
             if ('w' == $tile[0]) {
2103
-                $this->w_figures[] = $tile[1] . $coordinates;
2103
+                $this->w_figures[] = $tile[1].$coordinates;
2104 2104
             } elseif ('b' == $tile[0]) {
2105
-                $this->b_figures[] = $tile[1] . $coordinates;
2105
+                $this->b_figures[] = $tile[1].$coordinates;
2106 2106
             }
2107 2107
         }
2108 2108
 
@@ -2144,7 +2144,7 @@  discard block
 block discarded – undo
2144 2144
 
2145 2145
         // Then replace each string of x's with the string length.
2146 2146
 
2147
-        $this->gamestate['fen_piece_placement'] = \preg_replace_callback('/(x+)/', static function($matches) {return \strlen($matches[1]);}, \implode('/', $rows));
2147
+        $this->gamestate['fen_piece_placement'] = \preg_replace_callback('/(x+)/', static function($matches) {return \strlen($matches[1]); }, \implode('/', $rows));
2148 2148
     }
2149 2149
 
2150 2150
     /**
@@ -2160,15 +2160,15 @@  discard block
 block discarded – undo
2160 2160
 
2161 2161
         $counts = \count_chars($pieces, 1);
2162 2162
 
2163
-        $num_queens = (int)@$counts[\ord('Q')];
2163
+        $num_queens = (int) @$counts[\ord('Q')];
2164 2164
 
2165
-        $num_rooks = (int)@$counts[\ord('R')];
2165
+        $num_rooks = (int) @$counts[\ord('R')];
2166 2166
 
2167
-        $num_bishops = (int)@$counts[\ord('B')];
2167
+        $num_bishops = (int) @$counts[\ord('B')];
2168 2168
 
2169
-        $num_knights = (int)@$counts[\ord('N')];
2169
+        $num_knights = (int) @$counts[\ord('N')];
2170 2170
 
2171
-        $num_pawns = (int)@$counts[\ord('P')];
2171
+        $num_pawns = (int) @$counts[\ord('P')];
2172 2172
 
2173 2173
         return 0 == $num_queens && 0 == $num_rooks && ($num_bishops + $num_knights) <= 1 && 0 == $num_pawns;
2174 2174
     }
Please login to merge, or discard this patch.