How to easily convert a two-dimensional array into a two-dimensional vector?

I'm focusing on rust wasm tutorial. I hope to easily add a ship (a real shape) to the universe in the game of life

As a first step, I want to convert a two-dimensional array of 0 or 1 representing shapes into an index vector representing shape coordinates in the universe

I have a working code, but I want to make it more user-friendly:

const WIDTH: u32 = 64;
const HEIGHT: u32 = 64;

/// glider: [[0,1,0],[0,1],[1,1]]
fn make_ship(shape: Vec<Vec<u32>>) -> Vec<u32> {
    let mut ship: Vec<u32> = Vec::new();

    for row_idx in 0..shape.len() {
        for col_idx in 0..shape[row_idx].len() {
            let cell = shape[row_idx][col_idx];
            if cell == 1 {
                ship.push(col_idx as u32 + row_idx as u32 * WIDTH);
            }
        }
    }

    ship
}

#[test]
fn glider() {
    let glider  = vec![vec![0,vec![0,vec![1,1]];
    println!("{:?}",make_ship(glider));
}

The test showed my problem: VEC! S level of detail Ideally, I want to be able to write it without all VECs! make_ The ship code should not care about the size of the shape array Ideal example:

let glider = [[0,];

The problem is: how to express the shape well with a simple array and make the function make_ Ship uses a two-dimensional vector of any size?

Solution

Using custom macro can reduce VEC! Number of S:

#[macro_export]
macro_rules! vec2d {
    ($($i:expr),+) => { // handle numbers
        {
            let mut ret = Vec::new();
            $(ret.push($i);)*
            ret
        }
    };

    ([$($arr:tt),+]) => { // handle sets
        {
            let mut ret = Vec::new();
            $(ret.push(vec!($arr));)*
            ret
        }
    };
}

fn main() {
    let glider = vec2d![[0,1]];

    let glider2 = vec2d![[0,0]];


    println!("{:?}",glider);  // [[0,1]]
    println!("{:?}",glider2); // [[0,0]]
}

With the help of rust's iterator, your initial function can also use some improvements:

fn make_ship(shape: Vec<Vec<u32>>) -> Vec<u32> {
    shape
        .iter()
        .enumerate()
        .flat_map(|(row,v)| {
            v.iter().enumerate().filter_map(move |(col,x)| {
                if *x == 1 {
                    Some(col as u32 + row as u32 * WIDTH)
                } else {
                    None
                }
            })
        })
        .collect()
}
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>