Trädvy Permalänk
Medlem
Registrerad
Maj 2019

JS, hjälp

H

Trädvy Permalänk
Medlem
Plats
Stockholm
Registrerad
Aug 2013

@Valmd: Redigera ditt inlägg och placerade koden mellan [code]-taggar och se till att indenteringen är korrekt.

Jag hade gjort tärningarna som egna object som innehöll en funktion för att rolla.
Låt användaren välja 1-5, skapa upp antalet tärningar och placera de i en array och skicka in i funktionen för att starta spel.
Loopa arrayen och anropa roll() för varje tärning, addera summan till det totala.
Om tärningen visar 6 addera inte summan, skapa upp två ny tärning och placera de längst bak i arrayen.

Tänk inte på att de gamla ska slås om, addera istället nya i slutet av arrayen då de tidigare redan är förbrukade.

Trädvy Permalänk
Medlem
Registrerad
Maj 2019

menar du något sånt här?

h

Trädvy Permalänk
Medlem
Plats
Stockholm
Registrerad
Aug 2013
Skrivet av Valmd:

@zaibuf:

Det känns enklare att utgå från den här, det jag vill göra som jag inte får till är att ge varje "sida" ett värde från arrayen, och sen slå ihop det till totalen men jag får inte till det och sen då precis som du säger att när det blir 6 så ska den slå om två gånger. g

function roll(){ rolls=document.getElementById('rolls').value; dice_num=document.getElementById('dice_num').value; sex=6; ett=1; två=2; tre=3; fyra=4; fem=5; die=0; total=0 dice=new Array("ett","två","tre","fyra","fem","sex"); document.getElementById('output').innerHTML=""; for(i=rolls;i>0;i--){ for(y=dice_num;y > 0;y--){ r=Math.floor(Math.random()*6); die=dice[r]; document.getElementById('output'). innerHTML+=die + ", "; if(die == "sex"){ total =-sex; } if(die == "ett"){ total = ett; } if(die += "två"){ total = två; } if(die ="tre"){ total = tre; } if(die = "fyra"){ total = fyra; } if(die = "fem"){ total = fem; } } document.getElementById('output').innerHTML+="<br>"; } document.getElementById('output').innerHTML+="<br>================<br>"; document.getElementById('output').innerHTML+="Total: " + total + "<br>"; window.scrollTo(0, document.body.scrollHeight); } document.getElementById("btn").addEventListener("click", function(event){ var count = event.currentTarget; count.clicks = (count.clicks || 0) + 1; document.getElementById("demo").innerHTML = "Antalet kast:" + count.clicks; });

Kan visa hur jag hade gjort det. Det är utan HTML då jag visar med console.log istället.

/* Game variables * TOTALDICES representing the number of dices used. * DICEARRAY holds the games dices. * NUMBEROFSIDES representing the number of sides of the dice, 6 = 1-6. */ const TOTALDICES = 5; const DICEARRAY = []; const NUMBEROFSIDES = 6; // Class-object representing the Dice, has a function for roll. class Dice { roll() { return Math.floor(Math.random() * NUMBEROFSIDES) + 1; } } // Fills the games dice list function seedDices(totalDices) { for (let i = 0; i < totalDices; i++) { DICEARRAY.push(new Dice()); } } // Starts the game and logs the result. function startGame() { let totalSum = 0; let totalRolls = 0; for (let i = 0; i < DICEARRAY.length; i++) { totalRolls = i + 1; let rollValue = DICEARRAY[i].roll(); if (rollValue === 6) { DICEARRAY.push(new Dice(), new Dice()); } else { totalSum += rollValue; } console.log(`Roll nr ${i + 1} = ${rollValue} : Total = ${totalSum}`); } console.log(`Total rolls: ${totalRolls}`); console.log(`Total sum: ${totalSum}`); } // Seed the list and start the game seedDices(TOTALDICES); startGame();

Trädvy Permalänk
Medlem
Plats
Stockholm
Registrerad
Dec 2010

Det här känner jag igen!

Trädvy Permalänk
Medlem
Plats
Mjölby
Registrerad
Nov 2010

Inklusive HTML:

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Dice Simulator</title> <style> body { align-items: center; display: flex; justify-content: center; height: 100vh; margin: 0; padding: 0; width: 100vw; } #box { align-items: center; display: flex; flex-direction: column; width: 25%; } </style> </head> <body> <div id="box"> <label for="Dices"><span id="amount--of--dices"></span> dices</label> <input type="range" id="range--dices" min="1" max="5" name="Dices"> <button id="rollDices">Roll dices!</button> <p>Result: <span id="result">0</span> points over <span id="rolls">0</span> rolls.</p> </div> <script> document.addEventListener("DOMContentLoaded", () => { totalDices = 0; let rangeSlider = document.getElementById("range--dices"); let dicesOutput = document.getElementById("amount--of--dices"); dicesOutput.innerHTML = rangeSlider.value; rangeSlider.oninput = function() { dicesOutput.innerHTML = this.value; return totalDices = this.value; } function rollDices () { dices = []; sum = 0; totalRolls = 0; for (var i = 0; i < totalDices; i++) { totalRolls++; roll = Math.floor(Math.random()*6+1); dices.push(roll); if (roll == 6) { for (var j = 0; j < 2; j++) { totalRolls++; roll = Math.floor(Math.random()*6+1); dices.push(roll); } } } dices.forEach(i => { if (i < 6) { sum += i; } }); result.innerHTML = sum; rolls.innerHTML = totalRolls; } document.getElementById("rollDices").addEventListener("click", () => { rollDices(); }); }); </script> </body> </html>

Dold text

Jag har en tendens att blanda in lite ES6 every now and then. Vad ska ske om du får en 6a under ett extra kast? Ska det skapa upp ytterligare kast?

Main-PC: Bitfenix Phenom Mini | Asus Z170I Pro | Intel I5 6600K | Kingston HyperX 16GB 2133Mhz DDR4 | EVGA GeForce GTX 1070 | Corsair SF450 |

Trädvy Permalänk
Entusiast
Testpilot
Plats
Chalmers
Registrerad
Aug 2011

Några snabba och enkla men värdefulla JavaScript-tips

Använd inte var

Använd inte nyckelordet var. Använd istället const som standard, och let om och endast om du behöver kunna skriva över variabelns värde senare. Exempel:

const header = document.getElementById("header"); for (let i = 0; i < 10; i++) { // … }

Använd inte ==

Semantiken hos == är extremt ointuitiv i JavaScript; till exempel är dumheter som "" == 0 sanna. Använd istället ===. (De mycket få undantagsfall då == kan vara vettig är överkurs i sammanhanget.)

Subtrahera inte strängar

Undvik:

var subTotal = diceTotal - "6";

Det råkar fungera i just detta fall i ett svagt typat språk som JavaScript, men det är inte bra kod. Mycket bättre:

var subTotal = diceTotal - 6;

Några mer allmänna tankar om din kod

ett, två, tre, …?

Detta är i allmänhet inte vettiga definitioner:

sex=6; ett=1; två=2; tre=3; fyra=4; fem=5;

Tycker du att de tillför något?

Kolla om något element bland flera uppfyller ett visst predikat

Istället för

d1 == 6 || d2 == 6 || d3 == 6 || d4 == 6 || d5 == 6

skulle jag föreslå

[d1, d2, d3, d4, d5].some(x => x === 6)

som är mer generellt och robust. Men egentligen borde inte variablerna d1 osv ingå i koden överhuvudtaget. Vilket för oss till nästa punkt …

Don't Repeat Yourself

Tänk om du blir ombedd att ändra programmet så att man ska kunna slå upp till 1000 tärningar. Vad behöver du göra för ändringar då?

Du har tydliga mönster som upprepar sig flera gånger. Ta till exempel följande:

var d1 = Math.floor(Math.random() * 6) + 1; var d2 = Math.floor(Math.random() * 6) + 1; var d3 = Math.floor(Math.random() * 6) + 1; var d4 = Math.floor(Math.random() * 6) + 1; var d5 = Math.floor(Math.random() * 6) + 1;

Du har egentligen skrivit samma sak fem gånger, förutom en minimal detalj som skiljer sig åt. När man ser ett sådant mönster bör man försöka abstrahera ut det så att man bara behöver skriva varje sak en gång. Denna princip kallas Don't Repeat Yourself (DRY).

Exempelvis:

function randomDieValue(max) { return Math.floor(Math.random() * max) + 1; } const randomValues = Array(5).fill(null).map(_ => randomDieValue(6))

(Ovanstående är inte nödvändigtvis perfekt kod, men illustrerar principen.)

I allmänhet: Det ska aldrig vara så att du måste ändra på flera ställen i koden för att ändra en sak. Till exempel borde literalerna 5 (för antalet tärningar) och 6 (för antalet sidor på en tärning) bara förekomma en gång var i programmet, typ så här:

const MAX_DICE = 5; const DIE_SIDES = 6;

Resten av koden bör sedan vara byggd så att om man istället ska kunna slå upp till tio stycken 20-sidiga tärningar behöver du bara ändra till

const MAX_DICE = 10; const DIE_SIDES = 20;

och inget mer.

Bugg i randomDieValue.

Skrivet med hjälp av Better SweClockers

Trädvy Permalänk
Medlem
Registrerad
Maj 2019

@absoluteRango: Ja när en 6:a slås ska det resultera i att två ytterligare tärningar slås istället och för varje 6:a som slås ska det inte räknas in i totalen.

Trädvy Permalänk
Medlem
Registrerad
Maj 2019

Tack för bra tips!

@Alling: tack för ett gäng bra tips, uppskattas!

Trädvy Permalänk
Medlem
Plats
Mjölby
Registrerad
Nov 2010
Skrivet av Valmd:

@absoluteRango: Ja när en 6:a slås ska det resultera i att två ytterligare tärningar slås istället och för varje 6:a som slås ska det inte räknas in i totalen.

Då introducerar vi en while-loop!
Bör tillägga att zaibufs inlägg är mer åt best practice-hållet än mitt. Koden nedan är lite 'hackig'.

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Dice Simulator</title> <style> body { align-items: center; display: flex; justify-content: center; height: 100vh; margin: 0; padding: 0; width: 100vw; } #box { align-items: center; display: flex; flex-direction: column; width: 25%; } </style> </head> <body> <div id="box"> <label for="Dices"><span id="amount--of--dices"></span> dices</label> <input type="range" id="range--dices" min="1" max="5" name="Dices"> <button id="rollDices">Roll dices!</button> <p>Result: <span id="result">0</span> points over <span id="rolls">0</span> rolls.</p> </div> <script> document.addEventListener("DOMContentLoaded", () => { let totalDices = 3; const sides = 6; let rangeSlider = document.getElementById("range--dices"); let dicesOutput = document.getElementById("amount--of--dices"); dicesOutput.innerHTML = rangeSlider.value; rangeSlider.oninput = function() { dicesOutput.innerHTML = this.value; return totalDices = this.value; } function rollDices () { dices = []; sum = 0; totalRolls = 0; for (let i = 0; i < totalDices; i++) { totalRolls++; roll = Math.floor(Math.random()*sides+1); dices.push(roll); if (roll === 6) { let additionalRolls = 2; while (additionalRolls > 0) { // console.log(`Additional Roll! Rolls left ${additionalRolls-1}`); totalRolls++; roll = Math.floor(Math.random()*sides+1); if (roll === 6) { additionalRolls+2; // console.log(`New rolls added! Rolls left ${additionalRolls}`); } dices.push(roll); additionalRolls--; } } } dices.forEach(i => { if (i < 6) { sum += i; } }); result.innerHTML = sum; rolls.innerHTML = totalRolls; } document.getElementById("rollDices").addEventListener("click", () => { rollDices(); }); }); </script> </body> </html>

Dold text

Main-PC: Bitfenix Phenom Mini | Asus Z170I Pro | Intel I5 6600K | Kingston HyperX 16GB 2133Mhz DDR4 | EVGA GeForce GTX 1070 | Corsair SF450 |

Trädvy Permalänk
Medlem
Registrerad
Maj 2019

@zaibuf: Tack så mycket för hjälpen! det här är ju grymt!