Deleting used random elements from array


(Marthe Kalkhoven) #1

Hi fellow Hype-lovers :wink:

I’m making an educational ‘game’ about the Dutch language. And I could really use some javascript help.

The goal is: two kids play together. Player1 push the start-button and ‘get’ a random sentence. This sentence is copied in the players own list of 5. There player1 has to think about what kind of sentence it is and check the ‘doenzin’ or zijnzin’ checkbox. Then player2 has to evaluate and, if it is correct, player1 gets a point.
random elements game.zip (46.4 KB)

So far this works (yay!). But there are 3 things that I can’t manage. The most important is that I want already used sentences to be removed from the array. So there will be 10 unique sentences at the end of the game. I’ve read a lot about splice and tried some things, for example:

while (remainingAnswers.length) {
var randomAnswer = remainingAnswers[Math.floor(Math.random() * remainingAnswers.length)];
customTextElement.innerHTML = randomAnswer; // Put the item in the big textbox
remainingAnswers.splice (randomAnswer,1); // Remove the item from the array
}

But that makes only show the last element of the array. If I put “while (remainingAnswers.length) {” before the array alle 10 sentences are being showed at once (at one button click). What am I doing wrong?
By the way, I found this topic in which radom scenes are being deleted. But I don’t know how to translate it to string array.

The other problem I can’t solve is that the counters from the scoring are interfering with the counting from the start button. I think it has to do with window.clickCount, which is used both times, but I’m not skilled enough to solve it.

And the last thing has to be a simple thing…I would like some margin at the left of all text in the textboxes. But if I try to do that with innerHtml it gets overruled by the innerHtml that is scripted in de javascript. So I thought, maybe it’s possible to put some css inside the array in javascript? Is it?

Thanks in advance for any help!!


(Marthe Kalkhoven) #2

By the way…I know that I can start a code block in my message using ````. But how can I stop it??


(Jonathan Deutsch) #3

Looking at the code you posted, the first thing I notice is that randomAnswer is a resulting string, and you are supplying this to splice(), but splice takes integer indexes into the array. So the correct code would be something like:

var randomAnswerIndex = Math.floor(Math.random() * remainingAnswers.length);
customTextElement.innerHTML = remainingAnswers[randomAnswerIndex]; // Put the item in the big textbox
remainingAnswers.splice(randomAnswerIndex,1); // Remove the item from the array

I’m not quite sure I follow this problem; can you give steps to reproduce and the expected outcome that shows the behavior?

It might be that you just want a different variable, say window.mySpecificClickCount1 and window.mySpecificClickCount2 etc.

Theres’ a few ways you could go about doing this:

  • Add padding to the element itself in Hype’s Element Inspector (the border section)
  • Add a Class Name and use a bit of CSS that can add this
  • Re-add the inner HTML when you do the dynamic insertion

To make a code block, use three ticks ` and to end it also use three ticks.

Hope that helps!


(Marthe Kalkhoven) #4

Thanks Jonathan! With your help I’ve tackled almost all problems.
random elements game.zip (71.8 KB)

But I still get double sentences when pushing the startbutton. I’ve spend hours searching on the web, but can’t understand what goes wrong. (Only started learning javascript three week ago, so that is probably the problem :wink: )


(Marthe Kalkhoven) #5

Oke, I’ve been trying a different approach.

The plan is to first shuffle the array (at scene load) and then use the shuffled array items one by one on button click. It doesn’t work yet… But I think it can. I think it goes wrong with calling a var from another function. And also there is a function in a function at scene load. Can anyone take a look and tell me what I’m doing wrong?

This happens at scene load:

     var currentIndex = array.length, temporaryValue, randomIndex;

  // While there remain elements to shuffle...
  while (0 !== currentIndex) {

    // Pick a remaining element...
    randomIndex = Math.floor(Math.random() * currentIndex);
    currentIndex -= 1;

    // And swap it with the current element.
    temporaryValue = array[currentIndex];
    array[currentIndex] = array[randomIndex];
    array[randomIndex] = temporaryValue;
  }
  return array;
}

var arr = [
  "Ze maakt haar bed op.",
  "Haar broer wordt dokter.",
  "Wat zouden de anderen zeggen?",
  "We hebben hard gewerkt.",
  "Ze zaten in de klas te slapen.",
  "Anna is een geweldige kampioene.",
  "etc..."]

arr = shuffle(arr);

And on button click this happens:

// This is the big textbox
var customTextElement = document.getElementById('Zin');


// Count clicks on 'Start' button   
window.clickCount += 1;
hypeDocument.getElementById("teller").innerHTML = "" + window.clickCount;  
var boxNr = document.getElementById("teller").innerHTML        

// Get the next item from the array
var nextItem = shuffleArray();
// Put the item in the big textbox
customTextElement.innerHTML = nextItem[1]; 


//Copy the this random sentence into the next textbox 
var Box = document.getElementById('Box'+boxNr);
Box.innerHTML = customTextElement.innerHTML;

// Remove button when both players have had 5 sentences
if (boxNr > 9) {
	hypeDocument.startTimelineNamed('feedback');
}

nextItem[1] should be nextItem[boxNr] to get the next item every time you click te button. But is has 1 now, just for testing.

random elements game.zip (97.6 KB)


(Jonathan Deutsch) #6

If you look at the developer console logs on the page, you’ll see this error:

Error in undefined: ReferenceError: Can't find variable: shuffleArray

This is saying that it doesn’t know about the function. The issue is that the hype functions aren’t named in the global space. To access the function you can call it like this:

var nextItem = hypeDocument.functions().shuffleArray();

an alternative would be that you could on scene load define shuffleArray as part of the window object, like:

window.shuffleArray = function () {
  // .. do stuff
};

The next issue you hit will be this in the logs:

Error in undefined: TypeError: undefined is not an object (evaluating 'nextItem[1]')

The issue here is that your shuffleArray() function needs to use the return keyword to give back the array. The last two lines would then be:

arr = shuffle(arr);
return arr;

I hope that helps!


(Marthe Kalkhoven) #7

Thanks for helping Jonathan! I’m learning a lot :blush:

But I still did get doubles… I think the array got shuffled every time you push the button.

I tried something else and it works! Though it’s probably not the cleanest solution…
I made an empty rectangle outside of the canvas and at scene load let the array shuffle and put it in the InnerHTML of the rectangle. And than, when pushing the start button, taking one out of the array.

var shuffledArray = hypeDocument.getElementById("arrayStorage").innerHTML
const splitArray = shuffledArray.split(",");

Very happy it finally works. And thanks again for the help!!

random elements game2.zip (97.8 KB)


(Jonathan Deutsch) #8

Awesome, glad you got it!


(Dennis van Leeuwen) #9

Leuk spel. Ga ik met mijn zoon spelen. Waar is de live link, Marthe?
Lovely game. Will play this with my son. Is there a life link I can go to, Marthe?