//======================================================================================== // // the data and tension - 3.10.09 Joe Mariglio // //----------------------------------------------------------------------------------------- // // this library is for simulating tests of tdat rulesets and sourcetexts. // it should do so sonically. // // TDAT_Player : a single player. // each player has a potentially unique ruleset // players in the same game 'listen' for trigger words from each other, // changing state accordingly // turns may be taken synchronously or asynchronously, that's up to you. // // TDAT_Game : a game instance. // //========================================================================================= TDAT_Game { var <>txt, //-------> array of strings <>players, //--> array of TDAT_Players <>limit, //--> int <>status, //-------> array of booleans <>matrix, //-------> 2d Array of ints <>stops, //-------> array of ints <>turns = 0; //--> int *new {| txt, players, limit | ^super.newCopyArgs( txt ?? [""], players ?? [], limit ? 4 ).initGame } initGame { players.do{_.game_(this)} } initMatrix { matrix = (0!txt.size)!players.size } initStops { stops = 0!players.size; status = false!players.size; } addPlayer {| player | if (players.includes(player).not, { players = players.add(player); }); } writeStatFile {| path | var file, stats; file = File(path, "w"); file.write("~turns:"++"\n"); file.write(turns.asString++"\n"); file.write("wordlimit:"++"\n"); file.write(limit.asString++"\n"); if(matrix.notNil, { file.write("matrix:"++"\n"); file.write(matrix.asString++"\n"); file.write(matrix.normalizeSum.asString++"\n") }); if(stops.notNil, { file.write("stops:"++"\n"); file.write(stops.asString++"\n"); file.write((stops/turns).asString++"\n"); }); file.write("text:"++"\n"); file.write(txt.asString++"\n"); file.write("triggers:"); players.do{| player, i | file.write("\n"++"player"+i.asString++":\n"); player.rules.keys.do{| trig | file.write(trig.asString); }; }; file.close; } writeMatrixFile {| path | var file; file = File(path, "w"); matrix.do{| array | array.do{| value | file.write(value.asString++" "); }; file.write("\n"); }; file.close; } wTranMatFile {| path | var file, tmat; tmat = matrix.normalizeSum; file = File(path, "w"); tmat.do{| array | array.do{| value | file.write(value.asString++" "); }; file.write("\n"); }; file.close; } } TDAT_Player { var <>game, //-------> TDAT_Game <>rules, //-------> Dictionary <>page, //-------> Integer <>index, //-------> Integer <>stopped, //--> boolean <>count = 0, //--> int <>pindex = 0, //--> int <>said; //-------> 'word', at this point a Char *new {| game, rules, page, index, stopped | ^super.newCopyArgs( game ? {TDAT_Game.new}, rules ? {Dictionary.new}, page ? 0, index ? 0, stopped ? true ).initPlayer } initPlayer { game.addPlayer(this); pindex = game.players.indexOf(this); } choose { index = (game.txt[page].size -1).rand } jumpTo {| state | page = state; this.choose; count = 0; stopped = false; game.status[pindex] = true; } hear {| input | var state = rules.at(input); if (state.notNil, { if(state!=page, { this.jumpTo( state ); if(game.matrix.notNil, { game.matrix[pindex][page] = game.matrix[pindex][page] + 1; }); }); }); } readNext {| txt, pg, in | ^txt[pg][in] } readNextWrap {| txt, pg, in| ^txt[pg].wrapAt(in) } others { ^game.players.reject({|x| x==this}) } speak {| word | this.others.do({| player | player.hear(word) }); said = word; count = count + 1; stopped = count > game.limit; } turn { if(stopped.not, { var txt = game.txt; var word = this.readNextWrap(txt, page, index); index = index + 1; game.turns = game.turns + 1; this.speak(word.asString); }, { if(game.stops.notNil, { if(game.status[pindex] == true, { game.status[pindex] = false; game.stops[pindex] = game.stops[pindex] + 1; game.turns = game.turns + 1; }); }); }); } }