mirror of
https://github.com/coding-horror/basic-computer-games.git
synced 2025-12-27 13:14:15 -08:00
Merge pull request #578 from cowboy8625/main
A rust version of the Tic Tac Toe Game
This commit is contained in:
4
89_Tic-Tac-Toe/rust/Cargo.toml
Normal file
4
89_Tic-Tac-Toe/rust/Cargo.toml
Normal file
@@ -0,0 +1,4 @@
|
||||
[package]
|
||||
name = "rust"
|
||||
version = "0.1.0"
|
||||
[dependencies]
|
||||
6
89_Tic-Tac-Toe/rust/README.md
Normal file
6
89_Tic-Tac-Toe/rust/README.md
Normal file
@@ -0,0 +1,6 @@
|
||||
README.md
|
||||
|
||||
Original source downloaded from Vintage Basic
|
||||
|
||||
Conversion to Rust
|
||||
|
||||
110
89_Tic-Tac-Toe/rust/src/main.rs
Normal file
110
89_Tic-Tac-Toe/rust/src/main.rs
Normal file
@@ -0,0 +1,110 @@
|
||||
use std::fmt::{self, Display};
|
||||
use std::io::{stdin, stdout, Write};
|
||||
|
||||
const WIN: [(usize, usize, usize); 8] = [
|
||||
(0, 1, 2),
|
||||
(3, 4, 5),
|
||||
(6, 7, 8),
|
||||
(0, 4, 8),
|
||||
(2, 4, 6),
|
||||
(0, 3, 6),
|
||||
(1, 4, 7),
|
||||
(2, 5, 8),
|
||||
];
|
||||
|
||||
type Board = [Sign; 9];
|
||||
|
||||
fn main() {
|
||||
let mut board: Board = [Sign::E; 9];
|
||||
let mut sign = Sign::X;
|
||||
loop {
|
||||
clear();
|
||||
render(&board, &sign);
|
||||
let (win, winner) = check_board(board);
|
||||
if win {
|
||||
match winner {
|
||||
Sign::X => break println!("Looks like X own this one!"),
|
||||
Sign::O => break println!("O is the winner!!"),
|
||||
Sign::C => break println!("Cat got this one!"),
|
||||
Sign::E => {}
|
||||
}
|
||||
}
|
||||
let num = input("Pick a number 1 - 9:> ");
|
||||
if let Some(Sign::E) = board.get(num) {
|
||||
board.get_mut(num).map(|s| *s = sign);
|
||||
sign = if sign == Sign::X { Sign::O } else { Sign::X };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
enum Sign {
|
||||
X,
|
||||
O,
|
||||
C,
|
||||
E,
|
||||
}
|
||||
|
||||
impl Display for Sign {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let sign = match self {
|
||||
Self::X => 'X',
|
||||
Self::O => 'O',
|
||||
Self::C => 'C',
|
||||
Self::E => ' ',
|
||||
};
|
||||
write!(f, "{}", sign)
|
||||
}
|
||||
}
|
||||
|
||||
fn check_board(board: Board) -> (bool, Sign) {
|
||||
for &(a, b, c) in WIN.iter() {
|
||||
if board[a] == board[b] && board[a] == board[c] {
|
||||
return (true, board[a]);
|
||||
}
|
||||
}
|
||||
if !board.contains(&Sign::E) {
|
||||
return (true, Sign::C);
|
||||
}
|
||||
(false, Sign::E)
|
||||
}
|
||||
|
||||
fn clear() {
|
||||
println!("\x1b[2J\x1b[0;0H");
|
||||
}
|
||||
|
||||
fn input(message: &str) -> usize {
|
||||
let mut out = String::new();
|
||||
loop {
|
||||
print!("{}", message);
|
||||
stdout().flush().expect("Failed to flush to stdout.");
|
||||
stdin().read_line(&mut out).expect("Failed to read line");
|
||||
let num = out.trim().parse::<usize>();
|
||||
match num {
|
||||
Ok(n) => match n {
|
||||
1..=9 => return n - 1,
|
||||
_ => println!("The number needs to be between 1 - 9."),
|
||||
},
|
||||
Err(_) => println!("'{}' is not a number.", out.trim()),
|
||||
}
|
||||
out.clear();
|
||||
}
|
||||
}
|
||||
|
||||
fn render(spots: &Board, sign: &Sign) {
|
||||
println!(" The board is numbered");
|
||||
println!(
|
||||
" {} │ {} │ {} [{}: Turn] 1 │ 2 │ 3",
|
||||
spots[0], spots[1], spots[2], sign
|
||||
);
|
||||
println!("⎼⎼⎼╄⎼⎼⎼╄⎼⎼⎼ ⎼⎼⎼╄⎼⎼⎼╄⎼⎼⎼");
|
||||
println!(
|
||||
" {} │ {} │ {} 4 │ 5 │ 6 ",
|
||||
spots[3], spots[4], spots[5]
|
||||
);
|
||||
println!("⎼⎼⎼╄⎼⎼⎼╄⎼⎼⎼ ⎼⎼⎼╄⎼⎼⎼╄⎼⎼⎼");
|
||||
println!(
|
||||
" {} │ {} │ {} 7 │ 8 │ 9 ",
|
||||
spots[6], spots[7], spots[8]
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user