/// <summary> /// Extends a node by creating a child fore each available action /// </summary> /// <param name="node">Parent node</param> private void ExtendNode(M_Node node) { Debug.Log("Expandiendo nodos"); treeMutex.WaitOne(); //security check //if the game in the node has already been won we don't extend it if (node.State.SomeoneWon() != GlobalData.NO_PLAYER) { // Debug.Log("El nodo contiene victoria, no se expande"); return; } //if the array already has children if (tree[node.Position * 5 + 1] != null) { // Debug.LogError("EL NODO QUE SE HA EXPANDIDO YA TIENE HIJOS"); } //we get the state in the node TGame initial = node.State; M_Node aux; //for each action we... for (int i = 0; i < GlobalData.NUMBER_OF_ACTIONS; i++) { if (((Actions)i == Actions.AttackNeutral && !node.State.PlayerCanAttackNeutral()) || ((Actions)i == Actions.Heal && !node.State.PlayerCanHeal(id)) || ((Actions)i == Actions.Upgrade && !node.State.PlayerCanLevelUp(id))) { aux = new M_Node(null, ((node.Position * 5) + i + 1)); Debug.Log("El nodo " + aux.Position + " se ha hecho inalcanzable porque representa una accion que no puede ejecutarse"); aux.Available = false; node.freeChildren--; tree[aux.Position] = aux; } ///...execute the action and advance the corresponding turns... flowController.AdvanceTurnAndExecuteActions(id, (Actions)i, initial); ///...create the new node with a copy of this state aux = new M_Node(initial.TakeAndGetSnapshot(), ((node.Position * 5) + i + 1)); ///....restore the parent node state... initial.RestoreSnapshot(); ///...set the new node as a child tree[aux.Position] = aux; //if in this node someone already won... if (aux.State.SomeoneWon() != GlobalData.NO_PLAYER) { //if our player won, reward if (aux.State.SomeoneWon() == id) { aux.Score += GlobalData.MONTECARLO_REWARD; } else { aux.Score += GlobalData.MONTECARLO_PENALIZATION; } //backpropagate score BackpropagateScore(aux); //we mark th node as not available, so it wont be visited again aux.Available = false; node.freeChildren--; Debug.Log("El nodo " + aux.Position + " se ha hecho inalcanzable porque representa VICTORIA"); } Debug.Log("Se ha creado el nodo " + aux.Position); } treeMutex.ReleaseMutex(); }
private void Train() { someoneWon = false; currentWinner = GlobalData.NO_PLAYER; int turnsToAdvance = 1; int turnsBetweenAITicks = (int)(GlobalData.MILISECONDS_BETWEEN__AI_TICKS / GlobalData.MILISECONDS_BETWEEN_TICKS); int remainingTurnsForNextAITick = turnsBetweenAITicks; int gameTurns; while (gamesPlayed < TotalGamesToPlay) { //Debug.Log("COMENZANDO PARTIDA " + gamesPlayed + " DE " + TotalGamesToPlay); someoneWon = false; currentGame.RestoreSnapshot(); gameTurns = 0; RatioExtraScore = currentGame.GetUnitGenerationRatio(mPlayerId); while (!someoneWon) { if (gameTurns == 7) { RatioExtraScore = mPlayerId - RatioExtraScore; } if (gameTurns > 300) { currentWinner = GlobalData.TIE; someoneWon = true; break; } //check pending attacks and get turns for the arrival of the next attack turnsToAdvance = currentGame.CheckPendingAttacks(turnsToAdvance); //if the AI tick would happen before the attack arrived, we advance only //the necessary turns to trigger the AI tick if (turnsToAdvance > remainingTurnsForNextAITick) { turnsToAdvance = remainingTurnsForNextAITick; } //print("Avazamos " + turnsToAdvance + " turnos faltando " + remainingTurnsForNextAITick + " turnos para el AITick"); //check for victory (IMPORTANT TO DO IT AFTER THE ATTACKS AND NOT BEFORE) currentWinner = currentGame.SomeoneWon(); if (currentWinner != GlobalData.NO_PLAYER) { someoneWon = true; break; //Debug.Log("ALGUIEN HA GANADO: " + currentWinner); } //advance the obtained amount of normal turns currentGame.CreateUnits(turnsToAdvance); //print("Se han avanzado al fin " + turnsToAdvance + " turnos"); //if the time for an AI tick has come, do it remainingTurnsForNextAITick -= turnsToAdvance; if (remainingTurnsForNextAITick <= 0) { //Debug.Log("\n---------------------------TURNO------------------------\n"); //Debug.Log(" Tick de IA"); //Debug.Log("Ha ganado alguien? " + someoneWon); currentGame.AITick(); remainingTurnsForNextAITick = turnsBetweenAITicks; } /* while (!currentGame.EveryoneDecided()) * { * print("Esperando decision"); * yield return null; * }*/ //yield return null; } gamesPlayed++; } }