# AI Flappy Bird Processing Java

the problem is i use a table to get my walls into position. I find it easier in the long run just change the map and the table does the rest. So I should times the inputs by height & width right? How would I normalize the dist?

many ways how to normalize.
you can just invert it,
`inputs[i] = 1/distance;`
or something else

no problem, as long as you keep track where the walls in the program. you are good to go. heres the part where the player sees ( asteroid game by codebullet, again)

``````//looks in 32 directions to find asteroids
void look() {
vision = new float[32];
//look left
PVector direction;
for (int i = 0; i< vision.length; i++) {
direction = PVector.fromAngle(rotation + i*(PI/16));

direction.mult(10);

vision[i] = lookInDirection(direction);
}
// can shot?
if (canShoot && vision[0] !=0) {
vision[31] = 1;
} else {
vision[31] =0;
}
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------

float lookInDirection(PVector direction) {
//set up a temp array to hold the values that are going to be passed to the main vision array

PVector position = new PVector(pos.x, pos.y);//the position where we are currently looking for asteroids
float distance = 0;
//move once in the desired direction before starting
distance +=1;

//look in the direction until you reach a asteroid
while (distance< 60) {//!(position.x < 400 || position.y < 0 || position.x >= 800 || position.y >= 400)) {

for (Asteroid a : asteroids) {
if (a.lookForHit(position) ) {
// found an asteroid
return  1/distance;
}
}

//look further in the direction

//loop it
if (position.y < -50) {
position.y += height + 100;
} else
if (position.y > height + 50) {
position.y -= height -100;
}
if (position.x< -50) {
position.x += width +100;
} else  if (position.x > width + 50) {
position.x -= width +100;
}

distance +=1;
}
return 0; // if you got no asteroid
}
``````

I don’t understand it. I normalized the inputs.

i made it easier to see.
run this code to see the visualisation of how the player sees

``````ArrayList<Ball> balls = new ArrayList<Ball>();
Player p ;
void setup() {
noStroke();
fullScreen();
for (int i = 0; i < 10; i++) {
}
p = new Player();
rectMode(CENTER);
}

void draw() {
background(0);
for (Ball b : balls) {
b.show();
b.move();
}
for (int i=0; i < 10; i++) {
text("Blind Area", 10, i * 100);
text("Blind Area", width-60, i * 100);
}
p.look();
p.show();
}

class Ball {
PVector pos, vel;
Ball(float x, float y) {
pos = new PVector(x, y);
vel = PVector.random2D();
}

void show() {
fill(255, 100, 90);
noStroke();
ellipse(pos.x, pos.y, 100, 100);
}

void move(){
loopy();
}

// this function is determine if any given location is in the ball
// if it is a block, use rectangle collision detection instead of circle collision detection
boolean lookForHit(PVector loc) {
// circle collision detection
if (dist(pos.x, pos.y, loc.x, loc.y)< 50) {
return true;
}
return false;
}

// this is just wrapping edges
void loopy() {
// Wrap Edges
if (pos.y < -50) {
pos.y = height + 50;
} else
if (pos.y > height + 50) {
pos.y = -50;
}
if (pos.x< -50) {
pos.x = width +50;
} else  if (pos.x > width + 50) {
pos.x = -50;
}
}
}

class Player {
PVector pos;
Player() {
pos = new PVector(width/2, height/2);
}

void show() {
fill(255, 255, 0);
noStroke();
rect(pos.x, pos.y, 30, 30);
}

void look() {
PVector direction;
for (int i = 0; i< 16; i++) {
// player sees in 16 direction, so we have to divide one full rotation (360 degrees) with 16
// so angle between two nearest directions will be 22.5 degree
direction = PVector.fromAngle(i*(TWO_PI/16));
direction.mult(10);
// get the normalized distance to the ball if found in the current direction
// if got no ball in the current direction, mag will be zero
float mag = lookInDirection(direction);
// inputs[i] = mag; //feed this to the input

// this is how the visualisation
stroke(255);
if (mag > 0) {
direction.mult(1/mag);
fill(255);
text(1/mag, direction.x, direction.y);
stroke(0, 255,0);
}else{
//if no ball in current direction
direction.mult(60);
stroke(255, 0,0);
}

line(pos.x, pos.y, direction.x, direction.y);
}
}

float lookInDirection(PVector direction) {

PVector position = new PVector(pos.x, pos.y);//the position where we are currently looking for the balls
float distance = 0;
//move once in the desired direction before starting
distance +=1;

//look in the direction
while (distance< 60) {
for (Ball a : balls) {
if (a.lookForHit(position) ) {
// found ball
return  1/distance;
}
}

//look further in the direction

// next distance
distance +=1;
}
return 0;
}
}
``````

1 Like

So this gets the PVector of every ball. Then uses dist to see how far it is. So if i’m correct it draws a triangle to find the angle between player and ball and then say if angle is what you can see then um … I got lost. Am I correct of how it works so far? This code is easier to understand ty.

assume we are currently looking for the ball in front the player. start by adding a small step towards to the front of the player to current location that we are gonna check
`position.add(direction);`
`distance +=1;`

then check at that location if theres a ball

``````if (a.lookForHit(position) ) {
// found ball
``````

the function `lookForHit()` in the balll class, just return boolean value, not the distance

if theres a ball, then we ended up with normalized distance that we keep track
`return 1/distance;`
if not, look further in that direction until we found a ball or distance reached 60
if theres no ball along that direction, just return 0

now, we have to check in 16 directions. we have to loop through the checks for each direction

I’m guessing I would then place this in think. Then um … place each direction as an input?

for me, think and look is two different function. no matter at all, just making all the function in the nice looking.
yes, as inputs
this line

.

ty this is the kind of detection I wanted when I started making this.ai. Since mag is only in look would the inputs need to be placed there? ATM I got all my inputs in think().

great!
the think is just all of these

for the asteroid ai, the think is

`````` //---------------------------------------------------------------------------------------------------------------------------------------------------------
//convert the output of the neural network to actions
void think() {
//get the output of the neural network
decision = brain.feedForward(vision);

if (decision[0] > 0.8) {//output 0 is boosting
boosting = true;
} else {
boosting = false;
}
if (decision[1] > 0.8) {//output 1 is turn left
spin = -0.1;
} else {//cant turn right and left at the same time
if (decision[2] > 0.8) {//output 2 is turn right
spin = 0.1;
} else {//if neither then dont turn
spin = 0;
}
}
//shooting
if (decision[3] > 0.8) {//output 3 is shooting
shoot();
}
}
``````

So loop through look before calling think. This is new and fun. Ty for walking me through this.

1 Like

yeah thts right!
great!

Now to try to place this new stuff into my game and see how it works.

this part is exciting. good luck!

TY, i’ll keep you in the loop.

1 Like

Would it be better to center the walls or just leave them at the corners?

it depends the way you checking for collision detection. for me, i prefer corners

oh ok, i thought the look might need something special to work.

1 Like