设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
查看: 1649|回复: 4
打印 上一主题 下一主题

[已经解决] 关于bit与0x0f

[复制链接]

Lv1.梦旅人

梦石
0
星屑
49
在线时间
157 小时
注册时间
2013-8-14
帖子
203
跳转到指定楼层
1
发表于 2013-8-29 00:27:43 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有帐号?注册会员

x
本帖最后由 九靈 于 2013-8-29 00:32 编辑

Game_Map
RUBY 代码复制
  1. #--------------------------------------------------------------------------
  2.   # ● 可以通行判定
  3.   #     x          : X 坐标
  4.   #     y          : Y 坐标
  5.   #     d          : 方向 (0,2,4,6,8,10)
  6.   #                  ※ 0,10 = 全方向不能通行的情况的判定 (跳跃等)
  7.   #     self_event : 自己 (判定事件可以通行的情况下)
  8.   #--------------------------------------------------------------------------
  9.   def passable?(x, y, d, self_event = nil)
  10.     # 被给予的坐标地图外的情况下
  11.     unless valid?(x, y)
  12.       # 不能通行
  13.       return false
  14.     end
  15.     # 方向 (0,2,4,6,8,10) 与障碍物接触 (0,1,2,4,8,0) 后变换
  16.     bit = (1 << (d / 2 - 1)) & 0x0f
  17.     # 循环全部的事件
  18.     for event in events.values
  19.       # 自己以外的元件与坐标相同的情况
  20.       if event.tile_id >= 0 and event != self_event and
  21.          event.x == x and event.y == y and not event.through
  22.         # 如果障碍物的接触被设置的情况下
  23.         if @passages[event.tile_id] & bit != 0
  24.           # 不能通行
  25.           return false
  26.         # 如果全方向的障碍物的接触被设置的情况下
  27.         elsif @passages[event.tile_id] & 0x0f == 0x0f
  28.           # 不能通行
  29.           return false
  30.         # 这以外的优先度为 0 的情况下
  31.         elsif @priorities[event.tile_id] == 0
  32.           # 可以通行
  33.           return true
  34.         end
  35.       end
  36.     end



F1 :
passages
  通行表。是包含了通行标记,草木繁茂处标记和柜台标记的一维数组(Table)。
  取地图元件 ID 作为索引。各位的对应如下所示。
      0x01 : 下方向通行不能。
      0x02 : 左方向通行不能。
      0x04 : 右方向通行不能。
      0x08 : 上方向通行不能。
      0x40 : 草木繁茂处标记。
      0x80 : 柜台标记。


问题 :
1. 能说明下bit = (1 << (d / 2 - 1)) & 0x0f 的<<,  &, 0x0f 吗?
2. 说明@passages[event.tile_id] & bit != 0
3. 同上@passages[event.tile_id] & 0x0f == 0x0f














Lv2.观梦者 (暗夜天使)

万兽

梦石
0
星屑
597
在线时间
2271 小时
注册时间
2006-11-4
帖子
4868

贵宾

2
发表于 2013-8-29 00:39:40 | 只看该作者
<<表示左移,将左方的二进制值左移 (d / 2 - 1)单位,右方补0,比如1的二进制是01  1<<1 也就是01变成10,0x表示是16进制,0f =15
本人是个数字渣,深入下去要大触来解释了@orzfly  
回复 支持 反对

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
3582
在线时间
3065 小时
注册时间
2011-11-17
帖子
980
3
发表于 2013-8-29 01:54:50 | 只看该作者
要说明这问题要先了解2进制   我假设1是1个char型的数  char型有1个字节 1个字节有8个bit
那char型的 1 写成2进制 就是 00000001
你说的那些都是位运算 << 左移
1<<1 的话   就是  00000010   十进制的2
类推1<<2的话 就是 00000100  十进制的4
所以 左移N位 相当于 乘2的N次方 类似右移相当于除以 2的N次方
为毛要用位运算 不直接 做上面的 乘2的N次方这样的事情? 因为位运算高效
& 逻辑与运算符
我拿 10进制的 1 和 2 来解释下
1 的2进制是 01
2 的2进制是 10
(前面的0省略)
1&2 就是 00 也就是0  &就是 2个位都为1 变成1  只要有1个不是1 就变0   和我们用的&&很类似 要2个条件都为true才为true
类似的 还有 逻辑或 异或 按位取反等位运算符 具体的 自己查下
最有个 0x0f   0x代表这个数用16进制表示 0f是这个数的值(16进制的) 其实就是10进制的15  
你把这里直接写出15也行  其实 意义在于 这数的2进制是1111
把一个数与上1111  说明保持这数的后4位不变 因为 0&1 还是0 1&1还是1  至于为毛这么算 是算法问题了 不在这问题的考虑范围内了



评分

参与人数 1星屑 +105 收起 理由
弗雷德 + 105 认可答案

查看全部评分

回复 支持 反对

使用道具 举报

Lv6.析梦学徒

Fuzzy Ginkgo
Taciturn Knight

梦石
0
星屑
60819
在线时间
1934 小时
注册时间
2010-6-26
帖子
1605

烫烫烫开拓者

4
发表于 2013-8-29 04:11:01 | 只看该作者
本帖最后由 orzfly 于 2013-8-29 23:07 编辑

关于位运算的知识楼上说了,看 http://zh.wikipedia.org/wiki/%E4%BD%8D%E6%93%8D%E4%BD%9C 这里也可以。

首先把 passages 表转换为二进制。
  1. 0x01 : 0b00000001 : 下方向通行不能。
  2. 0x02 : 0b00000010 : 左方向通行不能。
  3. 0x04 : 0b00000100 : 右方向通行不能。
  4. 0x08 : 0b00001000 : 上方向通行不能。
  5. 0x40 : 0b01000000 : 草木繁茂处标记。
  6. 0x80 : 0b10000000 : 柜台标记。
复制代码
所以这个 passages 的值,从右往左起(从低位往高位):
第 1 位代表下方向。第 2 位代表左方向。以此类推。
因为最高 2 位是草木和柜台,不在讨论范围,因此以下二进制就只保留四位了。

问题1:bit = (1 << (d / 2 - 1)) & 0x0f
----------------------------------------------------------------
这是什么东西?实际上这目的不过是为了得到这样一个 d => bit 的对应关系:
0 => 0, 2 => 1, 4 => 2, 6 => 4, 8 => 8, 10 => 0

值得注意的是,方向 d 是 (0,2,4,6,8,10)。我想 2, 4, 6, 8 代表什么方向可以从你小键盘上的箭头看出来。
而 0, 10 注释中也提到:全方向不能通行的情况的判定 (跳跃等)

注意 bit 当 d=2, 4, 6, 8 时的取值,刚好和 passages 表中一致。

(d=6 时,是右方向。
1 << (d/2-1) 即将 1 左移 6/2-1=2 位得到 0b0100,
0x0f = 0b1111,
bit = 0b0100 & 0b1111 所以 bit = 0b0100 = 4。
而 passages 中这一位所对应的是右方向。和方向一致。)

问题2:@passages[tile_id] & bit != 0
----------------------------------------------------------------
我们假设当前图块可以向上向左向下通行,唯独不能向右通行。
@passages[tile_id] = 0b0100

先看 d = 6,即尝试从图块中向右走的情况。bit 这时等于 0b0100。
带入计算:0b0100 & 0b0100 = 0b0100。
因为 0b0100 != 0,所以不能通行。

再看 d = 2,即尝试从图块中向下走的情况。bit 这时等于 0b0001。
带入计算:0b0100 & 0b0001 = 0。
因为 0 == 0,所以进入第三问。

再看 d = 0,10,即全方向不能通行的情况的判定 (跳跃等)。bit 这时等于 0b0000。
此时无论图块通行情况如何,带入计算:@passages[tile_id] & 0b0000 都等于 0。
因为 0 == 0,所以进入第三问。

问题3:@passages[tile_id] & 0x0f == 0x0f
----------------------------------------------------------------
0x0f = 0b1111。

先假设当前图块可以向上向左向下通行,唯独不能向右通行。@passages[tile_id] = 0b0100。
此时 0b0100 & 0b1111 = 0b0100 != 0b1111,所以并非不能通行。

再假设当前图块上下左右都不能通行,@passages[tile_id] = 0b1111。
此时 0b1111 & 0b1111 = 0b1111 == 0b1111,所以立刻返回不能通行。

评分

参与人数 3星屑 +206 +1 收起 理由
miantouchi + 1 认可答案
明特·布兰马修 + 66 认可答案
弗雷德 + 140 认可答案

查看全部评分

我的言论只代表我个人的观点,不代表雇主及/或任何第三方的立场。
Opinions expressed are solely my own and do not express the views or opinions of my employer and/or any third parties.
捐赠 | GitHub
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
49
在线时间
157 小时
注册时间
2013-8-14
帖子
203
5
 楼主| 发表于 2013-8-29 13:34:15 | 只看该作者
本帖最后由 九靈 于 2013-9-3 08:53 编辑

终于懂了~~~
感谢各位前辈!


回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2024-11-17 16:44

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表