ИИ для 2D игры - C#

Узнай цену своей работы

Формулировка задачи:

Требовалось понять, не мешают ли стены (элементы world != 2) одному персонажу видеть другого. Решил делать через уравнение прямой y = k*x + b, в итоге видит через стены, за неделю так и не понял в чем проблема. plx,ply - координаты одного персонажа, x,y - другого.
Листинг программы
  1. private bool FOV(int plx, int ply)
  2. {
  3. if (x == plx)k = 0;
  4. else k = (Convert.ToDouble(y - ply) / Convert.ToDouble(x - plx));
  5. if (k > 0 ) b = System.Math.Min(ply, y);
  6. else b = System.Math.Max(ply, y);
  7. int i = System.Math.Min(plx, x);
  8. do // Выполнить хоть раз
  9. {
  10. if (k > -1)
  11. {
  12. for (int j = Convert.ToInt32(k * (i) + b); j < Convert.ToInt32(k * (i+1) + b); j++)
  13. {
  14. if (world[i, b + j] != 2) return false;
  15. }
  16. }
  17. else for (int j = Convert.ToInt32(k * (i) + b); j > Convert.ToInt32(k * (i + 1) + b); j--)
  18. {
  19. if (world[i, b + j] != 2) return false;
  20. }
  21. ++i;
  22. } while (i < System.Math.Max(plx, x)) ;
  23. return true;

Решение задачи: «ИИ для 2D игры»

textual
Листинг программы
  1. class FloatComparer : IComparer<float>
  2. {
  3.     private float Epsilon = 1e-6f;
  4.    
  5.     public int Compare(float x, float y)
  6.     {
  7.         if (Math.Abs(x - y) < Epsilon)
  8.             return 0;
  9.        
  10.         return x < y ? -1 : 1;
  11.     }
  12. }
  13.  
  14. // Центром системы координат считается центр клетки мира (0; 0)
  15. // Размер клеток - 1x1
  16. class CellsEnumerator
  17. {
  18.     // Возвращает клетки, пересекающиеся с отрезком [first; second]
  19.     public IEnumerable<Point> GetCellsBetween(PointF first, PointF second)
  20.     {
  21.         if (first.X > second.X)
  22.         {
  23.             var temp = first;
  24.             first = second;
  25.             second = temp;
  26.         }
  27.        
  28.         float left = first.X;
  29.         float right = second.X;
  30.  
  31.         // В случае попадания в одну вертикаль мира, разведём точки в стороны
  32.         if ((int)Math.Floor(left + 0.5) == (int)Math.Floor(right + 0.5))
  33.         {
  34.             left = (float)Math.Floor(left + 0.5) - 0.5f + 0.1f;
  35.             right = left + 0.8f;
  36.         }
  37.        
  38.         float bottom = Math.Min(first.Y, second.Y);
  39.         float top = Math.Max(first.Y, second.Y);
  40.        
  41.         // Строим уравнение прямой y = kx + b, содержащий отрезкок
  42.         float k = (second.Y - first.Y) / (right - left);
  43.         float b = first.Y - k * left;
  44.        
  45.         var xLines = GetBorderLinesBetween(left, right).ToArray();
  46.         var yLines = GetBorderLinesBetween(bottom, top).ToArray();
  47.        
  48.         var result = new List<Point>();
  49.         var nodes = new List<PointF>();
  50.        
  51.         foreach (var x in xLines)
  52.         {
  53.             float y = x * k + b;
  54.  
  55.             if (_comparer.Compare(y, (float)Math.Floor(y) + 0.5f) == 0)
  56.             {
  57.                 nodes.Add(new PointF(x, y));
  58.                 continue;
  59.             }
  60.            
  61.             int cellX = (int)Math.Floor(x + 0.6);
  62.             int cellY = (int)Math.Floor(y + 0.5);
  63.            
  64.             result.Add(new Point(cellX, cellY));
  65.             result.Add(new Point(cellX - 1, cellY));
  66.         }
  67.        
  68.         foreach (var y in yLines)
  69.         {
  70.             float x = (y - b) / k;
  71.  
  72.             if (_comparer.Compare(x, (float)Math.Floor(x) + 0.5f) == 0)
  73.             {
  74.                 nodes.Add(new PointF(x, y));
  75.                 continue;
  76.             }
  77.  
  78.             int cellX = (int)Math.Floor(x + 0.5);
  79.             int cellY = (int)Math.Floor(y + 0.6);
  80.            
  81.             result.Add(new Point(cellX, cellY));
  82.             result.Add(new Point(cellX, cellY - 1));
  83.         }
  84.        
  85.         foreach (var node in nodes.Distinct())
  86.         {
  87.             var leftBottomX = (int)Math.Floor(node.X + 0.5 - 0.1);
  88.             var leftBottomY = (int)Math.Floor(node.Y + 0.5 - 0.1);
  89.            
  90.             for (int dx = 0; dx < 2; dx++)
  91.                 for (int dy = 0; dy < 2; dy++)
  92.                     result.Add(new Point(leftBottomX + dx, leftBottomY + dy));
  93.         }
  94.        
  95.         return result.Distinct();
  96.     }
  97.    
  98.     private IEnumerable<float> GetBorderLinesBetween(float min, float max)
  99.     {
  100.         var x = (float)Math.Ceiling(min + 0.5) - 0.5f;
  101.        
  102.         while (_comparer.Compare(x, max) < 0)
  103.             yield return x++;
  104.     }
  105.  
  106.     private readonly FloatComparer _comparer = new FloatComparer();
  107. };
  108.  
  109. class MainForm : Form
  110. {
  111.     PointF first = PointF.Empty;
  112.     PointF second = PointF.Empty;
  113.     List<Point> cells = new List<Point>();
  114.    
  115.     public MainForm()
  116.     {
  117.         var tb = new TextBox { Parent = this };
  118.         var enumerator = new CellsEnumerator();
  119.        
  120.         tb.TextChanged += (_, __) =>
  121.         {
  122.             float[] numbers;
  123.             try
  124.             {
  125.                 numbers = Regex.Split(tb.Text, @"\s")
  126.                     .Select(word => float.Parse(word, CultureInfo.InvariantCulture))
  127.                     .ToArray();
  128.  
  129.                 if (numbers.Length == 4)
  130.                 {
  131.                     first = new PointF(numbers[0], numbers[1]);
  132.                     second = new PointF(numbers[2], numbers[3]);
  133.                     cells = enumerator.GetCellsBetween(first, second).ToList();
  134.                     Invalidate();
  135.                 }
  136.             }
  137.             catch (FormatException) { }
  138.         };
  139.        
  140.         tb.Text = "0 0 1 1";
  141.     }
  142.    
  143.     protected override void OnPaint(PaintEventArgs e)
  144.     {
  145.         e.Graphics.TranslateTransform(10, 220);
  146.         e.Graphics.ScaleTransform(20, -20);
  147.         e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
  148.        
  149.         for (float x = -0.5f; x < 10.5f; x++)
  150.             e.Graphics.DrawLine(new Pen(Color.Green, 0.05f), x, -0.5f, x, 9.5f);
  151.  
  152.         for (float y = -0.5f; y < 10.5f; y++)
  153.             e.Graphics.DrawLine(new Pen(Color.Green, 0.05f), -0.5f, y, 9.5f, y);
  154.  
  155.         foreach (var cell in cells)
  156.         {
  157.             e.Graphics.DrawRectangle(new Pen(Color.Blue, 0.05f), cell.X - 0.5f, cell.Y - 0.5f, 1, 1);
  158.         }
  159.        
  160.         e.Graphics.DrawLine(new Pen(Color.Red, 0.05f), first, second);
  161.     }
  162. }
  163.  
  164. void Main()
  165. {
  166.     new CellsEnumerator().GetCellsBetween(new PointF(0, 0), new PointF(0, 1)).Dump();
  167.     Application.Run(new MainForm());
  168. }

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

9   голосов , оценка 4.333 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут
Похожие ответы