SHARE
TWEET

Alfredo subnormal

a guest Nov 17th, 2019 69 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. using Assets.Scripts.DataStructures;
  2. using UnityEngine;
  3. using System.Linq;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.IO;
  7.  
  8. namespace Assets.Scripts.SampleMind {
  9.     public class RandomMind : AbstractPathMind {
  10.  
  11.         //Si ya está generado el .txt con las tablas, poner este valor a true evitará generar las tablas Q y R de nuevo.
  12.         bool tablaCreada = false;
  13.  
  14.         //Valores de alpha y gamma usados en la generación de la tabla Q.
  15.         float alpha = 0.3f;
  16.         float gamma = 0.8f;
  17.  
  18.         //Inicialización de tablas Q y R que se van a volcar en los .txt.
  19.         double[,] R = new double[112, 112];
  20.         double[,] Q = new double[112, 4];
  21.  
  22.         //Flag para que solo sea lean los .txt una vez.
  23.         bool flagRead = false;
  24.  
  25.         //Valores que controlan la generación de la tabla Q.
  26.         int iterations = 1000;
  27.         int maxPasos = 250;
  28.  
  29.         //Inicalización de la tabla Q tras leer el .txt.
  30.         double[,] QTable = new double[112, 4];
  31.  
  32.         public override void Repath() {
  33.  
  34.         }
  35.  
  36.         public override Locomotion.MoveDirection GetNextMove(BoardInfo boardInfo, CellInfo currentPos, CellInfo[] goals) {
  37.  
  38.             //Evita crear las tablas más de una vez.
  39.             if (!tablaCreada) {
  40.                 CreateTables(boardInfo, currentPos, goals[0]);
  41.                 tablaCreada = true;
  42.             }
  43.  
  44.             //Evita leer las tablas más de una vez.
  45.             if (!flagRead) {
  46.                 ReadTables(QTable);
  47.                 flagRead = true;
  48.             }
  49.  
  50.             //Elige el movimiento en función del valor de Q más alto.
  51.             double[] possibleQ = { QTable[currentPos.ColumnId + currentPos.RowId * boardInfo.NumColumns, 0], QTable[currentPos.ColumnId + currentPos.RowId * boardInfo.NumColumns, 1], QTable[currentPos.ColumnId + currentPos.RowId * boardInfo.NumColumns, 2], QTable[currentPos.ColumnId + currentPos.RowId * boardInfo.NumColumns, 3] };
  52.             Array.Sort(possibleQ);
  53.             for (int i = 3; i >= 0; i--) {
  54.                 if (possibleQ[i] == QTable[currentPos.ColumnId + currentPos.RowId * boardInfo.NumColumns, 0]) {
  55.                     if (boardInfo.CellInfos[currentPos.ColumnId, currentPos.RowId + 1].Walkable) {
  56.                         return Locomotion.MoveDirection.Up;
  57.                     }
  58.                 } else if (possibleQ[i] == QTable[currentPos.ColumnId + currentPos.RowId * boardInfo.NumColumns, 1]) {
  59.                     if (boardInfo.CellInfos[currentPos.ColumnId + 1, currentPos.RowId].Walkable) {
  60.                         return Locomotion.MoveDirection.Right;
  61.                     }
  62.                 } else if (possibleQ[i] == QTable[currentPos.ColumnId + currentPos.RowId * boardInfo.NumColumns, 2]) {
  63.                     if (boardInfo.CellInfos[currentPos.ColumnId, currentPos.RowId - 1].Walkable) {
  64.                         return Locomotion.MoveDirection.Down;
  65.                     }
  66.                 } else {
  67.                     if (boardInfo.CellInfos[currentPos.ColumnId - 1, currentPos.RowId].Walkable) {
  68.                         return Locomotion.MoveDirection.Left;
  69.                     }
  70.                 }
  71.             }
  72.             return Locomotion.MoveDirection.None;
  73.         }
  74.  
  75.         private void CreateTables(BoardInfo board, CellInfo currentPos, CellInfo goal) {
  76.  
  77.             //Inicializa las tablas a los valores por defecto, Q a 0, R a -1.
  78.             Array.Clear(Q, 0, Q.Length);
  79.             for (int i = 0; i < board.NumColumns * board.NumRows; i++) {
  80.                 for (int j = 0; j < board.NumColumns * board.NumRows; j++) {
  81.                     R[i, j] = -1;
  82.                 }
  83.             }
  84.  
  85.             CellInfo pos = currentPos;
  86.             CellInfo[] vecinos;
  87.  
  88.             //Rellena los valores de R que son 0 y 100.
  89.             for (int i = 0; i < board.NumColumns * board.NumRows; i++) {
  90.                 vecinos = pos.WalkableNeighbours(board);
  91.                 for (int j = 0; j < 4; j++) {
  92.                     if (vecinos[j] != null) {
  93.                         if (vecinos[j] == goal) {
  94.                             R[i, vecinos[j].ColumnId + vecinos[j].RowId * board.NumColumns] = 100;
  95.                         } else {
  96.                             R[i, vecinos[j].ColumnId + vecinos[j].RowId * board.NumColumns] = 0;
  97.                         }
  98.                     }
  99.                 }
  100.  
  101.                 if (i < (board.NumColumns * board.NumRows - 1)) {
  102.                     do {
  103.                         if (pos.ColumnId < (board.NumColumns - 1)) {
  104.                             pos = board.CellInfos[pos.ColumnId + 1, pos.RowId];
  105.                         } else {
  106.                             pos = board.CellInfos[0, pos.RowId + 1];
  107.                         }
  108.  
  109.                         if (!pos.Walkable) {
  110.                             i++;
  111.                         }
  112.                     } while (!pos.Walkable && i < (board.NumColumns * board.NumRows - 1));
  113.                 }
  114.             }
  115.  
  116.             int auxPos, auxSig;
  117.             CellInfo sig;
  118.             int rand;
  119.  
  120.             //Rellena la tabla Q.
  121.             for (int i = 0; i < iterations; i++) {
  122.                 //Asegura que la posición inicial de la simulación sea una celda caminable.
  123.                 do {
  124.                     pos = board.CellInfos[UnityEngine.Random.Range(0, board.NumColumns), UnityEngine.Random.Range(0, board.NumRows)];
  125.                 } while (!pos.Walkable);
  126.  
  127.                 //Simula de forma aleatoria los pasos hacia la meta. Si lleva *maxPasos* pasos sin dar con la meta, se salta a la siguiente simulación.
  128.                 for (int j = 0; j < maxPasos; j++) {
  129.                     //Si llega a la meta, se acaba esta simulación.
  130.                     if (pos == goal) {
  131.                         break;
  132.                     }
  133.                     //Cogemos los vecinos a los que puede moverse para elegir el siguiente movimiento.
  134.                     vecinos = pos.WalkableNeighbours(board);
  135.                     do {
  136.                         rand = UnityEngine.Random.Range(0, 4);
  137.                         sig = vecinos[rand];
  138.                     } while (sig == null);
  139.  
  140.                     //Actualiza la posición.
  141.                     auxPos = pos.ColumnId + pos.RowId * board.NumColumns;
  142.                     auxSig = sig.ColumnId + sig.RowId * board.NumColumns;
  143.                    
  144.                     //Actualizamos el valor de Q según la función de QLearning.
  145.                     double[] QPrima = { Q[auxSig, 0], Q[auxSig, 1], Q[auxSig, 2], Q[auxSig, 3] };
  146.                     double QMax = QPrima.Max();
  147.                     Q[auxPos, rand] = Q[auxPos, rand] * (1 - alpha) + alpha * (R[auxPos, auxSig] + gamma * QMax);
  148.                     pos = sig;
  149.                 }
  150.             }
  151.  
  152.             //Escribe en R.txt en el escritorio la tabla R.
  153.             StreamWriter outputFile = new StreamWriter(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "R.txt"));
  154.             string fila;
  155.             for (int i = 0; i < board.NumColumns * board.NumRows; i++) {
  156.                 fila = "";
  157.                 for (int j = 0; j < board.NumColumns * board.NumRows; j++) {
  158.                     fila += R[i, j] + " ";
  159.                 }
  160.                 outputFile.WriteLine(fila);
  161.             }
  162.             outputFile.Close();
  163.  
  164.             //Escribe en Q.txt en el escritorio la tabla Q.
  165.             outputFile = new StreamWriter(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Q.txt"));
  166.             for (int i = 0; i < board.NumColumns * board.NumRows; i++) {
  167.                 fila = Q[i, 0] + " " + Q[i, 1] + " " + Q[i, 2] + " " + Q[i, 3];
  168.                 outputFile.WriteLine(fila);
  169.             }
  170.             outputFile.Close();
  171.         }
  172.  
  173.         //Método que lee la tabla Q desde el archivo Q.txt.
  174.         private double[,] ReadTables(double[,] QTable) {
  175.             StreamReader file = new StreamReader(@"C:/Users/" + Environment.UserName + "/Desktop/Q.txt");
  176.  
  177.             string line;
  178.             int i = 0, j = 0;
  179.             while ((line = file.ReadLine()) != null) {
  180.                 foreach (string input in line.Split(' ')) {
  181.                     QTable[i, j] = double.Parse(input);
  182.                     j++;
  183.                 }
  184.                 j = 0;
  185.                 i++;
  186.             }
  187.             return QTable;
  188.         }
  189.     }
  190. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Not a member of Pastebin yet?
Sign Up, it unlocks many cool features!
 
Top