91 lines
2.5 KiB
Rust
91 lines
2.5 KiB
Rust
use std::io::{self, Write};
|
|
|
|
const EMPTY: char = ' ';
|
|
const PLAYER_X: char = 'X';
|
|
const PLAYER_O: char = 'O';
|
|
|
|
fn main() {
|
|
let mut board = vec![vec![EMPTY; 3]; 3];
|
|
let mut current_player = PLAYER_X;
|
|
|
|
loop {
|
|
print_board(&board);
|
|
let (row, col) = get_move(¤t_player);
|
|
if board[row][col] == EMPTY {
|
|
board[row][col] = current_player;
|
|
if check_winner(&board, current_player) {
|
|
print_board(&board);
|
|
println!("Player {} wins!", current_player);
|
|
break;
|
|
} else if check_draw(&board) {
|
|
print_board(&board);
|
|
println!("The game is a draw!");
|
|
break;
|
|
}
|
|
current_player = if current_player == PLAYER_X { PLAYER_O } else { PLAYER_X };
|
|
} else {
|
|
println!("That spot is already taken. Try again.");
|
|
}
|
|
}
|
|
}
|
|
|
|
fn print_board(board: &Vec<Vec<char>>) {
|
|
for row in board {
|
|
for cell in row {
|
|
print!("|{}|", cell);
|
|
}
|
|
println!("\n---------");
|
|
}
|
|
}
|
|
|
|
fn get_move(player: &char) -> std::io::Result<(usize, usize)> {
|
|
let mut input = String::new();
|
|
loop {
|
|
print!("Player {}, enter your move (row and column): ", player);
|
|
io::stdout().flush().unwrap();
|
|
input.clear();
|
|
io::stdin().read_line(&mut input).unwrap();
|
|
|
|
let inputs: Vec<usize> = input
|
|
.trim()
|
|
.split_whitespace()
|
|
.filter_map(|s| s.parse().ok())
|
|
.collect();
|
|
|
|
if inputs.len() == 2 && inputs[0] < 3 && inputs[1] < 3 {
|
|
return std::io::Result<(inputs[0], inputs[1])>;
|
|
} else {
|
|
println!("Invalid input. Please enter row and column as two numbers between 0 and 2.");
|
|
}
|
|
}
|
|
}
|
|
|
|
fn check_winner(board: &Vec<Vec<char>>, player: char) -> bool {
|
|
// Check rows and columns
|
|
for i in 0..3 {
|
|
if (board[i][0] == player && board[i][1] == player && board[i][2] == player) ||
|
|
(board[0][i] == player && board[1][i] == player && board[2][i] == player) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
// Check diagonals
|
|
if (board[0][0] == player && board[1][1] == player && board[2][2] == player) ||
|
|
(board[0][2] == player && board[1][1] == player && board[2][0] == player) {
|
|
return true;
|
|
}
|
|
|
|
false
|
|
}
|
|
|
|
fn check_draw(board: &Vec<Vec<char>>) -> bool {
|
|
for row in board {
|
|
for cell in row {
|
|
if *cell == EMPTY {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
true
|
|
}
|