public Tuple <CardGame, GameIterator> GetPrivateGame() { CardGame privategame = actualgameiterator.game.CloneSecret(idx); GameIterator privategameiterator = actualgameiterator.Clone(privategame); return(new Tuple <CardGame, GameIterator>(privategame, privategameiterator)); }
// TODO Find a better way to initialize AI Players public void AddPlayers(int numPlayers, GameIterator gameContext) { players = new Player[numPlayers]; for (int i = 0; i < numPlayers; ++i) { players[i] = new Player("p" + i, i); Perspective perspective = new Perspective(i, gameContext); players[i].decision = new RandomPlayer(perspective); } currentPlayer.Push(new StageCycle <Player>(players)); }
public bool TestingClone() { CardGame cg = actualgameiterator.game.Clone(); if (!cg.Equals(actualgameiterator.game)) { Console.WriteLine("Clone CardGame Not Equal -- Returning false"); return(false); } GameIterator g1 = new GameIterator(actualgameiterator.rules, cg, actualgameiterator.gameWorld, "blah", false); GameIterator g2 = actualgameiterator.Clone(cg); if (!g2.Equals(actualgameiterator)) { Console.WriteLine("Clone GameIterator Not Equal -- Returning false"); return(false); } return(true); }
public override int MakeAction(int numChoices) { // SetupPrivateGame sets "privategame" equal to actualgame.clonesecret(idx) and // sets "privateiterator" equal to actualgameiterator.clone() (CardGame privategame, GameIterator privateiterator) = perspective.GetPrivateGame(); int idx = perspective.GetIdx(); Debug.WriteLine("PIPMC making choice. items: " + numChoices); double[][] inverseRankSum = new double[perspective.NumberOfPlayers()][]; for (int i = 0; i < perspective.NumberOfPlayers(); i++) { inverseRankSum[i] = new double[numChoices]; } Debug.WriteLine("Start Monte"); // can parallellize here TODO ? // FOR EACH POSSIBLE MOVE for (int move = 0; move < numChoices; ++move) { Debug.WriteLine("iterating over item: " + move); Parallel.For(0, NUMTESTS, i => //number of tests for certain decision { Debug.WriteLine("****Made Switch**** : " + i); // JUST USING ONE CLONE SECRETGAME, CLONED FOR EACH MOVE CardGame cg = privategame.Clone(); GameIterator cloneContext = privateiterator.Clone(cg); // Make the chosen move List <GameActionCollection> allOptions = cloneContext.BuildOptions(); allOptions[move].ExecuteAll(); cloneContext.PopCurrentNode(); // Assign the AI players for rollout game for (int j = 0; j < numPlayers; j++) { cg.players[j].decision = new RandomPlayer(perspective); } Debug.WriteLine("Playing a simulated game"); while (!cloneContext.AdvanceToChoice()) { cloneContext.ProcessChoice(); } Debug.WriteLine("Simulated Game is Over"); // ProcessScore returns a sorted list // where the winner is rank 0 for either min/max games. var winners = cloneContext.ProcessScore(); Debug.WriteLine("past ProcessScore"); int topRank = 0; lock (this) { for (int j = 0; j < numPlayers; ++j) { if (j != 0 && winners[j].Item1 != winners[j - 1].Item1) { topRank = j; } inverseRankSum[winners[j].Item2][move] += (((double)1) / (topRank + 1)) / NUMTESTS; } } }); } // FIND BEST (and worst) MOVE TO MAKE var tup = MinMaxIdx(inverseRankSum[perspective.GetIdx()]); // Record info for heuristic evaluation RecordHeuristics(inverseRankSum); return(tup.Item2); }
// Perspective class: This class privitizes the actual game, while giving privileges to the player to // do whatever it wants with the cloned game and cloned game iterator. // A player who has a 'perspective' doesn't have privilege to accesss the gameiterator or cardgame. public Perspective(int idx, GameIterator actualgameiterator) { this.idx = idx; this.actualgameiterator = actualgameiterator; }
public void RunSimulation() { // Each turn, need to check to see if we have enough information to make move using UCB // If we do (movelist.count() == choicenum), and we check the stats of each move // A predictable player is set for the currentplayers idx which wil chose the move determined by // Movelist should be tuple array with each entry a state and a who played it // Its key should be a state and the idx of the player in charge HashSet <Tuple <CardGame, int> > visitedstates = new HashSet <Tuple <CardGame, int> >(); CardGame cg = privategame.Clone(); GameIterator gameIterator = privateiterator.Clone(cg); for (int j = 0; j < numPlayers; j++) { cg.players[j].decision = new RandomPlayer(perspective); } int idxme = cg.currentPlayer.Peek().idx; bool expand = true; bool first = true; // "Playing a simulated game" while (!gameIterator.AdvanceToChoice()) { int idx = cg.currentPlayer.Peek().idx; if (idxme == idx) { List <GameActionCollection> allOptions = gameIterator.BuildOptions(); Tuple <CardGame, int>[] movelist = null; int c = 0; if (expand) { int choicenum = allOptions.Count; Tuple <CardGame, int> deliberator = Tuple.Create <CardGame, int>(cg.Clone(), idx); if (!movestatetree.Keys.Contains(deliberator)) { movestatetree[deliberator] = new Tuple <CardGame, int> [choicenum]; } movelist = movestatetree[deliberator]; //Console.WriteLine("Choice num: " + choicenum + " Movelist Count: " + movelist.Count(s => s != null)); if (movelist.Count(s => s != null) == choicenum) { // USE UCB double bestscore = 0; c = 0; double totalplays = 0; foreach (Tuple <CardGame, int> stateandplay in (movelist)) { totalplays += plays[stateandplay]; } totalplays = Math.Log(totalplays); for (int i = 0; i < movelist.Length; i++) { Tuple <CardGame, int> stateandplay = movelist[i]; double temp = wins[stateandplay] / plays[stateandplay]; temp += Math.Sqrt(2 * totalplays / plays[stateandplay]); if (temp > bestscore) { bestscore = temp; c = i; } } allOptions[c].ExecuteAll(); gameIterator.PopCurrentNode(); } else { c = gameIterator.ProcessChoice(); } } else { c = gameIterator.ProcessChoice(); } CardGame savestate = gameIterator.game.Clone(); // THIS HELPS FIND ORIGINAL MOVE CHOICES if (first) { if (!movestates.Keys.Contains(c)) { movestates[c] = savestate; } first = false; } // Stateandplayer is Tuple with state after move, and the idx of the player who made the move Tuple <CardGame, int> stateandplayer = Tuple.Create <CardGame, int>(savestate, idx); // IF THIS IS THE FIRST SIMULATION WHICH HAS ARRIVED AT THIS STATE:: if (expand && (!plays.Keys.Contains(stateandplayer))) { expand = false; plays[stateandplayer] = 0; wins[stateandplayer] = 0; movelist[c] = stateandplayer; } visitedstates.Add(stateandplayer); } else { gameIterator.ProcessChoice(); } // IF IT ISNT MY MOVE, DONT KEEP ANY DATA } // ProcessScore returns a sorted list // where the winner is rank 0 for either min/max games. var winners = gameIterator.ProcessScore(); double[] inverseRankSum = new double[numPlayers]; int p = 0; foreach (Tuple <int, int> scoreandidx in winners) { inverseRankSum[scoreandidx.Item2] = ((double)1) / (p + 1); p++; } // GO THROUGH VISITED STATES foreach (Tuple <CardGame, int> stateandplayer in visitedstates) { if (plays.Keys.Contains(stateandplayer)) { plays[stateandplayer] += 1; wins[stateandplayer] += inverseRankSum[stateandplayer.Item2]; } } }