public int expand(Node p, HeuristicType ht) { Playfield afterState = new Playfield(p.state); ParetoMCTSPlayer m_player = new ParetoMCTSPlayer(new ParetoTreePolicy(0.7), GameManager.getRNG(), afterState, ht); m_player.run(afterState, 30000, false); //m_player.m_root.printStats(); //Helpfunctions.Instance.logg("turn: " + p.state.isOwnTurn); int memberSize = m_player.m_root.pa.m_members.size(); // will it always > 0? for (int i = 0; i < memberSize; i++) // this is other's turn { Node afterNode; Playfield pf = m_player.m_root.pa.m_members.get(i).m_state; if (ht == HeuristicType.DrawCard) { if (pf.moveTrigger.newHandcardList.Count == 0) { continue; } afterNode = new ChanceNode(p, pf, null, p.depth, 1); //last param is wrong pf.printActions(); } else if (ht == HeuristicType.LethalCheck) { if (pf.getLethalScore() == 1.0) { afterNode = new Node(p, pf, null, p.depth + 1); } continue; } else { afterNode = new Node(p, pf, null, p.depth + 1); } p.children.Add(afterNode); } return(p.children.Count); }
public Node advanceChance(ChanceNode p) { double prob = GameManager.getRNG().NextDouble(); int i; double probSum = 0.0; for (i = 0; i < p.probability.Count; i++) { probSum += p.probability[i]; if (prob < probSum) { break; } } if (i == 0 && p.children.Count == 0) { throw new NullReferenceException(); //p.state.printBoard(); } return(p.children[i]); }
public int expandDecision(Node p, int numIter) //0: chance node { bool lethalCheck = false; p.state.moveList = new List <Action>(Movegenerator.Instance.getMoveList(p.state, lethalCheck, true, true, 0.0)); Playfield afterState = new Playfield(p.state); //if (GameManager.Instance.debug == 2) //{ // //afterState.printBoard(); //} if (afterState.moveList.Count > 0) { p.children = new List <Node>(afterState.moveList.Count + 1); Node tn = null; Playfield nextState = new Playfield(afterState); foreach (Action a in afterState.moveList) { nextState = new Playfield(afterState); nextState.doAction(a); tn = new Node(null, nextState, a, p.depth); p.children.Add(tn); } return(p.children.Count); } else { //No move, so it's a chance node afterState.endTurn(false, false); Node afterNode = new ChanceNode(p, afterState, null, p.depth + 1, 1); p.children.Add(afterNode); return(0); } }
public int expand(Node p, HeuristicType ht, int numberIter) { Playfield afterState = new Playfield(p.state); ParetoMCTSPlayer m_player = new ParetoMCTSPlayer(new ParetoTreePolicy(0.7), GameManager.getRNG(), afterState, ht); m_player.run(afterState, numberIter, false); //m_player.m_root.printStats(); //Helpfunctions.Instance.logg("turn: " + p.state.isOwnTurn); int memberSize = m_player.m_root.pa.m_members.size(); // will it always > 0? //if (ht == HeuristicType.Boardvalue) // m_player.m_root.pa.printArchive(); if (ht == HeuristicType.DrawCard) { Console.WriteLine("chance: " + memberSize); if (memberSize > 1) { chanceCount += memberSize - 1; } m_player.m_root.pa.printArchive(); } for (int i = 0; i < memberSize; i++) // this is other's turn { Node afterNode; Playfield pf = m_player.m_root.pa.m_members.get(i).m_state; if (ht == HeuristicType.DrawCard) { if (pf.moveTrigger.newHandcardList.Count == 0) { continue; } if ((pf.isOwnTurn && pf.homeDeck.Count > 0) || (!pf.isOwnTurn && pf.awayDeck.Count > 0)) { List <Action> actionList = pf.getActions(); Playfield tempPf = new Playfield(afterState); for (int j = tempPf.getActions().Count; j < actionList.Count - 1; j++) { tempPf.doAction(actionList[j]); } afterNode = new ChanceNode(p, tempPf, actionList[actionList.Count - 1], p.depth, pf.moveTrigger.newHandcardList.Count); } else { afterNode = new Node(p, pf, null, p.depth); } if (memberSize > 1) { pf.printActions(); } //pf.printActions(); } else if (ht == HeuristicType.LethalCheck) { if (pf.getLethalScore() == 1.0) { afterNode = new Node(p, pf, null, p.depth + 1); } continue; } else { if ((pf.isOwnTurn && pf.homeDeck.Count > 0) || (!pf.isOwnTurn && pf.awayDeck.Count > 0)) { afterNode = new ChanceNode(p, pf, null, p.depth + 1, 1); } else { pf.drawTurnStartCard(); afterNode = new Node(p, pf, null, p.depth + 1); } } p.children.Add(afterNode); } return(p.children.Count); }
public void UCTRun(Node p, float c) { List <Node> visited = new List <Node>(); visited.Add(p); Node parent = null; while (!isLeaf(p) && p.depth < rolloutDepth) { parent = p; p = select(p, c); //chanceNode ChanceNode chanceNode = p as ChanceNode; if (chanceNode != null) { visited.Add(p); p = advanceChance(chanceNode); } visited.Add(p); //Console.WriteLine("Select D:" + p.depth + ", T:" + p.state.isOwnTurn); } float score; if (p.depth >= rolloutDepth) { //if (this.useNNEval) //{ // score = getDNNValue(p.state); //} //else //{ score = bh.getPlayfieldValue(p.state, this.playerSide); //} //score = bh.getPlayfieldValue(p.state, this.playerSide); } else { //int count = expand(p, HeuristicType.Boardvalue); //Helpfunctions.Instance.startTimer(); //p.state.drawTurnStartCard(); bool turnBefore = p.state.isOwnTurn; int depthBefore = p.depth; int count = expandDecision(p, playoutNumberIter); while (count == 0) { visited.Add(p); ChanceNode chanceNode = p.children[0] as ChanceNode; try { p = advanceChance(chanceNode); } catch (NullReferenceException ex) { throw; } count = expandDecision(p, playoutNumberIter); //Console.WriteLine("Ad D:" + p.depth + ", T:" + p.state.isOwnTurn); } //Helpfunctions.Instance.startTimer(); if (useNNEval) { score = MultilevelSample(p); } else { score = sample(p); } } if (log) { Console.WriteLine("score = " + score + "--------------------------------------"); } //update score foreach (Node visitedPos in visited) { float realScore = score; if (visitedPos.state.isOwnTurn != playerSide) { realScore = 1.0f - score; } if (log) { Console.WriteLine("turn:" + visitedPos.state.isOwnTurn + " score:" + realScore); } float lastMean = visitedPos.mean; visitedPos.mean = (realScore + lastMean * visitedPos.numVisited) / (visitedPos.numVisited + 1); visitedPos.numVisited++; } }