Advertisement
Guest User

Alfredo subnormal

a guest
Nov 17th, 2019
142
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.31 KB | None | 0 0
  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. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement