Replace first character of string

Hello Processing Foundation

I have this coding question, which I really hope someone will help me to solve:

This is my code so far:

String[] words = {"hello", "how", "helicopter", "who", "which", "that", "okay"}; //just some random words for showing purpose.
String CHAR = "-";

void setup() {
  size (300, 300);
}

void draw() {
  background(180);
  textSize(30);
  text(words[0], 10, 30);
  text(words[1], 10, 70);
  text(words[2], 10, 110);
  text(words[3], 10, 150);
  text(words[4], 10, 190);
  text(words[5], 10, 230);
}

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

void replaceLetter() {
  for (int i = 0; i < words.length; i++) {
    int idx = min(words[i].lastIndexOf(CHAR) + 1, words[i].length() - 1);
    char ch = words[i].charAt(idx); 

    if (ch == key) {
      words[i] = words[i].replaceFirst(str(ch), CHAR);
    }
  }
}

The problem I have with this code is that you can replace chars in more than one word at a time. For example if you type the key “w” on your keyboard it replaces “w” with “-” from all words which starts which “w” (“which” and “who”). Here I want the program to only replace chars from one word at a time. You therefore would need to type the whole word before you can begin typing the other words.
I really hope someone will help me with this :slight_smile:

Vestergaard

This is your problem

Get rid of this and make i a global variable

Increment i only when the word has been guessed

Thank you very much @Chrisir. I have now done that.

String[] words = {"hello", "how", "helicopter", "who", "which", "that", "okay"}; //just some random words for showing purpose.
String CHAR = "-";
int i = 0;

void setup() {
  size (300, 300);
}

void draw() {
  background(180);
  textSize(30);
  text(words[0], 10, 30);
  text(words[1], 10, 70);
  text(words[2], 10, 110);
  text(words[3], 10, 150);
  text(words[4], 10, 190);
  text(words[5], 10, 230);
}

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

void replaceLetter() {
  int idx = min(words[i].lastIndexOf(CHAR) + 1, words[i].length() - 1);
  char ch = words[i].charAt(idx); 

  if (ch == key) {
    words[i] = words[i].replaceFirst(str(ch), CHAR);
  }
  if (words[i].endsWith(CHAR)){
    i++;
  }
}

But in this code you cannot decide which word you want to type, since you have to write the words from the top and down.
Is there a way to fix this, so you can write the words in an order which the user decides?

You can write this with a for loop i
text(words[i], 10, 30 + (40*i));

You could make a small cursor (like “|”) and have this after a word in a line (behind word 0, behind word 1 etc.). With cursor UP or DOWN, the cursor could go up or down (behind a word) or also mouse.

Thank you very much @Chrisir but I am not sure I completely understand this.
Can you maybe give an example in order for me to understand what to do? :slight_smile:

like here:

hello ________
how |____
helicopter __________________

I am slightly new to processing so I am sorry for not understanding it correctly.

I do not understand how the cursor can make the user decide which words the user wants to type?

It would be hat you have an int variable

before setup()
int indexForWords = 0;

and when crs up say indexForWords -- and down say indexForWords ++

use indexForWords as index for words

This makes sense and I have now made it work :slight_smile:

Is there then a way to turn words[i] red if I stille uses this format:

  text(words[0], 10, 30);
  text(words[1], 10, 70);
  text(words[2], 10, 110);
...

say fill(255,0,0); before text




String[] words = {
  "hello", "how", "helicopter", "who", "which", "that", "okay"
}; //just some random words for showing purpose.
String CHAR = "-";
int i = 0;

int indexForWords = 0;

void setup() {
  size (1200, 400);
}

void draw() {
  background(180);
  textSize(30);

  fill(255, 0, 0); 
  text(words[0], 10, 30);
  text(words[1], 10, 70);
  text(words[2], 10, 110);
  text(words[3], 10, 150);
  text(words[4], 10, 190);
  text(words[5], 10, 230);
  text(words[6], 10, 230+40);

  for (int i=0; i<words.length; i++) {
    //text("________", 180, 30 + i*40);
    if (i==indexForWords)
      text("  <--- YOUR WORD (use cursor UP / DOWN to change)", 180, 30 + indexForWords*40);
  }
}

// ----------------------------------------------------------------------------------------------

void keyPressed() {
  if (keyCode==UP)
  {
    if (indexForWords > 0) 
      indexForWords -- ;
  } else if (keyCode==DOWN)
  {
    if (indexForWords < words.length-1)
      indexForWords ++;
  }
}

void keyTyped() {
  replaceLetter(); 
  //redraw();
}

void replaceLetter() {

  if (indexForWords >= words.length-1)
    indexForWords = words.length-1;

  int idx = min(words[indexForWords].lastIndexOf(CHAR) + 1, words[indexForWords].length() - 1);
  char ch = words[indexForWords].charAt(idx); 

  if (ch == key) {
    words[indexForWords] = words[indexForWords].replaceFirst(str(ch), CHAR);
  }
  if (words[indexForWords].endsWith(CHAR)) {
    indexForWords++;
  }

  if (indexForWords >= words.length-1)
    indexForWords = words.length-1;
}

Thank you very much.
I do not know if this is to much to ask for but I will try.
I am trying to program this game called ztype: https://zty.pe
I have (with your help @Chrisir ) figured out how to type the words in my program. The next thing I need to program is to make the words[] fall at a random speed. Any suggestions on how to do this properly?

I suggest to display just one word at a time.

So you have one number indexFalling and one words[indexFalling] and an x pos and y pos.

text(words[indexFalling] , x, y);

Move

say x += xadd; and y+=speed.

Declaration

before setup() :

float xadd= random (0.6, 3.6); 
float speed = 3;

Reflect

Word must reflect at left and right screen border (like a ball in pong: if(x >= width-33) xadd = -abs(xadd); and if(x <= 33) xadd = abs(xadd); )

word is finished

when word is finished typing or left the screen (y >= width) :

  • you increase indexFalling and reset x=width/2; and y = -33;

Thank you, I think I would know how to do this, but is there really not a way to make multiple words fall down from the top on the screen where the user decides which word to type, like the game ztype?

there is

just use an array for x and y and xadd and handle them in a for-loop

To remove the first letter:

String removeFirst(String txt) {
   String newTxt = "";
   for(int i = 1; i < txt.length; i++) newTxt += txt.charAt(i);
   return(newTxt);
}

I made a simple, but extremely buggy ztype prototype:
There are some unfinished features so yeah : P

ArrayList<String> words = new ArrayList<String>();
ArrayList<word> obj = new ArrayList<word>();
int selected = -1, cx=300, cy=500;
char acceptable[] = ("aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ").toCharArray();
boolean used[] = new boolean[acceptable.length];
void setup() {
  size(600, 600);
  addWord("a,e,g,h,i,j,k,l,m,new,brand,finnish,stop,space,ship,cow,dog,chair");
  for (int i = 0; i < 10; i++) createWord();
}
void draw() {
  background(0);
  for (int i = 0; i < obj.size(); i++) {
    obj.get(i).move();
    obj.get(i).display();
    if (obj.get(i).txt.length() == 0) {
      obj.remove(i);
      selected = -1;
      for (int j = 0; j < obj.size(); j++) {
        obj.get(j).id = j;
      }
    }
  }
}
void addWord(String words_) {
  String w[] = split(words_, ",");
  for (int i = 0; i < w.length; i++) words.add(w[i]);
}
class word {
  int id;
  float x, y, dir, speed;
  String word, txt;
  word(int id_, float x_, float y_, float dir_, float speed_, String word_) {
    id = id_;
    x = x_;
    y = y_;
    dir = dir_;
    speed = speed_;
    word = word_;
    txt = word;
    for (int i = 0; i < acceptable.length; i++) {
      if (word.charAt(0) == acceptable[i]) {
        used[i] = true;
      }
    }
  }
  void destroy() {
    String newTxt = "";
    for (int i = 1; i < txt.length(); i++) newTxt += txt.charAt(i);
    txt = newTxt;
    pushStyle();
    strokeWeight(5);
    stroke(255, 0, 0);
    line(x, y, cx, cy);
    popStyle();
    for (int i = 0; i < acceptable.length; i++) {
      if (word.charAt(0) == acceptable[i]) {
        used[i] = true;
      }
    }
  }
  void display() {
    fill( ((selected == id)? color(255, 255, 0) : color(255) ) );
    text(txt, x, y);
  }
  void move() {
    x += cos(dir)*speed;
    y += sin(dir)*speed;
  }
}
void keyPressed() {
  for (int i = 0; i < acceptable.length; i++) if (key == acceptable[i]) {
    if (selected == -1) {
      for (int j = 0; j < obj.size(); j++) {
        if (key == obj.get(j).txt.charAt(0)) {
          selected = obj.get(j).id;
        }
      }
      if (key == obj.get(selected).txt.charAt(0)) {
        obj.get(selected).destroy();
      }
    } else {
      if (key == obj.get(selected).txt.charAt(0)) {
        obj.get(selected).destroy();
      }
    }
    break;
  }
}
void createWord() {
  String nextWord = words.get((int)random(words.size()));
  for (int i = 0; i < acceptable.length; i++) {
    if (nextWord.charAt(0) == acceptable[i]) {
      if (!used[i]) {
        nextWord = words.get((int)random(words.size()));
        obj.add(new word(obj.size(), random(width), random(-100, 0), PI/2, 1, nextWord));
        break;
      } else {
        createWord();
      }
    }
  }
}

Thank you very much. If I want to replace the written letter with “-” instead of just being removed where do I do this in your code?

just do:

String newString = "-" + removeFirst("random message");

it will output: -andom message

String removeFirst(String txt) {
   String newTxt = "";
   for(int i = 1; i < txt.length(); i++) newTxt += txt.charAt(i);
   return("-"+newTxt);
}

but it is a one time thing. If you redo it again it will return the same result (-andom will remove the first letter, aka ‘-’ and add it again). To change it, use this code
(showing it)

Code
void setup() {
  String tryTxt = "random", newTxt = tryTxt;
  for (int i = 0; i < tryTxt.length(); i++) {
    newTxt = removeFirst(newTxt);
    println(newTxt);
  }
}

String removeFirst(String txt) {
  String newTxt = "";
  for (int i = 1; i < txt.length(); i++) newTxt += txt.charAt(i);
  return("-"+newTxt);
}

image

Can you explain to me what specifically happens in keyPressed() line by line?
Because I know what the keyPressed() function do/performs but I cannot figure out the structure of the keyPressed() code. :slight_smile:

void keyPressed() {
  for (int i = 0; i < acceptable.length; i++) if (key == acceptable[i]) {
  //here (the line above)  it checks if the key is acceptable 
  //(if you use things like '/' '\', ':',';',... it will ignore them.
    if (selected == -1) { //if no word is selected, it selects a new word to target
      for (int j = 0; j < obj.size(); j++) { //goes through all of the obj-s to check if any starts with the letter you 
     //pressed
        if (key == obj.get(j).txt.charAt(0)) {
          selected = obj.get(j).id;
        }
      }
      if (key == obj.get(selected).txt.charAt(0)) { //"destroys" the first letter, so you don't need to press twice
     //altho I guess you could just remove it & remove  the } else {
        obj.get(selected).destroy();
      }
    } else { //destroying the  next letter
      if (key == obj.get(selected).txt.charAt(0)) {
        obj.get(selected).destroy();
      }
    }
    //breaks the for loop, so it runs faster
    break;
  }
}