Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
M
myProjects
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Antoine Rollet
myProjects
Commits
c1e812c8
Commit
c1e812c8
authored
Nov 27, 2019
by
Antoine Rollet
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Upload New File
parent
f227c421
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
486 additions
and
0 deletions
+486
-0
battle_royale.py
battle_royale.py
+486
-0
No files found.
battle_royale.py
0 → 100644
View file @
c1e812c8
import
pygame
as
pg
import
numpy
as
np
from
numpy
import
cos
,
sin
from
time
import
time
,
sleep
from
random
import
shuffle
continuer
=
1
wd_width
=
600
wd_height
=
600
random
=
np
.
random
.
random
# color_set =[]
# c=open("C:/Users/Antoine/Desktop/colors.csv").read()
# for c1 in c.replace("\n","\t").split("\t"):
# print(c1)
# if c1!= '':
# color_set.append(tuple([int(e) for e in c1.split(', ')]))
# shuffle(color_set)
def
collisionDroiteSeg
(
A
,
B
,
O
,
P
):
# Soit une droite AB et un segment OP
# On cherche à savoir si il y a collision entre les deux
ABx
=
B
[
0
]
-
A
[
0
]
ABy
=
B
[
1
]
-
A
[
1
]
APx
=
P
[
0
]
-
A
[
0
]
APy
=
P
[
1
]
-
A
[
1
]
AOx
=
O
[
0
]
-
A
[
0
]
AOy
=
O
[
1
]
-
A
[
1
]
if
((
ABx
*
APy
-
ABy
*
APx
)
*
(
ABx
*
AOy
-
ABy
*
AOx
))
<
0
:
return
True
else
:
return
False
def
collisionSegSeg
(
A
,
B
,
O
,
P
):
return
collisionDroiteSeg
(
A
,
B
,
O
,
P
)
and
collisionDroiteSeg
(
O
,
P
,
A
,
B
)
def
collisionPolygPolyg
(
P1
,
P2
):
for
i
in
range
(
len
(
P1
)):
A1
=
P1
[
i
]
if
i
==
len
(
P1
)
-
1
:
B1
=
P1
[
0
]
else
:
B1
=
P1
[
i
+
1
]
for
j
in
range
(
len
(
P2
)):
A2
=
P2
[
j
]
if
j
==
len
(
P2
)
-
1
:
B2
=
P2
[
0
]
else
:
B2
=
P2
[
j
+
1
]
if
collisionSegSeg
(
A1
,
B1
,
A2
,
B2
):
return
True
return
False
def
pointInPolyg
(
P
,
poly
):
for
i
in
range
(
len
(
poly
)):
A
=
poly
[
i
]
if
i
==
len
(
poly
)
-
1
:
B
=
poly
[
0
]
else
:
B
=
poly
[
i
+
1
]
Dx
=
B
[
0
]
-
A
[
0
]
Dy
=
B
[
1
]
-
A
[
1
]
Tx
=
P
[
0
]
-
A
[
0
]
Ty
=
P
[
1
]
-
A
[
1
]
d
=
Dx
*
Ty
-
Dy
*
Tx
if
d
<
0
:
return
False
return
True
def
activationFunctionNotVect
(
x
):
if
1
/
(
1
+
np
.
exp
(
-
x
))
>
0.6
:
return
1
else
:
return
0
activationFunction
=
np
.
vectorize
(
activationFunctionNotVect
)
class
Agent
:
def
__init__
(
self
,
x
,
y
,
dir
,
id
=
1
,
color
=
(
255
,
255
,
255
)):
self
.
x
=
x
self
.
y
=
y
self
.
taille
=
12
self
.
dir
=
dir
self
.
id
=
id
self
.
alive
=
True
self
.
color
=
color
self
.
n_kills
=
0
pied_gauche
=
self
.
x
+
self
.
taille
/
2
*
cos
(
np
.
pi
/
2
+
self
.
dir
),
self
.
y
+
self
.
taille
/
2
*
sin
(
np
.
pi
/
2
+
self
.
dir
)
pied_droit
=
self
.
x
+
self
.
taille
/
2
*
cos
(
np
.
pi
/
2
-
self
.
dir
),
self
.
y
-
self
.
taille
/
2
*
sin
(
np
.
pi
/
2
-
self
.
dir
)
self
.
tete
=
self
.
x
+
self
.
taille
*
cos
(
self
.
dir
),
self
.
y
+
self
.
taille
*
sin
(
self
.
dir
)
self
.
hitbox
=
[
self
.
tete
,
pied_gauche
,
pied_droit
]
self
.
set_brain_structure
(
9
,
5
)
self
.
vision
=
np
.
zeros
((
9
))
angles
=
[
np
.
pi
/
21
*
i
for
i
in
range
(
-
7
,
8
,
2
)]
def
__str__
(
self
):
return
"Agent "
+
str
(
self
.
id
)
def
watch
(
self
,
storm_center
,
storm_radius
,
other_players
):
# Pour l'instant la "vue" est aléatoire sauf la vision de l'orage
# vue à 120°, 7 champs de vision
dist_to_storm
=
(
np
.
sqrt
((
self
.
x
-
storm_center
[
0
])
**
2
+
(
self
.
y
-
storm_center
[
1
])
**
2
))
/
storm_radius
ang_to_storm
=
np
.
arctan2
(
self
.
x
-
storm_center
[
0
],
self
.
y
-
storm_center
[
1
])
self
.
vision
=
np
.
zeros
(
9
)
self
.
vision
[
0
]
=
dist_to_storm
self
.
vision
[
1
]
=
ang_to_storm
self
.
watch_other_players
(
other_players
)
# print(self.vision)
def
watch_other_players
(
self
,
other_players
):
for
player
in
other_players
:
if
player
!=
self
:
if
(
self
.
x
-
player
.
x
)
**
2
+
(
self
.
y
-
player
.
y
)
**
2
<=
(
6
*
self
.
taille
)
**
2
:
angle
=
(
self
.
dir
-
np
.
arctan2
(
self
.
y
-
player
.
y
,
self
.
x
-
player
.
x
)
-
np
.
pi
)
%
(
2
*
np
.
pi
)
if
angle
>=
5
/
3
*
np
.
pi
or
angle
<=
np
.
pi
/
3
:
if
angle
>=
5
/
3
*
np
.
pi
:
angle
-=
2
*
np
.
pi
dist_to_other_player
=
1
-
np
.
sqrt
((
self
.
x
-
player
.
x
)
**
2
+
(
self
.
y
-
player
.
y
)
**
2
)
/
6
/
self
.
taille
i
=
1
while
angle
>=
np
.
pi
/
3
*
(
2
*
i
/
7
-
1
):
i
+=
1
# En % de 6 x taille (distance maximale)
self
.
vision
[
i
-
1
+
2
]
=
dist_to_other_player
# print(self.id,"is seeing", player.id)
def
take_action
(
self
,
fenetre
,
storm_center
,
storm_radius
,
other_players
):
self
.
watch
(
storm_center
,
storm_radius
,
other_players
)
actions
=
self
.
vision
.
dot
(
self
.
weights_1
.
dot
(
self
.
weights_2
))
actions
=
activationFunction
(
actions
)
# print(actions)
for
i
in
range
(
len
(
actions
)):
if
i
==
0
and
actions
[
i
]:
self
.
move_forward
()
if
i
==
1
and
actions
[
i
]:
self
.
move_backward
()
if
i
==
2
and
actions
[
i
]:
self
.
turn_left
()
if
i
==
3
and
actions
[
i
]:
self
.
turn_right
()
if
i
==
4
and
actions
[
i
]:
return
self
.
shoot
(
fenetre
)
def
set_brain_structure
(
self
,
input_size
,
output_size
):
self
.
weights_1
=
np
.
random
.
randint
(
-
2
,
2
,(
input_size
,
12
))
self
.
weights_2
=
np
.
random
.
randint
(
-
2
,
2
,(
12
,
output_size
))
self
.
brain
=
[
self
.
weights_1
,
self
.
weights_2
]
def
is_shot
(
self
,
shot
):
for
i
in
range
(
len
(
self
.
hitbox
)):
A
=
self
.
hitbox
[
i
]
if
i
==
len
(
self
.
hitbox
)
-
1
:
B
=
self
.
hitbox
[
0
]
else
:
B
=
self
.
hitbox
[
i
+
1
]
if
collisionSegSeg
(
A
,
B
,
shot
[
1
][
0
],
shot
[
1
][
1
]):
self
.
alive
=
False
print
(
self
.
id
,
" was shot by "
,
shot
[
0
],
"."
)
return
True
return
False
def
shoot
(
self
,
fenetre
):
# Un tir est un segment
depart
=
self
.
hitbox
[
0
]
# Début du tir au niveau de la tête
arrivee
=
depart
[
0
]
+
2
*
self
.
taille
*
cos
(
self
.
dir
),
depart
[
1
]
+
2
*
self
.
taille
*
sin
(
self
.
dir
)
# Arrivée après deux fois la taille du bonhomme
if
fenetre
!=
None
:
pg
.
draw
.
line
(
fenetre
,(
255
,
0
,
0
),
depart
,
arrivee
)
# self.afficher(fenetre)
pg
.
display
.
update
()
return
(
self
.
id
,[
depart
,
arrivee
])
def
refresh_hitbox
(
self
):
pied_gauche
=
self
.
x
+
self
.
taille
/
2
*
cos
(
np
.
pi
/
2
+
self
.
dir
),
self
.
y
+
self
.
taille
/
2
*
sin
(
np
.
pi
/
2
+
self
.
dir
)
pied_droit
=
self
.
x
+
self
.
taille
/
2
*
cos
(
np
.
pi
/
2
-
self
.
dir
),
self
.
y
-
self
.
taille
/
2
*
sin
(
np
.
pi
/
2
-
self
.
dir
)
tete
=
self
.
x
+
self
.
taille
*
cos
(
self
.
dir
),
self
.
y
+
self
.
taille
*
sin
(
self
.
dir
)
self
.
hitbox
=
[
tete
,
pied_gauche
,
pied_droit
]
def
check_in_storm
(
self
,
storm_center
,
storm_radius
):
if
(
self
.
x
-
storm_center
[
0
])
**
2
+
(
self
.
y
-
storm_center
[
1
])
**
2
<=
storm_radius
**
2
:
self
.
alive
=
True
else
:
self
.
alive
=
False
print
(
self
.
id
,
" died in the storm."
)
def
move_forward
(
self
,
speed
=
2
):
self
.
x
+=
speed
*
cos
(
self
.
dir
)
self
.
y
+=
speed
*
sin
(
self
.
dir
)
self
.
refresh_hitbox
()
def
move_backward
(
self
,
speed
=
2
):
self
.
x
-=
speed
*
cos
(
self
.
dir
)
self
.
y
-=
speed
*
sin
(
self
.
dir
)
self
.
refresh_hitbox
()
def
turn_left
(
self
):
self
.
dir
-=
np
.
pi
/
50
self
.
refresh_hitbox
()
def
turn_right
(
self
):
self
.
dir
+=
np
.
pi
/
50
self
.
refresh_hitbox
()
def
afficher
(
self
,
fenetre
,
color
=
None
):
self
.
refresh_hitbox
()
#à supprimer
x
,
y
=
self
.
x
,
self
.
y
direction_joueur
=
self
.
dir
taille
=
50
if
color
==
None
:
color
=
self
.
color
# print(x,y,direction_joueur)
# Détermination des trois "extrémités"=membres du joueur
tete
,
pied_gauche
,
pied_droit
=
self
.
hitbox
# Affichage des membres
pg
.
draw
.
circle
(
fenetre
,(
255
,
0
,
0
),(
int
(
tete
[
0
]),
int
(
tete
[
1
])),
taille
//
25
)
# pg.draw.circle(fenetre,(0,255,0),(int(pied_gauche[0]), int(pied_gauche[1])), taille//25)
# pg.draw.circle(fenetre,(0,0,255),(int(pied_droit[0]),int(pied_droit[1])),taille//25)
pg
.
draw
.
circle
(
fenetre
,(
255
,
255
,
0
),(
int
(
x
),
int
(
y
)),
taille
//
20
)
# Affichage du "corps" du joueur
pg
.
draw
.
polygon
(
fenetre
,
color
,
self
.
hitbox
)
# Affichage de l'id du joueur
# pg.font.init()
# font=pg.font.SysFont(None,20)
# font_image=font.render(str(self.id),True,(0,0,0))
# fenetre.blit(font_image,(self.x,self.y))
# pg.display.flip()
class
Storm
:
def
__init__
(
self
):
self
.
center
=
(
wd_width
//
2
,
wd_height
//
2
)
self
.
max_radius
=
(
max
(
wd_width
,
wd_height
)
/
np
.
sqrt
(
2
))
*
1.2
self
.
radius
=
self
.
max_radius
self
.
adv_quantum
=
self
.
radius
/
30
# ici le cercle ce sera réduit en le dénominateur secondes
def
storm_push
(
self
,
time_elapsed
):
self
.
radius
=
self
.
max_radius
-
time_elapsed
*
self
.
adv_quantum
def
afficher_storm
(
self
,
fenetre
):
pg
.
draw
.
circle
(
fenetre
,(
238
,
130
,
238
),(
wd_width
//
2
,
wd_height
//
2
),
int
(
self
.
radius
),
2
)
# pg.display.update()
class
BR_Game
(
Storm
,
Agent
):
def
__init__
(
self
,
agents
,
display
=
True
,
hurry
=
1
):
self
.
player_colors
=
[(
np
.
random
.
randint
(
256
),
np
.
random
.
randint
(
256
),
np
.
random
.
randint
(
256
))
for
i
in
range
(
len
(
agents
))]
self
.
alive_players
=
list
(
agents
.
values
())
# self.alive_players.append(p[0])
self
.
dead_players
=
[]
self
.
storm
=
Storm
()
self
.
start_time
=
time
()
self
.
time_elapsed
=
0
self
.
hurry
=
hurry
self
.
game_ongoing
=
True
self
.
display
=
display
self
.
fenetre
=
None
if
display
:
self
.
fenetre
=
pg
.
display
.
set_mode
((
wd_width
,
wd_height
))
def
play
(
self
):
# if self.display:
# pg.display.flip()
while
self
.
game_ongoing
:
self
.
time_elapsed
=
(
time
()
-
self
.
start_time
)
*
self
.
hurry
self
.
storm
.
storm_push
(
self
.
time_elapsed
)
shots
=
[]
for
player
in
self
.
alive_players
:
player
.
check_in_storm
(
self
.
storm
.
center
,
self
.
storm
.
radius
)
for
player
in
self
.
alive_players
:
#On va avoir des problemes ici si on ne veut pas de display
shoot
=
player
.
take_action
(
self
.
fenetre
,
self
.
storm
.
center
,
self
.
storm
.
radius
,
self
.
alive_players
)
if
shoot
!=
None
:
shots
.
append
(
shoot
)
for
shot
in
shots
:
for
player
in
self
.
alive_players
:
if
player
.
is_shot
(
shot
):
for
shooter
in
self
.
alive_players
:
if
shooter
.
id
==
shot
[
0
]:
shooter
.
n_kills
+=
1
if
self
.
display
:
self
.
fenetre
.
fill
((
0
,
0
,
0
))
self
.
storm
.
afficher_storm
(
self
.
fenetre
)
for
player
in
self
.
alive_players
:
if
player
.
alive
and
self
.
display
:
player
.
afficher
(
self
.
fenetre
)
elif
not
(
player
.
alive
):
self
.
dead_players
.
append
(
player
)
self
.
alive_players
.
remove
(
player
)
# Code qui détermine si deux joueurs se touchent
# for player_1 in self.alive_players:
# for player_2 in self.alive_players:
# if player_1.id != player_2.id:
# col=collisionPolygPolyg(player_1.hitbox,player_2.hitbox)
# if col:
# player_1.afficher(self.fenetre,(255,0,0))
# player_2.afficher(self.fenetre,(255,0,0))
if
self
.
display
:
pg
.
event
.
pump
()
# pg.display.update()
pg
.
display
.
flip
()
for
event
in
pg
.
event
.
get
():
#On parcours la liste de tous les événements reçus
if
event
.
type
==
pg
.
QUIT
:
#Si un de ces événements est de type QUIT
self
.
game_ongoing
=
False
#On arrête la boucle
pg
.
display
.
quit
()
if
event
.
type
==
pg
.
MOUSEBUTTONDOWN
:
sleep
(
3
)
self
.
game_ongoing
=
len
(
self
.
alive_players
)
>
1
self
.
dead_players
.
append
(
self
.
alive_players
[
0
])
print
(
"Player "
,
self
.
dead_players
[
-
1
],
" won the game!"
)
pg
.
quit
()
def
leaderboard
(
self
):
self
.
scores
=
dict
()
for
i
in
range
(
len
(
self
.
dead_players
)):
self
.
scores
[
self
.
dead_players
[
i
]
.
id
]
=
i
+
self
.
dead_players
[
i
]
.
n_kills
*
2
print
(
"#"
,
len
(
self
.
dead_players
)
-
i
,
". "
+
str
(
self
.
dead_players
[
i
]),
"with"
,
self
.
dead_players
[
i
]
.
n_kills
,
"kills!"
)
leaderboard
=
[
assoc
[
0
]
for
assoc
in
sorted
(
self
.
scores
.
items
(),
key
=
lambda
tupl
:
tupl
[
1
])]
return
leaderboard
,[
agent
.
id
for
agent
in
self
.
dead_players
]
class
AgentPool
(
Agent
):
def
__init__
(
self
,
new_agents
=
True
,
n_agents
=
20
,
agents
=
None
):
if
new_agents
:
self
.
agents
=
dict
()
for
i
in
range
(
n_agents
):
self
.
agents
[
i
]
=
Agent
(
random
()
*
wd_width
,
random
()
*
wd_height
,
random
()
*
2
*
np
.
pi
,
id
=
i
)
else
:
self
.
agents
=
agents
self
.
max_id
=
max
(
self
.
agents
.
keys
())
self
.
n_agents
=
n_agents
print
(
self
.
max_id
+
1
,
"agents in the pool."
)
def
make_them_fight
(
self
,
n_fights
=
1
,
display
=
False
,
hurry
=
1
):
for
id
,
agent
in
self
.
agents
.
items
():
agent
.
n_kills
=
0
leaderboards
=
[]
for
i
in
range
(
n_fights
):
print
(
"This is fight number"
,
i
+
1
,
"!"
)
for
id
,
agent
in
self
.
agents
.
items
():
agent
.
x
=
random
()
*
wd_width
agent
.
y
=
random
()
*
wd_height
agent
.
dir
=
random
()
*
2
*
np
.
pi
game
=
BR_Game
(
agents
=
self
.
agents
,
display
=
display
,
hurry
=
hurry
)
game
.
play
()
leaderboards
.
append
(
game
.
leaderboard
()[
1
])
scores
=
dict
()
for
id
,
agent
in
self
.
agents
.
items
():
scores
[
id
]
=
sum
([
lb
.
index
(
id
)
for
lb
in
leaderboards
])
+
agent
.
n_kills
self
.
leaderboard
=
[
assoc
[
0
]
for
assoc
in
sorted
(
scores
.
items
(),
key
=
lambda
tupl
:
tupl
[
1
])]
print
(
scores
)
print
(
self
.
leaderboard
)
def
kill_the_weakest
(
self
,
n_to_kill
):
for
dead
in
self
.
leaderboard
[:
n_to_kill
]:
self
.
agents
.
pop
(
dead
)
def
make_a_baby
(
self
):
father_id
=
np
.
random
.
choice
(
list
(
self
.
agents
.
keys
()))
father
=
self
.
agents
.
get
(
father_id
)
mother_id
=
np
.
random
.
choice
(
list
(
self
.
agents
.
keys
()))
mother
=
self
.
agents
.
get
(
mother_id
)
n
,
p
=
father
.
brain
[
0
]
.
shape
mix1
=
np
.
ones
((
n
,
1
))
.
dot
(
np
.
random
.
choice
(
2
,(
1
,
p
)))
#select random columns
mix1
+=
np
.
random
.
normal
(
size
=
mix1
.
shape
)
new_brain_1
=
father
.
brain
[
0
]
*
mix1
+
mother
.
brain
[
0
]
*
(
1
-
mix1
)
n
,
p
=
father
.
brain
[
1
]
.
shape
mix2
=
np
.
ones
((
n
,
1
))
.
dot
(
np
.
random
.
choice
(
2
,(
1
,
p
)))
mix2
+=
np
.
random
.
normal
(
size
=
mix2
.
shape
)
new_brain_2
=
father
.
brain
[
1
]
*
mix2
+
mother
.
brain
[
1
]
*
(
1
-
mix2
)
#no mutation yet
new_brain
=
[
new_brain_1
,
new_brain_2
]
baby
=
Agent
(
random
()
*
wd_width
,
random
()
*
wd_height
,
random
()
*
2
*
np
.
pi
,
id
=
self
.
max_id
+
1
)
baby
.
brain
=
new_brain
self
.
agents
[
baby
.
id
]
=
baby
self
.
max_id
+=
1
def
loop
(
self
,
n_loops
=
1
,
fights_per_loop
=
1
):
for
i
in
range
(
n_loops
):
self
.
make_them_fight
(
n_fights
=
fights_per_loop
,
display
=
False
,
hurry
=
2
)
self
.
kill_the_weakest
(
self
.
n_agents
//
2
)
for
e
in
range
(
self
.
n_agents
-
len
(
self
.
agents
)):
self
.
make_a_baby
()
game
=
BR_Game
(
AgentPool
()
.
agents
)
game
.
play
()
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a 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