4 Commits
0.1 ... 0.3

Author SHA1 Message Date
cc87ad378e handle simple draw
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/tag Build is passing
2019-11-01 21:54:37 +01:00
befc8128cd strip binary 2019-10-31 21:15:58 +01:00
3d243836eb auto test
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/tag Build is passing
2019-10-31 21:05:20 +01:00
38d638538b allow resumption 2019-10-31 20:54:44 +01:00
2 changed files with 73 additions and 7 deletions

32
.drone.yml Normal file
View File

@@ -0,0 +1,32 @@
kind: pipeline
name: default
steps:
- name: test
image: rust:1.38.0
commands:
- cargo test
- name: build_relase
image: rust:1.38.0
commands:
- cargo install --path . --root . -f
- strip bin/tictactoe
- tar cvzf ttt.tar.gz bin src Cargo.*
when:
event:
- tag
- name: gitea_release
image: plugins/gitea-release
settings:
api_key:
from_secret: gitea_tkn
base_url:
from_secret: gitea_url
files:
- ttt.tar.gz
checksum:
- md5
- sha512
when:
event:
- tag

View File

@@ -1,3 +1,4 @@
use std::env::args;
use std::fmt; use std::fmt;
use std::io; use std::io;
use std::io::Write; use std::io::Write;
@@ -72,7 +73,7 @@ impl FromStr for Board {
match c { match c {
'X' | 'x' => board.0.push(State::X), 'X' | 'x' => board.0.push(State::X),
'O' | 'o' => board.0.push(State::O), 'O' | 'o' => board.0.push(State::O),
'N' | 'n' => board.0.push(State::N), 'N' | 'n' | '_' => board.0.push(State::N),
_ => (), _ => (),
} }
} }
@@ -96,6 +97,16 @@ impl Board {
(self.0.len() as f64).sqrt() as usize (self.0.len() as f64).sqrt() as usize
} }
fn to_string_short(&self) -> String {
let mut s = String::with_capacity(self.0.len() + self.dimension());
for y in 0..self.dimension() {
for x in 0..self.dimension() {
s.push_str(&self[(x, y)].to_string())
}
}
s
}
fn winner(&self) -> Option<State> { fn winner(&self) -> Option<State> {
let mut winners = [State::N; 4]; let mut winners = [State::N; 4];
let dim = self.dimension(); let dim = self.dimension();
@@ -152,11 +163,24 @@ impl Board {
} }
//Diagonal winners require a full X pass //Diagonal winners require a full X pass
winner(&winners[2..4]) winner(&winners[2..4])
.or(Some(State::N).filter(|_| self.0.iter().filter(|s| *s == &State::N).count() == 0))
} }
} }
fn main() { fn main() {
let mut board = Board::default(); let mut board = {
if let Some(arg) = args().skip(1).next() {
if let Ok(size) = arg.parse::<usize>() {
Board::new(size)
} else if let Ok(board) = Board::from_str(&arg) {
board
} else {
Board::default()
}
} else {
Board::default()
}
};
let stdin = std::io::stdin(); let stdin = std::io::stdin();
println!("{}", &board); println!("{}", &board);
let winner = loop { let winner = loop {
@@ -204,7 +228,7 @@ fn main() {
println!("{}", &board); println!("{}", &board);
} }
}; };
println!("The winner is {}", winner); println!("{}\nThe winner is {}", board.to_string_short(), winner);
} }
#[cfg(test)] #[cfg(test)]
@@ -217,10 +241,7 @@ mod test {
Board::from_str("XXX,NNN,NNN").unwrap().winner(), Board::from_str("XXX,NNN,NNN").unwrap().winner(),
Some(State::X) Some(State::X)
); );
assert_eq!( assert_eq!(Board::from_str("XNX,NNN,NNN").unwrap().winner(), None);
Board::from_str("XNX,NNN,NNN").unwrap().winner(),
None
);
assert_eq!( assert_eq!(
Board::from_str("NNN,XXX,NNN").unwrap().winner(), Board::from_str("NNN,XXX,NNN").unwrap().winner(),
Some(State::X) Some(State::X)
@@ -233,5 +254,18 @@ mod test {
Board::from_str("OXN,OON,XNO").unwrap().winner(), Board::from_str("OXN,OON,XNO").unwrap().winner(),
Some(State::O) Some(State::O)
); );
println!("{}", Board::from_str("XOX,OOX,OXO").unwrap());
assert_eq!(
Board::from_str("XOX,OOX,OXO").unwrap().winner(),
Some(State::N)
);
}
#[test]
fn to_string() {
assert_eq!(
&Board::from_str("XXX,NNN,NNN").unwrap().to_string_short()[..],
"XXX______"
);
} }
} }