• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

random action selection script

Explorer ,
Feb 26, 2016 Feb 26, 2016

Copy link to clipboard

Copied

Hello,

I have made 10 actions with brush definitions. I need a script for random action execution(instead of executing them on the actions panel) if it is possible. Can someone show me how to do it or post a final example here?

I have very low knowledge for scripting, please be gentle with me.

Thank you for your kindness,

Nick

TOPICS
Actions and scripting

Views

4.0K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Guide , Feb 27, 2016 Feb 27, 2016

This version requires you change the variable to suit your LayerSet name.

#target photoshop;

if(documents.length){

    main();

    }else{

        alert("You need a document open to run this script!");

        }

function main(){

//////////////////////////////////////////////////////////////////////

// Change "Default Actions" to the name of your LayerSet

var ASname = "Default Actions";

/////////////////////////////////////////////////////////////////////

if(!checkActionExists(ASname.toString()))

...

Votes

Translate

Translate
Adobe
Explorer ,
Feb 26, 2016 Feb 26, 2016

Copy link to clipboard

Copied

Please, if someone could answer my question.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Feb 27, 2016 Feb 27, 2016

Copy link to clipboard

Copied

This version requires you change the variable to suit your LayerSet name.

#target photoshop;

if(documents.length){

    main();

    }else{

        alert("You need a document open to run this script!");

        }

function main(){

//////////////////////////////////////////////////////////////////////

// Change "Default Actions" to the name of your LayerSet

var ASname = "Default Actions";

/////////////////////////////////////////////////////////////////////

if(!checkActionExists(ASname.toString())) {

    alert("\"" +ASname+ "\"" + " does not exist!\nPlease check your spelling\nIt is case sensitive!")

    return;

    }

var ActionSets =getActionSets();

for(var a in ActionSets){

    if(ActionSets.toString() == ASname.toString()){

        var Actions = getActions(ActionSets.toString());

        var RA = Actions[Math.floor(Math.random() * Actions.length)];

        try{

        app.doAction(RA.toString(), ASname.toString());

        }catch(e){};

        break;

        }

}

};

function checkActionExists( setName, actionName ){

   var res = false;

   try{

      var ref = new ActionReference();

            if(actionName != undefined){

      ref.putName( charIDToTypeID( 'Actn' ), actionName );

      }

      ref.putName( charIDToTypeID( "ASet" ), setName );

      executeActionGet( ref );

      res = true;

   }catch(e){return false}

   return res;

};

function getActionSets(){

var aSets=[];

var z = 1;

while(true){

var ref = new ActionReference();

ref.putIndex(charIDToTypeID('ASet'), z);

try{

var desc = executeActionGet(ref);

var actName = desc.getString(charIDToTypeID('Nm  '));

aSets.push(actName);

z++;

}catch(e){return aSets;}

    }

};

function getActions(aSet){

var names = [];

var z =1;

while(true){

var ref = new ActionReference();

ref.putIndex(charIDToTypeID('Actn'), z);

ref.putName(charIDToTypeID('ASet'), aSet);

try{

var adesc = executeActionGet(ref);

var actName = adesc.getString(charIDToTypeID('Nm  '));

names.push(actName);

z++;

}catch(e){return names;}

    }

};

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advisor ,
Feb 27, 2016 Feb 27, 2016

Copy link to clipboard

Copied

cTID = function(s) { return app.charIDToTypeID(s); };

function getActions(aset) {
  var i = 1;
  var names = [];

  if (!aset) {
    throw Error.runtimeError(9001, "Action set must be specified");
  }

  while (true) {
    var ref = new ActionReference();
    ref.putIndex(cTID("ASet"), i);
    var desc;
    try {
      desc = executeActionGet(ref);
    } catch (e) {
      names = undefined;
      break;    // all done
    }
    if (desc.hasKey(cTID("Nm  "))) {
      var aname = desc.getString(cTID("Nm  "));
      if (aname == aset) {
        var count = desc.getInteger(cTID("NmbC"));
        for (var j = 1; j <= count; j++) {
          var ref = new ActionReference();
          ref.putIndex(cTID('Actn'), j);
          ref.putIndex(cTID('ASet'), i);
          var adesc = executeActionGet(ref);
          var actName = adesc.getString(cTID('Nm  '));
          names.push(actName);
        }
        break;
      }
    }
    i++;
  }

  return names;
};

function randomElement(ary) {

  return ary[Math.floor(Math.random(ary.length) * ary.length)];

};

function getRandomAction(aset) {

   return randomElement(getActions(aset));

};

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Feb 26, 2016 Feb 26, 2016

Copy link to clipboard

Copied

var actionSet = "myActionSet"; // name of your ActionSet

var actions = ["Action 01","Action 02","Action 03","Action 04","Action 05","Action 06","Action 07","Action 08"]; // names of your actions

var randomAction = actions[Math.floor(Math.random() * actions.length)];

app.doAction(actions[randomAction], actionSet );

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Sep 06, 2018 Sep 06, 2018

Copy link to clipboard

Copied

Hey Tom,

I use your script to load every few action i get an error : see image
please advice

Clip1.png

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Oct 30, 2020 Oct 30, 2020

Copy link to clipboard

Copied

LATEST

Did you Get Solution for this??

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 27, 2016 Feb 27, 2016

Copy link to clipboard

Copied

In case the number/names of the Actions changes in this thread

Re: Photoshop list actions with script

xbytor provided code to get a list of ActionsSets’ and the contains Actions’ names.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Feb 27, 2016 Feb 27, 2016

Copy link to clipboard

Copied

Wow! So many answers by great people here! I will study the complete code of SuperMerlin how it is made.

Thanks a bunch, especially to SuperMerlin!

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Feb 28, 2016 Feb 28, 2016

Copy link to clipboard

Copied

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Feb 29, 2016 Feb 29, 2016

Copy link to clipboard

Copied

Here is the basics of running a random script:

var scriptsFolder = Folder("your path to folder");

var Filelist = scriptsFolder.getFiles("*.jsx");

var RS = Actions[Math.floor(Math.random() * Filelist.length)];

$.evalfile(Filelist[RS]);

There is another method of running an Action that is NOT loaded in Photoshop, details can be found:-

JsDoc Reference - jamActions

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Feb 29, 2016 Feb 29, 2016

Copy link to clipboard

Copied

Thank you SuperMerlin, obviously I did not ask the question the right way. I will try to explain it with more details. For example, I have included three functions (Cut, Copy and Paste) that want to be randomized on each pressing of the button in the panel that I will link it later. I think that this is much clearer of what I need to do.

cTID = function(s) { return app.charIDToTypeID(s); };

sTID = function(s) { return app.stringIDToTypeID(s); };

//

//==================== Cut (selection) ==============

//

function Cut_selection() {

    try {

    if (documents.length == 0) {

        alert('Please open a document.')

        return;

    }

  // Cut

  function step1(enabled, withDialog) {

    if (enabled != undefined && !enabled)

      return;

    var dialogMode = (withDialog ? DialogModes.ALL : DialogModes.NO);

    executeAction(cTID('cut '), undefined, dialogMode);

  };

  step1();      // Cut

  } catch(e) {

    alert(e + ":" + e.line);

};

//

//==================== Copy (selection) ==============

//

function Copy_selection() {

    try {

    if (documents.length == 0) {

        alert('Please open a document.')

        return;

    }

  // Copy

  function step1(enabled, withDialog) {

    if (enabled != undefined && !enabled)

      return;

    var dialogMode = (withDialog ? DialogModes.ALL : DialogModes.NO);

    executeAction(cTID('copy'), undefined, dialogMode);

  };

  step1();      // Copy

  } catch(e) {

    alert(e + ":" + e.line);

};

//

//==================== Paste ==============

//

function Paste() {

    try {

    if (documents.length == 0) {

        alert('Please open a document.')

        return;

    }

  // Paste

  function step1(enabled, withDialog) {

    if (enabled != undefined && !enabled)

      return;

    var dialogMode = (withDialog ? DialogModes.ALL : DialogModes.NO);

    executeAction(cTID('past'), undefined, dialogMode);

  };

  step1();      // Paste

  } catch(e) {

    alert(e + ":" + e.line);

};

//

I found something on StackOverflow like this:

function randomact() {
  
var func = randomFrom(['Cut_selection', 'Copy_selection', 'Paste']);
  window
[func]();
}

or:

function randomact() {
  
var func = randomFrom([Cut_selection, 'Copy_selection, Paste]);
  
(func)();
}

`The only problem is I don't know how to make things in order for everything to function as it should.

Thank you!

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Feb 29, 2016 Feb 29, 2016

Copy link to clipboard

Copied

Ah, that would be :-

var ran = Math.floor(Math.random() * 3);

switch(ran){

    case 0: app.activeDocument.selection.copy(); break;

    case 1: app.activeDocument.selection.cut(); break;

    case 2: app.activeDocument.paste(); break;

    default : return;

}

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Feb 29, 2016 Feb 29, 2016

Copy link to clipboard

Copied

SuperMerlin‌, thank you, but I don' think this is what I need. As I understood, your code is strictly for random copy, cut and paste of a selection. I actually need the concept of random execution of the above mentioned functions (they could be brush or style selection functions or whatever). The first script that you wrote is doing exactly what I need. Now, I need function to randomize those functons execution and how to exactly implement it in my above mentioned code.

Thank you.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Feb 29, 2016 Feb 29, 2016

Copy link to clipboard

Copied

Once you have your functions writen tey can be called via the switch statement..

NumberOfFunctions = 7;//Number of functions in your switch statement.

var ran = Math.floor(Math.random() * NumberOfFunctions);

switch(ran){

    case 0: app.activeDocument.selection.copy(); break;

    case 1: app.activeDocument.selection.cut(); break;

    case 2: app.activeDocument.paste(); break;

    case 3: brushFunction(); break;

    case 4: anotherFunction(); break;

    case 5: yetAnotherFunction(); break;

    case 6: etcetc(); break();

    default : return;

}


					
				
			
			
				
			
			
			
			
			
			
			
		

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Feb 29, 2016 Feb 29, 2016

Copy link to clipboard

Copied

You are great SuperMerlin‌. Thank you for your effort explaining all of my requests! Please excuse my lack of JavaScript knowledge. This is much clear now.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Mar 03, 2016 Mar 03, 2016

Copy link to clipboard

Copied

I have successfully implemented this method of randomizing, but is it possible to randomize the cases with no repeat until each of them are passed in random order on each button press, for example [1,3,2,4],[3,2,4,1] etc. and not [1,1,3,2,2,4,4,1,1,1,3,2]?

Thank you.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Mar 03, 2016 Mar 03, 2016

Copy link to clipboard

Copied

Not that I know of, as then it isn't random.

Maybe someone knows different?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Mar 03, 2016 Mar 03, 2016

Copy link to clipboard

Copied

This code is for shuffling numbers that I have found:

/**
* Shuffles array in place.
* @param {Array} a items The array containing the items.
* @return {Array} a The shuffled array
*/

function shuffle(a) {
  
var j, x, i;
  
for (i = a.length; i; i -= 1) {
  j
= Math.floor(Math.random() * i);
  x
= a[i - 1];
  a
[i - 1] = a[j];
  a
[j] = x;
  
}
}

then use:

var myArray = ['1','2','3','4','5','6','7','8','9'];
shuffle
(myArray);

I have found these examples here:

https://stackoverflow.com/questions/6274339/how-can-i-shuffle-an-array-in-javascript#6274381

But instead of numbers, I want to make functions being shuffled and executed one random function on each button press without repeating that same function on next button press.

I have implemented the codes, but it doesn't work. Where do I get wrong?

P.S. rnd_act_select() is called by a button press.

function rnd_act_select() {

try {

    if (documents.length == 0) {

        alert('Please open a document.')

        return;

    }

// random selection

function shuffle(array) {

  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 = [func_one,func_two,func_three,func_four];

var shuf = shuffle(arr);

switch(shuf) {

    case 0: func_one(); break;

    case 1: func_two(); break;

    case 2: func_three(); break;

    case 3: func_four(); break;

    default : return;

}

// random selection end

    } catch(e) {

        alert(e + ":" + e.line);

    }

};

Thank you

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Mar 03, 2016 Mar 03, 2016

Copy link to clipboard

Copied

It would be something like this.

#target photoshop;

main();

function main(){

//add as many numbers as required.

var numArray = [0,1,2,3];

var Prefs ={};

try{

var desc1 = app.getCustomOptions('randomShuffle');

Prefs = eval(desc1.getString(0));

}catch(e){

Prefs.numbers = shuffle(numArray);

Prefs.count=0;

var desc1 = new ActionDescriptor();

desc1.putString(0, Prefs.toSource());

app.putCustomOptions(  'randomShuffle', desc1, true );

}

if(Prefs.count == numArray.length){

   // $.writeln("end of array count = " + Prefs.count);

    Prefs.count=0;

    Prefs.numbers=shuffle(numArray);

    var desc1 = new ActionDescriptor();

    desc1.putString(0, Prefs.toSource());

    app.putCustomOptions(  'randomShuffle', desc1, true );   

     var ran = Prefs.numbers[Prefs.count];

    Prefs.count++;

    var desc1 = new ActionDescriptor();

    desc1.putString(0, Prefs.toSource());

    app.putCustomOptions(  'randomShuffle', desc1, true );

    }else{

    var ran = Prefs.numbers[Prefs.count];

    Prefs.count++;

    var desc1 = new ActionDescriptor();

    desc1.putString(0, Prefs.toSource());

    app.putCustomOptions(  'randomShuffle', desc1, true );

        }

//$.writeln(ran);

switch(ran) { 

    case 0: func_one(); break; 

    case 1: func_two(); break; 

    case 2: func_three(); break; 

    case 3: func_four(); break; 

    default : return; 

}

//the following line when run will erase the CustomOptions

//app.eraseCustomOptions( 'randomShuffle');

};

function shuffle(array) {

  var currentIndex = array.length, temporaryValue, randomIndex;

  while (0 !== currentIndex) {

    randomIndex = Math.floor(Math.random() * currentIndex);

    currentIndex -= 1;

    temporaryValue = array[currentIndex];

    array[currentIndex] = array[randomIndex];

    array[randomIndex] = temporaryValue;

  }

  return array;

};

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Mar 04, 2016 Mar 04, 2016

Copy link to clipboard

Copied

Yes, this is it. It works a bit strange, rarely repeats same function, but I think it is because of some sluggishness in the script. I think it needs optimization.

Great SuperMerlin! Thank you very much!

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Mar 04, 2016 Mar 04, 2016

Copy link to clipboard

Copied

Something strange has happened, the panel button worked smoothly and now it suddenly stopped responding at all. I changed to previous script with the simple switch randomizing and it works well. I have backup of the script and nothing changed, resigned the zxp and everything is in order except it does not work. Is this in connection with JavaScript or with Photoshop bug?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Mar 04, 2016 Mar 04, 2016

Copy link to clipboard

Copied

What you could try is run this code from ExtendScript Toolkit to remove the saved details.

#target photoshop;

app.eraseCustomOptions( 'randomShuffle');

Then try your panel again?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Mar 04, 2016 Mar 04, 2016

Copy link to clipboard

Copied

It works now, but I am little bit confused why app.eraseCustomOptions( 'randomShuffle'); was commented out instead put active. I guess it can bring some consequences to other extensions(or documents) if using always when the extension loads?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Mar 05, 2016 Mar 05, 2016

Copy link to clipboard

Copied

That line must not be uncommented, if it is the script will not work.

The array is saved in Photoshops preferences also a count is stored, if you run that line all that information is wiped out.

At the moment you can shut Photoshop down an when restarted it will continue where it left off.

If you want it fresh each time Photoshop is loaded change app.putCustomOptions(  'randomShuffle', desc1, true );
to app.putCustomOptions(  'randomShuffle', desc1, false );

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines