0

PHPでゲームを書いています。配列には 0 から 51 までの 52 の要素があります。目標は、前のリストから一意になるたびにランダムなリストを作成することです。そのため、次のリストには最初のリストからのシーケンス パターンはありません。たとえば、最初のリストに 7654 というパターンが含まれている場合、7654 のパターンが次のリストにすぐに表示されることは望ましくありません。

ルールは、リストの最初の要素と最後の要素が、前のリストの開始要素と終了要素であってはならないということです。たとえば、最初のリストが次のように開始および終了する場合:

0
...
51

次のリストが 51 で始まり 0 で終わるのは望ましくありません。

これをどう捉えていくかを考えています。PHP の shuffle 関数は知っていますが、ランダムなリストを生成するたびに、以前のリストの知識がありません。繰り返しますが、リストは、プレーヤー用に生成された他のリストからではなく、以前のリストから直接一意である必要があります。

全体的な目標は、各リストが前のリストとの関係や共通パターンを持たないようにすることです。

この種のランダム リストに名前があるかどうかはわかりません。

これはPHPでどのように行うことができますか? ありがとう!

これは、リストをランダム化するたびに異なる「シード」番号を使用するランダムな方法を使用して行うことができますか?

パターン シーケンスは 4 です。したがって、前のリストに 7654 が表示された場合、新しいリストに 7654 を含めることはできません。

4

2 に答える 2

1

これらの制約を満たすために機能するはずのソリューションがあると思います。

function nextList($last) {
    $index = rand(1,50); // don't select first or last elements
    $out = array();
    do {
        list($value) = array_splice($last, $index, 1);
        $out[] = $value;
        $maxLoop = count($last);
        do {
            $newIndex = array_rand($last);
        } while ($newIndex == $index && --$maxLoop);
        $index = $newIndex;
    } while (count($last) > 1);
    $out[] = $last[0];

    return $out;
}

次のように使用します。

$first = range(0, 51);
shuffle($first);
$second = nextList($first);
$third = nextList($second);
// etc.

これは、新しい配列に追加する各要素について、最後の配列でそれを進めるのと同じ要素が先行しないことに基づいて機能します。

たとえば、最後の配列のどこかに values43,12,13...があり、その要素を新しい配列に追加した43場合、次の要素が任意の要素EXCEPT 12であることを確認します。このロジックでは、同じ繰り返しシーケンスを取得することは不可能です。

また、最初の要素が最後の配列の最初の要素でも最後の要素でもないことを保証しますが、この制約を配列の最後の要素に対しても機能させることは、はるかに困難です。

編集

Hendriqの回答で与えられた関数を実際に使用して、checkこのソリューションが機能するかどうかを確認できました.最後の配列からのシーケンスを含まない有効な新しいリストを常に返すようです=]

于 2013-06-06T13:42:28.003 に答える
1

さて、あなたが持っている仮定には小さな問題があります

ルール 1

The overall goal is that each list has no relationship or common pattern to it's previous list.

ルール 2

The rule is that the first element of the list and the last element can't be the start and end elements from the previous list.

その二つは互いに矛盾しています。最初は関係がないかもしれないので、ランダムです。あなたがシャッフルと言ったように(私はあなたの言葉を信じていませんでした)。しかし、2番目のものは前のものについて知る必要があります。以前のルールと矛盾するもの。

しかし、できることは、前の描画 (前の 52) の最初と最後の要素を持つことです。次に、現在のドローをシャッフルします。最初と最後の要素が同じ場合は、一致する要素がなくなるまで再度描画します。

また、これの言葉は半ランダムだと思います。

do{ }while();トリックについては、 を参照してください。


同じ 4 つの要素が連続していないというコメントの後、次の部分が来ました。

必要なのは要素を識別する方法なので、すべての「アイテム」にIDがあると仮定しましょう(この例では、5つの要素のみを使用しています)

以下を使用しましょう

array(
  0 => array('id' => 1,),
  1 => array('id' => 2,),
  2 => array('id' => 3,),
  3 => array('id' => 4,),
  4 => array('id' => 5,),
)

次の描画はまったく同じです (例の目的のためだけに)。描画される ID の配列を作成します。

array(
  0 => 1,
  1 => 2,
  2 => 3,
  3 => 4,
  4 => 5,
)

次に、この配列を次の関数で使用します(チェックされていませんが、適切なスタートが切れるはずです)

function check(array $prev, array $draw, $the_same = 4) {
  $to_check = count($prev) - $the_same;
  for($i = 0; $i < $to_check; $i++) {
    if ($array_slice($prev, $i, $the_same) === array_slice($draw, $i, $the_same)) {
       return false;
    }
  }
  return true;
}

つまり、古い配列と描画した配列を指定し、それと一緒に数を指定します。これは、おそらく同じである可能性があります。次に、ループと配列のスライスを開始して、それらが等しいかどうかを確認します。

于 2013-06-06T11:52:59.443 に答える