Diskuze: algoritmus vylucovacich checkboxu
V předchozím kvízu, Online test znalostí JavaScript, jsme si ověřili nabyté zkušenosti z kurzu.


DarkCoder:6.5.2021 10:49
To bys tomu dal, abys vše procházel cyklem a vylučoval možnosti.. Řešení je prosté.
Při kliknutí na checkbox znepřístupníš všechny ostatní checkboxy ve stejném řádku a ve stejném sloupci, pokud se checkbox stává vybraným. Pokud odškrtáváš checkbox, pak všechny ostatní checkboxy ve stejném řádku a sloupci naopak zpřístupníš. Tím zajistíš, že pro každý řádek (1 .. N) bude dostupný právě jeden bonus (A .. M) a že právě tento bonus se pro zbývající řádky nebude opakovat.
Zákazník si nemůže vymyslet co se mu zlíbí, vždy je třeba dodržet to, aby počet řádků (možností) bylo menší nebo rovno počtu bonusů. V opačném případě, se vždy nějaký bonus bude opakovat a to asi nechceš. Může ale být situace kde bude na výběr z vícero počtu bonusů na menší počet řádků. Pak jednoduše některý bonus/bonusy nebudou uplatněny.
Inicializace bonusů je rovněž prostá, pro každý řádek vygeneruješ unikátní hodnotu bonusu a aplikuješ pravidlo o zpřístupnění checkboxů viz výše.
Jde o tuhle stranku. Je to takovy pokus. Starsi verze, jeste tam nema
"priority".
https://mlich.zam.slu.cz/…r/index2.htm
Nevim, zda se chapene.
Bonusy se rozdeluji mezi atributy pro kategorie: Fyzicke, Spolecenske,
Dusevni.
Kdyz mas bonus A pro Fyzicke, tak ziskas +2 pro available points, cili 7+2.
A ted jde o to, kazde kategorii dat 1 bonus A B nebo C.
Nesmi mit dve kategorie stejny bonus.
Cili, vysledny stav by mel byt
+2 fyzicke +1 spolecenske, 0 dusevni NEBO
+1 fyzicke +2 spolecenske, 0 dusevni NEBO
... 6 moznych kombinaci ABC ACB BAC BCA CAB CBA
Cili, postava pro A pro fyzicke muze rozdelit o 2 body navic, treba pro fyzicke
atributy. Je specializovana na silu. A tento bonus A se pocita ve vzorcich
zvlast pro nektere pripady. Atd pro ostatni kategorie a bonusy.
Treba postava na pohled vypada fyzicky silne. To neznamena, ze postava bez
bonusy, ale se silou 5 neni silna, jen se to nepozna. A vsimne si toho jen nekdo
s vyssim stupnem vlastnosti postreh.
To, co popisujes, je podle mne, neco jineho. Ja to resim tak, ze uzivatel muze kliknout na cokoliv. A logika pak rozhodne, co se zasktne, co se prepne a co zustane sedive.
DarkCoder:6.5.2021 15:17
No však jo. Máš 3 kategorie (fyzické, společenské a duševní), kde pro každou bez bonusů můžeš přiřadit až 7 available points. Pomocí bonusů můžeš počet available points rozšířit. Dejme tomu že chceš přidat bonusy o hodnotě 0, +1 a +2 kategoriím tak, aby žádná kategorie neměla více bonusů (řádková priorita) a aby se nepřiřadil tentýž bonus i jiné kategorii (sloupcová priorita). Vybereš-li nějaký checkbox, pak nelze vybrat jiný checkbox ve stejném řádku ani ve stejném sloupci. Nelze klikat na cokoli, neboť tím bys mohl vybrat i dva rozdílné bonusy pro stejnou kategorii nebo dva stejné bonusy pro dvě různé kategorie. Logika by pak mohla měnit stavy které ty sám nechceš.
https://mlich.zam.slu.cz/…r/index2.htm
Silenost... Ukaz lepsi reseni
Edit: jako, nemam tam tu cas s bonusama, jen to samotne prepinaji.
if (field.type=='attPriorityBar')
{
var i, i_end, index;
var list = [12, 17, 22];
var val = [];
var available = [];
i_end = list.length;
value = value * 1; // to int
value = value>0 && value<=i_end ? value : i_end; // validace
//console.log('------')
//console.log('value id', value, id)
//console.log(val)
for(i=0; i<i_end; i++)
{
val[i] = fields[list[i]].value * 1; // zkopiruj vsechny values
available[i] = i + 1; // napln available
}
//console.log('val1', val)
//console.log('available1', available)
for(i=0; i<i_end; i++) // smaz vse, co duplikuje kliknutou hodnotu
{
if (list[i]!==id && val[i]==value)
{
val[i] = -1;
continue;
}
if (list[i]==id)
{
val[i] = value;
}
}
//console.log('val2', val)
available = removeItemOnce(available, value);
for(i=0; i<i_end; i++)
{
//console.log(val[i])
if (list[i]==id)
{
//console.log('continue')
continue;
}
if (val[i]>0 && val[i]<=i_end) // pokud je validni a existuje v available...
{
//console.log('valid')
index = available.indexOf(value);
//console.log('index')
if (index>-1)
{
//console.log('in available')
available.splice(index, 1);
continue;
}
}
val[i] = available[0];
//console.log('val shift', available, val[i])
available.shift();
}
//console.log('val3', val)
//console.log(available)
for(i=0; i<i_end; i++)
{
fields[list[i]].value = val[i]; // zkopiruj vsechny values zpet
}
}
DarkCoder:6.5.2021 20:25
Tak pokud Ti nevadí již zmíněné svévolné přepínání checkboxů nad kterým uživatel nemá úplnou kontrolu, pak je situace diametrálně jiná a řešení je ještě jednodušší. Jedná se o prostý swap. Jelikož hodnoty bonusů a kategorie jsou unikátní a nízké, lze to celé řešit pomocí inverzních polí (2 pole s prohozenými hodnotami a indexy), bez zbytečného použití cyklů.
Jo, no, vcera jsem delal nejake testy a tez dospel k zaveru, ze se to prepina
trochu nepredvidatelne.
Ocekaval bych, ze co nejvic hodnot se pokusi zachovat, coz se ale nedeje.
Ale, napadlo mne jine reseni. Vcera bracha rikal, ze by si to mozna
predstavoval jako drag and drop a presouvat cele bloky do urciteho poradi, na
zacatek, doprostred, na konec.
Takze, reseni je jednoduche, prepinace udelat jako zadani pozice. 1, 2, 3.
- z pole vyjmes meneny item
- vlozis jej na kliknutou pozici.
Brnkacka. Proc ja to resil tak slozite
DarkCoder:7.5.2021 11:56
Souhlasím, obě tato řešení (Drag and Drop, Select/Click) jsou lepší nežli všechny naše předchozí návrhy. Zajišťují plnou kontrolu uživatele nad výběrem, jednoduchost, efektivnost a rychlost provedení. Stejně tak tyto způsoby mnohem lépe zapadají do celkového pojetí návrhu.
Aby přiřazení jednotlivých bonusů bylo jednoduché a rychlé, záleží
na rozmístění checkboxů a jejich popisků v prostředí.
Viděl bych to rozmístění po řádcích takto:
bonus +0 [checkbox b0] [checkbox fyz] Fyzické
bonus +1 [checkbox b1] [checkbox spo] Společenské
bonus +2 [checkbox b2] [checkbox dus] Duševní
Možností je však mnohem více.
Ještě mě napadl jeden způsob přiřazení bonusů dané kategorii. Při výběru bonusů se vždy postupně podsvítí checkboxy kategorií jeden po druhém. Když je checkbox podsvícen, znamená to, že tomuto checkboxu bude přiřazován bonus. Bonus se vybere pouhým kliknutím na checkbox daného bonusu, ten se následně zprůhlední a na straně kategorií se objeví hodnota daného bonusu. Následně se podsvítí další checkbox kategorie a bonusy se vybírají dokud všechny kategorie nemají bonus.
Výhodou tohoto řešení je nejvyšší rychlost (přiřazení bonusu jedním klikem), nevýhodou je že bonusy se přiřazují postupně a ne libovolně. Zde by byla výhoda drag and drop způsobu, který umožňuje přetáhnout libovolný bonus ke konkrétní kategorii na úkor menšího komfortu ovládání, stejně tak způsobu Select/Click, který navrhuješ.
Ať už zvolíš ten nebo ten, každý z těchto způsobů rozdělení
bonusů kategoriím bych si dokázal ve hře představit.
Je až úsměvné, že první návrhy vedly ke způsobu řešit to pomalu
brutální silou.
Pozn: Můžeš k tomu přidat finální tlačítka Reset a OK. Kde reset
provede vrácení do výchozího stavu - zaplní bonusy a vyprázdní checkboxy
kategorií. Ok potvrdí a přiřadí vybrané bonusy jednotlivým kategoriím.
Zpřístupnění tlačítka Ok by mohlo být až po přiřazení bonusů všem
kategoriím. Ale to už jsou další záblesky ke zlepšení nad rámec které
sám jistě máš..
Uz mi to krasne funguje, posouvam to pole.
https://mlich.zam.slu.cz/…r/index2.htm
if (field.type=='attPriorityBar')
{
var x, index, i, i_end;
var list = [12, 17, 22];
i_end = list.length;
id *= 1; // to int
value*= 1; // to int
value = value>=0 && value<i_end ? value : i_end-1; // validace
var ordered = isExist(fields[list[0]]) && (x=fields[list[0]])==true && isExist(x.priority) && x.priority.length==i_end ? x.priority : list;
index = ordered.indexOf(id);
//console.log(id, ordered, index)
if (index>=0)
{
//console.log(1, ordered)
ordered.splice(index, 1); // odstran z pole stare id policka priority
//console.log(2, ordered)
ordered.splice(value, 0, id); // pridej id na novou pozici
}
//console.log(3, ordered)
for(i=0; i<i_end; i++)
{
fields[ordered[i]].value = i; // zkopiruj vsechny values zpet
}
//console.log(ordered[0], JSON.stringify(fields[ordered[0]]))
//console.log(ordered[1], JSON.stringify(fields[ordered[1]]))
//console.log(ordered[2], JSON.stringify(fields[ordered[2]]))
fields[list[0]].priority = ordered; // uloz serazene do prvni polozky
}
Neboj, dalsi veci jsou v planu, vcetne zobrazeni +2, +1 u available points.
Projekt si ridi bracha. Moc mu to rizeni nejde, ale uvidime. Zatim mame volnou
ruku, takze, kdyz tam pridame nejakou peknou feature, tak skonci mozna i ve
finalnim produktu.
Tez mu kluci ve firme doporucili spis Vue nez React. Takze, mozna, ze to jeste
prepiseme do Vue.
Neni to pro realnou hru. Existuje vypravecska hra Vampire. Zalozena na
Shadowland, ktery je zalozen na Draci doupe. A vicemene je tam asi u parametru
postavy volnost. Jenze, bracha uz to hral 20 let zpetne a acelkove zatim nema
moc predstavu, jak to resit.
Priority. Ve vetsine her muzes udelat to, ze mas 10 bodu a ty rozdelis mezi
atributy, jak chces. Zadanim priorit by melo omezit nabuseni vsech bodu do jedne
skupiny z tech tri Fyzické, Společenské, Duševní.
Pravdepodobne z toho hra nebude, jde spis o takove cviceni v reactu, 3 osoby,
ani jedna ho nezna. Blbe je, ze js znam jen ja, takze zatim mam nejkomplexnejsi
reseni
Ale, uz je tu napad na jinou hru. Jen neni jasny jazyk. Udelat takove bludiste ala ohnivy pohar pro vice hracu. A melo by to byt pro deti, takze tohle zjednodusit. A plan je, udelat z toho pro deti programovaci cviceni. Opet, zatim zadna komplexni predstava. Asi udelame nebo vyuzijeme engine a deti si budou klikat bludiste a schopnosti, neco na zpusob minecraftu. A bylo by dobr, aby neslo asi o isometricke zobrazeni (3d otocena kosticka), ale o neco, co se da rotovat, aby bylo mozne ztratit smer orintace, polohu severu.
Jeste to nebylo uplne ono, to preklikavani. On mi to pole spatne ukladal do x.priority = ordered a take spatne nacital. Ale myslenka byla spravna, jen mi to vzdy resetoval.
Bracha to predelaval do Vue a tam mi ten kod prijde
citelnejsi. Nema to sice tak bohate, prozatim.
https://lubomir.mlich.cz/quest/vue/
Na jinem forku mi doporucovali jeste pouzit **Svelte **(https://svelte.dev).
Zobrazeno 10 zpráv z 10.