网格背包的简单实现

如果是使用网格背包实现的的背包界面,类似于《暗黑》这种背包,我是这么来定义结构的。发现和原来做的一个开纸的算法很类似,但是恰好反过来。反正没事儿想起来实现一下也不错。

一个物品的占位,默认左上角为(0,0)点。策划在填表的时候,只需要根据对角线关系填写(1,1)这个点就可以了。

搜狗截图20150422210037

服务器Item对象,仅需要存储左上角(0,0)点所在的二维数组的位置即可,如果考虑到物品的旋转(行列互换)可以再加入一个值做判断.(感觉实际一般都不能旋转,因为美术做图案的时候也很难保证旋转之后的美观性)
class Item{
public:
int uid; //唯一ID
int quality; //品质
int pos[2]; //位于背包位置(左上角)
int isRota; //是否旋转
};

这样可以很方便的存储到一个map里面或者vector里面。

那么唯一的问题就是自动整理背包了!我是这么来排布背包的

搜狗截图20150422214423

每次放入背包一个物品,会将背包切割成两个区域,横向一个,下方一个,如果另起一行则会切割出来三个区域。占用一个格子的道具和物品,无论背包怎么整理这些物品都是能够放的下的。因为总的格子数是固定的。所以这些可以最后再填入。暂时不做考虑。

假设:存在n个不同品质的物品,占用标准如下,不考虑旋转,且保证背包(MAX_WIDTH,MAX_HEIGHT)能够放下,放不下舍弃。那么背包应该如何整理(不考虑旋转)。

搜狗截图20150422220737

输入:n个物品,数据结构如上

输出:n个物品,在背包内的位置信息,放不下的默认位置为(0,0)

算法描述,先横向放置,直到放置不下再换行放置。由于高度一致,从宽度大的往小的放,为了保证每一行都放满

根据MAX_WIDTH的奇偶性,分奇数先放还是偶数先放。

补充:为了保证新获得物品可以快速的放入到背包当中,其实可以存储一下int rightPos[2],int bottoPos[2]这两个的位置信息。由于实际情况存在占用一个格子物品的情况。为了防止对算法的影响。占用单个格子的物品,默认从背包底行进行放置如果底行占满则从右列开始进行放置。

   1: #include "stdafx.h"
   2: #include <map>
   3: #include <vector>
   4: #define MAX_WIDTH  100
   5: #define MAX_HEIGHT 100
   6: const int INITPOS_0[2] = { 0, 0 };
   7: const int INITPOS_1[2] = { 2, 0 };
   8: const int INITPOS_2[2] = { 2, 1 };
   9: const int INITPOS_3[2] = { 2, 2 };
  10:  
  11:  
  12: class Item;
  13: typedef std::map<int, Item*> ITEM_MAP;
  14: typedef std::map<int, Item*>::iterator  ITEM_ITERTOR_MAP;
  15:  
  16: class Item
  17: {
  18: public:
  19:     int uid;
  20:     int quality;
  21:     int pos[2];
  22:     int init[2]; //占用位置
  23:  
  24:     Item(int uid_val, int quality_val, const int pos_val[2], const int init_val[2])
  25:     {
  26:         uid = uid_val;
  27:         quality = quality_val;
  28:         memcpy(pos, pos_val, sizeof(pos));
  29:         memcpy(init, init_val, sizeof(init));
  30:     }
  31: };
  32:  
  33: void sort(ITEM_MAP itemMap)
  34: {
  35:     int rightPos[2] = { 0 }; //记录右侧剩余位置的起始
  36:     int bottoPos[2] = { 0 }; //记录底部剩余位置的起始
  37:     std::vector<Item*>    initPos1Vec;//INITPOS_1 一组
  38:     std::vector<Item*>  initPos2Vec;//INITPOS_2 一组
  39:     std::vector<Item*>  initPos3Vec;//INITPOS_3 一组
  40:     for (ITEM_ITERTOR_MAP itor = itemMap.begin(); itor != itemMap.end(); itor++)
  41:     {
  42:         Item* item = itor->second;
  43:         if (item->init[1] == 0)
  44:         {
  45:             initPos1Vec.push_back(item);
  46:         }
  47:         else if (item->init[1] == 1)
  48:         {
  49:             initPos2Vec.push_back(item);
  50:         }
  51:         else if (item->init[1] == 2)
  52:         {
  53:             initPos3Vec.push_back(item);
  54:         }
  55:     }
  56:     if (MAX_WIDTH % 2)
  57:     {//奇数先放 
  58:         //自己实现咯,保密
  59:     }
  60:     else
  61:     {//偶数先放
  62:         //自己实现咯,保密
  63:     }
  64:     return;
  65: }
  66:  
  67: void output(ITEM_MAP itemMap)
  68: {
  69:     for (ITEM_ITERTOR_MAP itor = itemMap.begin(); itor != itemMap.end(); itor++)
  70:     {
  71:         Item* item = itor->second;
  72:         if (item->uid < 10)
  73:         {
  74:             printf("uid:0%d,quality:%d,pos:[%d,%d],init:[%d,%d] \n", item->uid, item->quality, item->pos[0], item->pos[1], item->init[0], item->init[1]);
  75:             continue;
  76:         }
  77:         printf("uid:%d,quality:%d,pos:[%d,%d],init:[%d,%d] \n", item->uid, item->quality, item->pos[0], item->pos[1], item->init[0], item->init[1]);
  78:     }
  79: }
  80:  
  81: int _tmain(int argc, _TCHAR* argv[])
  82: {
  83:     ITEM_MAP itemmap;
  84:     for (int i = 0; i < 15; i++)
  85:     {
  86:         if (i < 5)
  87:         {
  88:             itemmap.insert(ITEM_ITERTOR_MAP::value_type(i + 1, new Item(i + 1, rand() % 3 + 1, INITPOS_0, INITPOS_1)));
  89:             continue;
  90:         }
  91:         if (i < 10)
  92:         {
  93:             itemmap.insert(ITEM_ITERTOR_MAP::value_type(i + 1, new Item(i + 1, rand() % 3 + 1, INITPOS_0, INITPOS_2)));
  94:             continue;
  95:         }
  96:         if (i < 15)
  97:         {
  98:             itemmap.insert(ITEM_ITERTOR_MAP::value_type(i, new Item(i, rand() % 3 + 1, INITPOS_0, INITPOS_3)));
  99:         }
 100:     }
 101:     sort(itemmap);
 102:     output(itemmap);
 103:     getchar();
 104:     return 0;
 105: }
 106:  
posted @ 2015-04-22 23:34  河豚  阅读(507)  评论(0编辑  收藏  举报