Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
PyGAAMAS
Manage
Activity
Members
Labels
Plan
Issues
0
Issue boards
Milestones
Wiki
Code
Merge requests
0
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Maxime Morge
PyGAAMAS
Commits
e8bef562
Commit
e8bef562
authored
5 months ago
by
Maxime MORGE
Browse files
Options
Downloads
Patches
Plain Diff
First commit
parent
655244f3
No related branches found
No related tags found
No related merge requests found
Changes
43
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
src/rps/rps_draw_3loop.py
+70
-0
70 additions, 0 deletions
src/rps/rps_draw_3loop.py
src/rps/rps_draw_constant.py
+65
-0
65 additions, 0 deletions
src/rps/rps_draw_constant.py
src/rps/rps_experiments.py
+108
-0
108 additions, 0 deletions
src/rps/rps_experiments.py
with
243 additions
and
0 deletions
src/rps/rps_draw_3loop.py
0 → 100644
+
70
−
0
View file @
e8bef562
import
pandas
as
pd
import
numpy
as
np
import
matplotlib.pyplot
as
plt
# Path to the CSV file
CSV_FILE_PATH
=
"
../../data/rps/rps.csv
"
# Load the data
df
=
pd
.
read_csv
(
CSV_FILE_PATH
)
# Convert necessary columns to appropriate types
df
[
"
idRound
"
]
=
df
[
"
idRound
"
].
astype
(
int
)
df
[
"
outcomeRound
"
]
=
df
[
"
outcomeRound
"
].
astype
(
float
)
# List of opponent strategies to consider
opponent_strategies
=
[
"
R-P-S
"
]
# **Fix Warning**: Ensure we work with a full copy
df_filtered
=
df
[
df
[
"
opponentStrategy
"
].
isin
(
opponent_strategies
)].
copy
()
# Custom color palette for models
color_palette
=
{
'
gpt-4.5-preview-2025-02-27
'
:
'
#7abaff
'
,
# BlueEscape
'
llama3
'
:
'
#32a68c
'
,
# vertAvenir
'
mistral-small
'
:
'
#ff6941
'
,
# orangeChaleureux
'
deepseek-r1
'
:
'
#5862ed
'
# indigoInclusif
}
# Group by model and round number, compute mean and standard deviation
summary
=
df_filtered
.
groupby
([
"
model
"
,
"
idRound
"
]).
agg
(
mean_outcome
=
(
"
outcomeRound
"
,
"
mean
"
),
std_outcome
=
(
"
outcomeRound
"
,
"
std
"
),
count
=
(
"
outcomeRound
"
,
"
count
"
)
).
reset_index
()
# Compute standard error (SEM)
summary
[
"
sem
"
]
=
summary
[
"
std_outcome
"
]
/
np
.
sqrt
(
summary
[
"
count
"
])
# Compute 95% confidence intervals
summary
[
"
ci_upper
"
]
=
summary
[
"
mean_outcome
"
]
+
(
1.96
*
summary
[
"
sem
"
])
summary
[
"
ci_lower
"
]
=
summary
[
"
mean_outcome
"
]
-
(
1.96
*
summary
[
"
sem
"
])
# Set the figure size
plt
.
figure
(
figsize
=
(
10
,
6
))
# Loop through each model and plot its performance with confidence interval
for
model
in
summary
[
"
model
"
].
unique
():
df_model
=
summary
[
summary
[
"
model
"
]
==
model
]
# Plot mean outcome
plt
.
plot
(
df_model
[
"
idRound
"
],
df_model
[
"
mean_outcome
"
],
label
=
model
,
color
=
color_palette
.
get
(
model
,
'
#333333
'
))
# Default to dark gray if model not in palette
# Plot confidence interval as a shaded region
plt
.
fill_between
(
df_model
[
"
idRound
"
],
df_model
[
"
ci_lower
"
],
df_model
[
"
ci_upper
"
],
color
=
color_palette
.
get
(
model
,
'
#333333
'
),
alpha
=
0.2
)
# Transparency for better visibility
# Add legends and labels
plt
.
xlabel
(
"
Round Number
"
)
plt
.
ylabel
(
"
Average Points Earned
"
)
plt
.
title
(
"
Average Points Earned per Round Against 3-Loop Behaviour (95% CI)
"
)
plt
.
legend
()
plt
.
grid
(
True
)
plt
.
ylim
(
0
,
2
)
# Points are between 0 and 2
# Save the figure as an SVG file
plt
.
savefig
(
'
../../figures/rps_3loop.svg
'
,
format
=
'
svg
'
)
This diff is collapsed.
Click to expand it.
src/rps/rps_draw_constant.py
0 → 100644
+
65
−
0
View file @
e8bef562
import
pandas
as
pd
import
matplotlib.pyplot
as
plt
import
numpy
as
np
# Path to the CSV file
CSV_FILE_PATH
=
"
../../data/rps/rps.csv
"
# Load the data
df
=
pd
.
read_csv
(
CSV_FILE_PATH
)
# Convert necessary columns to appropriate types
df
[
"
idRound
"
]
=
df
[
"
idRound
"
].
astype
(
int
)
df
[
"
outcomeRound
"
]
=
df
[
"
outcomeRound
"
].
astype
(
float
)
# List of opponent strategies to consider
opponent_strategies
=
[
"
always_rock
"
,
"
always_paper
"
,
"
always_scissor
"
]
# **Fix Warning**: Ensure we work with a full copy
df_filtered
=
df
[
df
[
"
opponentStrategy
"
].
isin
(
opponent_strategies
)].
copy
()
# Custom color palette for models
color_palette
=
{
'
gpt-4.5-preview-2025-02-27
'
:
'
#7abaff
'
,
# BlueEscape
'
llama3
'
:
'
#32a68c
'
,
# vertAvenir
'
mistral-small
'
:
'
#ff6941
'
,
# orangeChaleureux
'
deepseek-r1
'
:
'
#5862ed
'
# indigoInclusif
}
# Compute mean, standard error (SEM), and 95% confidence interval by model and round
agg_data
=
df_filtered
.
groupby
([
"
model
"
,
"
idRound
"
]).
agg
(
mean_outcome
=
(
"
outcomeRound
"
,
"
mean
"
),
sem_outcome
=
(
"
outcomeRound
"
,
lambda
x
:
np
.
std
(
x
,
ddof
=
1
)
/
np
.
sqrt
(
len
(
x
)))
# Standard error
).
reset_index
()
# Compute 95% Confidence Interval (CI)
agg_data
[
"
ci95
"
]
=
1.96
*
agg_data
[
"
sem_outcome
"
]
# 95% confidence interval
# Set the figure size
plt
.
figure
(
figsize
=
(
10
,
6
))
# Loop through each model and plot its aggregated performance across rounds
for
model
in
agg_data
[
"
model
"
].
unique
():
df_model
=
agg_data
[
agg_data
[
"
model
"
]
==
model
]
color
=
color_palette
.
get
(
model
,
'
#333333
'
)
# Default to dark gray if model not in palette
# Plot mean values
plt
.
plot
(
df_model
[
"
idRound
"
],
df_model
[
"
mean_outcome
"
],
label
=
model
,
color
=
color
)
# Add 95% confidence interval (shaded region)
plt
.
fill_between
(
df_model
[
"
idRound
"
],
df_model
[
"
mean_outcome
"
]
-
df_model
[
"
ci95
"
],
# Lower bound (95% CI)
df_model
[
"
mean_outcome
"
]
+
df_model
[
"
ci95
"
],
# Upper bound (95% CI)
color
=
color
,
alpha
=
0.2
)
# Transparency for shading
# Add legends and labels
plt
.
xlim
(
1
,
10
)
plt
.
xlabel
(
"
Round Number
"
)
plt
.
ylabel
(
"
Average Points Earned
"
)
plt
.
title
(
"
Average Points Earned per Round Against Constant Behaviour (with 95% Confidence Interval)
"
)
plt
.
legend
()
plt
.
grid
(
True
)
plt
.
ylim
(
0
,
2
)
# Points are between 0 and 2
# Save the figure as an SVG file
plt
.
savefig
(
'
../../figures/rps/rps_constant.svg
'
,
format
=
'
svg
'
)
This diff is collapsed.
Click to expand it.
src/rps/rps_experiments.py
0 → 100644
+
108
−
0
View file @
e8bef562
import
os
import
asyncio
import
csv
import
random
from
rps
import
RPS
from
typing
import
Dict
,
Literal
,
List
,
Callable
from
pydantic
import
BaseModel
,
ValidationError
from
autogen_agentchat.agents
import
AssistantAgent
from
autogen_agentchat.messages
import
TextMessage
from
autogen_core
import
CancellationToken
from
autogen_ext.models.openai
import
OpenAIChatCompletionClient
import
json
CSV_FILE_PATH
=
"
../../data/rps/rps.csv
"
# Define RPS Constant Experiment class
class
RPSExperiment
:
def
__init__
(
self
):
self
.
models
=
[
"
llama3
"
,
"
mistral-small
"
,
"
deepseek-r1
"
]
# You can also add "gpt-4.5-preview-2025-02-27"
self
.
opponent_strategies
=
{
"
always_rock
"
:
lambda
history
:
"
Rock
"
,
"
always_paper
"
:
lambda
history
:
"
Paper
"
,
"
always_scissor
"
:
lambda
history
:
"
Scissor
"
,
"
R-P
"
:
self
.
loop_R_P
,
"
P-S
"
:
self
.
loop_P_S
,
"
S-R
"
:
self
.
loop_S_R
,
"
R-P-S
"
:
self
.
loop_R_P_S
}
self
.
temperature
=
0.7
self
.
rounds
=
10
self
.
num_games_per_config
=
10
self
.
initialize_csv
()
def
loop_R_P
(
self
,
history
):
"""
Alternates between Rock and Paper (R-P)
"""
if
len
(
history
)
%
2
==
0
:
return
"
Rock
"
else
:
return
"
Paper
"
def
loop_P_S
(
self
,
history
):
"""
Alternates between Paper and Scissors (P-S)
"""
if
len
(
history
)
%
2
==
0
:
return
"
Paper
"
else
:
return
"
Scissor
"
def
loop_S_R
(
self
,
history
):
"""
Alternates between Scissors and Rock (S-R)
"""
if
len
(
history
)
%
2
==
0
:
return
"
Scissor
"
else
:
return
"
Rock
"
def
loop_R_P_S
(
self
,
history
):
"""
Alternates between Rock, Paper, and Scissors (R-P-S)
"""
strategies
=
[
"
Rock
"
,
"
Paper
"
,
"
Scissor
"
]
return
strategies
[
len
(
history
)
%
3
]
def
initialize_csv
(
self
):
if
not
os
.
path
.
exists
(
CSV_FILE_PATH
):
os
.
makedirs
(
os
.
path
.
dirname
(
CSV_FILE_PATH
),
exist_ok
=
True
)
with
open
(
CSV_FILE_PATH
,
mode
=
"
w
"
,
newline
=
""
)
as
file
:
writer
=
csv
.
writer
(
file
)
writer
.
writerow
([
"
idGame
"
,
"
model
"
,
"
opponentStrategy
"
,
"
idRound
"
,
"
playerMove
"
,
"
opponentMove
"
,
"
outcomeRound
"
,
"
currentPlayerScoreGame
"
,
"
motivations
"
])
def
sanitize_motivations
(
self
,
motivations
:
str
)
->
str
:
sanitized
=
motivations
.
replace
(
'"'
,
'""'
)
sanitized
=
sanitized
.
replace
(
'
\n
'
,
'
'
).
replace
(
'
\r
'
,
''
)
if
sanitized
and
sanitized
[
0
]
in
(
'
=
'
,
'
+
'
,
'
-
'
,
'
@
'
):
sanitized
=
"'"
+
sanitized
return
f
'"
{
sanitized
}
"'
def
log_to_csv
(
self
,
game_id
,
model
,
opponent_strategy
,
round_id
,
agent_move
,
opponent_move
,
outcome
,
player_score_game
,
motivations
):
sanitized_motivations
=
self
.
sanitize_motivations
(
motivations
)
with
open
(
CSV_FILE_PATH
,
mode
=
"
a
"
,
newline
=
""
)
as
file
:
writer
=
csv
.
writer
(
file
)
writer
.
writerow
([
game_id
,
model
,
opponent_strategy
,
round_id
,
agent_move
,
opponent_move
,
outcome
,
player_score_game
,
sanitized_motivations
])
async
def
run_experiment
(
self
):
"""
Runs the experiment for all configurations.
"""
tasks
=
[]
game_id
=
1
for
model
in
self
.
models
:
for
strategy_name
,
strategy_fn
in
self
.
opponent_strategies
.
items
():
for
_
in
range
(
self
.
num_games_per_config
):
tasks
.
append
(
self
.
run_game
(
model
,
strategy_name
,
strategy_fn
,
game_id
))
game_id
+=
1
await
asyncio
.
gather
(
*
tasks
)
async
def
run_game
(
self
,
model
,
opponent_strategy_name
,
opponent_strategy_fn
,
game_id
):
game
=
RPS
(
model
=
model
,
temperature
=
self
.
temperature
,
game_id
=
game_id
,
opponent_strategy_fn
=
opponent_strategy_fn
)
for
i
in
range
(
1
,
self
.
rounds
+
1
):
round_data
=
await
game
.
play_round
(
i
)
self
.
log_to_csv
(
game_id
,
model
,
opponent_strategy_name
,
i
,
round_data
[
"
Agent Move
"
],
round_data
[
"
Opponent Move
"
],
round_data
[
"
Outcome
"
],
game
.
player_score_game
,
round_data
[
"
Motivations
"
])
# Running the experiment:
if
__name__
==
"
__main__
"
:
experiment
=
RPSExperiment
()
asyncio
.
run
(
experiment
.
run_experiment
())
print
(
"
Experiment completed. Results saved in
"
,
CSV_FILE_PATH
)
\ No newline at end of file
This diff is collapsed.
Click to expand it.
Prev
1
2
3
Next
Preview
0%
Loading
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!
Save comment
Cancel
Please
register
or
sign in
to comment