La semana pasada estuve trabajando en un sistema de inventario con Unity3D. Al principio recibí ayuda de los chicos de Design3, pero no pasó mucho tiempo hasta que nos separamos, porque realmente no me gustó la forma en que hicieron su código, no olía a OOP en absoluto.
Avancé un paso más adelante: los artículos ocupan más de una ranura, el sistema de colocación avanzada (los artículos hacen todo lo posible para encontrar el mejor ajuste), el sistema de mouse local (el mouse queda atrapado en el área activa de la bolsa), etc.
Aquí hay una demostración de mi trabajo.
Lo que nos gustaría tener en nuestro juego es una función de organización automática, no una clasificación automática. Queremos esta función porque nuestro inventario estará en 'tiempo real', no como en Resident Evil 1,2,3, etc., donde pausarías el juego y harías cosas en tu inventario. Ahora imagínate a ti mismo en una situación difícil rodeada de zombis, y no tienes balas, miras a tu alrededor, ves que hay balas cerca en el suelo, así que ve por ellas e intenta recogerlas, pero no no encaja! Usted mira su inventario y descubre que si reorganiza algunos de los artículos, ¡encajará! - ahora el jugador - en esa situación no tiene tiempo para reorganizarse porque está rodeado de zombis y morirá si se detiene y organiza el inventario para hacer espacio (recuerde el inventario en tiempo real, sin pausa) - no ¿Sería bueno que eso sucediera automáticamente? - ¡Si!
(Creo que esto se ha implementado en algunos juegos como Dungeon siege o algo así, así que seguro que es factible)
Eche un vistazo a esta imagen, por ejemplo:
Sí, así que si ordena automáticamente el problema, obtendrá sus espacios, pero es malo porque: 1- Caro: no necesita una operación de clasificación completa para liberar esos espacios, en la primera imagen, simplemente deslice el elemento rojo en el abajo a la izquierda, y obtienes los mismos espacios que obtuviste de la clasificación automática. 2- Es molesto para el jugador: "¿Quién demonios te dijo que volvieras a ordenar mis cosas?"
No estoy preguntando "Cómo escribir el código" para esto, solo estoy pidiendo orientación, dónde buscar, ¿qué algoritmos están involucrados? ¿Es esto algo relacionado con gráficos y cosas de la ruta más corta? Espero que no, porque no pude continuar mis estudios universitarios: / Pero si es así, solo dímelo y aprenderé todo lo relacionado.
Tenga en cuenta que podría haber más de una solución. Así que supongo que lo primero que tengo que hacer es averiguar si la situación es 'solucionable'; si sé cómo determinar si una situación es solucionable o no, entonces puedo 'resolverla'. Solo necesito saber las condiciones que lo hacen 'solucionable'. Y creo que debe haber algún algoritmo / estructura de datos para esto.
Aquí hay una foto para más de una solución de tratar de ajustar un elemento 1x3:
Las flechas muestran solo una de las soluciones, pero si mira, encontrará más de una. Esto es lo que finalmente no clasifico automáticamente, sino que encuentro una solución y la aplico.
Tenga en cuenta que si paso el tiempo, encontraré una manera de resolverlo, pero no sería la mejor manera, ¡es como sostener una rueda de automóvil con los pies en lugar de las manos! XD O simplemente como tratar de resolver un problema que requiere matrices, ¡pero aún no eres consciente de su existencia! Entonces, ¿cuál es el enfoque correcto para esto?
Actualizaciones de comentarios
@Stephen Realmente no soy un gurú en Alogs, mencionaste 'mochila' y @BlueRaja - Danny Pflughoeft mencionó algo de embalaje de contenedores 2D. ¿Están de alguna manera relacionados / iguales? - Todavía estoy confundido sobre cómo debería abordar esto.
Y sí, ya estoy usando una "heurística", pero realmente no sabía que estaba: D encuentra la primera ranura disponible, y ver si el elemento encaja allí.
No sé si ordenar artículos en función de su "volumen" (que llamo nSlotsRequired = nRowsReq * nColsRec) funcionaría, porque tiene un 2x2 y 1x4, por ejemplo, tienen el mismo volumen, pero diferentes formas y tendrán un efecto diferente sobre cómo irá el resto de los elementos a continuación. ENTONCES... :/
Vi este video, me gustó mucho la idea de empaque completo, pero me pregunto cómo hacerlo, ya que el inventario es 2D. Ni siquiera estoy seguro de que el embalaje del contenedor sea la clave aquí porque, bueno, es cierto que puedo tener más de una bolsa, pero en nuestro juego solo será una bolsa. Por lo tanto, se trata de colocar artículos en una 'bolsa' y no más que eso. Entonces, los ejemplos en ese video (las tuberías y los autobuses) realmente no coinciden con mi problema. También vi algunas cosas sobre esta mochila, no vi cómo el 'valor' está relacionado con mis artículos / inventario, pero supongo que 'peso' es lo mismo que el volumen, no estoy seguro.
Respuestas:
Esta es una variación del problema de la mochila. Como Danny Pflughoeft menciona es NP-Complete. Lo que significa que no se puede resolver en tiempo lineal, si no recuerdo mal.
Pero puedes intentar resolver esto en varios pasos. Básicamente es un problema de clasificación.
Comenzaría calculando el 'volumen' de cada elemento: esto podría calcularse de varias maneras:
volumen = max (largo, ancho);
Volumen = largo * ancho
Volumen = sqrt (largo * ancho)
Luego comience a poner los artículos con la puntuación más alta primero en el inventario. Dado que lo más probable es que no encajen en el espacio restante más tarde. Los artículos pequeños encajarán siempre.
Necesita una heurística (un nombre elegante para adivinar con conocimiento de causa ;-)) para su estrategia de colocación. Algo así como tratar de encajar elementos en la primera ranura libre desde la parte superior izquierda o algo así.
La estrategia de clasificación de inventario de Diablo II funcionó de manera similar, creo. Cosas como espadas y lanzas terminarían arriba a la izquierda, luego ropa y armadura, luego escudo y así sucesivamente.
Creo que realmente necesita probar esto y ajustar el algoritmo (cálculo de volumen diferente, heurística diferente), hasta que funcione lo suficientemente razonable.
fuente
Jaja, @ Todos los que ayudaron, gracias. Finalmente pude resolverlo. Esto es lo que básicamente hice:
ACTUALIZAR:
Hice una matriz que almacenaba los índices de todos los elementos agregados, de esa manera no tengo que ir a buscar las ranuras ocupadas para liberarlas, gran impulso.
no es necesario agregar en el último espacio, de hecho, a veces puede que no funcione de esa manera, agregué el elemento deseado al resto de los otros elementos y lo ordené con ellos.
Como puede ver en el video, necesita un poco de optimización, la clasificación no es perfecta, me gustaría usar el empaquetado completo, pero ya es codicioso para el rendimiento. Estoy abierto a cualquier sugerencia de optimización, gracias de nuevo :)
fuente