Skip to content

Commit

Permalink
Initial Commit
Browse files Browse the repository at this point in the history
  • Loading branch information
elarroba committed Apr 22, 2021
0 parents commit a49108d
Show file tree
Hide file tree
Showing 6 changed files with 319 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/target
.idea
5 changes: 5 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[package]
name = "rust-tic-tac-toe"
version = "1.0.0"
authors = ["elarroba <[email protected]>"]
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
206 changes: 206 additions & 0 deletions src/board.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
use core::fmt;
use std::fmt::{Display, Formatter};

use crate::players::Player;

#[derive(PartialEq, Eq)]
pub enum CellValue {
Blank,
X,
O,
}

impl Display for CellValue {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
let tick = match self {
CellValue::Blank => { " " }
CellValue::X => { "X" }
CellValue::O => { "O" }
};
write!(f, "{}", tick)
}
}

pub struct TicTacToeBoard<'b> {
a1: &'b CellValue,
a2: &'b CellValue,
a3: &'b CellValue,

b1: &'b CellValue,
b2: &'b CellValue,
b3: &'b CellValue,

c1: &'b CellValue,
c2: &'b CellValue,
c3: &'b CellValue,
}

impl<'c> TicTacToeBoard<'c> {
pub fn new() -> TicTacToeBoard<'c> {
TicTacToeBoard {
a1: &CellValue::Blank,
a2: &CellValue::Blank,
a3: &CellValue::Blank,
b1: &CellValue::Blank,
b2: &CellValue::Blank,
b3: &CellValue::Blank,
c1: &CellValue::Blank,
c2: &CellValue::Blank,
c3: &CellValue::Blank,
}
}

pub fn get_display_value(cell: &CellValue) -> &'static str {
match cell {
CellValue::Blank => { " " }
CellValue::X => { "X" }
CellValue::O => { "O" }
}
}


pub fn add_move(&mut self, position: &str, player: &'c Player) -> bool {
return match position {
"a1" => {
if self.a1 == &CellValue::Blank {
self.a1 = player.tick;
true
} else { false }
}

"a2" => {
if self.a2 == &CellValue::Blank {
self.a2 = player.tick;
true
} else { false }
}
"a3" => {
if self.a3 == &CellValue::Blank {
self.a3 = player.tick;
true
} else { false }
}
"b1" => {
if self.b1 == &CellValue::Blank {
self.b1 = player.tick;
true
} else { false }
}
"b2" => {
if self.b2 == &CellValue::Blank {
self.b2 = player.tick;
true
} else { false }
}
"b3" => {
if self.b3 == &CellValue::Blank {
self.b3 = player.tick;
true
} else { false }
}
"c1" => {
if self.c1 == &CellValue::Blank {
self.c1 = player.tick;
true
} else { false }
}
"c2" => {
if self.c2 == &CellValue::Blank {
self.c2 = player.tick;
true
} else { false }
}
"c3" => {
if self.c3 == &CellValue::Blank {
self.c3 = player.tick;
true
} else { false }
}
_ => { false }
};
}


pub fn player_wins(&self, player: &'c Player) -> Option<&'c Player> {
let board_array: [&CellValue; 9] = [
self.a1,
self.a2,
self.a3,
self.b1,
self.b2,
self.b3,
self.c1,
self.c2,
self.c3,
];


println!("Player tick: {:?}", player.get_tick());

for n in 0..3 {
let mut r1 = board_array[n];
let mut r2 = board_array[n + 3];
let mut r3 = board_array[n + 6];


if r1 == r2 && r2 == r3 && !(r3 == &CellValue::Blank) {
return Some(&player);
} else {
r1 = board_array[n];
r2 = board_array[n + 1];
r3 = board_array[n + 2];

// Checking for line win...
if r1 == r2 && r2 == r3 && !(r3 == &CellValue::Blank) {
return Some(&player);
}
}
}

let mut r1 = board_array[0];
let mut r2 = board_array[4];
let mut r3 = board_array[8];
if r1 == r2 && r2 == r3 && !(r3 == &CellValue::Blank) {
return Some(&player);
}


r1 = board_array[2];
r2 = board_array[4];
r3 = board_array[5];
if r1 == r2 && r2 == r3 && !(r3 == &CellValue::Blank) {
return Some(&player);
}
None
}

pub fn print_board(&self) {
let head = " 1 2 3 \n";
let div = " _______\n";
let ln1 = format!("a |{}|{}|{}|\n",
TicTacToeBoard::get_display_value(&self.a1),
TicTacToeBoard::get_display_value(&self.a2),
TicTacToeBoard::get_display_value(&self.a3));
let ln2 = format!("b |{}|{}|{}|\n",
TicTacToeBoard::get_display_value(&self.b1),
TicTacToeBoard::get_display_value(&self.b2),
TicTacToeBoard::get_display_value(&self.b3));
let ln3 = format!("c |{}|{}|{}|\n",
TicTacToeBoard::get_display_value(&self.c1),
TicTacToeBoard::get_display_value(&self.c2),
TicTacToeBoard::get_display_value(&self.c3));

let mut board: String = String::new();

board.push_str(head);
board.push_str(div);
board.push_str(ln1.as_str());
board.push_str(div);
board.push_str(ln2.as_str());
board.push_str(div);
board.push_str(ln3.as_str());
board.push_str(div);

println!("{}", board);
}
}
62 changes: 62 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
use std::io::stdin;

use board::TicTacToeBoard;
use players::Player;

use crate::board::CellValue;

mod players;
mod board;


fn main() {
let player1 = Player::new("Miguel", "Sanda", 38, &CellValue::X);
let player2 = Player::new("Dayana", "Alonso", 36, &CellValue::O);

let players: [&Player; 2] = [&player1, &player2];

let mut game_board: TicTacToeBoard = TicTacToeBoard::new();
game_board.print_board();
let mut game_over = false;

for i in players.iter().cycle().enumerate() {
let p = i.1;
p.say_hello();

println!("Now is {}'s Turn!", p.full_name());

// read user input ....
loop {
let mut txt_in = String::new();
match stdin().read_line(&mut txt_in) {
Ok(..) => {
txt_in.pop();
let success_move = game_board.add_move(&txt_in, p);
if success_move {
let winner = game_board.player_wins(p);
match winner {
None => {}
Some(w) => {
game_over = true;
println!("Player {} Wins!", w.full_name());
break;
}
}
game_board.print_board();
break;
} else {
println!("Uhm... You cannot do that!...");
game_board.print_board();
}
}

Err(error) => println!("error: {}", error),
}
}

if game_over {
println!("Game Over!");
break;
}
}
}
35 changes: 35 additions & 0 deletions src/players.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
use crate::board::{CellValue};

pub struct Player<'b> {
first_name: String,
last_name: String,
age: i8,
pub tick: &'b CellValue,
}

impl<'b> Player<'b> {
pub fn new(first_name: &'static str, last_name: &'static str, age: i8, tick: &'b CellValue) -> Player<'b> {
Player {
first_name: first_name.to_string(),
last_name: last_name.to_string(),
age,
tick,
}
}

pub fn full_name(&self) -> String {
format!("{} {}", self.first_name, self.last_name)
}

pub fn get_tick(&self) -> char {
match self.tick {
CellValue::X => { 'X' }
CellValue::O => { 'O' }
_ => { ' ' }
}
}

pub fn say_hello(&self) {
println!("Hello, I'm {} and I'm {}. My tick is {}. Let's play!", self.full_name(), self.age, self.get_tick())
}
}

0 comments on commit a49108d

Please sign in to comment.