Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Jean Descamps
projet_IA04
Commits
7ee4792f
Commit
7ee4792f
authored
Dec 26, 2021
by
Alexandre Constantin
Browse files
Predator V1
parent
bf9d8743
Changes
9
Hide whitespace changes
Inline
Side-by-side
Boid/agent/predator/predator.go
0 → 100644
View file @
7ee4792f
package
predator
import
(
"math"
"math/rand"
boid
"gitlab.utc.fr/projet_ia04/Boid/agent/boid"
wall
"gitlab.utc.fr/projet_ia04/Boid/agent/wall"
constant
"gitlab.utc.fr/projet_ia04/Boid/utils/constant"
vector
"gitlab.utc.fr/projet_ia04/Boid/utils/vector"
)
type
Vector2D
=
vector
.
Vector2D
type
Predator
struct
{
ImageWidth
int
ImageHeight
int
Position
Vector2D
Velocity
Vector2D
Acceleration
Vector2D
Density
int
Angle
int
Dist
int
V1
Vector2D
V2
Vector2D
R
bool
}
//Permet de faire une rotation de la matrice v d'un ang (en degré)
func
Rotate
(
v
Vector2D
,
ang
int
)
Vector2D
{
aR
:=
AngleToRadians
(
ang
)
oldX
:=
v
.
X
oldY
:=
v
.
Y
v
.
X
=
oldX
*
math
.
Cos
(
aR
)
-
oldY
*
math
.
Sin
(
aR
)
v
.
Y
=
oldX
*
math
.
Sin
(
aR
)
+
oldY
*
math
.
Cos
(
aR
)
return
v
}
func
Sign
(
p1
Vector2D
,
p2
Vector2D
,
p3
Vector2D
)
float64
{
return
(
p1
.
X
-
p3
.
X
)
*
(
p2
.
Y
-
p3
.
Y
)
-
(
p2
.
X
-
p3
.
X
)
*
(
p1
.
Y
-
p3
.
Y
)
}
//Check si un point est un triangle
func
PointInTriangle
(
pt
Vector2D
,
v1
Vector2D
,
v2
Vector2D
,
v3
Vector2D
)
bool
{
d1
:=
Sign
(
pt
,
v1
,
v2
)
d2
:=
Sign
(
pt
,
v2
,
v3
)
d3
:=
Sign
(
pt
,
v3
,
v1
)
has_neg
:=
(
d1
<
0
)
||
(
d2
<
0
)
||
(
d3
<
0
)
has_pos
:=
(
d1
>
0
)
||
(
d2
>
0
)
||
(
d3
>
0
)
return
!
(
has_neg
&&
has_pos
)
}
// Convertie un angle en radian
func
AngleToRadians
(
angle
int
)
float64
{
return
(
math
.
Pi
/
180
)
*
float64
(
angle
)
}
//Permet de créer le triangle correspondant au champ de vision
func
(
preda
*
Predator
)
Vision
()
[]
Vector2D
{
x
:=
preda
.
Position
.
X
y
:=
preda
.
Position
.
Y
vx
:=
preda
.
Velocity
.
X
vy
:=
preda
.
Velocity
.
Y
//calculate angle between vect Velocity and x-axis
angR
:=
math
.
Atan2
(
vy
,
vx
)
angV
:=
int
(
angR
*
180
/
math
.
Pi
)
// Calulate upper and lower angle
angU
:=
angV
-
preda
.
Angle
angL
:=
angV
+
preda
.
Angle
// Calculate new point
l1x
:=
x
+
float64
(
preda
.
Dist
)
*
math
.
Cos
(
AngleToRadians
(
angU
))
l1y
:=
y
+
float64
(
preda
.
Dist
)
*
math
.
Sin
(
AngleToRadians
(
angU
))
l2x
:=
x
+
float64
(
preda
.
Dist
)
*
math
.
Cos
(
AngleToRadians
(
angL
))
l2y
:=
y
+
float64
(
preda
.
Dist
)
*
math
.
Sin
(
AngleToRadians
(
angL
))
p1
:=
Vector2D
{
X
:
l1x
,
Y
:
l1y
}
p2
:=
Vector2D
{
X
:
l2x
,
Y
:
l2y
}
mapP
:=
make
([]
Vector2D
,
2
)
mapP
[
0
]
=
p1
mapP
[
1
]
=
p2
return
mapP
}
func
(
preda
*
Predator
)
ApplyRules
(
restOfFlock
[]
*
boid
.
Boid
)
{
//preda.V1 = vPoint[0]
//preda.V2 = vPoint[1]
var
dens
int
var
newP
Predator
var
new
bool
var
densMax
=
0
var
densMax2
=
0
var
proie1
*
boid
.
Boid
var
proie2
*
boid
.
Boid
var
vPoint2
[]
Vector2D
//Tuer
for
_
,
Boid
:=
range
restOfFlock
{
if
(
preda
.
Position
.
Distance
(
Boid
.
Position
))
<
15
{
Boid
.
Dead
=
true
}
}
//Vision + stratégie d'attaque
vPoint
:=
preda
.
Vision
()
new
=
false
if
(
vPoint
[
0
]
.
X
>
constant
.
ScreenWidth
||
vPoint
[
0
]
.
X
<
0
)
||
(
vPoint
[
0
]
.
Y
>
constant
.
ScreenHeight
||
vPoint
[
0
]
.
Y
<
0
)
||
(
vPoint
[
1
]
.
X
>
constant
.
ScreenWidth
||
vPoint
[
1
]
.
X
<
0
)
||
(
vPoint
[
1
]
.
Y
>
constant
.
ScreenHeight
||
vPoint
[
1
]
.
Y
<
0
)
{
new
=
true
newP
=
*
preda
if
vPoint
[
0
]
.
X
>
constant
.
ScreenWidth
{
newP
.
Position
.
X
=
preda
.
Position
.
X
-
constant
.
ScreenWidth
}
else
if
vPoint
[
0
]
.
X
<
0
{
newP
.
Position
.
X
=
preda
.
Position
.
X
+
constant
.
ScreenWidth
}
if
vPoint
[
0
]
.
Y
>
constant
.
ScreenHeight
{
newP
.
Position
.
Y
=
preda
.
Position
.
Y
-
constant
.
ScreenHeight
}
else
if
vPoint
[
0
]
.
Y
<
0
{
newP
.
Position
.
Y
=
preda
.
Position
.
Y
+
constant
.
ScreenHeight
}
if
vPoint
[
1
]
.
X
>
constant
.
ScreenWidth
{
newP
.
Position
.
X
=
preda
.
Position
.
X
-
constant
.
ScreenWidth
}
else
if
vPoint
[
1
]
.
X
<
0
{
newP
.
Position
.
X
=
preda
.
Position
.
X
+
constant
.
ScreenWidth
}
if
vPoint
[
1
]
.
Y
>
constant
.
ScreenHeight
{
newP
.
Position
.
Y
=
preda
.
Position
.
Y
-
constant
.
ScreenHeight
}
else
if
vPoint
[
1
]
.
Y
<
0
{
newP
.
Position
.
Y
=
preda
.
Position
.
Y
+
constant
.
ScreenHeight
}
}
preda
.
V1
=
vPoint
[
0
]
preda
.
V2
=
vPoint
[
1
]
if
new
{
vPoint2
=
newP
.
Vision
()
if
(
vPoint
[
1
]
.
X
>
constant
.
ScreenWidth
||
vPoint
[
1
]
.
X
<
0
)
||
(
vPoint
[
1
]
.
Y
>
constant
.
ScreenHeight
||
vPoint
[
1
]
.
Y
<
0
)
{
preda
.
V2
=
vPoint2
[
1
]
}
if
(
vPoint
[
0
]
.
X
>
constant
.
ScreenWidth
||
vPoint
[
0
]
.
X
<
0
)
||
(
vPoint
[
0
]
.
Y
>
constant
.
ScreenHeight
||
vPoint
[
0
]
.
Y
<
0
)
{
preda
.
V1
=
vPoint2
[
0
]
}
}
for
_
,
Boid
:=
range
restOfFlock
{
if
!
Boid
.
Dead
{
dens
=
0
b
:=
PointInTriangle
(
Boid
.
Position
,
preda
.
Position
,
vPoint
[
0
],
vPoint
[
1
])
b2
:=
false
if
new
{
b2
=
PointInTriangle
(
Boid
.
Position
,
newP
.
Position
,
vPoint2
[
0
],
vPoint2
[
1
])
}
if
b
{
//print(1)
for
_
,
other
:=
range
restOfFlock
{
if
(
Boid
.
Position
.
Distance
(
other
.
Position
))
<
30
&&
!
other
.
Dead
{
dens
++
}
}
}
if
dens
>
densMax
{
densMax
=
dens
proie1
=
Boid
}
dens
=
0
if
b2
{
//print(1)
for
_
,
other
:=
range
restOfFlock
{
if
(
Boid
.
Position
.
Distance
(
other
.
Position
))
<
30
&&
!
other
.
Dead
{
dens
++
}
}
}
if
dens
>
densMax2
{
densMax2
=
dens
proie2
=
Boid
}
}
}
if
densMax
>=
densMax2
&&
densMax
>
preda
.
Density
{
Vit
:=
vector
.
Vector2D
{
X
:
proie1
.
Position
.
X
-
preda
.
Position
.
X
,
Y
:
proie1
.
Position
.
Y
-
preda
.
Position
.
Y
}
Vit
.
Normalize
()
Vit
.
X
=
Vit
.
X
*
10
Vit
.
Y
=
Vit
.
Y
*
10
preda
.
Velocity
=
Vit
}
else
if
densMax2
>
preda
.
Density
{
Vit
:=
vector
.
Vector2D
{
X
:
proie2
.
Position
.
X
-
newP
.
Position
.
X
,
Y
:
proie2
.
Position
.
Y
-
newP
.
Position
.
Y
}
Vit
.
Normalize
()
Vit
.
X
=
Vit
.
X
*
10
Vit
.
Y
=
Vit
.
Y
*
10
preda
.
Velocity
=
Vit
}
else
{
vit
:=
preda
.
Velocity
if
vit
.
X
>
1
||
-
vit
.
X
>
1
{
vit
.
X
=
vit
.
X
*
0.98
}
if
vit
.
Y
>
1
||
-
vit
.
Y
>
1
{
vit
.
Y
=
vit
.
Y
*
0.98
}
preda
.
Velocity
=
vector
.
Vector2D
{
X
:
vit
.
X
,
Y
:
vit
.
Y
}
if
rand
.
Float64
()
<
0.01
{
preda
.
Velocity
=
Rotate
(
preda
.
Velocity
,
rand
.
Intn
(
10
))
}
if
rand
.
Float64
()
>
0.99
{
preda
.
Velocity
=
Rotate
(
preda
.
Velocity
,
-
rand
.
Intn
(
10
))
}
}
}
func
(
preda
*
Predator
)
CheckEdges
()
bool
{
if
preda
.
Position
.
X
<
0
{
preda
.
Position
.
X
=
constant
.
ScreenWidth
}
else
if
preda
.
Position
.
X
>
constant
.
ScreenWidth
{
preda
.
Position
.
X
=
0
}
if
preda
.
Position
.
Y
<
0
{
preda
.
Position
.
Y
=
constant
.
ScreenHeight
}
else
if
preda
.
Position
.
Y
>
constant
.
ScreenHeight
{
preda
.
Position
.
Y
=
0
}
return
false
}
func
(
preda
*
Predator
)
CheckWalls
(
walls
[]
*
wall
.
Wall
)
{
if
preda
.
R
{
preda
.
Velocity
.
Normalize
()
preda
.
Velocity
.
X
=
preda
.
Velocity
.
X
*
2
preda
.
Velocity
.
Y
=
preda
.
Velocity
.
Y
*
2
preda
.
R
=
false
}
else
{
for
_
,
wall
:=
range
walls
{
d
:=
preda
.
Position
.
Distance
(
wall
.
Position
)
if
d
<=
30
{
preda
.
Velocity
.
Normalize
()
preda
.
Velocity
.
X
=
-
preda
.
Velocity
.
X
*
(
30
-
d
+
1
)
preda
.
Velocity
.
Y
=
-
preda
.
Velocity
.
Y
*
(
30
-
d
+
1
)
preda
.
R
=
true
}
}
}
}
func
(
preda
*
Predator
)
ApplyMovement
()
{
preda
.
Position
.
Add
(
preda
.
Velocity
)
}
Boid/flock/flock.go
View file @
7ee4792f
...
...
@@ -2,12 +2,14 @@ package flock
import
(
boid
"gitlab.utc.fr/projet_ia04/Boid/agent/boid"
predator
"gitlab.utc.fr/projet_ia04/Boid/agent/predator"
wall
"gitlab.utc.fr/projet_ia04/Boid/agent/wall"
)
type
Flock
struct
{
Boids
[]
*
boid
.
Boid
Walls
[]
*
wall
.
Wall
Boids
[]
*
boid
.
Boid
Walls
[]
*
wall
.
Wall
Predators
[]
*
predator
.
Predator
}
func
(
flock
*
Flock
)
Logic
()
{
...
...
@@ -19,4 +21,11 @@ func (flock *Flock) Logic() {
}
boid
.
ApplyMovement
()
}
for
_
,
preda
:=
range
flock
.
Predators
{
if
!
preda
.
CheckEdges
()
{
preda
.
ApplyRules
(
flock
.
Boids
)
preda
.
CheckWalls
(
flock
.
Walls
)
}
preda
.
ApplyMovement
()
}
}
Boid/game/game.go
View file @
7ee4792f
...
...
@@ -18,6 +18,7 @@ import (
"golang.org/x/image/font"
boid
"gitlab.utc.fr/projet_ia04/Boid/agent/boid"
predator
"gitlab.utc.fr/projet_ia04/Boid/agent/predator"
wall
"gitlab.utc.fr/projet_ia04/Boid/agent/wall"
flock
"gitlab.utc.fr/projet_ia04/Boid/flock"
constant
"gitlab.utc.fr/projet_ia04/Boid/utils/constant"
...
...
@@ -53,6 +54,8 @@ func NewGame(c chan string) *Game {
rand
.
Seed
(
time
.
Hour
.
Milliseconds
())
g
.
Flock
.
Boids
=
make
([]
*
boid
.
Boid
,
constant
.
NumBoids
)
g
.
Flock
.
Walls
=
make
([]
*
wall
.
Wall
,
constant
.
NumWalls
)
g
.
Flock
.
Predators
=
make
([]
*
predator
.
Predator
,
constant
.
NumPreda
)
for
i
:=
range
g
.
Flock
.
Boids
{
w
,
h
:=
variable
.
BirdImage
.
Size
()
x
,
y
:=
rand
.
Float64
()
*
float64
(
constant
.
ScreenWidth
-
w
),
rand
.
Float64
()
*
float64
(
constant
.
ScreenWidth
-
h
)
...
...
@@ -78,6 +81,25 @@ func NewGame(c chan string) *Game {
Position
:
Vector2D
{
X
:
x
,
Y
:
y
},
}
}
for
i
:=
range
g
.
Flock
.
Predators
{
w
,
h
:=
variable
.
BirdImage
.
Size
()
x
,
y
:=
rand
.
Float64
()
*
float64
(
constant
.
ScreenWidth
-
w
),
rand
.
Float64
()
*
float64
(
constant
.
ScreenWidth
-
h
)
min
,
max
:=
-
constant
.
MaxForce
,
constant
.
MaxForce
vx
,
vy
:=
rand
.
Float64
()
*
(
max
-
min
)
+
min
,
rand
.
Float64
()
*
(
max
-
min
)
+
min
g
.
Flock
.
Predators
[
i
]
=
&
predator
.
Predator
{
ImageWidth
:
w
,
ImageHeight
:
h
,
Position
:
Vector2D
{
X
:
x
,
Y
:
y
},
Velocity
:
Vector2D
{
X
:
vx
,
Y
:
vy
},
Acceleration
:
Vector2D
{
X
:
0
,
Y
:
0
},
Density
:
5
,
Dist
:
400
,
Angle
:
10
,
V1
:
Vector2D
{
X
:
0
,
Y
:
0
},
V2
:
Vector2D
{
X
:
0
,
Y
:
0
},
R
:
false
,
}
}
// Variable Initialisations
variable
.
RepulsionFactorBtwnSpecies
=
100
variable
.
SeparationPerception
=
50
...
...
@@ -189,6 +211,25 @@ func (g *Game) Draw(screen *ebiten.Image) {
}
}
}
for
_
,
preda
:=
range
g
.
Flock
.
Predators
{
op
.
GeoM
.
Reset
()
op
.
GeoM
.
Translate
(
-
float64
(
w
)
/
2
,
-
float64
(
h
)
/
2
)
op
.
GeoM
.
Rotate
(
-
1
*
math
.
Atan2
(
preda
.
Velocity
.
Y
*-
1
,
preda
.
Velocity
.
X
)
+
math
.
Pi
)
op
.
GeoM
.
Translate
(
preda
.
Position
.
X
,
preda
.
Position
.
Y
)
screen
.
DrawImage
(
variable
.
PredImage
,
&
op
)
op
.
GeoM
.
Reset
()
//op.GeoM.Translate(-float64(w)/2, -float64(h)/2)
op
.
GeoM
.
Translate
(
preda
.
V2
.
X
,
preda
.
V2
.
Y
)
screen
.
DrawImage
(
variable
.
BirdImage
,
&
op
)
op
.
GeoM
.
Reset
()
//op.GeoM.Translate(-float64(w)/2, -float64(h)/2)
op
.
GeoM
.
Translate
(
preda
.
V1
.
X
,
preda
.
V1
.
Y
)
screen
.
DrawImage
(
variable
.
BirdImage
,
&
op
)
}
w
,
h
=
variable
.
WallImage
.
Size
()
for
_
,
wall
:=
range
g
.
Flock
.
Walls
{
op
.
GeoM
.
Reset
()
...
...
Boid/main.go
View file @
7ee4792f
...
...
@@ -48,6 +48,14 @@ func init() {
variable
.
FishImage3
=
ebiten
.
NewImage
(
w
,
h
)
variable
.
FishImage3
.
DrawImage
(
fish3
,
op
)
preda
,
_
,
err
:=
ebitenutil
.
NewImageFromFile
(
"utils/fish/predT3.png"
)
if
err
!=
nil
{
log
.
Fatal
(
err
)
}
w
,
h
=
fish1
.
Size
()
variable
.
PredImage
=
ebiten
.
NewImage
(
w
+
100
,
h
+
100
)
variable
.
PredImage
.
DrawImage
(
preda
,
op
)
back
,
_
,
err
:=
ebitenutil
.
NewImageFromFile
(
"utils/fish/background.png"
)
if
err
!=
nil
{
log
.
Fatal
(
err
)
...
...
Boid/utils/constant/constant.go
View file @
7ee4792f
...
...
@@ -3,8 +3,9 @@ package constant
const
(
ScreenWidth
=
1152
ScreenHeight
=
648
NumBoids
=
200
NumWalls
=
20
NumBoids
=
300
NumPreda
=
3
NumWalls
=
30
MaxForce
=
2.0
MaxSpeed
=
4.0
AlignPerception
=
75.0
...
...
Boid/utils/fish/predT2.png
0 → 100644
View file @
7ee4792f
783 Bytes
Boid/utils/fish/predT3.png
0 → 100644
View file @
7ee4792f
1.05 KB
Boid/utils/fish/predT4.png
0 → 100644
View file @
7ee4792f
1.32 KB
Boid/utils/variable/variable.go
View file @
7ee4792f
...
...
@@ -9,6 +9,7 @@ var (
FishImage1
*
ebiten
.
Image
FishImage2
*
ebiten
.
Image
FishImage3
*
ebiten
.
Image
PredImage
*
ebiten
.
Image
BackgroundImage
*
ebiten
.
Image
WallImage
*
ebiten
.
Image
RepulsionFactorBtwnSpecies
float64
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment