Système d'inventaire auto-organisé / intelligent?

11

la semaine dernière, je travaille sur un système d'inventaire avec Unity3D. Au début, j'ai reçu l'aide des gars de Design3, mais il ne nous a pas fallu longtemps pour nous séparer, car je n'aimais vraiment pas la façon dont ils faisaient leur code, cela n'avait aucune odeur de POO.

Je suis allé plus loin - les articles prennent plus d'un emplacement, un système de placement avancé (les articles font de leur mieux pour trouver le meilleur ajustement), le système de souris local (la souris est coincée dans la zone active du sac), etc.

Voici une démo de mon travail.

Ce que nous aimerions avoir dans notre jeu, c'est une fonction d'auto-organisation - pas de tri automatique. Nous voulons cette fonctionnalité parce que notre inventaire sera en 'temps réel' - pas comme dans Resident Evil 1,2,3 etc où vous mettriez le jeu en pause et feriez des choses dans votre inventaire. Imaginez maintenant votre auto dans une situation collante entourée de zombies, et vous n'avez pas de balles, vous regardez autour de vous, vous voyez qu'il y a des balles à proximité par terre, alors allez-y et essayez de les ramasser, mais ils ne ne va pas! vous examinez votre inventaire et découvrez que si vous réorganisez certains des articles, il conviendra! - maintenant le joueur - dans cette situation n'a pas le temps de se réorganiser car il est entouré de zombies et mourra s'il s'arrête et organise l'inventaire pour faire de la place (rappelez-vous l'inventaire en temps réel, pas de pause) - ne le ferait pas t-il agréable que cela se produise automatiquement? - Oui!

(Je crois que cela a été implémenté dans certains jeux comme Dungeon Siege ou quelque chose, alors c'est sûr que c'est faisable)

jetez un oeil à cette photo par exemple:

À quoi sert le tri automatique

Oui, donc si vous triez automatiquement le problème, vous obtiendrez vos espaces mais c'est mauvais parce que: 1- Cher: il n'a pas besoin d'une opération de tri complète pour libérer ces espaces, dans la première image, faites simplement glisser l'élément rouge au du bas à l'extrême gauche, et vous obtenez les mêmes espaces que ceux obtenus lors du tri automatique. 2- C'est ennuyeux pour le joueur: "Qui le F t'a dit de réorganiser mes affaires?"

Je ne demande pas "Comment écrire le code" pour cela, je demande juste quelques conseils, où chercher, quels algorithmes sont impliqués? Est-ce quelque chose lié aux graphiques et aux trucs de chemin le plus court? J'espère que non parce que je n'ai pas réussi à poursuivre mes études collégiales: / Mais même si c'est le cas, dites-le moi et j'apprendrai les trucs liés.

Notez qu'il pourrait y avoir plus d'une seule solution. Je suppose donc que la première chose que je dois faire est de déterminer si la situation est «résoluble» - si je sais comment déterminer si une situation est résoluble ou non, alors je peux la «résoudre». J'ai juste besoin de connaître les conditions qui le rendent «résoluble». Et je crois qu'il doit y avoir un algorithme / une structure de données pour cela.

Voici une image de plus d'une solution pour essayer d'installer un élément 1x3:

entrez la description de l'image ici

Les flèches ne montrent qu'une des solutions, mais si vous regardez, vous en trouverez plus d'une. C'est finalement ce que je n'effectue pas de tri automatique, mais trouve une solution et l'applique.

Notez que si j'y passe du temps, je trouverai un moyen de le résoudre, mais ce ne serait pas le meilleur moyen, c'est comme tenir une roue de voiture avec vos pieds au lieu de vos mains! XD Ou tout simplement comme essayer de résoudre un problème qui nécessite des tableaux, mais vous n'êtes pas encore au courant de leur existence! Quelle est donc la bonne approche à ce sujet?

Mises à jour du commentaire

@Stephen Je ne suis vraiment pas un gourou dans Alogs, vous avez mentionné «sac à dos» et @BlueRaja - Danny Pflughoeft a mentionné un algo d'emballage de bacs 2D. Sont-ils en quelque sorte liés / identiques? - Je suis toujours confus quant à la façon dont je dois aborder cela.

Et oui j'utilise déjà une "heuristique" mais je ne savais pas vraiment que j'étais: D il trouve le premier emplacement disponible, et voir si l'élément y tient.

Je ne sais pas si la commande d'articles en fonction de leur "encombrement" (que j'appelle nSlotsRequired = nRowsReq * nColsRec) fonctionnerait, parce que vous avez des éléments 2x2 et 1x4 par exemple, ils ont le même encombrement, mais des formes différentes et auront un effet différent sur la suite des autres éléments. DONC... :/

J'ai regardé cette vidéo, j'ai vraiment aimé l'idée d'emballage complet, mais je me demande comment s'y prendre car l'inventaire est en 2D. Je ne suis même pas sûr que l'emballage de la poubelle soit la clé ici parce que, bien c'est vrai que je peux avoir plus d'un sac, mais dans notre jeu ça va juste être un sac. Il s'agit donc de ranger des objets dans un seul sac et pas plus. Ainsi, les exemples de cette vidéo (les tuyaux et les bus) ne correspondent pas vraiment à mon problème. J'ai également regardé des trucs sur ce truc de sac à dos, je n'ai pas vu comment la «valeur» est liée à mes articles / inventaire, mais je suppose que le «poids» est identique à l'encombrement, je ne sais pas.

vexe
la source
7
Il s'agit d'un emballage bin 2D, qui est NP-Complete. Ainsi, tout algorithme qui vous dira si vous pouvez ajuster tous les éléments sera inefficace (dans le pire des cas). Vous pouvez cependant trouver de très bons algorithmes d'approximation.
BlueRaja - Danny Pflughoeft
C'est exactement pourquoi j'ai opté pour le modèle d'inventaire de type un emplacement par article (plus courant de nos jours) au lieu de cela. J'aimerais avoir une solution pour toi, j'ai abandonné ce problème ...
Ryno
@ BlueRaja-DannyPflughoeft Je me demande si un algorithme simple / efficace est disponible si les articles étaient limités à certaines formes?
congusbongus
Limiter les formes ne réduit pas la complexité, mais facilite la réflexion, vous pensez donc que la complexité a été gérée, afaik.
Patrick Hughes
@VeXe Désolé d'avoir raté la mise à jour de votre question. L'emballage et le sac à dos ne sont pas les mêmes. Mais les deux sont des problèmes d'emballage. La «valeur» dans votre cas est la forme et la taille de vos objets d'inventaire.
Stephen

Réponses:

8

Il s'agit d'une variante du problème du sac à dos. Comme Danny Pflughoeft le mentionne, c'est NP-Complete. Cela signifie qu'il ne peut pas être résolu en temps linéaire, si je me souviens bien.

Mais vous pouvez essayer de résoudre ce problème en plusieurs étapes. C'est essentiellement un problème de tri.

Je commencerais par calculer le «volume» de chaque article: cela pourrait être calculé de plusieurs façons:

  • encombrement = max (longueur, largeur);

  • encombrement = longueur * largeur

  • encombrement = sqrt (longueur * largeur)

Commencez ensuite par mettre les objets ayant le score le plus élevé en premier dans l'inventaire. Puisqu'ils ne rentreront probablement pas dans l'espace restant plus tard. Les petits articles s'adapteront toujours.

Vous avez besoin d'une heuristique (un nom de fantaisie pour les devinettes éclairées ;-)) pour votre stratégie de placement. Quelque chose comme essayer de placer des articles dans le premier emplacement libre en haut à gauche ou quelque chose.

Je pense que la stratégie de tri des stocks de Diablo II a fonctionné de façon assez similaire. Des trucs comme des épées et des lances finiraient en haut à gauche, puis des vêtements et des armures, puis des boucliers et ainsi de suite.

Je pense que vous devez vraiment essayer cela et modifier l'algorithme (calcul de volume différent, heuristique différente), jusqu'à ce qu'il fonctionne suffisamment.

Stephen
la source
1
NP-complete est un ensemble de problèmes dont la complexité est supérieure à celle du polynôme. Pour un inventaire relativement petit (moins de mille articles, je dirais :)), même un algorithme exponentiel fonctionnerait assez rapidement, car une étape de cet algorithme prend très peu de temps. Néanmoins, l'utilisation de votre idée devrait être assez bonne et plus facile que la mise en œuvre d'un algorithme de programmation dynamique -> +1
MartinTeeVarga
merci pour le vote positif. Oui, l'inventaire ne devrait pas être potentiellement infini, donc les algorithmes exponentiels devraient bien fonctionner ^^
Stephen
@ sm4: Un millier est généralement un nombre énorme pour les problèmes NP-Complete. Rappelez-vous, ces problèmes sont O (2 ^ n) - même juste 2 ^ 64 est impossible à calculer!
BlueRaja - Danny Pflughoeft
3

Haha, @Tout le monde qui a aidé, merci. J'ai réussi à le résoudre enfin. Voici ce que j'ai essentiellement fait:

IEnumerator AddItem_Sorted (Item item)
  1. Condition triviale: vérifiez si nous avons obtenu les min nRequiredSlots pour que l'article s'intègre, si nous l'avons, continuez ...
  2. nous allons vider tout le sac - mettre les articles dans un espace réservé (liste ou quelque chose)
  3. ajouter l'article voulu au TRÈS dernier emplacement / emplacement où il pourrait tenir, en s'assurant qu'il est sûr dans sa forme horizontale
  4. en utilisant l'algo décroissant de premier ajustement, nous ajouterons le reste de nos articles
  5. lors de l'ajout, nous utiliserons la programmation dynamique (mémoisation) pour mémoriser cet index auquel nous ajoutons (index du prochain slot disponible)
  6. si tout ajout est un succès, nous avons réussi à ajuster notre article recherché et à trier le sac - des gros aux petits articles
  7. si nous ne pouvions pas ajouter tous les articles, cela signifie que ce n'était pas une situation résoluble, nous devons donc remettre le sac à son état précédent
  8. une façon de le faire, (sortie de la surface de mon esprit), est de copier l'état du sac avant toute cette opération, puis s'il échoue, nous reviendrons à cet état précédent, ou mieux encore, pendant le ' vidage 'du sac, nous mémorisons où se trouvait chaque article, de sorte que si l'opération échoue, nous les récupérons - en utilisant AddItem (article, index) - à leurs indices précédents :)
  9. tout ce processus pourrait prendre du temps, nous pourrions donc diviser la charge sur des images séparées, en utilisant mon joli rendement :)
  10. FAIT ! \ m / (@ ~ 9: 00)

MISE À JOUR:

  1. J'ai créé un tableau qui stockait les indices de tous les éléments ajoutés, de cette façon, je n'ai pas à aller chercher les emplacements occupés pour moi à libérer - gros coup de pouce.

  2. pas besoin d'ajouter au dernier emplacement, en fait parfois cela peut ne pas fonctionner de cette façon, j'ai ajouté l'élément recherché au reste des autres éléments et trié avec eux.

Comme vous pouvez le voir dans la vidéo, il a besoin d'un peu d'optimisation, le tri n'est pas parfait, je voudrais utiliser un emballage plein, mais c'est déjà gourmand en performances. Je suis ouvert à toute suggestion d'optimisation, merci encore :)

vexe
la source
Vous êtes les bienvenus! :) Je tiens à remercier BlueRaja - Danny Pflughoeft pour avoir mentionné l'emballage bin, @Stephen pour l'idée d'encombrement et Richard Buckland pour sa conférence de programmation dynamique et toutes les conférences.
vexe