aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAiden Woodruff <woodra@rpi.edu>2025-11-16 23:38:16 -0500
committerAiden Woodruff <woodra@rpi.edu>2025-11-16 23:38:16 -0500
commitf7d2e7c8a70e4d96c5cbc4e8774599f351e59216 (patch)
tree214525435c077203944fdaa0a273801f5b381aea
parente3b2c19dae58430823913c5b6dc0e45617ca6116 (diff)
downloadtipping-points-f7d2e7c8a70e4d96c5cbc4e8774599f351e59216.tar.gz
tipping-points-f7d2e7c8a70e4d96c5cbc4e8774599f351e59216.tar.bz2
tipping-points-f7d2e7c8a70e4d96c5cbc4e8774599f351e59216.zip
add strategy_record
- src/NameGame.h: add strategy record as vector of tuples. - src/NameGame.cc (runRound): remove each round printout but update the strategy record. - fix speaker memory update. - (clearRecord): add function. - (writeRecord): add function to output CSV file with record info. - (NameGame::run): print average strategy. - src/main.cc: clear memory and run 1000 rounds. - TASKS.md: update tasks Signed-off-by: Aiden Woodruff <woodra@rpi.edu>
-rw-r--r--TASKS.md2
-rw-r--r--src/NameGame.cc42
-rw-r--r--src/NameGame.h5
-rw-r--r--src/main.cc3
4 files changed, 44 insertions, 8 deletions
diff --git a/TASKS.md b/TASKS.md
index 2c2e8cf..2947571 100644
--- a/TASKS.md
+++ b/TASKS.md
@@ -3,5 +3,7 @@
3## To do 3## To do
4 4
5- Collect stats on game rounds. 5- Collect stats on game rounds.
6 - Add round number so that the tipping point can be found in time.
7 - Add group size, cm size, memory length.
6- Output data for graphing. 8- Output data for graphing.
7 9
diff --git a/src/NameGame.cc b/src/NameGame.cc
index 8ea3dcf..022b951 100644
--- a/src/NameGame.cc
+++ b/src/NameGame.cc
@@ -1,3 +1,4 @@
1#include <fstream>
1#include <iostream> 2#include <iostream>
2#include <map> 3#include <map>
3#include <stdexcept> 4#include <stdexcept>
@@ -75,9 +76,16 @@ void NameGame::run(int rounds) {
75 for (int i = 0; i < rounds; ++i) runRound(); 76 for (int i = 0; i < rounds; ++i) runRound();
76 // Track all plays and plays by non-CM. 77 // Track all plays and plays by non-CM.
77 // Report average plays. 78 // Report average plays.
79 float avg = 0;
80 for (const auto r : strategy_record) {
81 avg += std::get<2>(r) + std::get<3>(r);
82 }
83 avg /= strategy_record.size();
84 std::cout << avg << std::endl;
78} 85}
79 86
80void NameGame::runRound() { 87void NameGame::runRound() {
88 bool verbose_flag = false;
81 // Select random speaker and hearer. 89 // Select random speaker and hearer.
82 auto speaker = graph.GetNI(dist(rng)); 90 auto speaker = graph.GetNI(dist(rng));
83 auto hearer = graph.GetNI( 91 auto hearer = graph.GetNI(
@@ -86,21 +94,26 @@ void NameGame::runRound() {
86 94
87 // Speaker chooses best strategy. 95 // Speaker chooses best strategy.
88 int s_strategy = best_move(speaker.GetId()); 96 int s_strategy = best_move(speaker.GetId());
89 std::cout << "speaker (" << speaker.GetId() << " " 97 if (verbose_flag) {
90 << std::boolalpha << speaker().Val1 98 std::cout << "speaker (" << speaker.GetId() << " "
91 << ") chose: " << s_strategy << std::endl; 99 << std::boolalpha << speaker().Val1
100 << ") chose: " << s_strategy << std::endl;
101 }
92 102
93 // Listener updates memory. 103 // Listener updates memory.
94 update_memory(hearer.GetId(), s_strategy); 104 update_memory(hearer.GetId(), s_strategy);
95 105
96 // Listener chooses best strategy. 106 // Listener chooses best strategy.
97 int h_strategy = best_move(hearer.GetId()); 107 int h_strategy = best_move(hearer.GetId());
98 std::cout << "hearer (" << hearer.GetId() << " " 108 if (verbose_flag) {
99 << std::boolalpha << hearer().Val1 109 std::cout << "hearer (" << hearer.GetId() << " "
100 << ") chose: " << h_strategy << std::endl; 110 << std::boolalpha << hearer().Val1
111 << ") chose: " << h_strategy << std::endl;
112 }
101 113
102 // Speaker updates memory. 114 // Speaker updates memory.
103 update_memory(speaker.GetId(), s_strategy); 115 update_memory(speaker.GetId(), h_strategy);
116 strategy_record.emplace_back(speaker.GetId(), hearer.GetId(), s_strategy, h_strategy);
104} 117}
105 118
106int NameGame::best_move(int nId) const { 119int NameGame::best_move(int nId) const {
@@ -127,4 +140,19 @@ void NameGame::update_memory(int nId, int strategy) {
127 } 140 }
128} 141}
129 142
143void NameGame::clearRecord() {
144 strategy_record.clear();
145}
146
147void NameGame::writeRecord(const char* fname) {
148 std::ofstream f(fname);
149 f << "speaker,hearer,speaker_strategy,hearer_strategy\n";
150 int speaker, hearer, s_strategy, h_strategy;
151 for (const auto& r : strategy_record) {
152 std::tie(speaker, hearer, s_strategy, h_strategy) = r;
153 f << speaker << ',' << hearer << ',' << s_strategy << ','
154 << h_strategy << '\n';
155 }
156}
157
130} // namespace tp 158} // namespace tp
diff --git a/src/NameGame.h b/src/NameGame.h
index 8a817ce..73f5630 100644
--- a/src/NameGame.h
+++ b/src/NameGame.h
@@ -2,6 +2,8 @@
2#define TIPPING_POINTS_NAMEGAME_H 2#define TIPPING_POINTS_NAMEGAME_H
3 3
4#include <random> 4#include <random>
5#include <tuple>
6#include <vector>
5 7
6#include <Snap.h> 8#include <Snap.h>
7 9
@@ -15,7 +17,9 @@ public:
15 17
16 void initGraph(); 18 void initGraph();
17 void initMemory(); 19 void initMemory();
20 void clearRecord();
18 void run(int rounds); 21 void run(int rounds);
22 void writeRecord(const char* fname);
19 23
20protected: 24protected:
21 int best_move(int nId) const; 25 int best_move(int nId) const;
@@ -27,6 +31,7 @@ private:
27 std::mt19937 rng; 31 std::mt19937 rng;
28 std::uniform_int_distribution<> dist; 32 std::uniform_int_distribution<> dist;
29 TNodeNet<TPair<TBool, TIntV>> graph; 33 TNodeNet<TPair<TBool, TIntV>> graph;
34 std::vector<std::tuple<int, int, int, int> > strategy_record;
30}; // class NameGame 35}; // class NameGame
31 36
32} // namespace tp 37} // namespace tp
diff --git a/src/main.cc b/src/main.cc
index e41f4ff..9f47446 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -7,10 +7,11 @@ int main(int argc, char* argv[]) {
7 tp::NameGame namegame(group_size, 0); 7 tp::NameGame namegame(group_size, 0);
8 for (int cmperc = 18; cmperc < 28; cmperc += 2) { 8 for (int cmperc = 18; cmperc < 28; cmperc += 2) {
9 int cmsize = group_size * cmperc / 100; 9 int cmsize = group_size * cmperc / 100;
10 namegame.clearRecord();
10 namegame.setCMsize(cmsize); 11 namegame.setCMsize(cmsize);
11 namegame.initMemory(); 12 namegame.initMemory();
12 std::cout << "CM " << cmsize << " / " << group_size << std::endl; 13 std::cout << "CM " << cmsize << " / " << group_size << std::endl;
13 namegame.run(10); 14 namegame.run(1000);
14 } 15 }
15 return 0; 16 return 0;
16} 17}