rust-cli-arcade 0.1.0

A collection of classic CLI games: Tic-Tac-Toe, Connect Four, Hangman, and Rock Paper Scissors
use std::io;

struct TicTacToe {
    board: [[char; 3]; 3],
    turn: bool,
}

impl TicTacToe {
    fn new() -> Self {
        Self {
            board: [['.'; 3]; 3],
            turn: true,
        }
    }

    fn print(&self) {
        println!();
        for row in &self.board {
            for &cell in row {
                print!("{} ", cell);
            }
            println!();
        }
    }

    fn make_move(&mut self, row: usize, col: usize) -> bool {
        if row >= 3 || col >= 3 || self.board[row][col] != '.' {
            return false;
        }

        self.board[row][col] = if self.turn { 'X' } else { 'O' };
        self.turn = !self.turn;
        true
    }

    fn check_win(&self) -> bool {
        // Rows
        for row in &self.board {
            if row[0] != '.' && row[0] == row[1] && row[1] == row[2] {
                return true;
            }
        }

        // Columns
        for col in 0..3 {
            if self.board[0][col] != '.' && self.board[0][col] == self.board[1][col] 
               && self.board[1][col] == self.board[2][col] {
                return true;
            }
        }

        // Diagonals
        if self.board[1][1] != '.' {
            if (self.board[0][0] == self.board[1][1] && self.board[1][1] == self.board[2][2]) ||
               (self.board[0][2] == self.board[1][1] && self.board[1][1] == self.board[2][0]) {
                return true;
            }
        }

        false
    }

    fn is_full(&self) -> bool {
        for row in &self.board {
            for &cell in row {
                if cell == '.' {
                    return false;
                }
            }
        }
        true
    }
}

pub fn play() {
    let mut game = TicTacToe::new();
    
    println!("\nTic-Tac-Toe - Enter row col (0-2), ex. \"0 0\"");

    loop {
        game.print();
        println!("Player {} turn", if game.turn { 'X' } else { 'O' });

        let mut input = String::new();
        io::stdin().read_line(&mut input).unwrap();

   
        let parts: Vec<&str> = input.trim().split_whitespace().collect();
        if parts.len() != 2 {
            continue;
        }

        let row: usize = match parts[0].parse() {
            Ok(n) => n,
            Err(_) => continue,
        };

        let col: usize = match parts[1].parse() {
            Ok(n) => n,
            Err(_) => continue,
        };

        if !game.make_move(row, col) {
            println!("Invalid move!");
            continue;
        }

        if game.check_win() {
            game.print();
            match game.turn{
                true => println!("O's win!"),
                false => println!("X's win!")
            }
            break;
        }
        
        if game.is_full() {
            game.print();
            println!("Draw!");
            break;
        }
    }
}