无需嵌套循环与x/y坐标,基于索引生成棋盘格图案的简化实现方案问询
更简洁的棋盘格颜色生成实现(仅用索引)
绝对有更简洁的实现!而且完全符合你提出的「不依赖x/y坐标、不用嵌套循环」的要求——我们可以直接通过索引和棋盘宽度的数学关系来推导,同时保留原逻辑的正确性。
优化后的Rust代码
fn get_bg_color_of(idx: usize) -> &'static str { const BG_BLACK: &str = "\u{001b}[48;5;126m"; const BG_WHITE: &str = "\u{001b}[48;5;145m"; if (idx / Board::WIDTH + idx % Board::WIDTH) % 2 == 0 { BG_WHITE } else { BG_BLACK } }
如果你偏爱更紧凑的匹配表达式风格,也可以写成这样:
fn get_bg_color_of(idx: usize) -> &'static str { const BG_BLACK: &str = "\u{001b}[48;5;126m"; const BG_WHITE: &str = "\u{001b}[48;5;145m"; match (idx / Board::WIDTH + idx % Board::WIDTH) % 2 { 0 => BG_WHITE, _ => BG_BLACK, } }
实现原理详解
你原来的逻辑核心是判断:(偶数行且偶数列) 或者 (奇数行且奇数列),这个规则本质等价于行号+列号是偶数——因为:
- 偶数+偶数 = 偶数
- 奇数+奇数 = 偶数
- 只有偶数+奇数(或反之)才会得到奇数
而在你的原代码中:
- 行号
y=idx / Board::WIDTH(整数除法,索引除以宽度得到所在行) - 列号
x=idx % Board::WIDTH(取余运算,索引对宽度取余得到所在列)
所以我们直接把这两个值相加,再对2取余,就能得到和原逻辑完全一致的判断结果。这样既省去了中间变量的定义,也简化了条件判断的写法,代码更简洁易读。
进阶:用位运算替代取余(可选)
如果想追求极致的性能(虽然对于这个场景来说差异可以忽略),可以用位运算代替对2取余——因为一个数对2取余的结果,等于它二进制最后一位的值(0为偶数,1为奇数)。代码如下:
fn get_bg_color_of(idx: usize) -> &'static str { const BG_BLACK: &str = "\u{001b}[48;5;126m"; const BG_WHITE: &str = "\u{001b}[48;5;145m"; let sum = idx / Board::WIDTH + idx % Board::WIDTH; if (sum & 1) == 0 { // 检查二进制最后一位是否为0 BG_WHITE } else { BG_BLACK } }
这种写法性能略优,但可读性会稍差一点,你可以根据自己的需求选择。
内容的提问来源于stack exchange,提问作者Elias
相关产品推荐
相关产品推荐

