Skip to content

Commit 0aa1483

Browse files
authored
Added files via upload
1 parent 7f8c8ee commit 0aa1483

8 files changed

Lines changed: 819 additions & 0 deletions

File tree

PoolAI/Ball.pde

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
class Ball {
2+
3+
float radius = 10;
4+
Body body;//the body representing the ball in the box2d world
5+
boolean isWhite = false;
6+
boolean stopped = true; //has the ball stopped or is it still moving
7+
Box2DProcessing world;
8+
boolean sunk = false;//whether the ball is sunk or not
9+
color colour;//colour of the ball
10+
11+
//------------------------------------------------------------------------------------------------------------------------------------------------------------------
12+
//constructor
13+
Ball(float x, float y, Box2DProcessing box2d, color col) {
14+
15+
colour = col;
16+
world = box2d;
17+
Vec2 pos = new Vec2(x, y);
18+
19+
20+
float r = world.scalarPixelsToWorld(radius);//convert the radius to world coordinates
21+
22+
//CREATE BODY DEFINITION
23+
BodyDef df = new BodyDef();
24+
df.type = BodyType.DYNAMIC;
25+
df.position.set(world.coordPixelsToWorld(pos.x, pos.y));
26+
27+
//APPPLY IT TO THE BODY
28+
body = world.createBody(df);
29+
30+
31+
//CREATE SHAPE AS CIRCLE
32+
CircleShape circle = new CircleShape();
33+
circle.setRadius(r);
34+
35+
//CREATE FIXTURE
36+
FixtureDef fd = new FixtureDef();
37+
fd.shape = circle;
38+
fd.density = 0.0000001;//very low density
39+
fd.friction = 0.001;//low friction
40+
fd.restitution = 0.8;//high bounciness
41+
42+
//FIX THE SHAPE TO THE BODY;
43+
body.createFixture(fd);
44+
}
45+
//------------------------------------------------------------------------------------------------------------------------------------------------------------------
46+
void applyFriction() {//called every step to simulate friction between the table and ball
47+
Vec2 vel = body.getLinearVelocity();
48+
vel.mulLocal(0.98);//slow by 2%
49+
if (vel.length() < 4) {//increase friction when slower
50+
vel.mulLocal(0.98);
51+
}
52+
if (vel.length() < 0.1) {//stop the ball if the speed is slow enough because without this the speed will never reach 0
53+
vel.mulLocal(0);
54+
}
55+
}
56+
57+
//------------------------------------------------------------------------------------------------------------------------------------------------------------------
58+
//whether the ball is in a hole or not
59+
boolean isInHole() {
60+
if (sunk) {//if ball is already sunk then problem solved
61+
return true;
62+
}
63+
Vec2 pos = world.getBodyPixelCoord(body);//get the position and if its within 15 of a holes center then it is sunk
64+
for (int i =0; i < 6; i++) {
65+
if (dist(pos.x, pos.y, tables[0].holes[i].pos.x, tables[0].holes[i].pos.y) < 15) {
66+
Vec2 vel = body.getLinearVelocity();
67+
vel.mulLocal(0);//set speed to 0
68+
sunk = true;
69+
world.destroyBody(body);//remove ball from world
70+
return true;
71+
}
72+
}
73+
return false;
74+
}
75+
76+
//------------------------------------------------------------------------------------------------------------------------------------------------------------------
77+
boolean isStopped() {//is the ball stopped
78+
79+
if (body.getLinearVelocity().length() == 0) {
80+
return true;
81+
} else {
82+
return false;
83+
}
84+
}
85+
//------------------------------------------------------------------------------------------------------------------------------------------------------------------
86+
void update() {//update ball (kind of useless but I though I would do more than just apply friction each update)
87+
applyFriction();
88+
}
89+
//------------------------------------------------------------------------------------------------------------------------------------------------------------------
90+
//draw a circle representing the ball
91+
void show() {
92+
if (!sunk) {//if sunk then dont bother showing it
93+
Vec2 pos = world.getBodyPixelCoord(body); //get position
94+
95+
pushMatrix();
96+
translate(pos.x, pos.y);
97+
if (isWhite) {//choose colour
98+
fill(255);
99+
} else {
100+
fill(colour);
101+
}
102+
noStroke();
103+
ellipse(0, 0, 2*radius, 2*radius);//draw ball
104+
popMatrix();
105+
}
106+
}
107+
//------------------------------------------------------------------------------------------------------------------------------------------------------------------
108+
//simulates a shot
109+
void applyForce(Vec2 force) {
110+
Vec2 scaledForce = new Vec2(force.x, force.y);
111+
scaledForce.mulLocal(500000);
112+
body.applyForce(scaledForce, body.getWorldCenter());//apply force on ball
113+
}
114+
115+
//---------------------------------------------------------------------------------------------------------------------------------------------------------------
116+
//creates and returns a clone of this ball object in the parameter world
117+
Ball clone(Box2DProcessing World) {
118+
119+
Vec2 pos = World.getBodyPixelCoord(body);//get pixel coord
120+
Ball clone = new Ball(pos.x, pos.y, World, colour);
121+
122+
clone.isWhite = isWhite;
123+
clone.sunk = sunk;
124+
if (sunk) {//if the ball is sunk then remove the body from the world
125+
World.destroyBody(clone.body);
126+
}
127+
return clone;
128+
}
129+
}

PoolAI/Cushion.pde

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
//an object containing all the cushions on the pool table
2+
class Cushions {
3+
Body[] bodies = new Body[6];//the cushions
4+
Box2DProcessing world;
5+
6+
//------------------------------------------------------------------------------------------------------------------------------------------------------------------
7+
//constructor
8+
Cushions ( Box2DProcessing box2d) {
9+
10+
world = box2d;
11+
12+
//Create left top cushion
13+
createCushion(0, 200, 0, 20, 0, 385, 20, 380, 20, 50, 0);
14+
//Create left bottom cushion
15+
createCushion(0, 600, 0, 415, 0, 780, 20, 750, 20, 420, 1);
16+
//create top
17+
createCushion(200, 0, 20, 0, 50, 20, 350, 20, 380, 0, 2);
18+
//right top
19+
createCushion(200, 0, 400, 20, 380, 50, 380, 380, 400, 385, 3);
20+
//right bottom
21+
createCushion(200, 0, 400, 415, 380, 420, 380, 750, 400, 780, 4);
22+
//bottom
23+
createCushion(200, 0, 20, 800, 380, 800, 350, 780, 50, 780, 5);
24+
}
25+
26+
//------------------------------------------------------------------------------------------------------------------------------------------------------------------
27+
//creates a cushion in the box2d world with input position and dimensions
28+
void createCushion(int posX, int posY, int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4, int bodyNo) {
29+
//CREATE BODY DEFITION
30+
BodyDef bd = new BodyDef();
31+
bd.type = BodyType.STATIC;//STATIC means that the body is fixed
32+
bd.position.set(world.coordPixelsToWorld(posX, posY));
33+
34+
//CREATE BODY
35+
bodies[bodyNo] = world.createBody(bd);//add body to the array
36+
37+
//CREATE SHAPE
38+
//a polygon with 4 vertices
39+
PolygonShape ps = new PolygonShape();
40+
Vec2[] vertices = new Vec2[4];
41+
vertices[0] = world.vectorPixelsToWorld(new Vec2(x1-posX, y1-posY));
42+
vertices[1] = world.vectorPixelsToWorld(new Vec2(x2-posX, y2-posY));
43+
vertices[2] = world.vectorPixelsToWorld(new Vec2(x3-posX, y3-posY));
44+
vertices[3] = world.vectorPixelsToWorld(new Vec2(x4-posX, y4-posY));
45+
46+
ps.set(vertices, vertices.length);
47+
//CREATE FIXTURE
48+
FixtureDef fd = new FixtureDef();
49+
fd.shape = ps;
50+
fd.density = 1;
51+
fd.friction = 0.0001;
52+
fd.restitution = 0.9;//high restitution or bounciness
53+
54+
//ATTACH FIXTURE TO BODY
55+
bodies[bodyNo].createFixture(fd);
56+
}
57+
//------------------------------------------------------------------------------------------------------------------------------------------------------------------
58+
//draw the cushions as polygons
59+
void show() {
60+
61+
fill(40);
62+
//top left cushion
63+
beginShape();
64+
vertex(0, 20);
65+
vertex(20, 50);
66+
vertex(20, 380);
67+
vertex(0, 385);
68+
endShape(CLOSE);
69+
70+
//bottom left
71+
beginShape();
72+
vertex(0, 415);
73+
vertex(20, 420);
74+
vertex(20, 750);
75+
vertex(0, 780);
76+
endShape(CLOSE);
77+
78+
//upper cushion
79+
beginShape();
80+
vertex(20, 0);
81+
vertex(380, 0);
82+
vertex(350, 20);
83+
vertex(50, 20);
84+
endShape(CLOSE);
85+
86+
//top right
87+
beginShape();
88+
vertex(400, 20);
89+
vertex(380, 50);
90+
vertex(380, 380);
91+
vertex(400, 385);
92+
endShape(CLOSE);
93+
94+
//bottom right
95+
beginShape();
96+
vertex(400, 415);
97+
vertex(380, 420);
98+
vertex(380, 750);
99+
vertex(400, 780);
100+
endShape(CLOSE);
101+
102+
//bottom
103+
beginShape();
104+
vertex(20, 800);
105+
vertex(380, 800);
106+
vertex(350, 780);
107+
vertex(50, 780);
108+
endShape(CLOSE);
109+
}
110+
}

PoolAI/Genotype.pde

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
class Genotype { //the encoded form of each players behaviour
2+
Vec2[] shots;//each player can be represented by a vector array
3+
//using Vec2s because thats what box2d uses
4+
5+
//-----------------------------------------------------------------------------------------------------------------------------
6+
//constructor
7+
Genotype() {
8+
shots = new Vec2[1];//only starts with a single shot
9+
randomize();//set all the shots as random vectors
10+
}
11+
//------------------------------------------------------------------------------------------------------------------------------
12+
//Mutation function for genetic algorithm
13+
void mutate() {
14+
int i = shots.length -1; //only mutate the very last shot
15+
float mutationRate =0.8; //mutate 80% of the players
16+
17+
float rand = random(1);
18+
if (rand<mutationRate) {//80% of the time mutate the player
19+
if (rand<mutationRate/5) {
20+
//20% of the time change the vector to a random vector
21+
shots[i] = new Vec2(random(-1, 1), random(-1, 1));
22+
} else {
23+
//80% of the time rotate the vector a small amount
24+
PVector temp = new PVector(shots[i].x, shots[i].y);//convert to PVector because i don't know how to do this with Vec2s
25+
temp.rotate(randomGaussian()/30);//rotate it
26+
shots[i] = new Vec2(temp.x, temp.y);//convert it back
27+
}
28+
}
29+
}
30+
//------------------------------------------------------------------------------------------------------------------------------
31+
//randomizes all vectors in shots
32+
void randomize() {
33+
for (int i = 0; i < shots.length; i++) {
34+
shots[i] = new Vec2(random(-1, 1), random(-1, 1));
35+
}
36+
}
37+
//------------------------------------------------------------------------------------------------------------------------------
38+
//returns a clone
39+
Genotype clone() {
40+
Genotype clone = new Genotype();
41+
clone.shots = shots.clone();
42+
return clone;
43+
}
44+
//------------------------------------------------------------------------------------------------------------------------------
45+
//increases the number of shots by 1
46+
void increaseShotLength() {
47+
Vec2[] newShots = new Vec2[shots.length +1];//create a new array which is one bigger than the current shots array
48+
for (int i = 0; i < shots.length; i++) {//for each element of shots copy it into newShots
49+
newShots[i] = new Vec2(shots[i].x, shots[i].y);
50+
}
51+
52+
newShots[shots.length] = new Vec2(random(-1, 1), random(-1, 1));//randomise the last Vec2
53+
shots = newShots.clone();//set shots as newShots
54+
}
55+
}

PoolAI/Hole.pde

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
class Hole {
2+
Vec2 pos;
3+
float radius = 30;
4+
5+
//------------------------------------------------------------------------------------------------------------------------------------------------------------------
6+
//constructor
7+
Hole(int x, int y) {
8+
pos = new Vec2(x, y);
9+
}
10+
//------------------------------------------------------------------------------------------------------------------------------------------------------------------
11+
//draw a black circle representing the hole
12+
void show() {
13+
fill(0);
14+
stroke(0);
15+
ellipse(pos.x, pos.y, radius, radius);
16+
}
17+
}

0 commit comments

Comments
 (0)