Skip to content
Snippets Groups Projects
Commit e2c643f8 authored by sven.wikberg's avatar sven.wikberg
Browse files

initial commit 2

parent 33762a62
No related branches found
No related tags found
No related merge requests found
[[package]]
name = "bitflags"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "fuchsia-zircon"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "fuchsia-zircon-sys"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "libc"
version = "0.2.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "rand"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rust_hepia_lib"
version = "0.1.0"
dependencies = [
"rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "tp5_connect4"
version = "0.1.0"
dependencies = [
"rust_hepia_lib 0.1.0",
]
[[package]]
name = "winapi"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata]
"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12"
"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
"checksum libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "76e3a3ef172f1a0b9a9ff0dd1491ae5e6c948b94479a3021819ba7d860c8645d"
"checksum rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8356f47b32624fef5b3301c1be97e5944ecdd595409cc5da11d05f211db6cfbd"
"checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0"
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[package]
name = "tp5_connect4"
version = "0.1.0"
authors = ["sven.wikberg"]
[dependencies]
rust_hepia_lib = { path = "./src/rust_hepia_lib" }
extern crate rust_hepia_lib;
const WIDTH: usize = 7;
const HEIGHT: usize = 6;
#[derive(Copy, Clone, PartialEq)]
enum Connect4Case {
Empty,
Red,
Yellow,
}
struct Connect4 {
board: [[Connect4Case; WIDTH]; HEIGHT],
game_mode: u8,
turn_count: u32,
width: usize,
height: usize,
}
impl Connect4 {
fn new() -> Connect4 {
Connect4 {
board: [[Connect4Case::Empty; WIDTH]; HEIGHT],
game_mode: 0,
turn_count: 0,
width: WIDTH,
height: HEIGHT,
}
}
fn get_max_turn(&self) -> u32 {
(self.width as u32 * self.height as u32)
}
fn is_red_turn(&self) -> bool {
if self.turn_count % 2 == 1 {
return true;
} else {
return false;
}
}
fn choose_game_mode() -> u8 {
let mut x: i32;
loop {
println!("Choose your game mode : (1) Player vs Player. (2) Player vs IA, easy. (3) Player vs IA, hard.");
x = rust_hepia_lib::read_int();
match x {
1 | 2 | 3 => return x as u8,
_ => println!("This is not a valid number"),
}
}
}
fn place_piece(&mut self, x: usize) -> bool {
if x >= self.width {
// si on veut placer une piece en dehors du tableau
return false;
}
if self.board[0 as usize][x] != Connect4Case::Empty {
// si la colonne est deja pleine
return false;
}
for i in 1..self.height {
if self.board[i][x] != Connect4Case::Empty {
// on place la nouelle piece au dessus de la plus haute piece de la colonne
self.board[i - 1][x] = if self.is_red_turn() {
Connect4Case::Red
} else {
Connect4Case::Yellow
};
return true;
}
}
self.board[self.height - 1][x] = if self.is_red_turn() {
// si la colonne est vide
Connect4Case::Red
} else {
Connect4Case::Yellow
};
return true;
}
fn choose_col(&self) -> usize {
let mut col: i32;
loop {
println!("Choose a column (1-{})", self.width);
col = rust_hepia_lib::read_int();
if col < 1 || col > self.width as i32 {
println!("This is not a valid column");
} else {
return (col - 1) as usize;
}
}
}
fn play_turn(&mut self) {
self.turn_count += 1;
println!(
"This is {}'s turn !!",
if self.is_red_turn() { 'O' } else { 'X' }
);
if self.is_red_turn() || self.game_mode == 1 {
let mut col: usize;
loop {
col = self.choose_col();
if !self.place_piece(col) {
println!("This is not a valid column");
} else {
break;
}
}
} else if self.game_mode == 2 {
let mut col: usize;
loop {
col = rust_hepia_lib::gen(0, self.width as i32) as usize;
if self.place_piece(col) {
break;
}
}
}
}
fn display(&self) {
for y in 0..self.height {
if y == 0 {
print!("┌─");
for _x in 1..self.width {
print!("┬─");
}
println!("┐");
} else {
print!("├─");
for _x in 1..self.width {
print!("┼─");
}
println!("┤");
}
for x in 0..self.width {
print!(
"|{}",
match self.board[y][x] {
Connect4Case::Empty => ' ',
Connect4Case::Red => 'O',
Connect4Case::Yellow => 'X',
}
);
if x + 1 == self.width {
print!("|");
}
}
println!();
}
print!("└─");
for _x in 1..self.width {
print!("┴─");
}
println!("┘");
for x in 1..self.width + 1 {
print!(" {0}", x);
}
println!();
}
fn is_won(&self) -> bool {
for y in 0..self.height {
for x in 0..self.width {
if self.board[y][x] != Connect4Case::Empty {
if x + 3 < WIDTH {
// verif horizontale
if self.board[y][x + 1] == self.board[y][x]
&& self.board[y][x + 2] == self.board[y][x]
&& self.board[y][x + 3] == self.board[y][x]
{
return true;
}
}
if y + 3 < HEIGHT {
// verif verticale
if self.board[y + 1][x] == self.board[y][x]
&& self.board[y + 2][x] == self.board[y][x]
&& self.board[y + 3][x] == self.board[y][x]
{
return true;
}
}
if x + 3 < WIDTH && y + 3 < HEIGHT {
// verif diagonale 1 : \
if self.board[y + 1][x + 1] == self.board[y][x]
&& self.board[y + 2][x + 2] == self.board[y][x]
&& self.board[y + 3][x + 3] == self.board[y][x]
{
return true;
}
}
if x >= 3 && y + 3 < HEIGHT {
// verif diagonale 2 : /
if self.board[y + 1][x - 1] == self.board[y][x]
&& self.board[y + 2][x - 2] == self.board[y][x]
&& self.board[y + 3][x - 3] == self.board[y][x]
{
return true;
}
}
}
}
}
return false;
}
fn is_full(&self) -> bool {
if self.turn_count >= self.get_max_turn() {
true
} else {
false
}
}
fn play_game(&mut self) {
self.game_mode = Connect4::choose_game_mode();
self.display();
loop {
self.play_turn();
self.display();
if self.is_won() {
if self.is_red_turn() {
println!("O won GG !");
} else {
println!("X won, well played !");
}
break;
}
if self.is_full() {
println!("Draw, nobody won !");
break;
}
}
}
}
fn main() {
let mut c: Connect4 = Connect4::new();
c.play_game();
}
[package]
name = "rust_hepia_lib"
version = "0.1.0"
authors = ["Orestis Malaspinas <orestis.malaspinas@hesge.ch>",
"Orphée Antoniadis <orphee.antoniadis@hesge.ch>"]
[dependencies]
rand = "0.4"
\ No newline at end of file
# Librairie de Rust pour le cours de programmation séquentielle
Plusieurs fonctions sont définies dans cette librairie pour simplifier la vie aux étudiants
de première année de programmation séquentielle.
## Prérequis
Pour pouvoir utiliser cette librairie, il faut posséder la chaîne de compilation Rust (et une connexion à internet), qui s'installe à l'aide de la commande
sur les systèmes Linux
```
curl https://sh.rustup.rs -sSf | sh
```
Pour d'autres systèmes ou plus d'informations veuillez vous référer au [guide d'installation](https://www.rust-lang.org/en-US/install.html).
Vous pouvez aussi utiliser le programme de gestion de version `git` (pas obligatoire).
## Installation
Pour installer cette librairie vous avez deux choix:
1. Télécharger le fichier `.zip` en cliquant sur l'icône "download" sur la page <https://githepia.hesge.ch/orestis.malaspin/rust_hepia_lib> (le petit nuage à droite sur la page)
et décompresser l'archive dans le répertoire de votre choix.
2. *Cloner* un dépôt *git* dans le répertoire de votre choix à l'aide de la commande
```
git clone https://githepia.hesge.ch/orestis.malaspin/rust_hepia_lib.git
```
Pour plus d'informations sur `git`, il existe une introduction disponible sur [githepia](https://githepia.hesge.ch/orestis.malaspin/git_tutorial).
## Test
Une fois la librairie installée vous pouvez tester si elle compile avec la commande
```
cargo build
```
Si tout se passe bien vous devriez obtenir un message du genre
```
Compiling libc v0.2.43
Compiling rand v0.4.3
Compiling rust_hepia_lib v0.1.0 (file:///home/orestis.malaspin/svn/projects/rust_hepia_lib)
Finished dev [unoptimized + debuginfo] target(s) in 2.75s
```
# Mac
.DS_Store
# Rust
target
**/*.rs.bk
Cargo.lock
image: omalaspinas/archlinux-pandoc:latest
build_only:
script:
- cd ..
- git clone https://github.com/milliams/plotlib.git plotlib 2> /dev/null || (cd plotlib; git pull)
- cd rust_hepia_lib
- cargo build
\ No newline at end of file
extern crate rand;
use rand::distributions::range::SampleRange;
use rand::Rng;
use std::cmp::PartialOrd;
use std::io;
use std::iter::Rev;
use std::{f32, i32};
pub use std::f32::consts::PI;
pub fn gen<T: SampleRange + PartialOrd + Copy>(min: T, max: T) -> T {
rand::thread_rng().gen_range(min, max)
}
fn read_line() -> String {
let mut guess = String::new();
io::stdin()
.read_line(&mut guess)
.expect("Failed to read line.");
guess
}
fn str_to_int<T: std::str::FromStr>(line: &str) -> Option<T> {
match line.trim().parse() {
Ok(num) => Some(num),
Err(_) => None,
}
}
fn str_to_char(line: &str) -> char {
match line.trim().parse() {
Ok(c) => c,
Err(_) => panic!("This is not a char."),
}
}
pub fn read_int() -> i32 {
loop {
match str_to_int(&read_line()) {
Some(num) => return num,
None => println!("This is not a number, please enter a number."),
}
}
}
pub fn read_char() -> char {
str_to_char(&read_line())
}
pub fn get_bytes(name: &String) -> &[u8] {
name.as_bytes()
}
pub fn pow(x: i32, y: i32) -> i32 {
x.pow(y as u32)
}
pub fn powf(x: f32, y: f32) -> f32 {
x.powf(y)
}
pub fn abs(num: i32) -> i32 {
num.abs()
}
pub fn absf(num: f32) -> f32 {
num.abs()
}
pub fn reverse<T: Sized + DoubleEndedIterator>(it: T) -> Rev<T> {
it.rev()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn str_to_int_test() {
assert_eq!(str_to_int::<i32>("4"), 4);
assert_eq!(str_to_int::<i32>("101"), 101);
assert_eq!(str_to_int::<i32>("-4"), -4);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment