Чтобы найти объекты с одинаковым значением, используя Queue.contains() в C#, Unity

Я пытаюсь найти значения координат с одинаковыми значениями. И я собираюсь связать три значения координат.

Я делаю это, чтобы сделать сетку в Unity.

Эти же координаты я сначала нашел методом bfs.

И есть проблема с попыткой соединить три соседние координаты.

Чтобы найти объекты с одинаковым значением, используя Queue.contains() в C#, Unity

Я сделал следующее, чтобы узнать, есть ли соседние точки в восьми направлениях.

private int[,] fx = new int[8, 2] { { -1, 0 }, { -1, 0 }, { 1, 0 }, { 1, 1 }, 
                                    { -1, 0 }, { -1, 0 }, { 0, 1 }, { 0, 1 } };

private int[,] fy = new int[8, 2] { { -1, -1 }, { 0, -1 }, { -1, -1 }, { -1, 0 }, 
                                    { 0, 1 }, { 1, 1 }, { 1, 0 }, { 1, 1 } };

void CreateTriangle()
{
    int index = 0;
    while (SegNode.Count > 0)
    {
        Node curNode = SegNode.Peek();
        for (int i = 0; i < 8; i++)
        {


            Node nextNode = new Node(curNode.x + fx[i, 0], curNode.y + fy[i, 0], curNode.color);
            Node nextNode2 = new Node(curNode.x + fx[i, 1], curNode.y + fy[i, 1], curNode.color);

            Debug.Log("CurNode " + curNode.x + " , " + curNode.y + 
                " NextNode " + nextNode.x + " , " + nextNode.y + 
                " NextNode2 " + nextNode2.x + " , " + nextNode2.y);


            if (SegNode.Contains(nextNode) && SegNode.Contains(nextNode2))
            {
                newTriangles.Add(SegNode.ToArray().ToList().IndexOf(curNode) + index);
                newTriangles.Add(SegNode.ToArray().ToList().IndexOf(nextNode) + index);
                newTriangles.Add(SegNode.ToArray().ToList().IndexOf(nextNode2) + index);
            }
        }
        index++;
        SegNode.Dequeue();
    }
}

Чтобы найти объекты с одинаковым значением, используя Queue.contains() в C#, UnityЧтобы найти объекты с одинаковым значением, используя Queue.contains() в C#, Unity

явно есть пункт про (0,1) (1,0), но я не могу найти его с помощью Queue.Contains()

Может быть, Contains() не распознает его, потому что я использовал [new] для создания нового объекта. Как я могу найти объект?

Вот мой полный код

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;

public class MeshCreator : MonoBehaviour
{

// This first list contains every vertex of the mesh that we are going to render
public List<Vector3> newVertices = new List<Vector3>();

// The triangles tell Unity how to build each section of the mesh joining
// the vertices
public List<int> newTriangles = new List<int>();

// The UV list is unimportant right now but it tells Unity how the texture is
// aligned on each polygon
public List<Vector2> newUV = new List<Vector2>();


// A mesh is made up of the vertices, triangles and UVs we are going to define,
// after we make them up we'll save them as this mesh


private Mesh mesh;
// Start is called before the first frame update

private int[,] pixel = new int[15, 15] {
                                        { 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
                                        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
                                        { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
                                        { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
                                        { 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
                                        { 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
                                        { 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
                                        { 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
                                        { 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
                                        { 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 2, 0, 0, 0 },
                                        { 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 2, 2, 0, 0, 0 },
                                        { 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0 },
                                        { 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0 },
                                        { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0 },
                                        { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
                                       };


private bool[,] visit = new bool[15, 15];

private int[] dx = new int[4] { 0, 1, -1, 0 };
private int[] dy = new int[4] { 1, 0, 0, -1 };

public int idx = 0;

public class Node
{
    public int x, y, color;

    public Node(int x, int y, int color)
    {
        this.x = x;
        this.y = y;
        this.color = color;
    }
}


public Queue<Node> SegNode = new Queue<Node>();

void bfs(int r, int c, int color)
{
    Queue<Node> q = new Queue<Node>();
    q.Enqueue(new Node(r, c, color));

    while (q.Count > 0)
    {
        Node curNode = q.Dequeue();
        SegNode.Enqueue(curNode);
        for (int i = 0; i < 4; i++)
        {
            int tr = curNode.x + dx[i];
            int tc = curNode.y + dy[i];

            if (tr >= 0 && tr < 15 && tc >= 0 && tc < 15)
            {
                if (!visit[tr, tc] && pixel[tr, tc] == color)
                {
                    visit[tr, tc] = true;
                    q.Enqueue(new Node(tr, tc, color));

                    newVertices.Add(new Vector3(tr, tc, 0));
                }
            }
        }
    }
}

private int[,] fx = new int[8, 2] { { -1, 0 }, { -1, 0 }, { 1, 0 }, { 1, 1 }, 
                                    { -1, 0 }, { -1, 0 }, { 0, 1 }, { 0, 1 } };
private int[,] fy = new int[8, 2] { { -1, -1 }, { 0, -1 }, { -1, -1 }, { -1, 0 }, 
                                    { 0, 1 }, { 1, 1 }, { 1, 0 }, { 1, 1 } };


void CreateTriangle()
{
    int index = 0;
    while (SegNode.Count > 0)
    {
        Node curNode = SegNode.Peek();
        for (int i = 0; i < 8; i++)
        {


            Node nextNode = new Node(curNode.x + fx[i, 0], curNode.y + fy[i, 0], curNode.color);
            Node nextNode2 = new Node(curNode.x + fx[i, 1], curNode.y + fy[i, 1], curNode.color);

            Debug.Log("CurNode " + curNode.x + " , " + curNode.y + 
                " NextNode " + nextNode.x + " , " + nextNode.y + 
                " NextNode2 " + nextNode2.x + " , " + nextNode2.y);


            if (SegNode.Contains(nextNode) && SegNode.Contains(nextNode2))
            {
                newTriangles.Add(SegNode.ToArray().ToList().IndexOf(curNode) + index);
                newTriangles.Add(SegNode.ToArray().ToList().IndexOf(nextNode) + index);
                newTriangles.Add(SegNode.ToArray().ToList().IndexOf(nextNode2) + index);
            }
        }
        index++;
        SegNode.Dequeue();
    }
}



void Start()
{

    //int result = 0;
    for (int r = 0; r < 15; r++)
    {
        for (int c = 0; c < 15; c++)
        {
            if (!visit[r, c] && pixel[r, c] != 0)
            {
                newVertices.Add(new Vector3(r, c, 0));
                bfs(r, c, pixel[r, c]);
                //result++;
            }
        }
    }

    CreateTriangle();

    mesh = GetComponent<MeshFilter>().mesh;
}
}
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
506
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

классы ссылочные типы. Это означает, что ваша очередь SegNode на самом деле содержит не значения, а использованная литература для экземпляров Node.

Как вы уже сказали, ваша проверка Contains не работает так, поскольку вы проверяете, существует ли в очереди одна и та же ссылка на точно такой же экземпляр Node.


Вместо этого вы можете просто сделать свой Nodeтип значения, изменив его с class на struct

public struct Node
{
    public int x, y, color;

    public Node(int x, int y, int color)
    {
        this.x = x;
        this.y = y;
        this.color = color;
    }
}

чем ваш чек

Node nextNode = new Node(curNode.x + fx[i, 0], curNode.y + fy[i, 0], curNode.color);
Node nextNode2 = new Node(curNode.x + fx[i, 1], curNode.y + fy[i, 1], curNode.color);

Debug.Log("CurNode " + curNode.x + " , " + curNode.y + 
          " NextNode " + nextNode.x + " , " + nextNode.y + 
          " NextNode2 " + nextNode2.x + " , " + nextNode2.y);

if (SegNode.Contains(nextNode) && SegNode.Contains(nextNode2))
{
    //...
}

должно сработать.


В качестве альтернативы вы можете использовать, например. Linq ФерстОрДефаулт нравится

var nextNode = SegNode.FirstOrDefault(n => n.x == curNode.x + fx[i, 0] 
                                        && n.y == curNode.y + fy[i, 0]);

var nextNode2 = SegNode.FirstOrDefault(n => n.x == curNode.x + fx[i, 1] 
                                        && n.y == curNode.y + fy[i, 1]);

if (nextNode != null && nextNode2 != null)
{
    // ...
}
  • FirstOrDefault возвращает первое совпадение, определенное предикатом, например.

    n.x == curNode.x + fx[i, 0] && n.y == curNode.y + fy[i, 0]
    

    или null, если совпадений не найдено или список/очередь пусты


в качестве более широкой альтернативы вы также можете позволить своему Node реализовать IEquatable, но это может быть немного излишним для вашего варианта использования;)

Другие вопросы по теме