I am currently working on a program that scans a page and highlights dice rolls and then lets you click to rolls those dice.
The program mostly works as expected, for example if the page contains stuff like 1d6, 1d6 + 3, d20, or 1d6 x 100 it picks up and rolls it. However I would like the ability to detect more complicated roles for example 1d20 + 4 1d12 + 12 and then parse that out into its individual roles. I would like to avoid detecting things like 1d20 + 4 the 1d12 + 12, basically, avoid things that have words instead of spaces in the dice roll.
My script uses regex to match patterns on the page and highlight them. I am not sure if this is something I could add to my regex since this is really been my project for learning regex. Here is the current regex I am using
([+−-]\d+)|(([1-9]\d*)?d([1-9]\d*)\s*([+-−]\s*\d+)?([,]\s*\d+)?)
And a sample on https://regexr.com/3tl1o
I think this is what you want
((?:[+-]?[1-9]\d*)?d[1-9]\d*(?:\s+[-+x]\s+[1-9]\d*)?(?:\s+(?:[+-]?[1-9]\d*)?d[1-9]\d*(?:\s+[+-x]\s+[1-9]\d*))*)
See https://regex101.com/r/Ap0HZw/1 for the explination
Related
I'm making a bot for a gaming chatroom with some friends, but I've hit an impasse. Is there a reliable way to get numbers from inside a string of text that won't completely break an inexperienced script kiddy's brain? Here's the best I've been able to come up with so far, variables simplified slightly for illustration's sake:
var k = [0];
function dieRoll(m,n) {
for(i = 0; i < m; i++) {
k[i] = Math.floor(Math.random()*n)+1;
}
}
var m = text[5];
var n = text[7];
if (text === 'roll '+m+'d'+n) {
dieRoll(m,n)
console.log(k);
}
The biggest problem as-is is that it's limited to single-digit input.
EDIT: Looping through the text looking for integers is exactly the kind of thing I'm looking for. I don't have much experience with programming, so I probably tend to end up with overly complicated and confusing messes of spaghetti code that would embarrass anyone remotely professional. As for the format of the input I'm looking for, "roll [number of dice]d[highest number on the dice]". For anyone who doesn't know, it's the notation most tabletop rpgs use. For example, "roll 2d6" for two normal six-sided dice.
EDIT: It's not that I'm necessarily against regex, I just want to be able to understand what's going on, so that if and when I need to edit or reuse the code it I can do so without going completely insane.
EDIT: Thank you all very much! split() seems to be exactly what I was looking for! It'll probably take some trial and error, but I think I'll be able to get her working how she's supposed to this weekend (Yes I call my bots 'she').
Basically, you need to look at the format of the input you're using, and identify certain facts about it. Here are the assumptions I've taken based on your question.
1) The "roll" command comes first followed by a space, and
2) After the command, you are provided with dice information in the form xdy.
Here's something that should work given those constraints:
function getRollParameters(inputCommand) {
var inputWords = inputCommand.split(' '); //Split our input around the space, into an array containing the text before and after the space as two separate elements.
var diceInfo = inputWords[1]; //Store the second element as "diceInfo"
var diceDetails = diceInfo.split('d'); //Split this diceInfo into two sections, that before and after the "d" - ie, the number of dice, and the sides.
//assign each part of the dicedetails to an appropriate variable
var dice = diceDetails[0];
var sides = diceDetails[1];
//return our two pieces of information as a convenient object.
return {
"dice": dice,
"sides": sides
};
}
//a couple of demonstrations
console.log(getRollParameters("roll 5d8"));
console.log(getRollParameters("roll 126d2"));
Effectively, we're first splitting the string into the "command", and the "arguments" - the information we want. Then, we split our arguments up using the "d" as a midpoint. That gives us two numbers - the one before and the one after the d. Then we assign those values to variables, and can use them however we like.
This obviously won't deal with more creative or flexible inputs, and isn't tested beyond the examples shown but it should be a decent starting point.
A disclaimer: I'm not familiar with Javascript. I've merely cobbled together a basic understanding of what I need to do for this task from Stack Overflow and other resources. My apologies if something below is unclear.
My problem: I need to generate a random number between 0 and 8,764, using Javascript, that will not repeat itself between Qualtrics survey responses.
Currently, I've found code to create an array that contains all numbers between 0 and 8,764, shuffles the array, and pops the last number off the end of the array.
It then adds embedded data to Qualtrics with that popped number, and I can then pipe the embedded data into a Qualtrics question to display it to my survey respondent. See below:
Qualtrics.SurveyEngine.addOnReady(function()
{
for (var i = 0, ar = []; i < 8; i++) {
ar[i] = i;
}
ar.sort(function () {
return Math.random() - 0.5;
});
var randomnumber = ar.pop();
Qualtrics.SurveyEngine.addEmbeddedData("randomnumber", randomnumber);
});
However, as far as I can tell, this Javascript code "resets" itself between survey responses, meaning it will re-create and re-shuffle the array each time a new respondent enters the survey. I'd like to find a way to make it so that it will be impossible for a new respondent to see the same popped "randomnumber" as a previous respondent. So, if the first survey respondent saw a 1, then the next survey respondent could see any number besides a 1 (let's say they see a 100 instead), and the next respondent could see any number except a 1 or a 100, etc etc.
I think it's possible to use embedded data in Javascript code and manipulate it (see here). It seems like there might be a way to access the randomnumber embedded data and write Javascript code to not remove any numbers from the array that match one of the previously popped randomnumbers. I lack the technical knowledge to execute this, if it's even the best way to accomplish the task.
Any and all help appreciated!
You can do what you want with Advanced Randomization in Qualtrics.
Set up a multiple choice question with your numbers 0 through 8,764 as the choices. Then use Advanced Randomization to select a random subset of 1 from all the numbers and click "Evenly Present" (Evenly Present is what tells Qualtrics to use every number before reusing any). Use JavaScript to hide the multiple choice question:
$(this.questionId).hide();
Now you can pipe your unique random number into a subsequent question. For example:
${q://QID1/ChoiceGroup/DisplayedChoices}
I am trying to truncate complex html by lines in order to be able to display a show more link after a certain number of lines has been reached. I found a great library trunk8.js which truncates by lines..but if falls short when it comes to truncating complex html. So for my particular case I overrode the truncate function so that I can handle complex the using another truncation function which gracefully leaves complex html tags intact. Truncation will work great with html but I am stuck on how to accurately calculate where to put show more more based on the number of lines
As seen in the image above I am trying to truncate to 7 lines but if the user input contains white spaces shown in yellow my calculations will be wrong because I am not accounting for the white spaces. My initial line of thought was that if I can calculate the length of the spaces in yellow for each line and convert it to characters, I can add this offset to the maximum number number of characters, then I can know where to put approximately the show more link. Is this the best approach to this problem and if not ,any suggestions to make my life easier.
This is a plunker of what I have tried so far and I am stuck in my truncateHTML() function in the trunk8.js where I am only now truncating based on the maximum length of the string.
Eureka!! After a couple of google searches and heavy debugging sprints, I stumbled upon a library truncate.js which I customized the truncatedNestednode() function for my needs.
element.appendChild(child);
/** Customized--here **/
var clonedNode = {};
if ($clipNode.length) {
if ($.inArray(element.tagName.toLowerCase(), BLOCK_TAGS) >= 0) {
// Certain elements like <li> should not be appended to.
$element.after($clipNode);
}
else
{ //Removed the commented line to put showmore next to the last line of text
$element.prev().append($clipNode);
//$element.append($clipNode);
}
}
In case someone faced this problem in the past, I have posted my revised plunker here
I've got a basic Space Invaders type game going, and I can't get it to recognise when the shot from the player hits the alien. (I'm only checking Alien2 atm, the one second from the left). Since they're both moving, I've decided the only way to check for collisions is with either a range-based if statement (with 2 top coordinates and one left coordinate), or directly comparing the positions along the Y axis with Jquery.
I'm using the range-based solution at the moment, but so far it hasn't worked (not sure why).
My code so far:
if (key == "87"/*&& document.getElementById('BarrelOne').id=='BarrelOne'*/){
var Invader2 = document.getElementById('Alien2');
var Shot1 = document.getElementById('ShortShot');
Shot1.style.webkitAnimationPlayState="running";
setTimeout(function(){
Shot1.style.webkitAnimationPlayState="paused";
}, 1200);
if(document.elementFromPoint(625.5, 265.5) == Shot1){
Invader2.style.visibility="hidden";
}
};
Jsfiddle:
http://jsfiddle.net/ZJxgT/2/
I did something similar, and i found that it was much easier to achieve using gameQuery.
to test for collisions:
var collided = $("#div1").collision("#div2");
you can see full working example here
EDIT
If you're having trouble check out the API. For example, to find out how to use collisions check this part of the API.
the collision works in the following way:
This method returns the list of elements collisioning with the selected one but only those that match with the filter given as parameter. It takes two optional arguments (their order is not important). The filter is a string filtering element used to detect collision, it should contain all the elements the function should search collision into. For example if you look for collision with element of the class ‘foo’ that may be contained in a group you will use the filter ".group,.foo".
So, write something like this:
$("#ShortShot").collision("#Alien2").hide();
// will return the alien if it collides with ShortShot
or, to hide them both:
if (($("#ShortShot").collision("#Alien2")).length) {
$("#ShortShot").remove();
$("#Alien2").remove();
}
Instead of losing hours reinventing the wheel, I would suggest to switch (if still possible, depending on your time deadline) to a real 2D game engine for Javascript, with easy collision detection.
Check as well: 2D Engines for Javascript
I wonder if I can simplify and use less lines of code for this purpose:
I have a class called "worker", and that class has a method that reads the properties (name, age, etc...) from a series of simple arrays.
Until there, everything is fine. Now, one of the properties that I want to add is a boolean value that makes reference to which months of the year the worker is active. For the moment, I have solved it like this:
var months_worker_1 = [{"jan":true},{"feb":true},{"mar":true},{"apr":false}] //and so on
And then, my property reads months_worker_1, but I have one array like that for each worker. I wonder if there is a way to do this that requires less lines of code, like for example, create a "master" array with all the months of the year, and in the array for each worker, specify just the months they are working. Those months become "true", and the rest of months become "false" automatically without specifying so... I have been scratching my head for some time, and for the moment only my current system is working fine, but I am guessing that there must be a simpler way...
Thanks very much!
Edit: I clarify, there is no "big picture". I am just doing some exercises trying to learn javascript and this one woke my interest, because the solution I thought seems too complicated (repeating same array many times). There is no specific goal I need to achieve, I am just learning ways to do this.
A really nice trick that I use sometimes is to use a binary number to keep track of a fixed amount of flags, and convert it to a decimal for easier storage / URL embedding / etc. Let's assume Mark, a user, is active all months of the year. Considering a binary number, in which 1 means "active" and 0 inactive, Mark's flag would be:
111111111111 (twelve months)
if Mark would only be active during january, february and december, his flag value would be:
11000000001
Checking if Mark is active during a specific months is as simple as checking if the character that corresponds to that month's index in Mark's flag is 1 or 0.
This technique has helped me in the past to send values for a large number of flags via URLs, while also keeping the URL reasonably short. Of course, you probably don't need this, but it's a nice thing to know:
Converting from binary to decimal is easy in JS:
parseInt(11000000001, 2).toString(10); // returns 1537
And the reverse:
parseInt((1537).toString(2)); // returns 11000000001
Edit
You could just as easily use an array made out of the month numbers:
var months_worker_1 = [1, 2, 3]; // this would mean that the user is active during january, february and march