还原拼图, 把妹收小弟神器, 让你逼格提高好几个档次.

这里给链接: 自动拼图 http://pan.baidu.com/s/1sjoNv7f

其实呢, 也没多少技术含量. 当然, 我比较谦虚.

源码

  1 #include "Game.h"
  2
  3 #include <map>
  4
  5 static const auto PUZZLE_COUNT = 16;
  6 static const auto PUZZLE_WIDTH = WINDOW_WIDTH / PUZZLE_COUNT;
  7 static const auto PUZZLE_HEIGHT = WINDOW_HEIGHT / PUZZLE_COUNT;
  8
  9 static const auto RAND_COUNT = 2000;
 10
 11 inline bool operator <(const D2D1_POINT_2F &pos1, const D2D1_POINT_2F &pos2)
 12 {
 13     if (pos1.x == pos2.x)
 14     {
 15         return pos1.y < pos2.y;
 16     }
 17     return pos1.x < pos2.x;
 18 }
 19
 20 enum EnumDirect {
 21     UP,
 22     RIGHT,
 23     DOWN,
 24     LEFT
 25 };
 26
 27 namespace Utils {
 28     inline EnumDirect flipDirect(EnumDirect direct)
 29     {
 30         return direct == EnumDirect::UP ? EnumDirect::DOWN
 31             : direct == EnumDirect::DOWN ? EnumDirect::UP
 32             : direct == EnumDirect::LEFT ? EnumDirect::RIGHT
 33             : EnumDirect::LEFT;
 34     }
 35 }
 36
 37 class Puzzle : public mmc::LImage {
 38 public:
 39     Puzzle(int x, int y, int width, int height, const std::wstring &filename) : LImage(filename)
 40     {
 41         _cliprc = D2D1::RectF(x * 1.0f, y * 1.0f, x + width * 1.0f, y + height * 1.0f);
 42     }
 43
 44     ~Puzzle()
 45     {
 46
 47     }
 48
 49     virtual void doDraw(ID2D1RenderTarget *pRT, float opacity) override
 50     {
 51         auto pImg = getD2dBitmap();
 52         if (pImg)
 53         {
 54             pRT->DrawBitmap(pImg,
 55                 D2D1::RectF(0.0f, 0.0f, PUZZLE_WIDTH * 1.0f, PUZZLE_HEIGHT * 1.0f),
 56                 opacity, D2D1_BITMAP_INTERPOLATION_MODE_LINEAR, _cliprc);
 57         }
 58     }
 59
 60 private:
 61     D2D1_RECT_F _cliprc;
 62 };
 63
 64 class Game::impl {
 65 public:
 66     impl(Game *pGame) : _pGame(pGame)
 67     {
 68         srand(time(0));
 69     }
 70
 71     ~impl()
 72     {
 73
 74     }
 75
 76     void init()
 77     {
 78         for (auto x = 0; x != PUZZLE_COUNT; ++x)
 79         {
 80             for (auto y = 0; y != PUZZLE_COUNT; ++y)
 81             {
 82                 auto pos = D2D1::Point2F(x * PUZZLE_WIDTH * 1.0f, y * PUZZLE_HEIGHT * 1.0f);
 83
 84                 auto pChild = new Puzzle((int)pos.x, (int)pos.y, PUZZLE_WIDTH, PUZZLE_HEIGHT, L"res/img.png");
 85                 pChild->setParent(_pGame);
 86                 pChild->setPosition(pos.x, pos.y);
 87
 88                 _posMap.insert(std::make_pair(pos, pChild));
 89             }
 90         }
 91
 92         mmc::LRootWindow::getInstance()->redrawWindow();
 93
 94         auto hWnd = mmc::LRootWindow::getInstance()->getWindowHandle();
 95         rand(RAND_COUNT);
 96     }
 97
 98     void rand(u_int count)
 99     {
100         for (auto i = 0; i != count; ++i)
101         {
102             auto direct = EnumDirect(::rand() % 4);
103             if (next(direct))
104             {
105                 _directs.push(direct);
106             }
107         }
108         mmc::LRootWindow::getInstance()->redrawWindow();
109     }
110
111     void next()
112     {
113         static auto isIgnore = [](EnumDirect direct, std::stack<EnumDirect> &directs) {
114             return Utils::flipDirect(direct) == directs.top();
115         };
116
117         if (_directs.empty())
118         {
119             //rand(RAND_COUNT);
120             return;
121         }
122
123         auto isOk = false;
124         auto direct = EnumDirect::UP;
125
126         while (!_directs.empty() && !isOk)
127         {
128             isOk = true;
129             direct = _directs.top();
130             _directs.pop();
131
132             if (!_directs.empty() && isIgnore(direct, _directs))
133             {
134                 _directs.pop();
135                 isOk = false;
136             }
137
138             if (_directs.size() > 1 && isOk)
139             {
140                 auto direct2 = _directs.top();
141                 _directs.pop();
142                 if (isIgnore(direct2, _directs))
143                 {
144                     _directs.pop();
145                     _directs.push(direct);
146                     isOk = false;
147                 }
148                 else
149                 {
150                     _directs.push(direct2);
151                 }
152             }
153         }
154
155         if (isOk)
156         {
157             next(Utils::flipDirect(direct));
158             mmc::LRootWindow::getInstance()->redrawWindow();
159         }
160     }
161
162     void doDraw(ID2D1RenderTarget *pRT, float opacity)
163     {
164
165     }
166
167     void doInput(UINT uMsg, WPARAM wParam, LPARAM lParam)
168     {
169         switch (uMsg)
170         {
171         case WM_CREATE:
172             {
173                 init();
174             }
175         break;
176         case WM_TIMER:
177             {
178                 if (wParam == 1001)
179                 {
180                     next();
181                     mmc::LRootWindow::getInstance()->redrawWindow();
182                 }
183             }
184             break;
185         case WM_KEYUP:
186             {
187                 if (wParam == VK_RETURN)
188                 {
189                     SetTimer(mmc::LRootWindow::getInstance()->getWindowHandle(), 1001, 16, nullptr);
190                 }
191             }
192             break;
193         }
194     }
195 private:
196     bool next(EnumDirect direct)
197     {
198         auto pGap = getGap();
199         auto pMoveObj = find(direct);
200         if (pMoveObj != nullptr)
201         {
202             swap(pMoveObj);
203         }
204         return pMoveObj != nullptr;
205     }
206
207     mmc::LNode *find(EnumDirect direct)
208     {
209         auto pGap = getGap();
210         auto pos = pGap->getPosition();
211         switch (direct)
212         {
213             case EnumDirect::UP:
214                 pos.y += PUZZLE_HEIGHT;
215                 break;
216             case EnumDirect::RIGHT:
217                 pos.x -= PUZZLE_WIDTH;
218                 break;
219             case EnumDirect::DOWN:
220                 pos.y -= PUZZLE_HEIGHT;
221                 break;
222             case EnumDirect::LEFT:
223                 pos.x += PUZZLE_WIDTH;
224                 break;
225         }
226         auto iter = _posMap.find(pos);
227         return iter != std::end(_posMap) ? iter->second : nullptr;
228     }
229
230     mmc::LNode *getGap()
231     {
232         return _pGame->getChilds().back();
233     }
234
235     void swap(mmc::LNode *pNode)
236     {
237         auto pGap = getGap();
238         auto pos1 = pGap->getPosition();
239         auto pos2 = pNode->getPosition();
240         pNode->setPosition(pos1.x, pos1.y);
241         pGap->setPosition(pos2.x, pos2.y);
242
243         _posMap.at(pos1) = pNode;
244         _posMap.at(pos2) = pGap;
245     }
246
247     std::stack<EnumDirect>                    _directs;
248     std::map<D2D1_POINT_2F, mmc::LNode*>    _posMap;
249     Game *_pGame;
250 };
251
252 Game::Game() : _pimpl(new impl(this))
253 {
254
255 }
256
257 Game::~Game()
258 {
259
260 }
261
262 void Game::doDraw(ID2D1RenderTarget *pRT, float opacity)
263 {
264     _pimpl->doDraw(pRT, opacity);
265 }
266
267 void Game::doInput(UINT uMsg, WPARAM wParam, LPARAM lParam)
268 {
269     _pimpl->doInput(uMsg, wParam, lParam);
270 }

这里是最关键的代码, 里面用了一些我封装的dx库. 在我给的连接里有源码. 代码写的潦草, 大伙也不要见笑.

我没有加入用户控制的功能, 因为呢, 我不想加. 呵呵!

咱们说说这个程序的效果, 启动之后按下回车键, 然后眼睁睁看着就好了.

原理是这样的.

把图片切成若干块, 沿着x, y轴对称铺好.

然后将其位置"打乱", rand 这个这个函数实现了打乱的功能, 随机生成方向, 然后图块移动, 并且在移动生效之后记录方向. 重复 count 次结束.

这里有一个槽点, 如果你是一个急性子, 也许你就忽略了. 本作者估计在这里断句, 让你有时间发现槽点.

在打乱的时候保存了方向, 在还原的时候反方向走一遍就OK了. 哈哈哈哈哈, 就是这么简单.

但是, 这是不可能的.

这样做会导致一个看起来很傻逼的效果.

因为打乱是随机生成的, 也就是说极有可能出现生成 up, down, up, down, 这种方向.

那么在还原的时候就出现了, down, up, down, up.. 走了好几步, 位置都没变.

那如何解决这一问题, 参见 next(), 这个next 不带参数, 看仔细..

它的实现过程是:

1, 如果当前的方向跟下一个方向造成冲突, 那就把这2个方向pop掉.

2, 如果当前的方向跟下一个方向不造成冲突, 那就检测下一个方向跟下下一个方向是否造成冲突.

如果你是一个菜鸟, 同时很有想法, 那就跟我学做菜吧. 呵呵!

开个玩笑, 如果你是一个菜鸟, 同时很有想法, 你大概会觉得第二条有些莫名其妙.

如果有 down, left, right, up 这种情况.

down作为当前方向, 跟下一个方向 left 做比较, 明显不会造成冲突, 因此第一条是不成立的, down顺利执行.

left作为当前方向, 跟下一个方向right 做比较, 这里造成了冲突, 这2个方向都被pop, 接下来 up 成了当前方向.

up已经是最后一个方向或者跟下一个方向不造成冲突, 那它就被顺利执行了.

问题就来了, 前面执行了down, 这里又执行up, 那就移动了位置也没变化..

晒晒博主的背影

时间: 2024-10-02 02:34:01

还原拼图, 把妹收小弟神器, 让你逼格提高好几个档次.的相关文章

评测媒体猫:解决新媒体运营与营收的神器

进入新媒体或者自媒体较早的新媒体人可能依托平台用户红利以及内容稀缺性获得了营收先机,但是后续加入或者现在有计划做新媒体的人群来说,如何利用好的工具辅助内容创作以及传播是关键点,例如,目前很多微信运营人都面临着一个问题就是内容创作以及传播的困惑,大部分人没有找到更好的方式. 新媒体现在遇到了什么难题 未来新媒体以及自媒体发展规模还将越来越广泛,各个行业都会产生具有一定粉丝以及竞争对手的新媒体人,例如单单从SEO这个行业来区分目前就已经产生出来了SEO优化.SEO培训.SEO诊断.SEO顾问等细分,

双十一大战马上就到,这个神器一定会看到!

突然的降温和强冷空气告诉我,是时候为保暖秋裤来一波购物血拼了.第十一个双十一马上到达战场,你准备贡献多少战绩呢! 是不是每年都很期待阿里巴巴汇报双十一最后的成交额,我们可以搬个小板凳一起观看一下那块弥漫着八亿人硝烟的大屏幕. 每年双十一都会出现的这块大屏到底有什么神通广大呢?要想今年双十一吹不一样的牛逼,就要了解一下不一样的神器——DataV数据可视化 专业解释:DataV是一个拖拽式可视化工具,可以在零售.物流.电力.水利.环保,还有交通领域,通过交互式实时数据可视化视屏墙来帮助业务人员发现.

拼图游戏(数码还原游戏)的实现

一.游戏规则 首先,这里的拼图游戏是滑块拼图,类似于华容道,游戏者通过移动拼图块将拼图还原为初始形状.关于拼图,常见的有3x3,4x4,多的以至于有16x16不等.一般块数越多拼图越复杂. 这里对游戏规则进行较严格的定义: 1. 游戏初始化时,将图形分为nxn个正方形块,随机摆放在原图形位置.一般以原图形右下角的一块为空白块,已进行移动.这里初始化时,也令新图形的右下角为空. 2. 游戏中,拼图的移动只能向空白块移动.从移动方向来说,有两种情况,分别是横移与纵移. 3. 游戏的胜利条件是将打乱的

分享一些 Windows 平台上的神器

下面分享一些 Windows 平台上日常开发使用的软件,有些软件我自认为是神器,可以大大提高效率. 编辑器类软件 IntelliJ IDEA IntelliJ IDEA 内部集成 Java 开发环境,具有代码智能提示,智能搜索,代码重构,版本控制工具集成(git,svn等),以及支持主流开源框架,如Spring.另外 IntelliJ IDEA 拥有一个丰富的插件库,可以很方便安装插件.通过安装插件,IDEA 还可以支持其他语言,如 Python. 建议通过 ToolBox 安装 Intelli

融资晚报:一大波创业公司获得融资

融资晚报:一大波创业公司获得融资 2015-03-16 25 公众小额捐赠平台路人甲完成200万天使融资,“路人甲”由友成基金会孵化,是北京汇涓时代网络科技有限公司旗下产品.路人甲亦是在猎云投融资对接平台挂牌的创业项目.路人甲之后可能会沉淀 积分系统等新的方式,近期会联合各个公益组织,结合阶段性热点,组织各类主题活动,将大量的零散存量捐赠人导入“路人甲”,形成核心用户群体. 3D虚拟试衣系统量体试衣获得来自浙商创投的天使投资,投资数额未透露.量体试衣亦是去年底在猎云投融资对接平台上挂牌的创业项目

改进方案博客汇总

9-652 界面与功能都非常齐全,有各个层次分明的模板,比如高等数学,C++课程等等,非常具有实用性,可以帮助学弟学妹们学习知识,也能提高及格率.缺点就是数据是在本地载入的,随着软件规模越做越大,数据量越来越多,那么就非常不好管理,这是一个待解决的问题. “荒野大镖客”回复:首先谢谢大家对于我们工作的认可,针对你们说的问题,我们组的解决方法是,虽然仍然不联网,但是加入了页面内容从文件读取的功能,这样解决了我们内容完全是静态文本的弊端,减少了页面数量,同时,离线文件也有较联网更加便利的优点,避免了

各组博客意见汇总

9-652 界面与功能都非常齐全,有各个层次分明的模板,比如高等数学,C++课程等等,非常具有实用性,可以帮助学弟学妹们学习知识,也能提高及格率.缺点就是数据是在本地载入的,随着软件规模越做越大,数据量越来越多,那么就非常不好管理,这是一个待解决的问题. hzsy 手机端学习助手(组名:荒野大镖客)初步做出了界面功能比较简单.无法在大量类似软件中打开市场毕竟类似的软件太多做得好的太多所以最好能做出自己的特色,界面也太过于简单,功能也是过于简单,毕竟要想督促学生学习过于简单的界面不会对学生有吸引力

再见童年

小时候,我们没有ipad ,不懂 LV ,理解不了阿玛尼 .我们只会打纸包玩烟壳,打玻璃球,用小霸王打魂斗罗.那时候,男孩追女孩,一追就是好几年,比的是心,念的是情.这年头儿,男人追女人,几天抱得美人归,看的是钱,拼的是爹.以前我们春游烧烤,坐在一起谈天说地.现在各自埋头刷微博,聊微信 .生活里,貌似所有人都不再那么无可取代 .满口忙事业,赚大钱虚荣,利益,气场儿让爱情,友情,亲情都遗失了当初的那份美好与纯真 .小时候,我们吃一毛钱一支的冰棒,二毛五一瓶的汽水,一块钱十根的粘牙糖 .如果哪个小朋

Android 6.0监听短信(有Git真好,简单方便+轻松愉快)

转载请注明出处:王亟亟的大牛之路 最近在最后的任职期还被榨了一顿忙的飞起,不过今天是最后一天了,帮着处理个BUG就功德圆满了.然后最近在做一个手机间通信+XX监听的Demo,其中一部分是关于短信监听的,然后正好6.0授权的一些因素,那就把这部分的实现单独拆出来做这么个Demo,顺道把这几天觉得发现的不错的第三方库贡献给大家 先来看一下运行效果 先是配置把要过滤的短信字段输入 输入框控件 compile 'com.github.florent37:materialtextfield:1.0.5'