Skip to content

Commit 25897cb

Browse files
committed
adding tictactoe game
1 parent 8400597 commit 25897cb

File tree

5 files changed

+142
-0
lines changed

5 files changed

+142
-0
lines changed

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ println!("{}, {}, {}", a.0, a.1, a.2);
9595

9696
Arrays are limited to 32 length. Vectors are preferred over Arrays.
9797

98+
To inspect an array use `println!("{:?}", arr);`.
99+
98100
## Variables
99101

100102
Variables are immutable in Rust, however, you can mutate them by declaring using `let mut`. Rust is strongly typed, but if it can deduce what the variable is, it will automatically create that type for you.
@@ -195,6 +197,13 @@ https://crates.io/
195197

196198
## Ownership and References
197199

200+
## Command line
201+
202+
```rust
203+
let args: Vec<String> = std::env::args().skip(1).collect();
204+
println!("{:?}", args);
205+
```
206+
198207
## Resources
199208

200209
- [Actix api framework](https://actix.rs)

tictactoe/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/target
2+
**/*.rs.bk

tictactoe/Cargo.toml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[package]
2+
name = "tictactoe"
3+
version = "0.1.0"
4+
authors = ["Mark Robson <[email protected]>"]
5+
edition = "2018"
6+
7+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
8+
9+
[dependencies]

tictactoe/src/lib.rs

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
#[cfg(test)]
2+
mod tests {
3+
use super::*;
4+
5+
#[test]
6+
fn empty_matrix_should_return_false () {
7+
let matrix: [String; 9] = Default::default();
8+
assert_eq!(check_results(&matrix), false);
9+
}
10+
11+
#[test]
12+
fn row_matrix_should_return_true () {
13+
let mut matrix: [String; 9] = Default::default();
14+
matrix[0 as usize] = "x".to_string();
15+
matrix[1 as usize] = "x".to_string();
16+
matrix[2 as usize] = "x".to_string();
17+
assert_eq!(check_results(&matrix), true);
18+
}
19+
20+
#[test]
21+
fn column_matrix_should_return_true () {
22+
let mut matrix: [String; 9] = Default::default();
23+
matrix[0 as usize] = "x".to_string();
24+
matrix[3 as usize] = "x".to_string();
25+
matrix[6 as usize] = "x".to_string();
26+
assert_eq!(check_results(&matrix), true);
27+
}
28+
29+
#[test]
30+
fn draw_matrix_should_return_true () {
31+
let matrix: [String; 9] = [
32+
"x".to_string(), "o".to_string(), "x".to_string(),
33+
"o".to_string(), "x".to_string(), "o".to_string(),
34+
"x".to_string(), "x".to_string(), "o".to_string()
35+
];
36+
assert_eq!(check_results(&matrix), true);
37+
}
38+
}
39+
40+
const WINNING_SEQUENCES: [[i8; 3]; 8] = [[0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 3, 6], [1, 4, 7], [2, 5, 8], [0, 4, 8], [2, 4, 6]];
41+
42+
pub fn check_results (matrix: &[String; 9]) -> bool {
43+
let mut game_over = false;
44+
for sequence in WINNING_SEQUENCES.iter() {
45+
if (
46+
!matrix[sequence[0] as usize].is_empty() &&
47+
!matrix[sequence[1] as usize].is_empty() &&
48+
!matrix[sequence[2] as usize].is_empty()
49+
) &&
50+
(
51+
matrix[sequence[0] as usize] == matrix[sequence[1] as usize] &&
52+
matrix[sequence[1] as usize] == matrix[sequence[2] as usize]) {
53+
println!("Player {} wins!", matrix[sequence[0] as usize]);
54+
game_over = true;
55+
} else {
56+
let default = matrix.iter().position(|r| r.is_empty());
57+
if !default.is_some() {
58+
println!("Its a draw!");
59+
game_over = true;
60+
} else {
61+
game_over = game_over || false;
62+
}
63+
}
64+
}
65+
return game_over;
66+
}

tictactoe/src/main.rs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/**
2+
* Tic Tac Toe or Naughts and crosses
3+
*
4+
* Two players take turns with adding their moniker on a 3x3 grid with the aim of having a winning swequence:
5+
*
6+
* Winning sequences are:
7+
* - first line horizontal
8+
* - second line horizontal
9+
* - third line horizontal
10+
* - first line vertical
11+
* - second line vertical
12+
* - third line vertical
13+
* - diagonal l - r
14+
* - diagonal r - l
15+
**/
16+
17+
use tictactoe::check_results;
18+
use std::io;
19+
use std::io::prelude::*;
20+
21+
fn main() {
22+
let stdin = io::stdin();
23+
let lookup = ["a1", "b1", "c1", "a2", "b2", "c2", "a3", "b3", "c3"];
24+
let players = ["x", "o"];
25+
let mut current_player = 0;
26+
let mut matrix: [String; 9] = Default::default();
27+
28+
println!("Tic-tac-toe");
29+
println!("Ready player {}? Enter target square:", players[current_player].to_string());
30+
println!("|----|----|----|");
31+
println!("| a1 | b1 | c1 |");
32+
println!("|____|____|____|");
33+
println!("| a2 | b2 | c3 |");
34+
println!("|____|____|____|");
35+
println!("| a3 | b3 | c3 |");
36+
println!("|____|____|____|");
37+
38+
for line in stdin.lock().lines() {
39+
let input = line.unwrap();
40+
let index = lookup.iter().position(|&r| r == input);
41+
if index.is_some() {
42+
if matrix[index.unwrap()].to_string() != "" {
43+
println!("Already taken");
44+
continue;
45+
}
46+
matrix[index.unwrap()] = players[current_player].to_string();
47+
current_player = if current_player == 0 { 1 } else { 0 };
48+
if check_results(&matrix) {
49+
std::process::exit(1);
50+
}
51+
println!("Player {}, your go", players[current_player].to_string());
52+
} else {
53+
println!("Oops! Invalid square");
54+
}
55+
}
56+
}

0 commit comments

Comments
 (0)