Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using DeepCopyExtensions;
- public class MinMaxAlgorithm: MoveMaker
- {
- public EvaluationFunction evaluator;
- private UtilityFunction utilityfunc;
- public int depth = 0;
- private PlayerController MaxPlayer;
- private PlayerController MinPlayer;
- private int MaxDepthTerminal= 1000;
- private bool Win;
- private State bestMove=null;
- public MinMaxAlgorithm(PlayerController MaxPlayer, EvaluationFunction eval, UtilityFunction utilf, PlayerController MinPlayer)
- {
- this.MaxPlayer = MaxPlayer;
- this.MinPlayer = MinPlayer;
- this.evaluator = eval;
- this.utilityfunc = utilf;
- }
- public override State MakeMove()
- {
- // The move is decided by the selected state
- Debug.Log("Entrou\n");
- return GenerateNewState();
- }
- private State GenerateNewState()
- {
- Debug.Log("Entrou2\n");
- // Creates initial state
- State initialState = new State(this.MaxPlayer, this.MinPlayer);
- // Call the MinMax implementation
- Debug.Log("Entrou3\n");
- State bestMove = MinMax(initialState);
- return bestMove;
- }
- //nos terminais-> funcao utilidade/recompensa
- //nos nao terminais-> funcao de avaliacao ->prever melhor jogada
- //10000
- public State MinMax(State currentState)
- {
- Debug.Log("Entrou4\n");
- float Value = ValMax(currentState);
- Debug.Log(Value);
- //Devolve movimento associado a esse valor máximo
- //State bestMove=null;
- return this.bestMove;
- }
- private float ValMin(State stateNode){
- Debug.Log("min\n");
- List<State> sucessors= GeneratePossibleStates(stateNode);
- if(stateNode.depth==MaxDepthTerminal|| evaluator.evaluate(stateNode)==-1){
- return utilityfunc.evaluate(stateNode);
- }
- float Value= Int32.MaxValue;
- foreach(State suc in sucessors){
- Value= Math.Min(Value, ValMax(suc));
- }
- return Value;
- }
- private float ValMax(State StateNode){
- Debug.Log("max\n");
- List<State> sucessors= GeneratePossibleStates(StateNode);
- if(StateNode.depth==MaxDepthTerminal|| evaluator.evaluate(StateNode)==-1){
- return utilityfunc.evaluate(StateNode);
- }
- float Value= Int32.MinValue;
- foreach(State suc in sucessors){
- Debug.Log(Value);
- // float result= evaluator.evaluate(suc);
- Value = Math.Max(Value, ValMin(suc));
- }
- return Value;
- }
- private List<State> GeneratePossibleStates(State state)
- {
- List<State> states = new List<State>();
- //Generate the possible states available to expand
- foreach(Unit currentUnit in state.PlayersUnits)
- {
- // Movement States
- List<Tile> neighbours = currentUnit.GetFreeNeighbours(state);
- foreach (Tile t in neighbours)
- {
- State newState = new State(state, currentUnit, true);
- newState = MoveUnit(newState, t);
- states.Add(newState);
- }
- // Attack states
- List<Unit> attackOptions = currentUnit.GetAttackable(state, state.AdversaryUnits);
- foreach (Unit t in attackOptions)
- {
- State newState = new State(state, currentUnit, false);
- newState = AttackUnit(newState, t);
- states.Add(newState);
- }
- }
- // YOU SHOULD NOT REMOVE THIS
- // Counts the number of expanded nodes;
- this.MaxPlayer.ExpandedNodes += states.Count;
- //
- return states;
- }
- private State MoveUnit(State state, Tile destination)
- {
- Unit currentUnit = state.unitToPermormAction;
- //First: Update Board
- state.board[(int)destination.gridPosition.x, (int)destination.gridPosition.y] = currentUnit;
- state.board[currentUnit.x, currentUnit.y] = null;
- //Second: Update Players Unit Position
- currentUnit.x = (int)destination.gridPosition.x;
- currentUnit.y = (int)destination.gridPosition.y;
- state.isMove = true;
- state.isAttack = false;
- return state;
- }
- private State AttackUnit(State state, Unit toAttack)
- {
- Unit currentUnit = state.unitToPermormAction;
- Unit attacked = toAttack.DeepCopyByExpressionTree();
- Tuple<float, float> currentUnitBonus = currentUnit.GetBonus(state.board, state.PlayersUnits);
- Tuple<float, float> attackedUnitBonus = attacked.GetBonus(state.board, state.AdversaryUnits);
- attacked.hp += Math.Min(0, (attackedUnitBonus.Item1)) - (currentUnitBonus.Item2 + currentUnit.attack);
- state.unitAttacked = attacked;
- if (attacked.hp <= 0)
- {
- //Board update by killing the unit!
- state.board[attacked.x, attacked.y] = null;
- int index = state.AdversaryUnits.IndexOf(attacked);
- state.AdversaryUnits.RemoveAt(index);
- }
- state.isMove = false;
- state.isAttack = true;
- return state;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement