array2ds 0.2.1

Simple Package for handling sized 2d arrays in rust, without the usage of the keyword unsafe cuz why not
Documentation
# array2ds
## May God let rust have better constant generics


Array2ds is a none-bloated library in rust for rust by rust for handling staticly sized 2d array/grids
to run the examples:
cargo run --example 'example_name'

- Uses only Safe Rust, no usage of "unsafe"
- Works I guess
- ✨Magic ✨

## Features

- creating 2d arrays
- iterating over rows both mutable and not
- grid sized cant be changed after created
- can index with (row,column) or [row,column] and easily overload to other ways
- can iterate over columns

```rust
use array2ds::array2d::*;
use std::io::stdin;

struct Square {
    data: char,
}

impl Default for Square {
    fn default() -> Self {
        Square { data: '#' }
    }
}

fn main() {
    run_game();
}

fn run_game() {
    let mut board: Array2d<Square> = Array2d::filled_with_default(3, 3);
    println!("enter location as: row col, for example: `0 1`, row: 0 column 1");
    print_board(&board);

    let mut winner = false;
    let mut current_player = 'X';

    while !winner {
        let (row, column) = read_grid_location();

        if board[[row, column]].data == '#' {
            board[[row, column]].data = current_player;

            match current_player {
                'X' => current_player = 'O',
                'O' => current_player = 'X',
                _ => panic!("invalid data for square"),
            }
            println!();
            print_board(&board);
            winner = check_horizontal(&board)  || check_vertical(&board) || check_diagnol(&board);
        } else {
            println!("invalid location, try another");
        }
    }
}

fn read_grid_location() -> (usize, usize) {
    let mut buffer = String::new();
    stdin().read_line(&mut buffer).unwrap();
    let buffer = buffer.trim();
    let splitted: Vec<&str> = buffer.split(' ').collect();
    if splitted.len() < 2 {
        panic!("enter data as `row col` ");
    }
    let r = splitted[0].parse::<usize>().unwrap();
    let c = splitted[1].parse::<usize>().unwrap();
    (r, c)
}

fn check_diagnol(board: &Array2d<Square>) -> bool{
    
    let mid = &board[(1,1)];
    if mid.data == '#'{
        return false
    }
    if board[[0,0]].data == mid.data && mid.data == board[(2,2)].data{
        return true
    }
    if board[[2,0]].data == mid.data && mid.data == board[(0,2)].data{
        return true
    }
    false
}

fn check_vertical(board: &Array2d<Square>) -> bool {
    for col in 0..3 {
        let mut x_count = 0;
        let mut o_count = 0;
        for row in 0..3 {
            match board[[row, col]].data {
                'X' => x_count += 1,
                'O' => o_count += 1,
                _ => {}
            }
        }

        if x_count == 3 || o_count == 3 {
            return true;
        }
    }
    false
}

fn check_horizontal(board: &Array2d<Square>) -> bool {
    for row in board.iter_rows() {
        let mut o_count = 0;
        let mut x_count = 0;
        for player in row {
            match player.data {
                'O' => o_count += 1,
                'X' => x_count += 1,
                _ => {}
            }
        }
        if o_count == 3 || x_count == 3 {
            return true;
        }
    }
    false
}

fn print_board(board: &Array2d<Square>) {
    for row in board.iter_rows() {
        for square in row {
            print!("{}", square.data);
        }
        println!();
    }
}

```

## License

MIT