Есть ли простой способ манипулировать побитовым перечислением в PHP? - PullRequest
0 голосов
/ 23 января 2019

Я создаю пользовательский профиль для игры (osu!) И пытаюсь получить, какие "моды" использовались в "топ-игре".API предоставляет десятичное число, содержащее все моды, используемые игроком в его игре.

Пример: 72 для DoubleTime + скрытые моды, поскольку DoubleTime равен 64 и Hidden 8

$hidden = 8;
$doubletime = 64;
$hiddendoubletime = ($hidden|$doubletime);

. Я хочуиз 72 например, знайте, что это 8 и 64. или даже из 88, что это 8 и 16 и 64.

Я думал о tansform 88, например, в двоичном (01011000), а затем обнаружить все "1"позиции, так как каждый" 1 "дает мод.

Здесь: 01011000 - первый «1» в позиции 4 - это скрытый мод, второй «1» в позиции 5 - это мод Hardrock, и, наконец, «1» в позиции 7 - это мод DoubleTime.

Тогда перечисление будет следующим:

enum Mods
{
    None           = 0,
    NoFail         = 1,
    Easy           = 2,
    TouchDevice    = 4,
    Hidden         = 8,
    HardRock       = 16,
    SuddenDeath    = 32,
    DoubleTime     = 64,
    Relax          = 128,
    HalfTime       = 256,
    Nightcore      = 512, // Only set along with DoubleTime. i.e: NC only gives 576
    Flashlight     = 1024,
    Autoplay       = 2048,
    SpunOut        = 4096,
    Relax2         = 8192,  // Autopilot
    Perfect        = 16384, // Only set along with SuddenDeath. i.e: PF only gives 16416  
    Key4           = 32768,
    Key5           = 65536,
    Key6           = 131072,
    Key7           = 262144,
    Key8           = 524288,
    FadeIn         = 1048576,
    Random         = 2097152,
    Cinema         = 4194304,
    Target         = 8388608,
    Key9           = 16777216,
    KeyCoop        = 33554432,
    Key1           = 67108864,
    Key3           = 134217728,
    Key2           = 268435456,
    ScoreV2        = 536870912,
    LastMod        = 1073741824,
}

Как видите, список довольно большой, поэтому я не могу просто попробовать комбинацию всех модов в условии if ().

Ответы [ 2 ]

0 голосов
/ 23 января 2019

Я подумал, что было бы лучше циклически переключаться между опциями, заданными пользователем (-ями), таким образом, вам не нужно перебирать все параметры game_options, когда, возможно, установлены только несколько битов с меньшим номером ...

<?php

$user_options = 344;

$game_options = array (
'NoFail' => 1, 
'Easy' => 2, 
'TouchDevice'=> 4, 
'Hidden' => 8, 
'HardRock' => 16, 
'SuddenDeath' => 32, 
'DoubleTime' => 64, 
'Relax' => 128, 
'HalfTime' => 256, 
'Nightcore' => 512, 
'Flashlight' => 1024, 
'Autoplay' => 2048, 
'SpunOut' => 4096, 
'Relax2' => 8192, 
'Perfect' => 16384,  
'Key4' => 32768, 
'Key5' => 65536, 
'Key6' => 131072, 
'Key7' => 262144, 
'Key8' => 524288, 
'FadeIn' => 1048576, 
'Random' => 2097152, 
'Cinema' => 4194304, 
'Target' => 8388608, 
'Key9' => 16777216, 
'KeyCoop' => 33554432, 
'Key1' => 67108864, 
'Key3' => 134217728, 
'Key2' => 268435456, 
'ScoreV2' => 536870912, 
'LastMod' => 1073741824
);

function get_options ( $game_options, $user_options )
{
    /* if no options are set, return this */

    $nil = array ( 'None' => 0 );

    /* if option(s) are set, return the array of set option(s) */

    $set = array ( );

    /* only loop the $game_options up until the max set $user_options */

    $stop = $user_options;

    foreach ( $game_options AS $on => $ov )
    {
        if ( $ov > $stop )
        {
            break;
        }
        else if ( ( $ov & $user_options ) == $ov )
        {
            $set[$on] = $ov;

            $stop -= $ov;
        }
    }

    return empty ( $set ) ? $nil : $set;
}

print_r ( get_options ( $game_options, $user_options ) );


?>
0 голосов
/ 23 января 2019

Я бы сделал что-то вроде этого ...

<?php

$user_options = 88;

$no_options = array ( 'None' => 0 );

$game_options = array (
'NoFail' => 1, 
'Easy' => 2, 
'TouchDevice'=> 4, 
'Hidden' => 8, 
'HardRock' => 16, 
'SuddenDeath' => 32, 
'DoubleTime' => 64, 
'Relax' => 128, 
'HalfTime' => 256, 
'Nightcore' => 512, 
'Flashlight' => 1024, 
'Autoplay' => 2048, 
'SpunOut' => 4096, 
'Relax2' => 8192, 
'Perfect' => 16384,  
'Key4' => 32768, 
'Key5' => 65536, 
'Key6' => 131072, 
'Key7' => 262144, 
'Key8' => 524288, 
'FadeIn' => 1048576, 
'Random' => 2097152, 
'Cinema' => 4194304, 
'Target' => 8388608, 
'Key9' => 16777216, 
'KeyCoop' => 33554432, 
'Key1' => 67108864, 
'Key3' => 134217728, 
'Key2' => 268435456, 
'ScoreV2' => 536870912, 
'LastMod' => 1073741824
);

$filtered = array_filter ( $game_options, function ( $value ) use ( $user_options )
{
    return ( $value & $user_options ) == $value ? $value : NULL;
});

if ( empty ( $filtered ) )
{
    print_r ( $no_options );
}
else
{
    print_r ( $filtered );
}

?>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...