1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
use prettytable::{cell, table, Table};
use std::io;
use std::io::Write;
use std::str::FromStr;
const CROSS: &'static str = "X";
const EMPTY: &'static str = " ";
const ROUND: &'static str = "O";
fn main() {
let mut table = table![
[EMPTY, EMPTY, EMPTY],
[EMPTY, EMPTY, EMPTY],
[EMPTY, EMPTY, EMPTY]
];
let mut height = table.print_tty(false).unwrap();
let stdin = io::stdin();
let mut stdout = io::stdout();
let mut current = CROSS;
let mut terminal = term::stdout().unwrap();
loop {
let mut line = String::new();
print!("{} plays > ", current);
height += 1;
stdout.flush().unwrap();
stdin.read_line(&mut line).expect("Cannot read input");
let i = match usize::from_str(line.trim()) {
Ok(i) => i,
_ => {
println!("Bad input");
height += 1;
continue;
}
};
if i < 1 || i > 9 {
println!("Bad input, should be between 1 and 9");
height += 1;
continue;
}
let x = (i - 1) % 3;
let y = (i - 1) / 3;
{
let row = table.get_mut_row(y).unwrap();
if row.get_cell(x).unwrap().to_string() != EMPTY {
println!("There's already someone there");
height += 1;
continue;
}
row.set_cell(cell!(current), x).unwrap();
}
for _ in 0..height {
terminal.cursor_up().unwrap();
terminal.delete_line().unwrap();
}
height = table.print_tty(false).unwrap();
if check(&table) {
return;
}
if current == CROSS {
current = ROUND;
} else {
current = CROSS;
}
}
}
fn get(table: &Table, x: usize, y: usize) -> String {
match table.get_row(y) {
Some(r) => match r.get_cell(x) {
Some(c) => c.to_string(),
_ => EMPTY.to_string(),
},
_ => EMPTY.to_string(),
}
}
fn is(table: &Table, s: &str, x: usize, y: usize) -> bool {
get(table, x, y).as_str() == s
}
fn check(table: &Table) -> bool {
let mut full = true;
for y in 0..3 {
for x in 0..3 {
if is(table, EMPTY, x, y) {
full = false;
continue;
}
let current = get(table, x, y);
let c = current.as_str();
if is(table, c, x + 1, y) && is(table, c, x + 2, y)
|| is(table, c, x + 1, y + 1) && is(table, c, x + 2, y + 2)
|| x >= 2 && is(table, c, x - 1, y + 1) && is(table, c, x - 2, y + 2)
|| is(table, c, x, y + 1) && is(table, c, x, y + 2)
{
println!("Game is over. {} is the winner", current);
return true;
}
}
}
if full {
println!("Game is over. It's a draw");
}
full
}