multiple loops google app script - javascript

I am currently working in GAS to create and optimize a search function based on multiple criteria.
I have code that works, but it is inconsistent on whether or not the function call will time-out before the search is completed.
//Top level function to run the sub-level OD, ID, End Ring, Pusher, and Bushing Length functions
function toolSearch(od, id, mat) {
var od1 = parseFloat(od);
var id1 = parseFloat(id);
var inc = .25; //change to 0 when standardized bushings are implemented
var passOutput = [];
var failOutput = ["Tooling Unavailable", "Contact CPI Stafford Materials Engineer"];
if (od1 > 49 || id1 > 46)
return failOutput;
//If statement to determine amount of end rings required based on OD shell size and material
if (mat == "Hot Mold" && od < 10)
var qER = 4;
else
qER = 2;
//Initial tooling search
var od2 = toolSearchOD(od1);
var id2 = toolSearchID(id1);
var er = toolSearchER(od2, id2);
var ps = toolSearchPS(od2);
var wall = wallCall(od2, id2);
//return variables must be parsed from strings to integers and decimals
od2 = parseFloat(od2);
id2 = parseFloat(id2);
er = parseInt(er);
ps = parseInt(ps);
wall = parseFloat(wall);
//Remove comments when standardized bushings are implemented
/*if(id>10)
{inc = .5;}
else
{inc = .25;}*/
//If statement to check for pusher and end ring requirments before moving into for loop
if (er < qER || ps < 1) {
//For loop to find OD and ID shells, the required quantity of end rings, and the pusher
for (var i = 0; i < 50; i++) { //Loop is set at 75 in order to prevent 30 second function time out. May need to be adjusted.
od2 += inc;
od2 = toolSearchOD(od2);
od2 = parseFloat(od2);
wall = wallCall(od2, id2);
wall = parseFloat(wall);
er = toolSearchER(od2, id2);
er = parseInt(er);
ps = toolSearchPS(od2);
ps = parseInt(ps);
if (wall > 3) {
id2 -= inc
id2 = toolSearchID(id2);
id2 = parseFloat(id2);
od2 = od1 - inc;
od2 = parseFloat(od2);
er = toolSearchER(od2, id2);
er = parseInt(er);
}
if (er >= qER && ps >= 1)
break;
}
}
//A final check to make sure that the variable is parsed to an integer or decimal
od2 = parseFloat(od2);
id2 = parseFloat(id2);
er = parseInt(er);
ps = parseInt(ps);
wall = parseFloat(wall);
var blength = bLength(mat, od2, id2); //Bushing Length function input/output
//If statement to check if requirements have been met to return the proper information
if (er < qER || ps < 1 || wall > 3) {
return failOutput;
} else {
passOutput = [od2, id2, blength, er, ps, wall];
return passOutput;
}
}
//A final check to make sure that the variable is parsed to an integer or decimal
od2 = parseFloat(od2);
id2 = parseFloat(id2);
er = parseInt(er);
ps = parseInt(ps);
wall = parseFloat(wall);
var blength = bLength(mat,od2, id2); //Bushing Length function input/output
//If statement to check if requirements have been met to return the proper information
if(er < qER || ps < 1 || wall > 3){
Logger.log("FAILURE TO FIND SIZE " + passOutput);
return failOutput;}
else{
passOutput = [od2,id2, blength,er, ps, wall];
return passOutput;}
}
//****************************************************************************************
//Sub-function for searching the shell OD inventory, based on the updated OD from toolSearch
function toolSearchOD(od) {
var range = CacheService.getScriptCache().get('rangeSHOD');//Call to data in cache
range = Utilities.parseCsv(range);//All returns from cache need to be parsed from a CSV format to a horizontal array with a permanent row of zero
var size = lastRow("Shell Inventory");//Call to sub-function to determine index of last row of the sheet with data in it.
var found = 0;
od = parseFloat(od);//A built in check to make sure that the variable is parsed to a decimal
var inc = .25;//change to 0 when standardized bushings are implemented
//Remove comments when standardized bushings are implemented
/*if(od>10)
{var inc = .5;}
else
{inc = .25;}*/
while (found != 1){
for(var j=0;j<size;j++)
{
if(range[0][j] == od){
od = range[0][j];
found = 1;
}
}
if(found != 1)
od+=inc;
}
return od;
}
//****************************************************************************************
//Sub-function for searching the shell OD inventory, based on the updated ID from toolSearch
function toolSearchID(id) {
var range = CacheService.getScriptCache().get('rangeSHID');
range = Utilities.parseCsv(range);
var size = lastRow("Shell Inventory");
var found = 0;
id = parseFloat(id);
var inc = .25;//change to 0 when standardized bushings are implemented
//Remove comments when standardized bushings are implemented
/*if(id>10)
{var inc = .5;}
else
{inc = .25;}*/
while (found != 1){
for(var j=0;j<size;j++)
{
if(range[0][j] == id){
id = range[0][j];
found = 1;
}
}
if(found != 1)
id-=inc;
}
return id;
}
//****************************************************************************************
//Sub-function for searching the end ring inventory, based on the updated ID and OD values from toolSearchID and toolSearchOD.
function toolSearchER(od,id) {
var rangeOD = CacheService.getScriptCache().get('rangeEROD');
var rangeID = CacheService.getScriptCache().get('rangeERID');
var rangeQTY = CacheService.getScriptCache().get('rangeERQTY');
rangeOD = Utilities.parseCsv(rangeOD);
rangeID = Utilities.parseCsv(rangeID);
rangeQTY = Utilities.parseCsv(rangeQTY);
var size = lastRow("End Ring Inventory");
var erQTY = 0;
od = parseFloat(od);
id = parseFloat(id);
for(var j=0;j<size;j++)
{
if(rangeID[0][j] == id && rangeOD[0][j] == od){
erQTY += parseInt(rangeQTY[0][j]);
}
}
return erQTY;
}
//****************************************************************************************
//Sub-function for searching the end ring inventory, based on the updated ID and OD values from toolSearchID and toolSearchOD.
function toolSearchPS(od) {
var rangeQTY = CacheService.getScriptCache().get('rangePSQTY');
var rangeOD = CacheService.getScriptCache().get('rangePSOD');
rangeOD = Utilities.parseCsv(rangeOD);
rangeQTY = Utilities.parseCsv(rangeQTY);
var size = lastRow("Pusher Inventory");
var psQTY = 0;
od = parseFloat(od);
od -= .25;
for(var j=0;j<size;j++)
{
if(rangeOD[0][j] == od){
psQTY = rangeQTY[0][j];
}
}
return psQTY;
}
//****************************************************************************************
//Sub-function to calculate bushing wall size based on updated OD and ID inputs from toolSearch, toolSearchOD, and toolSearchID
function wallCall(od,id){
var wall;
wall = (od-id)/2;
return wall;
}
//****************************************************************************************
//Sub-function that puts all required data into a Google cache for more efficent processing. Cache time limit is 1 hour
function cache(){
var ss = SpreadsheetApp.getActive();
var sheetSH = ss.getSheetByName("Shell Inventory");
var sheetSHL = sheetSH.getRange("F2:F").getValues();
var sheetER = ss.getSheetByName("End Ring Inventory");
var sheetPS = ss.getSheetByName("Pusher Inventory");
var rangeSHOD = sheetSH.getRange("D2:D").getValues();
var rangeSHID = sheetSH.getRange("C2:C").getValues();
var rangeERQTY = sheetER.getRange("H2:H").getValues();
var rangeEROD = sheetER.getRange("C2:C").getValues();
var rangeERID = sheetER.getRange("D2:D").getValues();
var rangePSQTY = sheetPS.getRange("G2:G").getValues();
var rangePSOD = sheetPS.getRange("B2:B").getValues();
CacheService.getScriptCache().put('rangeSHOD',rangeSHOD,3600);
CacheService.getScriptCache().put('rangeSHID',rangeSHID,3600);
CacheService.getScriptCache().put('sheetSHL' ,sheetSHL,3600);
CacheService.getScriptCache().put('rangeERID',rangeERID,3600);
CacheService.getScriptCache().put('rangeEROD',rangeEROD,3600);
CacheService.getScriptCache().put('rangeERQTY',rangeERQTY,3600);
CacheService.getScriptCache().put('rangePSQTY',rangePSQTY,3600);
CacheService.getScriptCache().put('rangePSOD',rangePSOD,3600);
}
//****************************************************************************************
//Sub-function to calculate the index of last row of data for a sheet
function lastRow(sheetName){
var ss = SpreadsheetApp.getActive();
var sheet = ss.getSheetByName(sheetName);
var size=sheet.getLastRow();
return size;
}
//****************************************************************************************
//Sub-function to calculate bushing length based on OD and ID shell lengths and type of material
function bLength (mat,od, id){
var rangeID = CacheService.getScriptCache().get('rangeSHID');
var rangeOD = CacheService.getScriptCache().get('rangeSHOD');
var rangeL = CacheService.getScriptCache().get('sheetSHL');
rangeID = Utilities.parseCsv(rangeID);
rangeOD = Utilities.parseCsv(rangeOD);
rangeL = Utilities.parseCsv(rangeL);
var size = lastRow("Shell Inventory");
var lengthID = 0;
var lengthOD = 0;
var blength = 0;
id = parseFloat(id);
od = parseFloat(od);
//Find ID shell length
for(var j=0;j<size;j++)
{
if(rangeID[0][j] == id){
lengthID = rangeL[0][j];
}
}
found = 0;
//Find OD shell length
for(var j=0;j<size;j++)
{
if(rangeOD[0][j] == od){
lengthOD = rangeL[0][j];
}
if(lengthID == 18){
blength = "5 inches *Configuration not recommended*.";}
else if (lengthOD == 18)
blength = "5 inches";
else if(mat == "Hot Mold"){
blength = "6 inches";}
else
blength = "9 inches";
return blength;
}
}
function matType(mat){
var hot = 0;
var matType;
switch (mat){
case 620:
hot = 1;
break;
case 603:
hot = 1;
break;
case 604:
hot = 1;
break;
case 611:
hot = 1;
break;
case 605:
hot = 1;
break;
case 608:
hot = 1;
break;
case 580:
hot = 1;
break;
case 607:
hot = 1;
break;
default:
break;
}
if (hot == 1)
matType = "Hot Mold";
else
matType = "Cold Mold";
return matType;
}
Yes I know it's clunky. The "for" loop requirement is there to keep the script from timing out but it is far from effective and I know there is a better way.
The data is on 3 separate sheets and their is a function that caches all the relevant data to try and limit the amount of calls to the sheet, which helped, but not enough.
How can I make this code more efficient? I need to add more criteria which will require more looping to find the correct set of tooling for a job and I'm afraid this will cause the top level function to exceed the function call time very quickly.

Related

Certain number question being missed in regex

I have the following if statement that removes the first instances of a number followed by the period. However, I am noticing it is missing to catch some of them (ex. "16.", "23.", "24.", etc.) and not sure why.
Here is the function:
function quesCleanUp(ques){
//Checks the first instance of "." and removes it and the number
if(ques.match(/[0-9]\./g)?.length > 1){//(ques.match(/./g)?.length > 1){
var quesClean = ques.replace(/^[^\.]*\./, '').trim();
} else{
var quesClean = ques.trim();
}
return quesClean;
}
The following for loop extracts the question from the google form:
for (var i = 0; i < items.length; i++) {
var item = items[i];
switch(item.getType()) {
case FormApp.ItemType.MULTIPLE_CHOICE:
var question = item.asMultipleChoiceItem();
var ques = quesCleanUp(question.getTitle().trim());//replace(/\s/g, "");
var question_type = "Multiple Choice";
var optns = [];
var answr;
var answers = question.getChoices();
answer_val = false;
for (var j = 0; j < answers.length; j++) {
var clean = answers[j].getValue().trim();
optns.push(clean);
if(answers[j].isCorrectAnswer()){
answr = answers[j].getValue().trim();
for(var x = 0; x < optns.length; x++){
if(answr == optns[x]){
answer_val = true;
break;
}
}
}
}
var multiJSON = makeJSON(ques, question_type, optns, answr);
console.log("JSON1: " + JSON.stringify(multiJSON));
constructedJSON[i+1] = multiJSON;
break;
case FormApp.ItemType.CHECKBOX:
var question = item.asCheckboxItem();
//var ques = question.getTitle().trim();//.replace(/\s/g, "");
var ques = quesCleanUp(question.getTitle().trim());//replace(/\s/g, "");
var question_type = "CheckBox";
var optns = [];
var answr = [];
var answers = question.getChoices();
for (var j = 0; j < answers.length; j++) {
var clean = answers[j].getValue().trim();//replace(/\s/g, "");
optns.push(clean);
if(answers[j].isCorrectAnswer()){
answr.push(answers[j].getValue().trim());
}
}
var checkJSON = makeJSON(ques, question_type, optns, answr);
console.log("JSON2: " + JSON.stringify(checkJSON));
constructedJSON[i+1] = checkJSON;
break;
case FormApp.ItemType.PARAGRAPH_TEXT:
var question = item.asParagraphTextItem();
//var ques = question.getTitle().trim();//.replace(/\s/g, "");
var ques = quesCleanUp(question.getTitle().trim());//replace(/\s/g, "");
var question_type = "free response";
var optns = [];
var answr;
var paraJSON = makeJSON(ques, question_type, optns, answr);
console.log("JSON3: " + JSON.stringify(paraJSON));
constructedJSON[i+1] = paraJSON;
break;
case FormApp.ItemType.TEXT:
var question = item.asTextItem();
//var ques = question.getTitle().trim();
var question_type = "free response";
var ques = quesCleanUp(question.getTitle().trim());//replace(/\s/g, "");
var optns = "";
var answr = "";
var textJSON = makeJSON(ques, question_type, optns, answr);
console.log("JSON4: " + JSON.stringify(textJSON));
constructedJSON[i+1] = textJSON;
break;
}
The following example is the type of question 16. What is the meaning of life?
And the expected output: What is the meaning of life?
Try using /[0-9]+./g to catch more than one digit
As a quick fix, in the function quesCleanUp() try to change the line:
if(ques.match(/[0-9]\./g)?.length > 1){//(ques.match(/./g)?.length > 1){
With:
if (ques.match(/^[0-9]+\./g).length > 0) {
I suspect you got the downvotes because you posted the code with glared typos. It looks like you didn't even try to debug it first. And as the icing on the cake you accepted a wrong answer.
And probably the function can be boiled down to just one line:
const quesCleanUp = q => q.replace(/^\d+\./,'').trim();
Here is how it works:
var questions = ['1. aaa', '16. What', '23. That', 'No nums'];
const quesCleanUp = q => q.replace(/^\d+\./,'').trim();
questions.forEach(q => console.log(quesCleanUp(q)));
Expected output:
aaa
What
That
No nums

JS / JSX Script to generate unique PNGs from all permutations across all Photoshop Layer Groups and their Photoshop Layers

I'm looking into getting into generative art. My idea is to have Photoshop (CS5) generate a unique PNG for all permutations that exist while the script iterates through every LAYER across each LAYER GROUP (layerSets).
As an example, it would be similar to a character generator where:
PARENT layerSets consist of parts or locations across the face/body (A,B)
CHILD layers consist of accessories/styles (1,2,3)
Such that all generated PNG permutations would be: A1B1,A2B1,A3B1;A2B1,A2B2,A2B3;A3B1,A3B2,A3B3 only. (A1A2, A2A3, A1A3; B1B2, B2B3, B1B3 are not necessary; Standalone A1,A2,A3,B1,B2,B3 are not necessary).
I've found some code from #Mr.Online that generates random, and potentially redundant combinations from user-inputted quantity. His script requires that all layers be hidden by the user prior to running.
Thanks so much. Hopefully this'll help:
function Visible() {
var Grps = app.activeDocument.layerSets; // loops through all groups
for(var i = 0; i < Grps.length; i++){
var tmp = app.activeDocument.layerSets[i].layers.length;
app.activeDocument.layerSets[i].visible=true;
var groupChildArr = app.activeDocument.layerSets[i].layers;
var randLays = Math.floor(Math.random() * tmp);
groupChildArr[randLays].visible = true;
Save();
}
Revert();
}
function Save() {
var outFolder = app.activeDocument; // psd name
var outPath = outFolder.path;
var fName = "PNG"; // define folder name
var f = new Folder(outPath + "/" + fName);
if ( ! f.exists ) {
f.create()
}
var saveFile = new File(outPath + "/" + fName +"/" + "Pattern_" + num + ".png");
pngSaveOptions = new PNGSaveOptions();
pngSaveOptions.interlaced = false;
app.activeDocument.saveAs(saveFile, pngSaveOptions, true, Extension.LOWERCASE);
}
// Original code - revert function does not work
// for some users
//function Revert(){
// var idslct = charIDToTypeID( "slct" );
// var desc300 = new ActionDescriptor();
// var idnull = charIDToTypeID( "null" );
// var ref163 = new ActionReference();
// var idSnpS = charIDToTypeID( "SnpS" );
// ref163.putName( idSnpS, "test.psd" );
// desc300.putReference( idnull, ref163 );
// executeAction( idslct, desc300, DialogModes.NO );
//}
function Revert(){
var idRvrt = charIDToTypeID( "Rvrt" );
executeAction( idRvrt, undefined, DialogModes.NO );
}
var count = prompt("How many patterns you want","");
for (var x=0 ; x<count;x++){
var num = x+1;
Visible();
}
As you say, you need to ignore the random layers. However, if you know the number of layers & groups it's quite straight forward:
show_layers("A", "1");
show_layers("B", "1");
function show_layers(g, n)
{
// g is the name of the group (layerset)
// n is the name of the layer (artlayer)
srcDoc.activeLayer = srcDoc.layerSets.getByName(g).artLayers.getByName(n);
srcDoc.activeLayer.visible = true;
}
So, assuming all layers are switched off, you can get the layers by name and then make them visible.
Switching off all the layers is a bit more involved. You have to loop over all groups and then loop over its sublayers. Working with groups is a bit of a learning curve.
function switch_off_all_layers(bool)
{
var numLayers = app.activeDocument.layers.length;
// want to hide the background as well?
// default: background = visible
if (bool == undefined) bool = false;
if (bool == false)
{
numLayers -=1; // -1 for background
}
for(var i = 0 ; i < numLayers; i++)
{
if (app.activeDocument.layers[i].typename == "LayerSet")
{
app.activeDocument.layers[i].visible = true;
var subDoc = app.activeDocument.layers[i];
var numOfSubLayers = subDoc.layers.length;
for (var j = numOfSubLayers -1; j >= 0; j--)
{
var tempSubLayer = subDoc.layers[j];
tempSubLayer.visible = false;
}
}
}
}
Further to my explanation, if you can't supply the group layers & names then you fill want to loop over all groups and all layers.
var groupLayers = [];
var artLayers = [];
var theLayers = collectAllLayers(app.activeDocument, 0);
alert("Group layers\n" + groupLayers);
alert("Art layers\n" + artLayers);
// function collect all layers
function collectAllLayers (theParent, level)
{
for (var m = theParent.layers.length - 1; m >= 0; m--)
{
var theLayer = theParent.layers[m];
// apply the function to layersets;
if (theLayer.typename == "ArtLayer")
{
if (theLayer.isBackgroundLayer == true)
{
// add background layer (if needed)
// artLayers.push(theLayer.name);
}
else
{
// find the art layers
artLayers.push(theLayer.name);
}
}
else
{
// find the group layers
groupLayers.push(theLayer.name);
collectAllLayers(theLayer, level + 1)
}
}
}

SuiteScript to sum the weight based on ship-out location

I want to be able to calculate the total weights of the items on the sales order based on their ship-out locations and store the values in custom fields. I created a before submitting script on this. The custom field is set to decimal number type and the store value box is checked, but nothing shows up under the field on sales order page.
function calculateWeight(type){
var lines = nlapiGetLineItemCount('item');
var totalWeight2 = 0 ;
var totalWeight1 = 0 ;
if (lines >0){
for(var i = 1; i<= lines ; i++){
var location = nlapiGetLineItemValue('item','location', i);
var quantitycommitted = nlapiGetLineItemValue('item','quantitycommitted', i);
var weight = nlapiGetLineItemValue('item','custcol_individual_weight', i);
//var com_wgt = nlapiGetLineItemValue('item','custcol1',i);
if (location === '2'){
var total2 = weight * quantitycommitted;
totalWeight2 += total2 ;
}
if (location === '1'){
var total1 = weight * quantitycommitted;
totalWeight1 += total1 ;
}
}
nlapiSetFieldValue('custbody5', totalWeight1);
nlapiSetFieldValue('custbody4', totalWeight2);
}
}
I am still learning SuiteScript and I am not exactly sure where went wrong... Can somebody help?
Updated code, only worked for some of the orders...
function calculateWeight(type){
var lines = nlapiGetLineItemCount('item');
//nlapiLogExecution('DEBUG', 'Number of lines', lines);
var totalWeight2 = 0 ;
var totalWeight1 = 0 ;
if (lines >0){
for(var i = 1; i<= lines ; i++){
var location = nlapiGetLineItemValue('item','location', i);
//nlapiLogExecution('DEBUG', 'Locations', location);
var quantitycommitted = parseInt(nlapiGetLineItemValue('item','quantitycommitted', i),10) || 0;
//nlapiLogExecution('DEBUG', 'QtyCom', quantitycommitted);
var weight = parseFloat(nlapiGetLineItemValue('item','custcol_individual_weight', i)) ||0;
//nlapiLogExecution('DEBUG', 'Wgt', weight);
//var com_wgt = nlapiGetLineItemValue('item','custcol1',i);
if (location == '2'){
var total2 = weight * quantitycommitted;
totalWeight2 += total2 ;
nlapiLogExecution('DEBUG', 'Total2', totalWeight2);
}
if (location == '1'){
var total1 = weight * quantitycommitted;
totalWeight1 += total1 ;
nlapiLogExecution('DEBUG', 'Total1', totalWeight1);
}
}
nlapiSetFieldValue('custbody_ms_weight_ppt_page', totalWeight1);
nlapiSetFieldValue('custbody_wi_weight_ppt_page', totalWeight2);
}
}
You need to parse the line values:
var quantitycommitted = parseInt(nlapiGetLineItemValue('item','quantitycommitted', i),10) || 0;
var weight = parseFloat(nlapiGetLineItemValue('item','custcol_individual_weight', i)) ||0;
also in some contexts your location ids will not be strings so that may also be the issue. Relying on == instead of === works.

Reset values Issue

Building a dice game and you get 3 rolls. Once you finish your turn i'm trying to have a "reset" button that will reset the values back to the original spot so the "next person" can play. The values reset as I expected but when I "roll" none of the functions are taking place and i'm pretty new in js so i'm not sure what the problem is.
var playerScore = document.getElementById('firstPlayerScore');
var rollButton = document.getElementById('roll_button');
var dice1 = new dice(1);
var dice2 = new dice(2);
var dice3 = new dice(3);
var dice4 = new dice(4);
var dice5 = new dice(5);
var diceArray = [dice1, dice2, dice3, dice4, dice5];
var cargo = 0;
var numOfRolls = 0;
var cargoButton = document.getElementById('cargo');
var canHaveCargo = false;
function restart(){
dice1 = new dice(1);
dice2 = new dice(2);
dice3 = new dice(3);
dice4 = new dice(4);
dice5 = new dice(5);
diceArray = [dice1, dice2, dice3, dice4, dice5];
cargo = 0;
numOfRolls = 0;
canHaveCargo = false;
addGlow();
updateDiceImageUrl();
document.getElementById("dice1").classList.remove('glowing');
document.getElementById("dice2").classList.remove('glowing');
document.getElementById("dice3").classList.remove('glowing');
document.getElementById("dice4").classList.remove('glowing');
document.getElementById("dice5").classList.remove('glowing');
}
//dice object
function dice(id){
this.id = id;
this.currentRoll = 1;
this.previousRoll = 1;
this.isSelected = false;
this.diceImageUrl = "img/dice/dice1.png";
this.roll = function(){
this.previousRoll = this.currentRoll;
this.currentRoll = getRandomRoll(1, 6);
}
}
//returns an array of all dice that are not currently selected so they can be rolled.
function getRollableDiceList(){
var tempDiceList = [];
for(var i = 0; i < diceArray.length; i++){
if(!diceArray[i].isSelected){
tempDiceList.push(diceArray[i]);
}
}
return tempDiceList;
}
// gets a random number between min and max (including min and max)
function getRandomRoll(min,max){
return Math.floor(Math.random() * (max-min + 1) + min);
}
// calls the roll function on each dice
function rollDice(rollableDiceList){
for(var i = 0; i < rollableDiceList.length; i++){
rollableDiceList[i].roll();
}
}
// updates each dice with the new url for the image that corresponds to what their current roll is
function updateDiceImageUrl(){
for(var i = 0; i < diceArray.length; i++){
var currentDice = diceArray[i];
currentDice.diceImageUrl = "http://boomersplayground.com/img/dice/dice" + currentDice.currentRoll + ".png";
//update div image with img that cooresponds to their current roll
updateDiceDivImage(currentDice);
}
}
//Displays the image that matches the roll on each dice
function updateDiceDivImage(currentDice) {
document.getElementById("dice"+currentDice.id).style.backgroundImage = "url('" + currentDice.diceImageUrl +"')";
}
// returns an array of all
function getNonSelectedDice(){
var tempArray = [];
for(var i = 0; i < diceArray.length; i++){
if(!diceArray[i].isSelected){
tempArray.push(diceArray[i]);
}
tempArray.sort(function(a, b){
return b.currentRoll - a.currentRoll;
});
}
return tempArray;
}
function getSelectedDice(){
var selectedDice = [];
for(var i = 0; i < diceArray.length; i++){
if(diceArray[i].isSelected){
selectedDice.push(diceArray[i]);
}
}
return selectedDice;
}
//boolean variables
var shipExist = false;
var captExist = false;
var crewExist = false;
//checks each dice for ship captain and crew. Auto select the first 6, 5 , 4.
function checkForShipCaptCrew(){
//array of dice that are not marked selected
var nonSelectedDice = getNonSelectedDice();
for(var i = 0; i < nonSelectedDice.length; i++){
//temp variable that represents the current dice in the list
currentDice = nonSelectedDice[i];
if (!shipExist) {
if (currentDice.currentRoll == 6) {
shipExist = true;
currentDice.isSelected = true;
}
}
if (shipExist && !captExist) {
if (currentDice.currentRoll == 5) {
captExist = true;
currentDice.isSelected = true;
}
}
if (shipExist && captExist && !crewExist) {
if (currentDice.currentRoll == 4) {
crewExist = true;
currentDice.isSelected = true;
canHaveCargo = true;
}
}
}
}
function addGlow(){
var selectedDice = getSelectedDice();
for (var i = 0; i < selectedDice.length; i++){
var addGlowDice = selectedDice[i];
var element = document.getElementById('dice' + addGlowDice.id);
element.className = element.className + " glowing";
}
}
function getCargo(){
var cargo = 0;
var moreDice = getNonSelectedDice();
if (canHaveCargo){
for(var i=0; i < moreDice.length; i++){
cargo += moreDice[i].currentRoll;
playerScore.innerHTML = 'You have got ' + cargo + ' in ' + numOfRolls + ' rolls!';
}
} else {
alert("You don't have Ship Captain and the Crew yet!");
}
}
rollButton.addEventListener('click', function(){
//generate rollable dice list
if (numOfRolls < 3) {
var rollableDiceList = getRollableDiceList();
//roll each dice
rollDice(rollableDiceList);
//update dice images
updateDiceImageUrl();
getNonSelectedDice();
// //auto select first 6, 5, 4 (in that order)
checkForShipCaptCrew();
addGlow();
// //adds a red glow to each dice that is selected
numOfRolls++;
}
});
cargoButton.addEventListener('click', getCargo);
var startButton = document.getElementById('restart');
startButton.addEventListener('click', restart);
http://boomer1204.github.io/shipCaptainCrew/
Here is a link to the live game since it's the only way I can describe the problem since I don't know what's not working. If you roll the dice a couple times the dice will get a blue border and be "saved" according to the rules. Now after you hit th restart button that doesn't happen anymore.
Thanks for the help in advance guys
Just add this to your restart()
function restart(){
...
shipExist = false;
capExist = false;
crewExist = false;
...
}
It's hard to replicate without a fiddle, but it seems that you are adding and removing the 'glowing' class using separate processes. Have you tried adding the glowing class the same way you are removing it?
element.classList.add("glowing")
See an example within a fiddle: https://jsfiddle.net/5tstf2f8/

JavaScript - Improve my grid search algorithm

I have made my own "GhettoSearch," which is used to find the closest path between 2 given coordinates over a Grid, AKA a "list of coordinates."
The grid is an array like this:
var grid [ [somedata, [x,y,z], somedata], [somedata, [x,y,z], somedata] ]etc..
My start and stop positions is only coordinates, the Z coordinate is irrelevant at the moment.
I can almost get to the end, but some detoures are made because of my cost function.
Here is how the search looks complete: http://i.imgur.com/2ZjQBrh.png
Here is the code I currently use for the search:
var Main = {
GhettoSearch: function(Start, Stop, Grid){
var Pgreed = 1; //From current position to next nearby nodes
var Tgreed = 0.25; //from current position to target node
var Pcost = 0;
var Tcost = 0;
var open = [];
var closed = [];
var aReturn = [];
for (i = 0; i < Grid.length; i++) {
Worldmap.GetNode("Node_" + Grid[i][0]).style.backgroundColor = "#FFFFFF";
Pcost = Heuristics.Distance.Manhattan(Grid[i][1], Start, Pgreed);
Tcost = Heuristics.Distance.Manhattan(Grid[i][1], Stop, Tgreed);
open.push([i, (Pcost + Tcost)]);
}
do {
var TmpData = [0, Infinity];
var TmpForI = null;
for (i = 0; i < open.length; i++) {
if (open[i][1] < TmpData[1]) {
TmpData[0] = open[i][0];
TmpData[1] = open[i][1];
TmpForI = i;
}
}
closed.push(TmpData);
open.splice(TmpForI, 1);
for (i = 0; i < open.length; i++) {
Start = Grid[TmpData[0]][1]; //is now the start for recently closed node
Pcost = Heuristics.Distance.Manhattan(Grid[open[i][0]][1], Start, Pgreed);
Tcost = Heuristics.Distance.Manhattan(Grid[open[i][0]][1], Stop, Tgreed);
open[i] = [open[i][0], (Pcost + Tcost)];
}
} while (open.length > 0);
var PathID = null;
var TmpDist = Infinity;
for (i = 0; i < closed.length; i++) {
var NodeID = Grid[closed[i][0]][0];
var NodeCoords = Grid[closed[i][0]][1];
var NodeCost = closed[i][1];
aReturn.push([NodeID, NodeCoords, NodeCost]);
//var Dist = Heuristics.Distance.Manhattan(NodeCoords, Stop, 1);
if (NodeCost < TmpDist) {
TmpDist = NodeCost;
PathID = i;//Because you will remove the closest cord elese. OR? will u xD
}
}
aReturn.splice(PathID, closed.length);
return aReturn;
}
};
As you can see on the image, while going upwards it goes back and fills the empty spots besides the straight path up, how can I avoid this?
Yes, I have looked at different search aproaches such as BFS and a star, but I have problems implementing this in my own search function

Categories

Resources