Skip to content

Instantly share code, notes, and snippets.

@wjurkowlaniec
Last active January 1, 2023 18:54
Show Gist options
  • Save wjurkowlaniec/30f18e6261611c25a3648d7c55c085f7 to your computer and use it in GitHub Desktop.
Save wjurkowlaniec/30f18e6261611c25a3648d7c55c085f7 to your computer and use it in GitHub Desktop.
use std::io::{self, BufRead};
use std::process::exit;
const PLAYER_SYMBOL: [&str; 2] = ["X", "O"];
// TODO use enum instead of string representation
// TODO maybe use Display for printing proper values
fn main() {
let mut board: [[&str; 3]; 3] = [[" ", " ", " "], [" ", " ", " "], [" ", " ", " "]];
let mut current_player: usize = 0;
let mut moves_count: u8 = 0;
loop {
get_player_input(&mut board, current_player);
moves_count += 1;
print_board(board);
if current_player_won(board, PLAYER_SYMBOL[current_player]) {
println!("Player {} won!", PLAYER_SYMBOL[current_player]);
break;
}
if moves_count == 9 {
println!("Nobody won");
break;
}
current_player = (current_player == 0) as usize;
}
}
fn current_player_won(board: [[&str; 3]; 3], current_player: &str) -> bool {
// horizontal
for i in 0..3 {
if board[i][0] == current_player
&& board[i][1] == current_player
&& board[i][2] == current_player
{
return true;
}
}
// vertical
for i in 0..3 {
if board[0][i] == current_player
&& board[1][i] == current_player
&& board[2][i] == current_player
{
return true;
}
}
// diagonal
if board[0][0] == current_player
&& board[1][1] == current_player
&& board[2][2] == current_player
{
return true;
}
if board[0][2] == current_player
&& board[1][1] == current_player
&& board[2][0] == current_player
{
return true;
}
return false;
}
fn get_player_input(board: &mut [[&str; 3]; 3], current_player: usize) {
loop {
// TODO Use Option or Result with ? operator instead of default values
let mut x: usize = 100;
let mut y: usize = 100;
println!("Enter coordinates (ex. 2,3): ");
// TODO https://doc.rust-lang.org/std/io/struct.Stdin.html#method.read_line
let mut line = String::new();
std::io::stdin().read_line(&mut line).unwrap();
line = line.trim().to_owned();
// splitting just once - https://doc.rust-lang.org/std/primitive.str.html#method.split_once
let coordinates: Vec<&str> = line.split(",").collect();
if coordinates.len() == 2 {
x = coordinates[0].parse::<usize>().unwrap_or(100);
y = coordinates[1].parse::<usize>().unwrap_or(100);
}
if x < 4 && x > 0 && y < 4 && y > 0 {
if board[x - 1][y - 1] == " " {
board[x - 1][y - 1] = PLAYER_SYMBOL[current_player];
return;
}
}
println!("Wrong input, try again");
}
}
fn print_board(board: [[&str; 3]; 3]) {
for i in 0..3 {
println!("{}", board[i].join("|"));
if i < 2 {
println!("-----");
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment