私は、0-5のマーキングでどこからでも戦うためのランダムな動物を生成するブラウザゲームのスクリプトを作成しています。その動物のマーキングは無作為に生成され、配列に現れる順番にそれらを追加するカスタムimagick関数に送られます。不確実なデータで配列を並べ替える
マーキングはランダムに決定されますが、動物にどのように表示されるのかについては多くのルールがあります。たとえば、「全身」領域のマーキングは「腹」領域のマーキングの上に表示されます。良く説明するために、私はこれまで、テスターの画像を添付します:
だから、このランダムに生成された動物の5つのマーキングを打破するために、マーキングeyeshadow
は、目領域に属し
、undertail
は尾に属し、streaks
はfullbodyに属し、appaloosa
は後ろに属し、okapi
は脚に属します。今すぐ注文は、データベースをループしたスクリプトと無作為に選択されたマーキングとして追加されます。そのため、okapi(脚の縞模様)は配列の最後にあり、最後に追加されたものです。しかし、注文ルールに従って、アレイ内の最後のものは、フルボディマーキングが上に上がるため、ストリーク(身体全体の水平ストリーク)であったはずです。私はif文の複合体の多くでこれを達成することができます理解
// Determine number of markings
$num = mt_rand(1,10);
if ($num == 1) {
$markingNum = 0;
} elseif ($num > 1 && $num < 4) {
$markingNum = 1;
} elseif ($num > 4 && $num < 6) {
$markingNum = 2;
} elseif ($num > 6 && $num < 8) {
$markingNum = 3;
} elseif ($num > 8 && $num < 10) {
$markingNum = 4;
} else {
$markingNum = 5;
}
// Calculate Marking type and color
$markings = array();
if ($markingNum > 0) {
for ($m = 0 ; $m < $markingNum; $m++) {
// Set color values (pulls from the "pallet" selected earlier in the code, which will determine the range of color that marking can be)
if ($m == 1) {
$pal = $pallet->marking1;
} elseif ($m == 2) {
$pal = $pallet->marking2;
} elseif ($m == 3) {
$pal = $pallet->marking3;
} elseif ($m == 4) {
$pal = $pallet->marking4;
} else {
$pal = $pallet->marking5;
}
// Pull previous marking info
if (count($markings) != 0) {
$previous = DataMarking::whereIn('name', array_keys($markings))->get();
// This pulls the regions of the current markings in the array so it won't select a region that already has a marking.
foreach ($previous as $p) {
$regions[$p->region] = $p->name;
}
// Uncommon marking (10% chance)
$r = mt_rand(1, 10);
if ($r == 10) {
$marking = DataMarking::where('rarity', 1)
->where('public', 1)
->whereNotIn('name', array_keys($markings))
->whereNotIn('region', array_keys($regions))
->orderByRaw("RAND()")
->first();
// Common markings
} else {
$marking = DataMarking::where('rarity', 0)
->where('public', 1)
->whereNotIn('name', array_keys($markings))
->whereNotIn('region', array_keys($regions))
->orderByRaw("RAND()")
->first();
}
// Colors marking
if ($pal == 0) {
$markingColor = rand_color();
} else {
$range = ColorRange::where('id', $pal)->firstOrFail();
$markingColor = "#" . mixRange(substr($range->start_hex, 1), substr($range->end_hex, 1));
}
$markings[$marking->name] = $markingColor;
} else {
// Uncommon marking (10% chance)
$r = mt_rand(1, 10);
if ($r == 10) {
$marking = DataMarking::where('rarity', 1)
->where('public', 1)
->orderByRaw("RAND()")->first();
// Common marking
} else {
$marking = DataMarking::where('rarity', 0)
->where('public', 1)
->orderByRaw("RAND()")->first();
}
// Colors marking
if ($pal == 0) {
$markingColor = rand_color();
} else {
$range = ColorRange::where('id', $pal)->firstOrFail();
$markingColor = "#" . mixRange(substr($range->start_hex, 1), substr($range->end_hex, 1));
}
$markings[$marking->name] = $markingColor;
}
}
}
それだけでエレガントなように見えるしていません。ここで
これはLaravelのエンジンを使用して行われ、コード選択マーキングです解決策さらに、フルボディマーキングである「グラディエント」は、フルボディマーキングであるにもかかわらずすべての下にあります。これまでのところ、この種の例外は唯一のマーキングです。私は様々なsort
関数をPHPで提供してみましたが、私は大したことはありません。 uksort
がもっとも有望ですが、ソートしている値はデータベースに存在し、ソートしている配列ではないので(imagick関数にはマーキング=>カラー配列形式を与えなければなりません)、作業が困難です。
Tl; dr:キーのDB(マーキングの領域)に存在する値に基づいて不確実な量のデータを並べ替える必要があります。これを達成する最もエレガントな方法は何ですか?
私は奇妙な見たいの犬であっても、犬のイメージが好きです。 – Phiter
ハハ!それは変な犬だよね? –
'DataMarking'テーブルに' z-index'(int)カラムが必要です。このプロパティは深度として機能します。たとえば、「アイシャドー」の「z-インデックス」は1とすることができ、「ストリーク」の「z-インデックス」は5とすることができる。「z-インデックス」が高いほどマーキングが引き出され、 「ストリーク」は他のすべての上に描かれています。 マーキングの配列を検索した後、昇順で 'z-index'で並べ替えます。それをループして、すべてのマーキングを描きます。 – Alexander