0

I have another window open with another program that responds when specific keys are being pressed I will call this program1.

I am now testing it with the program at the end of the message I will call this program2, the program2 code is supposed to press the keys that program 1 responds to with specific cues.

It should press w, s, a, and d in random order. and it should press either up, left, down, or right depending on which side of gx,gy an object with the RGB color (255,106,100) is.

Program2 also streams what is on my screen, so it can see the color. (I know some variables are useless. I was just too lazy to delete them if I found out I didn't use them, you only have to point this out if it is what causes the problem)

The code:

int x=1;
int y=0;

int gxbeta=0;
int gybeta=0;
int gx;
int gy;


int targetx=0;
int targety=0; 
int i;
int h;

int dice=0;
color z=color(76,140,90);

color team= color(255,106,100);


import java.awt.AWTException;
import java.awt.Robot;
import java.awt.event.KeyEvent;

import java.awt.image.BufferedImage;
import java.awt.Rectangle;


Robot robot;

void setup(){
size(1920, 1080);
  //Let's get a Robot...
  try { 
    robot = new Robot();
  } catch (AWTException e) {
    e.printStackTrace();
    println(e.getMessage());
    exit();
  }}


void draw(){
background(0);
  Rectangle r = new Rectangle(0, 0, width, height);
  BufferedImage img1 = robot.createScreenCapture(r);
  PImage img2 = new PImage(img1);
  image(img2, 0, 0);


//Zoek de kleur met de nieuwe get
y++;
if(y==height){ 
y=0;
}
if(y==0){
x=x+1;
}
color colorFromget= get(gxbeta,gybeta);
color colorFromGet = get(x,y);
if(colorFromGet == team){targetx=x; 
targety=y;}
if(z==colorFromget){gx=gxbeta; gy=gybeta;}

//Kijk of hij in range van een kant is en schiet

if ((targetx<gy)&&(targety < (gy + 38)) && (targetx > (gy - 38))){
  robot.keyPress(KeyEvent.VK_LEFT);
delay(10000);
robot.keyRelease(KeyEvent.VK_LEFT);}


//Etc 
ellipse(gx, gy, 25, 25);
//loop een random kant op en laat dan de key los
dice=random(0.3);

if(dice==0){robot.keyPress(KeyEvent.VK_W);
delay(10000);
robot.keyRelease(KeyEvent.VK_W);}

if(dice==0.1){robot.keyPress(KeyEvent.VK_A);
delay(10000);
robot.keyRelease(KeyEvent.VK_A);}

if(dice==0.2){robot.keyPress(KeyEvent.VK_S);
delay(10000);
robot.keyRelease(KeyEvent.VK_S);}

if(dice==0.3){robot.keyPress(KeyEvent.VK_D);
delay(10000);
robot.keyRelease(KeyEvent.VK_D);}

}

1 Answers1

0

You should double check your conditions.

Here's a common source mistakes regarding numeric data types and precision: dice=random(3);

dice is a float, however you're using integer comparisons (e.g. if(dice==0), etc.)

Since random(3) will return fractional values most of the time your integer conditions won't be met. You can use rounding methods (e.g. round(random(3)) / ceil(random(3)) / floor(random(3))) as well as integer casting ((int)random(3)) depending on what makes sense for your program. Bare in mind flooring or casting random(3) to int will have maximum value of 2, hence this condition will not be met: if(dice==3). Adjust your ranges accordingly.

e.g.

dice = round(random(3));

Remember that delay() is a blocking function. Hopefully the calls are intentional and solve you're problem, otherwise I'd advise considering millis() since it won't block the rest of the code.

It's a bit tricker to guarantee this condition:

if ((targetx<gy)&&(targety < (gy + 38)) && (targetx > (gy - 38)))

Initially targetx, targety as well as gx, gy are 0 so targetx(0) will never be > gy-38(-38). Some of these value will be updated, but there's still room for error.

Speaking of updating these values, currently the assumptions is that these colours will match perfectly(if (colorFromGet == red) / if (z==colorFromget)). If you get a feedback loop of screenshots there's a chance each feedback repetition of the screenshot may have colours altered slightly (different saturation, brightness, etc.). It might be worth either avoiding the feedback loop or doing colour comparison with a bit of threshold per colour channel. Here's a rough illustration comparing one colour channel:

if(abs(red(colorFromGet) - red(red)) < redThreshold))...

same for green()/blue(), each with a threshold value. alternatively you could compare hue()/saturation()/brightness().

Back home we have a saying that roughly translates to "the lazy work harder" :)

Overall, avoid naming variables like this: colorFromget. colorFromGet is much better. Perhaps you were trying save time/be lazy using two very similar names, but this easily spirals into messy code that is hard to read, understand and debug which means on the long it's more likely you'll accidentally run into more bugs hence spend even more time fixing the code. It will save you tons of time and headaches investing a bit of time to name variables properly and organise the code from the start and maintaining at such.

George Profenza
  • 50,687
  • 19
  • 144
  • 218
  • if im not wrong, `color colorFromGet = get(x,y); if(colorFromGet == red){targetx=x; targety=y;}` should assign targetx, targety the location where the colour has been spotted – Kaj van Veen Jun 27 '21 at 19:44
  • and i dont really understand what `if(abs(red(colorFromGet) - red(red)) < redThreshold))...` is supposed to do. im pretty new to programming and have no idea what this means (exept the values i made myself ofcourse) – Kaj van Veen Jun 27 '21 at 19:46
  • Yes, as I mentioned above, targetx and y *should* be set, but only if that condition passed. You need to thoroughly test that. I cannot recreate your environment. A `color` hold alpha, red, green, blue data in one integer. `red(colorFromGet)` will retrieve the amount of red in that colour. Do the same for the owner colour your comparing too and you can compare the amount of red in reach colour. `abs()` returns the absolute difference. Because the difference between reds can be positive or negative and we only career how different overall. Abs simply makes negative numbers positive – George Profenza Jun 27 '21 at 21:20
  • i have changed red to team and turned the max for the random to 0.3 and its still not working – Kaj van Veen Jun 28 '21 at 19:19
  • You might have made these changes on your machine alone: currently I don't see the changes you mention above in the snippet you posted with your question. (You could post one and mention it's an updated version). Regarding `max()`, I never mentioned it. min()/max() for example still return a float. I've mentioned functions that take in a float as an argument and return an integer. Try the alternatives I've mentioned above (floor/round/ceil or `(int)random(3)`: I've tested and on my machine that worked as expected. – George Profenza Jun 29 '21 at 00:27
  • with max i meant the number after it. setting that to 0.3 is the only thing i could come up with because if i turn dice into an int, causes the program to say cannot convert from float to int – Kaj van Veen Jun 29 '21 at 12:49
  • Maybe you meant `random(0, 3)` instead of `random(0.3)` ? Look at [`random()` reference](https://processing.org/reference/random_.html): in particular notice "**Returns** float". This means you'll always get a float back from random. That's why multiple times I've mentioned converting into an int. Have you tried `dice=round(random(3));` ? Use Ctrl+T / CMD +T to easily format you code. Break your problem down into simpler ones (e.g. getting that dice random to work, getting the color comparison to work, getting conditions to work) in isolation. After each sketch solving one problem works... – George Profenza Jun 29 '21 at 18:37
  • ...bring them together into a new main sketch, but add one functionality at a time, testing after each addition to ensure no accidental bugs were introduced when merging code. – George Profenza Jun 29 '21 at 18:38