Write code smarter and better

Hello Processing Foundation

How would you compromize this code, for example into a for-loop or one simple function?

   if (key == c[n]) {
      n++;
      text1[0] = text1[0].substring(0, n-1) + '-' +  text1[0].substring(n, text1[0].length());
    } 

    if (key == c2[n2]) {
      n2++;
      text1[1] = text1[1].substring(0, n2-1) + '-' +  text1[1].substring(n2, text1[1].length());
    } 

    if (key == c3[n3]) {
      n3++;
      text1[2] = text1[2].substring(0, n3-1) + '-' +  text1[2].substring(n3, text1[2].length());
    } 
  }

To turn those checks into 1 loop the 1D arrays c[], c2[] & c3[] have to become 1 single 2D array c[][].

1 Like

Thank you for the answer :slight_smile:
I will make 1 single 2d array c[][] then, but I need a little help to do this. This is the code I have for my c, c2 and c3 varible:
(The c, c2 and c3 variables explodes a string into chars.)

char[] c, c2, c3;

void draw() {
  //...  
  c = explode(text1[0]); 
  c2 = explode(text1[1]); 
  c3 = explode(text1[2]);

char[] explode(String s_) { 
  return 
    s_.toCharArray();
}
final String[] texts = { "write", "code", "smarter" };
final char[][] letters = new char[texts.length][];

void setup() {  
  for (int i = 0; i < texts.length; letters[i] = explode(texts[i++]));
  for (final char[] chars : letters)  println(str(chars));
  exit();
}

static final char[] explode(final String s) { 
  return s.toCharArray();
}

Thank you very much, I have now done that:)
But then how do you use that code to do this:

   if (key == c[n]) {
      n++;
      text1[0] = text1[0].substring(0, n-1) + '-' +  text1[0].substring(n, text1[0].length());
    } 

    if (key == c2[n2]) {
      n2++;
      text1[1] = text1[1].substring(0, n2-1) + '-' +  text1[1].substring(n2, text1[1].length());
    } 

    if (key == c3[n3]) {
      n3++;
      text1[2] = text1[2].substring(0, n3-1) + '-' +  text1[2].substring(n3, text1[2].length());
    } 
  }

Your last code post above is exactly the same as your 1st code post. :neutral_face:

You haven’t created your 2D array like I had done for letters[][]. :pensive:

I am sorry for poor communication.
I have created the 2D array “letters[][]” but the thing is that I do not know how I can change the thing my code does into your code?
In my code (as you probably can see) I want to replace the first letter of the word with “-”, when the key pressed is equal to the front letter of the string. I want to do this by using 2d char-arrays and not the variables c, c2 and c3 which I did before :slight_smile:

Something like this below: :question:

final String[] words = { "write", "code", "smarter" };

void setup() {
  noLoop();
}

void draw() {
  println(words);
}

void keyTyped() {
  println(key);

  for (int i = 0; i < words.length; ++i) {
    final String word = words[i];
    final int len = word.length() - 1;
    final int idx = min(word.lastIndexOf('-') + 1, len);
    final char ch = word.charAt(idx);

    println(len, idx, ch);

    if (ch == key)  words[i] = word.replaceFirst(str(ch), "-");

    if (words[i].endsWith("-"))  println("Index", i, "got no more letters!");
  }

  redraw();
}

docs.Oracle.com/en/java/javase/11/docs/api/java.base/java/lang/String.html#lastIndexOf(int)
docs.Oracle.com/en/java/javase/11/docs/api/java.base/java/lang/String.html#replaceFirst(java.lang.String,java.lang.String)

exactly :slight_smile:
If I when want the word to randomly change into another word from the string array when you have written all letters in the word, how would you set this up?

You can use method String::endsWith(): :bulb:
docs.Oracle.com/en/java/javase/11/docs/api/java.base/java/lang/String.html#endsWith(java.lang.String)
if (words[i].endsWith("-")) println("Index", i, "got no more letters!");

Thank you very much, this works just as intended :slight_smile:
I just have one question left:
How would you set the for-loop/code up when the string-array (words[]) is 2D (words[][]) instead of 1D?
Lets say this is the 2D string-array:

String[][] words2 = {
  {"write","code","smarter","and","better"},
  {"ok","i","will","do","so"},
  {"thank","you","very","much"},
};

Here I first want to select a random word from the first index of words ({“write”,“code”…) and when you have typed the random selected word correct on your computer keyboard, the word will change to another word from the first index of the string-array. When you have done this 4 times, the words should change to only be taken form the second index of the array ({“ok”,“I”,…). I hope you understand, and have a little time to help me?

What about when you think of a solution and post your attempt here?

Then we can help you with where you stuck.

Otherwise, we would do your work. What you ask here is a project, an entire Sketch, not a question about an isolated data structure.

Anyway

My guess would be you could make a IntList 0,1,2… and then use shuffle() on it (see reference: https://www.processing.org/reference/IntList_shuffle_.html) and use it as indexes.
When you increment the index “indexForIntList” you use for IntList, you don’t have to use random() because the list is shuffled already. (Explanation: this approach is easier than to use random() every time and check whether this number has already been used and if so, use random() again…).

Then you receive the input. Word is guessed: Increase the index “indexForIntList”.

Once “indexForIntList” is >=words2[indexForWords2].length you increase indexForWords2

Here is a quick demo for the pure data structure and IntList

You can of course not use it for your Quiz since it doesn’t have the structure:

  • ask user,
  • receive input,
  • go to next word…

A for-loop and while-loop won’t help your there, maybe states…

String[][] words2 = { // They don't have the same length!
  {"write", "code", "smarter", "and", "better"},  // 5
  {"ok", "i", "will", "do", "so"}, 
  {"thank", "you", "very", "much"},               // 4
};

int indexForWords2=0;  // index #1 in String[][] words2 

// list for index # 2 in String[][] words2 
IntList listOfIndexes = new IntList(); // https://www.processing.org/reference/IntList_shuffle_.html 

void setup() {
  size(200, 200);

  while (indexForWords2 < words2.length) {

    makeListOfIndexes();

    for (int indexForIntList : listOfIndexes) {
      println( words2[indexForWords2][indexForIntList] );
    }//for

    indexForWords2++;
    println("----");

  }//while
}

void makeListOfIndexes() { // list of random numbers 
  listOfIndexes.clear(); 
  for (int i=0; i<words2[indexForWords2].length; i++) {
    listOfIndexes.append(i);
  }
  listOfIndexes.shuffle();
}
//

1 Like

So you wanna organize your words as phrases within a 2D array, right?

@Chrisir had the idea to use an IntList to append() & shuffle() indices for your 2D array.

But I think it’s more practical to use a StringList to append() & shuffle() 1 selected row of the 2D array:

Below is the actions of the loop from my previous sketch w/ 2D String[][] + StringList:

/**
 * Random Word Typing (v1.0.1)
 * GoToLoop (2020/Dec/18)
 * https://Discourse.Processing.org/t/write-code-smarter-and-better/26213/13
 */

static final String[][] PHRASES = {
  { "write", "code", "smarter", "and", "better" }, 
  { "ok", "i", "will", "do", "so" }, 
  { "thank", "you", "very", "much" }
};

static final String CHAR = "-";

final StringList shuffledPhrase = new StringList();

String word = CHAR;
int idx = -1;

void setup() {
  noLoop();
  pickRandomWordWithinPhrase();
}

void draw() {
  println(idx, PHRASES[idx].length - shuffledPhrase.size() - 1, word);
}

void keyTyped() {
  checkTypedKeyMatches1stLetterWithinWord();
  redraw();
}

void checkTypedKeyMatches1stLetterWithinWord() {
  final int idx = min(word.lastIndexOf(CHAR) + 1, word.length() - 1);
  final char ch = word.charAt(idx);
  if (ch == key)  word = word.replaceFirst(str(ch), CHAR);
  if (word.endsWith(CHAR))  pickRandomWordWithinPhrase();
}

void pickRandomWordWithinPhrase() {
  if (shuffledPhrase.size() == 0)  selectNextPhrase();
  word = shuffledPhrase.pop();
}

void selectNextPhrase() {
  idx = (idx + 1) % PHRASES.length;
  shuffledPhrase.clear();
  shuffledPhrase.append(PHRASES[idx]);
  shuffledPhrase.shuffle(this);
  println(shuffledPhrase);
}
2 Likes

Thank you very much @GoToLoop !
I used your code and have know made it work exactly as I want :slight_smile:
The only thing I am having af little trouble with is that i want to put the “word”-string into a string-array (words):

String[] words = {CHAR,CHAR,CHAR};

I then will be able to draw 3 different “word”, and not only one at a time.

it would really help me a lot if someone could help me here…

In my sketch the statement shuffledPhrase.append(PHRASES[idx]); is responsible to add a selected row[] of PHRASES[][] into the StringList shuffledPhrase.

It means that the number of strings added is determined by the length of the selected row[].

If you need to add exactly 3 String words you’re gonna need to call append() 3 times for each chosen 3 strings out of a row[].

Although I’m using a StringList you may choose to switch it to a vanilla 1D array or some other container instead.

B/c we don’t know exactly your final goal our examples are just meant to give you ideas not full solutions.

That’s why you should post a complete attempt rather than telling us your most immediate problem.