Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
d23b5ed
player 4 logic
akshatbhandari15 Sep 15, 2025
7348a38
ruff fix
akshatbhandari15 Sep 15, 2025
829b180
ruff fix 2
akshatbhandari15 Sep 15, 2025
421cb3e
ruff fix 3
akshatbhandari15 Sep 15, 2025
95fabfb
some changes with thresholding
akshatbhandari15 Sep 15, 2025
482c44d
some changes with thresholding
akshatbhandari15 Sep 15, 2025
4e20556
remove some print statements
akshatbhandari15 Sep 15, 2025
65089df
Merge branch 'main' into player-4
akshatbhandari15 Sep 15, 2025
5e337a4
remove some print statements 2
akshatbhandari15 Sep 15, 2025
e5bd8ad
player4 py
akshatbhandari15 Sep 15, 2025
8539200
added preferences scores for ranking items to propose
akshatbhandari15 Sep 17, 2025
ea89a9b
Merge branch 'lsig:main' into player-4
akshatbhandari15 Sep 17, 2025
ae930d3
added preferences scores for ranking items to propose
akshatbhandari15 Sep 17, 2025
36d8473
wrong repo
Cyno00 Sep 21, 2025
6f43167
wrong repo
Cyno00 Sep 21, 2025
319f6cd
readme
Cyno00 Sep 21, 2025
44cc858
restore latest player
Cyno00 Sep 21, 2025
18c1ca2
updated threshold
akshatbhandari15 Sep 22, 2025
920d2b2
Merge branch 'main' into player-4
akshatbhandari15 Sep 22, 2025
b3d32a4
formatting
akshatbhandari15 Sep 22, 2025
36f7408
formatting
akshatbhandari15 Sep 22, 2025
2fd1647
formatting
akshatbhandari15 Sep 24, 2025
bc424ca
Merge branch 'main' into player-4
akshatbhandari15 Sep 24, 2025
b1bb4ef
sim framework
Cyno00 Sep 24, 2025
694e956
remove torch dep
Cyno00 Sep 24, 2025
891eee0
sync
Cyno00 Sep 24, 2025
ecc1fd8
redo deps
Cyno00 Sep 24, 2025
de8f676
Merge branch 'player-4' into sim-framework
Cyno00 Sep 24, 2025
0c299dc
add readme and instructions on how to simulate
Cyno00 Sep 24, 2025
ae1baaf
Merge branch 'sim-framework' of https://github.com/Cyno00/Conversatio…
Cyno00 Sep 24, 2025
7bde430
Merge pull request #1 from Cyno00/sim-framework
akshatbhandari15 Sep 24, 2025
30bced5
analysis
Cyno00 Sep 29, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 3 additions & 19 deletions players/player_4/player.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,8 @@ def _coherence_prev3_score(self, item: Item, history: list[Item | None]) -> floa
"""
Coherence over the previous up to 3 non-pause items:
- Hot-streak penalty: if any subject in `item` appears in *each* of the last 3 -> -1.0
- Otherwise, reward based on total matched frequency across prev-3:
- Otherwise, reward based on total matched frequency across prev-3 for each subject:
sum_match/len(item.subjects)
sum_match >= 4 -> +1.5 (e.g., 2+2)
sum_match == 3 -> +1.0 (e.g., 2+1)
sum_match == 2 -> +0.5
sum_match == 1 -> +0.25
else -> 0.0
The window does not cross pauses.
"""
prev3 = self._take_preceding_block(history, 3)
Expand All @@ -93,15 +88,6 @@ def _coherence_prev3_score(self, item: Item, history: list[Item | None]) -> floa
common_all3 = sets[0] & sets[1] & sets[2]
if any(s in common_all3 for s in item.subjects):
return -1.0
"""if sum_match >= 4:
elif sum_match == 3:
return 1.0
elif sum_match == 2:
return 0.5
elif sum_match == 1:
return 0.25
else:
return 0.0"""
# Count subject frequencies across prev-3
counts = Counter()
for it in prev3:
Expand Down Expand Up @@ -200,9 +186,7 @@ def propose_item(self, history: list[Item | None]) -> Item | None:
if not scored:
return None
best_score = max(s for s, _ in scored)
# print(best_score)
# print(history)
# max_possible = 1.0 + 2.0 + 1.5 # importance + pause + coherence

threshold = 1
if len(history) != 0 and best_score < threshold:
return None
Expand All @@ -212,6 +196,6 @@ def propose_item(self, history: list[Item | None]) -> Item | None:

choice = tied[0] if len(tied) == 1 else min(tied, key=self._preference_tiebreak_key)

# Track contribution if you care downstream
# Track contribution
self.contributed_items.append(choice)
return choice
4 changes: 4 additions & 0 deletions players/player_4/readme.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
To simulate games:

1. Make changes to scenarios.yaml
2. From the root of the folder, uv run players/player_4/sim.py
59 changes: 59 additions & 0 deletions players/player_4/scenarios.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
scenarios:
- name: "test"
runs: 10
args:
subjects: 20
memory_size: 10
length: 10
players:
- ["p4", 5]
- ["prp", 1]

- name: "20s_10m_10l_2p_allprp"
runs: 100
args:
subjects: 20
memory_size: 10
length: 10
players:
- ["prp", 2]
- name: "20s_10m_10l_6p_allprp"
runs: 100
args:
subjects: 20
memory_size: 10
length: 10
players:
- ["prp", 6]
- name: "20s_10m_10l_10p_allprp"
runs: 100
args:
subjects: 20
memory_size: 10
length: 10
players:
- ["prp", 10]
- name: "20s_10m_10l_11p_allprp"
runs: 100
args:
subjects: 20
memory_size: 10
length: 10
players:
- ["prp", 11]
- name: "20s_10m_10l_12p_allprp"
runs: 100
args:
subjects: 20
memory_size: 10
length: 10
players:
- ["prp", 12]
- name: "20s_10m_10l_20p_allprp"
runs: 100
args:
subjects: 20
memory_size: 10
length: 10
players:
- ["prp", 20]
127 changes: 127 additions & 0 deletions players/player_4/sim.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
import asyncio
import json
import yaml
from datetime import datetime
from pathlib import Path
import multiprocessing
import time
import random

async def run_simulation(scenario_name, args, run_index, semaphore):
"""Run a single simulation"""
cmd = ['uv', 'run', 'main.py']

# Generate random seed for this run
run_seed = random.randint(0, 2**31 - 1)
cmd.extend(['--seed', str(run_seed)])

# Add simple arguments
for key in ['subjects', 'memory_size', 'length']:
if key in args:
cmd.extend([f'--{key}', str(args[key])])

# Add player arguments
if 'players' in args:
for player_type, count in args['players']:
cmd.extend(['--player', player_type, str(count)])

async with semaphore:
proc = await asyncio.create_subprocess_exec(
*cmd,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE
)

stdout, _ = await proc.communicate()

# Parse JSON output
json_output = "{" + stdout.decode().split("{", 1)[-1]
result = json.loads(json_output)

# Filter scores to only keep player_scores with id and scores fields
filtered_scores = {}
if 'scores' in result:
if 'player_scores' in result['scores']:
filtered_scores['player_scores'] = [
{'id': player['id'], 'scores': player['scores']}
for player in result['scores']['player_scores']
]
if "shared_score_breakdown" in result['scores']:
filtered_scores['shared_score_breakdown'] = result['scores']['shared_score_breakdown']

# Keep only turn_impact and filtered scores
filtered_result = {
# 'turn_impact': result.get('turn_impact'),
'scores': filtered_scores
}

return {
'scenario': scenario_name,
'run': run_index,
'seed': run_seed,
'args': args,
'result': filtered_result
}

async def run_scenario(scenario, semaphore):
"""Run all iterations of a single scenario"""
name = scenario['name']
runs = scenario['runs']

print(f"Starting scenario '{name}' ({runs} runs)...")
start = time.time()

# Run all iterations of this scenario
results = await asyncio.gather(*[
run_simulation(name, scenario['args'], i, semaphore)
for i in range(runs)
])

elapsed = time.time() - start
print(f" Completed '{name}': {runs} runs in {elapsed:.1f}s ({elapsed/runs}s per run)")

return results

async def main():
import sys

# Load config
config_file = sys.argv[1] if len(sys.argv) > 1 else 'players/player_4/scenarios.yaml'
with open(config_file) as f:
scenarios = yaml.safe_load(f)['scenarios']

# Create all tasks
tasks = []
for scenario in scenarios:
for i in range(scenario['runs']):
tasks.append((scenario['name'], scenario['args'], i))

print(f"Running {len(tasks)} simulations on {multiprocessing.cpu_count()*2} parallel processes...")
start_time = time.time()

# Run with concurrency limit
semaphore = asyncio.Semaphore(multiprocessing.cpu_count() * 2)

# Run each scenario and flatten results
all_results = []
for scenario in scenarios:
scenario_results = await run_scenario(scenario, semaphore)
all_results.extend(scenario_results)

elapsed = time.time() - start_time
print(f"\nAll scenarios complete!")

# Save results
output_dir = Path('players/player_4/results')
output_dir.mkdir(exist_ok=True)

timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
output_file = output_dir / f'results_{timestamp}.json'

with open(output_file, 'w') as f:
json.dump(all_results, f, indent=2)

print(f"Saved {len(all_results)} results to {output_file}")

if __name__ == '__main__':
asyncio.run(main())
5 changes: 5 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ dependencies = [
"ruff>=0.12.8",
"numpy>=2.3.3",
"torch>=2.8.0",
"aiofiles",
"numpy",
"pandas",
"matplotlib",
"seaborn"
]

[tool.ruff]
Expand Down
Loading
Loading