Skip to content

Commit

Permalink
Add russian-roulette
Browse files Browse the repository at this point in the history
  • Loading branch information
mbrav committed Mar 4, 2023
1 parent ba1495f commit 67cbdd2
Show file tree
Hide file tree
Showing 5 changed files with 135 additions and 2 deletions.
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ opt-level = 2

# Build optimizations: https://github.com/johnthagen/min-sized-rust
[profile.release]
panic = "abort"
strip = true # Strip symbols from binary
opt-level = "s" # Optimize for size
opt-level = "z" # Optimize for size
lto = true # Enable link time optimization
codegen-units = 1 # Maximize size reduction optimizations (takes longer)

Expand Down
40 changes: 40 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,43 @@
<p align="center">A collection of crazy CLI tools in Rust.
<br>Inspired by the "nuttertools" cheat code from <i>Grand Theft Auto: ViceCity</i>.
</p>


## Install

```bash
cargo install
```

## Run

First, build release binary

```bash
cargo build --release
```

The run the binary

```bash
./target/release/nuttertools --help
```

You will get the following output:

```text
A collection of crazy CLI tools in Rust
Usage: nuttertools <COMMAND>
Commands:
phone-gen Brute force all possible phone numbers
prosecho The drunk pro's alternative to echo
rat A program that will rat on all files you pass to it
russian-roulette Famous Russian gun game that blows brains
help Print this message or the help of the given subcommand(s)
Options:
-h, --help Print help
-V, --version Print version
```
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use std::fmt;

pub mod phone_gen;
pub mod prosecho;
pub mod russian_roulette;
pub mod rat;

/// nuttertools Error
Expand Down
4 changes: 3 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use clap::{Parser, Subcommand};

use nuttertools::{phone_gen, prosecho, rat, Error};
use nuttertools::{phone_gen, prosecho, rat, russian_roulette, Error};
use std::time::{Duration, Instant};

#[derive(Parser)]
Expand All @@ -17,6 +17,7 @@ pub enum Commands {
PhoneGen(phone_gen::Options),
Prosecho(prosecho::Options),
Rat(rat::Options),
RussianRoulette(russian_roulette::Options),
}

fn main() -> Result<(), Error> {
Expand All @@ -28,6 +29,7 @@ fn main() -> Result<(), Error> {
Commands::PhoneGen(options) => phone_gen::main(options)?,
Commands::Prosecho(options) => prosecho::main(options)?,
Commands::Rat(options) => rat::main(options)?,
Commands::RussianRoulette(options) => russian_roulette::main(options)?,
}

let end: Duration = start.elapsed();
Expand Down
89 changes: 89 additions & 0 deletions src/russian_roulette.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
use clap::{arg, Args};

use crate::Error;

fn c_rand_u8() -> u8 {
unsafe { rand() }
}

extern "C" {
fn rand() -> u8;
}

/// Famous Russian gun game that blows brains
#[derive(Args)]
pub struct Options {
/// Barrel size
#[arg(short, long, value_name = "NUM", default_value_t = 6)]
barrel: u8,
/// Bullet count
#[arg(short = 'l', long, value_name = "NUM", default_value_t = 1)]
bullets: u8,
/// Clicks number
#[arg(short, long, value_name = "NUM", default_value_t = 6)]
clicks: u8,
}

#[derive(Debug)]
struct Gun {
barrel: Vec<bool>,
hammer_pos: u8,
}

impl Gun {
// Create new Gun instance
pub fn new(barrel_size: u8, mut bullets: u8) -> Self {
match barrel_size {
0 => panic!("0 Barrel size!"),
_ => println!("Barrel with size {} opened", &barrel_size),
}
let mut barrel = vec![false; barrel_size as usize];
let mut hammer_pos: usize = 0;
match bullets {
0 => panic!("0 Bullets!"),
_ => {
if bullets > barrel_size {
panic!("Cannot fit {} bullets inside barrel", &bullets);
} else {
println!("Barrel loading with {} bullets", &bullets);
while bullets > 0 {
hammer_pos = (c_rand_u8() % barrel_size) as usize;
if barrel[hammer_pos] == false {
barrel[hammer_pos] = true;
bullets -= 1;
}
}
}
}
}
Self {
barrel: barrel,
hammer_pos: hammer_pos as u8,
}
}

// Trigger gun an fire round if loaded in barrel
pub fn trigger(&mut self) {
self.hammer_pos += 1;
let real_pos = self.hammer_pos as usize % self.barrel.len();
if self.barrel[real_pos] {
self.barrel[real_pos] = false;
println!("BAAANNG!!")
} else {
println!("*Click*, {} empty", real_pos)
}
}
}

/// # Errors
///
/// Will return `Err` string is empty
pub fn main(opts: &Options) -> Result<(), Error> {
let mut gun = Gun::new(opts.barrel, opts.bullets);

for _ in 0..opts.clicks {
gun.trigger();
}

Ok(())
}

0 comments on commit 67cbdd2

Please sign in to comment.