Page 2 of 2

Re: Implementing team settings: your go!

Posted: 26 November 2019, 18:11
by Woodruff
Hi,
Thanks very much for your replies :)

@RicardoRix: you're right, there are several (plenty) ways of doing it. But since I tried different which appear to be buggy, I wanted to ask you first if you think there is a more advisable way. But I know a theoretical better way to do does not necessarely exists. No problem, I will just try one alletrnative way you guys suggest, and hope for the best...

@DrKarotte: Yes, the whole things works without bug on Studio. I simulated plenty of game setup without generating any bug. But on prod, things seem a lot different... Your idea that altering the value of "player_no" could break something on the framework may be true. So, I'll try not to use them on the next version and manage the order using custom fields in Db, and set the player panels accordingly in JS setup. I told the admins, maybe they can tell me more about what's wrong.

For info, here's the current code I use in game.php:

Code: Select all

	// in setupNewGame
	...
        if (!$individual_game) { // Team game
            // Get the wishes for teams
            $player_table_orders_by_team = self::getWishesForTeams($nbr_players);
            
            if (self::rearrangeNeeded($player_table_orders_by_team)) { // Rearrange is not needed if all is set to Random except a maximum of one player
                // Rearrange the player array so that indicated teammates are facing each other
                $players = self::rearrangePlayersForTeams($players, $player_table_orders_by_team);
            }
        }
        
        ...
        
    function array_key_first(array $arr) {
        foreach($arr as $key => $unused) {
            return $key;
        }
        return NULL;
    }
    
    function getWishesForTeams($nbr_players) {
        $four_players = $nbr_players == 4;
        $player_table_orders_by_team = array();
        
        // Get player teams when specified in the option
        if ($four_players) { // 2 vs 2
            $player_table_orders_by_team[] = array(self::getGameStateValue('team_A1_2vs2'), self::getGameStateValue('team_A2_2vs2'));
            $player_table_orders_by_team[] = array(self::getGameStateValue('team_B1_2vs2'), self::getGameStateValue('team_B2_2vs2'));
        }
        else { // Six players, 2 vs 2 vs 2
            $player_table_orders_by_team[] = array(self::getGameStateValue('team_A1_2vs2vs2'), self::getGameStateValue('team_A2_2vs2vs2'));
            $player_table_orders_by_team[] = array(self::getGameStateValue('team_B1_2vs2vs2'), self::getGameStateValue('team_B2_2vs2vs2'));
            $player_table_orders_by_team[] = array(self::getGameStateValue('team_C1_2vs2vs2'), self::getGameStateValue('team_C2_2vs2vs2'));
        }
        return $player_table_orders_by_team;
    }
    
    function rearrangeNeeded($player_table_orders_by_team) {
        $nb_specified_player_table_orders = 0;
        foreach($player_table_orders_by_team as $player_table_orders_teammates) {
            foreach($player_table_orders_teammates as $player_table_order) {
                if ($player_table_order > 0) { // This player table order has been affected already
                    $nb_specified_player_table_orders++;
                    if ($nb_specified_player_table_orders > 1) {
                        // Two or more players are listed for team creation
                        return true;
                    }
                }
            }
        }
        return false;
    }

    function rearrangePlayersForTeams($players, $player_table_orders_by_team) {
        // The player array has been shuffled. Rearrange it so that it matches the admin wills in the options for team constitution
        $nbr_players = count($players);
        $nb_teams = $nbr_players/2;
        
        // Get the list of player table orders who are not bound to a team yet
        $all_player_table_orders = array();
        for($p=1;$p<=$nbr_players;$p++) {
            $all_player_table_orders[] = $p;
        }
        
        $specified_player_table_orders = array();
        foreach($player_table_orders_by_team as $player_table_orders_teammates) {
            foreach($player_table_orders_teammates as $player_table_order) {
                if ($player_table_order > 0) { // This player table order has been affected already
                    $specified_player_table_orders[] = $player_table_order;
                }
            }
        }
        
        $unsettled_player_table_orders = array_diff($all_player_table_orders, $specified_player_table_orders);
        
        // Shuffle the players not bound to set their teams after that
        shuffle($unsettled_player_table_orders);
        
        // Set the not specified teammates by picking from the not bound players
        for($t=0;$t<$nb_teams;$t++){
            for($i=0;$i<=1;$i++) {
                $player_table_order = $player_table_orders_by_team[$t][$i];
                if ($player_table_order > 0) { // Already set
                    continue;
                }
                
                // Pick the last player from the not bound players
                $player_table_order = array_pop($unsettled_player_table_orders);
                $player_table_orders_by_team[$t][$i] = $player_table_order;
            }
        }
        
        // Build the teams with all player info
        $teams = array();
        for($p=0;$p<$nb_teams;$p++) {
            $player_id = self::array_key_first($players);
            $player = $players[$player_id];
            $player_table_order = $player['player_table_order'];
            $player['player_id'] = $player_id;
            unset($players[$player_id]);
            
            // Find the team of that player
            for($t=0;$t<$nb_teams;$t++){
                for($i=0;$i<=1;$i++) {
                    $current_player_table_order = $player_table_orders_by_team[$t][$i];
                    if ($player_table_order == $current_player_table_order) {
                        $teammate_table_order = $player_table_orders_by_team[$t][1-$i];
                        
                        // Retrieve the full info of the teammate
                        foreach($players as $current_player_id => $current_player) {
                            if ($current_player['player_table_order'] == $teammate_table_order) {
                                $teammate = $current_player;
                                $teammate_id = $current_player_id;
                                $teammate['player_id'] = $teammate_id;
                                break;
                            }
                        }
                        unset($players[$teammate_id]);
                        
                        $teams[] = array($player, $teammate);
                        
                        break 2;
                    }
                }
            }
        }
        
        // Unroll the team array to reflect the new order of the players
        $reordered_players = array();
        for($i=0;$i<=1;$i++) {
            for($t=0;$t<$nb_teams;$t++){
                $player = $teams[$t][$i];
                $player_id = $player['player_id'];
                $reordered_players[$player_id] = $player;
            }
        }
        return $reordered_players;
    }

Re: Implementing team settings: your go!

Posted: 05 January 2020, 17:36
by Woodruff
Hi!
OK, I have completely redesign the player order mechanism independently from the framework.
  • Added a new custom field in Db: player_next_id
  • Replaced all instances of self::activeNextPlayer by a function that reads that new field and call $this->gamestate->changeActivePlayer accordingly
  • Removed all references to the framework field player_no and leaving it unaltered
This seem to work in Studio. I just can't change the order of player panels in JS and I don't know why. But I assume this will be solved soon.
I posted a new issue about this here: viewtopic.php?f=12&t=14325

When it eventually works, I will push this on prod and hope no more bugs of this kind occurs...

Cheers,

Woodruff