コード例 #1
0
ファイル: chessdb.inc.php プロジェクト: nicefirework/chess
function savePromotion()
{
    global $mysql;
    global $movesArray, $FENarray, $curTurn;
    $num_moves = count($FENarray) - 1;
    // subtract one for initpos
    // when we run the promotion script, the color to be promoted
    // is the oppposite of the color who's turn it is
    $piece = $_POST['promotion'];
    if ('white' == $curTurn) {
        $piece = strtolower($piece);
    }
    // save the promoted piece in the movesArray
    $movesArray[$num_moves]['promo'] = $piece;
    // seperate the FEN board from the rest of the FEN
    $FEN = $FENarray[$num_moves];
    $FENbits = trim(substr($FEN, strpos($FEN, ' ')));
    $xFEN = expandFEN(substr($FEN, 0, strpos($FEN, ' ')));
    // insert the promoted piece
    sqr2idx($movesArray[$num_moves]['toSq'], $idx);
    FENplace($xFEN, $idx, $movesArray[$num_moves]['promo']);
    // and repack the FEN
    $FENhead = packFEN($xFEN);
    $FEN = $FENhead . ' ' . $FENbits;
    // and save the new and improved FEN to the history
    $query = "\n\t\tSELECT MAX(h_time)\n\t\tFROM " . T_HISTORY . "\n\t\tWHERE h_game_id = '{$_SESSION['game_id']}'\n\t";
    $result = $mysql->fetch_value($query, __LINE__, __FILE__);
    $query = "\n\t\tUPDATE " . T_HISTORY . "\n\t\tSET h_fen = '{$FEN}'\n\t\tWHERE h_game_id = '{$_SESSION['game_id']}'\n\t\t\tAND h_time = '{$result}'\n\t";
    $mysql->query($query, __LINE__, __FILE__);
    updateTimestamp();
}
コード例 #2
0
ファイル: pharaoh.class.php プロジェクト: benjamw/pharaoh
 /** static public function fire_laser
  *		FIRE ZEE MISSILES !!!
  *		But I am le tired
  *
  *		Fires the laser of the given color
  *
  * @param string color (red or silver)
  * @param string board (expanded FEN)
  * @param array [optional] extra info
  * @return array (laser path array, and squares hit (empty array if none) array)
  */
 public static function fire_laser($color, $board, $extra_info = false)
 {
     call(__METHOD__);
     // search for the sphynx in the board
     $has_sphynx = Setup::has_sphynx($board);
     $color = strtolower($color);
     $board = expandFEN($board);
     $extra_info = self::extra_info($extra_info);
     call($color);
     call($board);
     call($extra_info);
     if (!in_array($color, array('silver', 'red'))) {
         throw new MyException(__METHOD__ . ': Trying to fire laser for unknown color: ' . $color);
     }
     $reflections = array('A' => array(I_LEFT => I_UP, I_DOWN => I_RIGHT), 'B' => array(I_LEFT => I_DOWN, I_UP => I_RIGHT), 'C' => array(I_RIGHT => I_DOWN, I_UP => I_LEFT), 'D' => array(I_RIGHT => I_UP, I_DOWN => I_LEFT), 'X' => array(I_RIGHT => I_DOWN, I_LEFT => I_UP, I_DOWN => I_RIGHT, I_UP => I_LEFT), 'Y' => array(I_RIGHT => I_UP, I_LEFT => I_DOWN, I_DOWN => I_LEFT, I_UP => I_RIGHT), 'H' => array(I_RIGHT => array(I_RIGHT, I_DOWN), I_LEFT => array(I_LEFT, I_UP), I_DOWN => array(I_RIGHT, I_DOWN), I_UP => array(I_LEFT, I_UP)), 'I' => array(I_RIGHT => array(I_RIGHT, I_UP), I_LEFT => array(I_LEFT, I_DOWN), I_DOWN => array(I_LEFT, I_DOWN), I_UP => array(I_RIGHT, I_UP)));
     // fire the laser
     if (!$has_sphynx) {
         if ('silver' == $color) {
             $laser_path = array(array(array(79, I_UP)));
         } else {
             // red
             $laser_path = array(array(array(0, I_DOWN)));
         }
     } else {
         list($shoot_sphynx_idx, $shoot_sphynx_dir) = self::find_sphynx($board, 'silver' === $color);
         list($hit_sphynx_idx, $hit_sphynx_dir) = self::find_sphynx($board, 'silver' !== $color);
         $laser_path = array(array(array($shoot_sphynx_idx + $shoot_sphynx_dir, $shoot_sphynx_dir)));
     }
     // because we can now possibly move the laser around and rotate it
     // make sure we don't hit a wall right out of the gate
     // check if we hit a wall
     list($current, $dir) = $laser_path[0][0];
     $long_wall = 0 > $current || 80 <= $current;
     $short_wall = 1 == abs($dir) && floor($current / 10) !== floor(($current - $dir) / 10);
     if ($long_wall || $short_wall) {
         // we hit the wall...  just stop
         $laser_path[0][0][0] = false;
         return array('laser_path' => $laser_path, 'hits' => array(), 'laser_hit' => false);
     }
     // also check and make sure that the sphynx was not hit right out of the gate
     $hit_silver = $hit_red = false;
     $var_name = 'hit_' . ('silver' == $color ? 'silver' : 'red');
     if ($has_sphynx && $hit_sphynx_idx == $current) {
         if (!$extra_info['battle_front_only']) {
             ${$var_name} = true;
         } elseif ($hit_sphynx_dir == -$dir) {
             ${$var_name} = true;
         }
     }
     if ($hit_red || $hit_silver) {
         // we hit the sphynx...  just stop
         $laser_path[] = array(array(true, $dir));
         return array('laser_path' => $laser_path, 'hits' => array(), 'laser_hit' => true);
     }
     $i = 0;
     // infinite loop protection
     $paths = $laser_path[0];
     $used = array();
     $next = array();
     $hits = array();
     $laser_hit = false;
     while ($i < 999) {
         // no ad infinitum here
         $split = 0;
         $continue = false;
         foreach ($paths as $key => $node) {
             if (false === $node[0] || true === $node[0]) {
                 unset($node[2]);
                 $next[$key] = $node;
                 // propagate the individual path indexes
                 continue;
             }
             // let the loop know we still have valid nodes
             $continue = true;
             // current is the current board index
             // dir is the direction that the laser was heading
             // when it entered the current index
             list($current, $dir) = $node;
             // check the current location for a piece
             if ('0' !== ($piece = $board[$current])) {
                 // check for hit or reflection
                 if (!isset($reflections[strtoupper($piece)][$dir])) {
                     // dont track the hit for the following situations:
                     // is an anubis and hit the front
                     $front_anubis = preg_match('/[LMNO]/i', $piece) && $dir == -self::get_anubis_dir($piece);
                     // hit the sphynx (laser hits get tracked elsewhere)
                     $hit_sphynx = $has_sphynx && ($current == $hit_sphynx_idx || $current == $shoot_sphynx_idx);
                     // if any of those hit, don't track the hit
                     if (!($front_anubis || $hit_sphynx)) {
                         $hits[] = $current;
                     }
                     // but still change the path data to recognize the path stopped
                     // we store dir here because it keeps the output format consistent
                     // we don't really care at this point because we just hit a piece
                     // ... the laser isn't going any further
                     $next[$key] = array(true, $dir);
                     // stop this path
                     continue;
                 }
                 $dir = $reflections[strtoupper($piece)][$dir];
             }
             // this is where we split off in two directions through the beam splitter
             $do_split = false;
             if (is_array($dir)) {
                 // add a new entry in the paths for the reflection
                 // and change dir to be the pass-through beam
                 // if we've already split a beam once,
                 // we'll need to add a few more to the index
                 // (it is possible to hit a single splitter from two sides,
                 // as well as hit both splitters from two sides, so...)
                 // also note: if there are no beam splitters, there is no way
                 // of doubling back or going over the same path again, ever
                 // before we add to $next, make sure we haven't been here, or hit any walls
                 $do_split = true;
                 $split_dir = $dir[0];
                 $split_current = $current + $split_dir;
                 // make sure we haven't been here before
                 if (in_array(array($split_current, $split_dir), $used, true)) {
                     // don't even create a new path
                     $do_split = false;
                 } else {
                     // check if we hit the laser
                     $hit_silver = $hit_red = false;
                     if (!$has_sphynx) {
                         $hit_red = -10 == $split_current && 'silver' == $color;
                         $hit_silver = 89 == $split_current && 'red' == $color;
                     } else {
                         // find the laser
                         $var_name = 'hit_' . ('silver' == $color ? 'silver' : 'red');
                         if ($hit_sphynx_idx == $split_current) {
                             if (!$extra_info['battle_front_only']) {
                                 ${$var_name} = true;
                             } elseif ($hit_sphynx_dir == -$split_dir) {
                                 ${$var_name} = true;
                             }
                         }
                     }
                     if ($hit_red || $hit_silver) {
                         $laser_hit = true;
                     }
                     // check if we hit a wall
                     $long_wall = 0 > $split_current || 80 <= $split_current;
                     $short_wall = 1 == abs($split_dir) && floor($split_current / 10) !== floor(($split_current - $split_dir) / 10);
                     if ($long_wall || $short_wall) {
                         // set split_current to false, so we know we hit a wall,
                         // but keep going, we need to store the dir so we can show any reflection properly
                         // and we need to add the new path index below
                         // we store dir here because we need to know in which direction the laser left the node
                         // for edge/corner piece hits that send the laser through the wall
                         $split_current = false;
                     }
                     $next[count($paths) + $split] = array($split_current, $split_dir);
                     if (false !== $split_current) {
                         $used[] = array($split_current, $split_dir);
                     }
                     $split += 1;
                 }
                 // now that the split is done, go back and keep processing the new path
                 $dir = $dir[1];
             }
             // increment $current and run a few tests
             // so we don't shoot through walls
             // or loop back on ourselves forever
             $current += $dir;
             // make sure we haven't been here before
             if (in_array(array($current, $dir), $used, true)) {
                 // we store dir here because it keeps the output format consistent
                 // we don't really care at this point because we've been here before
                 // and know what's going to happen
                 $next[$key] = array(false, $dir);
                 // stop this path
                 continue;
             }
             // check if we hit the laser
             $hit_silver = $hit_red = false;
             if (!$has_sphynx) {
                 $hit_red = -10 == $current && 'silver' == $color;
                 $hit_silver = 89 == $current && 'red' == $color;
             } else {
                 $var_name = 'hit_' . ('silver' == $color ? 'silver' : 'red');
                 if ($hit_sphynx_idx == $current) {
                     if (!$extra_info['battle_front_only']) {
                         ${$var_name} = true;
                     } elseif ($hit_sphynx_dir == -$dir) {
                         ${$var_name} = true;
                     }
                 }
             }
             if ($hit_red || $hit_silver) {
                 $laser_hit = true;
             }
             // check if we hit a wall
             $long_wall = 0 > $current || 80 <= $current;
             $short_wall = 1 == abs($dir) && floor($current / 10) !== floor(($current - $dir) / 10);
             if ($long_wall || $short_wall) {
                 // set current to false, so we know we hit a wall,
                 // but keep going, we need to store the dir so we can show any reflection properly
                 // and we need to add the new path index below
                 // we store dir here because we need to know which direction the laser left the node in
                 // for corner piece hits that send the laser through the wall
                 $current = false;
             }
             $next[$key] = array($current, $dir);
             if ($do_split) {
                 // add the new path index here so we know which path was the original path
                 // and where are the splits came from
                 $next[$key][2] = count($paths) + $split - 1;
             }
             if (false !== $current) {
                 $used[] = array($current, $dir);
             }
         }
         // end foreach $current
         // if we have no valid nodes left
         // break the loop
         if (!$continue) {
             break;
         }
         // add to our laser path
         // and pass along to the next round
         $laser_path[] = $paths = $next;
         ++$i;
         // keep those pesky infinite loops at bay
     }
     // end while
     call(self::get_laser_ascii($board, $laser_path));
     call($hits);
     // straighten up the laser path
     array_walk($laser_path, create_function('& $val', 'ksort($val);'));
     return compact('laser_path', 'hits', 'laser_hit');
 }
コード例 #3
0
ファイル: stats.php プロジェクト: benjamw/pharaoh
<?php

require_once 'includes/inc.global.php';
$setups = Game::get_setup_stats_list();
$setup_selection = '<option value="0">Random</option>';
$setup_javascript = '';
foreach ($setups as $setup) {
    $setup_selection .= '
		<option value="' . $setup['setup_id'] . '">' . $setup['name'] . '</option>';
    $setup_javascript .= "'" . $setup['setup_id'] . "' : '" . expandFEN($setup['board']) . "',\n";
}
$setup_javascript = substr(trim($setup_javascript), 0, -1);
// remove trailing comma
$meta['title'] = 'Statistics';
$meta['head_data'] = '
	<link rel="stylesheet" type="text/css" media="screen" href="css/board.css" />

	<script type="text/javascript">//<![CDATA[
		var setups = {
			' . $setup_javascript . '
		};
	/*]]>*/</script>

	<script type="text/javascript" src="scripts/board.js">></script>
	<script type="text/javascript" src="scripts/stats.js">></script>
';
$hints = array('View ' . GAME_NAME . ' Player and Setup statistics.', 'Click on Setup table row to view setup.');
$contents = '';
// grab the wins and losses for the players
$list = Game::get_player_stats_list();
$table_meta = array('sortable' => true, 'no_data' => '<p>There are no player stats to show</p>', 'caption' => 'Player Stats', 'init_sort_column' => array(1 => 1));
コード例 #4
0
ファイル: game.class.php プロジェクト: benjamw/pharaoh
 /** static public function get_invites
  *		Returns a list array of all the invites in the database
  *		for the given player
  *
  * @param int player's id
  * @return 2D array invite list
  */
 public static function get_invites($player_id)
 {
     call(__METHOD__);
     $Mysql = Mysql::get_instance();
     $player_id = (int) $player_id;
     $query = "\n\t\t\tSELECT G.*\n\t\t\t\t, DATE_ADD(NOW( ), INTERVAL -1 DAY) AS resend_limit\n\t\t\t\t, R.username AS invitor\n\t\t\t\t, E.username AS invitee\n\t\t\t\t, S.name AS setup\n\t\t\tFROM " . self::GAME_TABLE . " AS G\n\t\t\t\tLEFT JOIN " . Setup::SETUP_TABLE . " AS S\n\t\t\t\t\tON S.setup_id = G.setup_id\n\t\t\t\tLEFT JOIN " . Player::PLAYER_TABLE . " AS R\n\t\t\t\t\tON R.player_id = G.white_id\n\t\t\t\tLEFT JOIN " . Player::PLAYER_TABLE . " AS E\n\t\t\t\t\tON E.player_id = G.black_id\n\t\t\tWHERE G.state = 'Waiting'\n\t\t\t\tAND (G.white_id = {$player_id}\n\t\t\t\t\tOR G.black_id = {$player_id}\n\t\t\t\t\tOR G.black_id IS NULL\n\t\t\t\t\tOR G.black_id = FALSE\n\t\t\t\t)\n\t\t\tORDER BY G.create_date DESC\n\t\t";
     $list = $Mysql->fetch_array($query);
     call($list);
     $in_vites = $out_vites = $open_vites = array();
     foreach ($list as $item) {
         $extra_info = array_merge_plus(self::$_EXTRA_INFO_DEFAULTS, unserialize($item['extra_info']));
         $white_color = 'random' == $extra_info['white_color'] ? 'Random' : ('white' == $extra_info['white_color'] ? 'Silver' : 'Red');
         $black_color = 'random' == $extra_info['white_color'] ? 'Random' : ('white' == $extra_info['white_color'] ? 'Red' : 'Silver');
         $hover = array();
         if (!empty($item['extra_info'])) {
             $hover = unserialize($item['extra_info']);
             unset($hover['invite_setup']);
             unset($hover['white_color']);
         }
         $hover_text = array();
         foreach ($hover as $key => $value) {
             if (is_bool($value)) {
                 $value = $value ? 'Yes' : 'No';
             }
             $hover_text[] = humanize($key) . ': ' . $value;
         }
         $item['hover_text'] = implode(' | ', $hover_text);
         $item['board'] = 'setup_display';
         if (!empty($extra_info['invite_setup'])) {
             $item['board'] = expandFEN($extra_info['invite_setup']);
         }
         if ($player_id == $item['white_id']) {
             $item['color'] = $white_color;
             $out_vites[] = $item;
         } elseif ($player_id == $item['black_id']) {
             $item['color'] = $black_color;
             $in_vites[] = $item;
         } else {
             $item['color'] = $black_color;
             $open_vites[] = $item;
         }
     }
     return array($in_vites, $out_vites, $open_vites);
 }
コード例 #5
0
ファイル: chessutils.inc.php プロジェクト: nicefirework/chess
function movetoFEN()
{
    global $FENarray, $movesArray, $board, $COLS, $initpos, $pieceColor;
    $num_moves = count($FENarray) - 1;
    // get the post info out
    foreach ($_POST as $key => $var) {
        ${$key} = $var;
    }
    // reverse row and col so i don't confuse myself
    $colFrom = $fromCol;
    $colTo = $toCol;
    $rowFrom = $fromRow;
    $rowTo = $toRow;
    // and convert it to something we can use
    colrow2idx($colFrom, $rowFrom, $idxFrom);
    colrow2idx($colTo, $rowTo, $idxTo);
    // get the current FEN data
    $FENitems = explode(' ', $FENarray[$num_moves]);
    $thatFEN = expandFEN($FENitems[0]);
    $CM = $FENitems[1];
    $CI = $FENitems[2];
    $EP = $FENitems[3];
    $PN = $FENitems[4];
    $MN = $FENitems[5];
    $newEP = '-';
    // get original placement of rooks
    $origARookPos = strpos($initpos, 'R');
    $origHRookPos = strrpos($initpos, 'R');
    $origKingPos = strpos($initpos, 'K');
    // separate the castle indicator
    $WK = false !== strpos($CI, 'K') ? 'K' : '';
    $WQ = false !== strpos($CI, 'Q') ? 'Q' : '';
    $BK = false !== strpos($CI, 'k') ? 'k' : '';
    $BQ = false !== strpos($CI, 'q') ? 'q' : '';
    // put board into expanded FEN string
    $xFEN = "";
    for ($i = 7; $i >= 0; $i--) {
        for ($j = 0; $j < 8; $j++) {
            $xFEN .= $board[$i][$j];
        }
    }
    // get the piece that is moving
    $piece = FENplace($xFEN, $idxFrom);
    // check for castling move
    if ('false' != $_POST['castleMove']) {
        if ('white' == $pieceColor[$piece]) {
            // clear the castle indicators
            $WK = '';
            $WQ = '';
            // make the move
            if ('a' == $_POST['castleMove']) {
                FENplace($xFEN, $origKingPos + 56, '0');
                // delete the king
                FENplace($xFEN, $origARookPos + 56, '0');
                // delete the rook
                FENplace($xFEN, 2 + 56, 'K');
                // place the king
                FENplace($xFEN, 3 + 56, 'R');
                // place the rook
            } elseif ('h' == $_POST['castleMove']) {
                FENplace($xFEN, $origKingPos + 56, '0');
                // delete the king
                FENplace($xFEN, $origHRookPos + 56, '0');
                // delete the rook
                FENplace($xFEN, 6 + 56, 'K');
                // place the king
                FENplace($xFEN, 5 + 56, 'R');
                // place the rook
            } else {
                die("castleMove is incorrect");
            }
        } elseif ('black' == $pieceColor[$piece]) {
            // clear the castle indicators
            $BK = '';
            $BQ = '';
            // make the move
            if ('a' == $_POST['castleMove']) {
                FENplace($xFEN, $origKingPos, '0');
                // delete the king
                FENplace($xFEN, $origARookPos, '0');
                // delete the rook
                FENplace($xFEN, 2, 'k');
                // place the king
                FENplace($xFEN, 3, 'r');
                // place the rook
            } elseif ('h' == $_POST['castleMove']) {
                FENplace($xFEN, $origKingPos, '0');
                // delete the king
                FENplace($xFEN, $origHRookPos, '0');
                // delete the rook
                FENplace($xFEN, 6, 'k');
                // place the king
                FENplace($xFEN, 5, 'r');
                // place the rook
            } else {
                die("castleMove is incorrect");
            }
        } else {
            echo "<pre>";
            for ($i = 0; $i < $idxFrom; $i++) {
                echo " ";
            }
            echo "|\n";
            echo $xFEN . "</pre>";
        }
    } else {
        // make the move
        $piece = FENplace($xFEN, $idxFrom, '0');
        $capt = FENplace($xFEN, $idxTo, $piece);
        $PN++;
        // if we have a pawn advance, or a capture
        if ('P' == strtoupper($piece) || '0' != $capt) {
            $PN = 0;
        }
        // reset the ply count
        // if we have a pawn double advance
        if ('P' == strtoupper($piece) && 2 == abs($rowFrom - $rowTo)) {
            colrow2til($colTo, ($rowFrom + $rowTo) * 0.5, $newEP);
        }
        // set the en passant indicator
        // if we moved a castling piece
        if ('K' == $piece) {
            $WK = '';
            $WQ = '';
        } elseif ('k' == $piece) {
            $BK = '';
            $BQ = '';
        } elseif ('R' == $piece) {
            if ($colFrom == $origARookPos) {
                // a-side moved
                $WQ = '';
            } elseif ($colFrom == $origHRookPos) {
                // h-side moved
                $WK = '';
            }
        } elseif ('r' == $piece) {
            if ($colFrom == $origARookPos) {
                // a-side moved
                $BQ = '';
            } elseif ($colFrom == $origHRookPos) {
                // h-side moved
                $BK = '';
            }
        }
    }
    // check for en passant capture
    colrow2til($colTo, $rowTo, $tilTo);
    if ($tilTo == $EP && 'P' == strtoupper($piece)) {
        // get the idx of the captured pawn
        colrow2idx($colTo, $rowFrom, $idxCapt);
        // and remove the captured pawn
        FENplace($xFEN, $idxCapt, '0');
    }
    $FENbit = packFEN($xFEN);
    // search for ambiguous castle notation
    //--------------------------------------------
    // remove any extra information from the current castle notations
    if ('' != $WK) {
        $WK = 'K';
    }
    if ('' != $WQ) {
        $WQ = 'Q';
    }
    if ('' != $BK) {
        $BK = 'k';
    }
    if ('' != $BQ) {
        $BQ = 'q';
    }
    // get current position of main pieces
    $whiteBackRank = substr($xFEN, -8);
    $blackBackRank = substr($xFEN, 0, 8);
    // search the ends of the back ranks for rooks
    // and add unambiguous notation if needed
    if (strrpos($whiteBackRank, 'R') > $origHRookPos && '' != $WK) {
        $WK = $WK . substr($COLS, $origHRookPos, 1);
    }
    if (strpos($whiteBackRank, 'R') < $origARookPos && '' != $WQ) {
        $WQ = $WQ . substr($COLS, $origARookPos, 1);
    }
    if (strrpos($blackBackRank, 'r') > $origHRookPos && '' != $BK) {
        $BK = $BK . substr($COLS, $origHRookPos, 1);
    }
    if (strpos($blackBackRank, 'r') < $origARookPos && '' != $BQ) {
        $BQ = $BQ . substr($COLS, $origARookPos, 1);
    }
    $castlingAvail = $WK . $WQ . $BK . $BQ;
    if ('' == $castlingAvail) {
        $castlingAvail = '-';
    }
    // increase the move number (if needed)
    $MN = "w" == $CM ? $MN : ++$MN;
    // make sure to use the pre-increment (++var) here
    // toggle the current move
    $CM = "w" == $CM ? "b" : "w";
    // put the whole thing together and return
    return "{$FENbit} {$CM} {$castlingAvail} {$newEP} {$PN} {$MN}";
}
コード例 #6
0
ファイル: game.php プロジェクト: benjamw/pharaoh
        ?>

							<input type="button" name="nudge" id="nudge" value="Nudge" />

						<?php 
    }
    ?>

					<?php 
}
?>

				</div></form>
			</div> <!-- #board_wrapper -->

			<?php 
echo $chat_html;
?>

		</div> <!-- #contents -->

		<script type="text/javascript">
			document.write('<'+'div id="setup"'+'>'+create_board('<?php 
echo expandFEN($Game->get_setup());
?>
', true)+'<'+'/'+'div'+'>');
		</script>

<?php 
call($GLOBALS);
echo get_footer($meta);
コード例 #7
0
ファイル: setup.class.php プロジェクト: benjamw/pharaoh
 /** static public function _get_reflection
  *		Gets the reflection type for the given setup
  *
  * @param string board
  * @return string reflection type
  */
 public static function _get_reflection($setup)
 {
     call(__METHOD__);
     call($setup);
     // expand the board FEN
     $xFEN = expandFEN($setup);
     foreach (array('Origin', 'Long', 'Short', 'None') as $type) {
         try {
             self::is_valid_reflection($xFEN, $type);
         } catch (MyException $e) {
             continue;
         }
         break;
     }
     return $type;
 }