From 977dadaa07f86a3ebabedb425cc6f68b2e14d569 Mon Sep 17 00:00:00 2001 From: Katharina Fey Date: Wed, 29 Jan 2020 07:56:26 +0000 Subject: Adding some more stat functions to handle incoming packets --- src/data.rs | 1 + src/gens.rs | 47 ++++++++++++++++++++++++++++++++++ src/main.rs | 1 + src/stats.rs | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 4 files changed, 126 insertions(+), 5 deletions(-) create mode 100644 src/gens.rs diff --git a/src/data.rs b/src/data.rs index b1c248860b02..2a4ab8a03019 100644 --- a/src/data.rs +++ b/src/data.rs @@ -86,6 +86,7 @@ pub enum Owner { } /// Encodes upgrade level without numbers +#[derive(Copy, Clone)] pub enum Level { /// 1 One, diff --git a/src/gens.rs b/src/gens.rs new file mode 100644 index 000000000000..cd0af16754f3 --- /dev/null +++ b/src/gens.rs @@ -0,0 +1,47 @@ +//! Helpers to determine if a node can send a particular packet. + +/// These functions are unfortunately all a bit stringly typed atm +pub mod can_send { + use crate::data::{Level, PacketType, Upgrade}; + use Level::*; + + #[inline] + pub fn base() -> Vec<&'static str> { + vec!["ping", "capture"] + } + + /// Guard nodes are the most versatile + #[inline] + pub fn guard(lvl: Level) -> Vec<&'static str> { + match lvl { + // This is just kinda gross + One => { + let mut p = base(); + p.append(&mut vec!["payload", "cns", "reset"]); + p + } + Two => { + let mut p = guard(One); + p.append(&mut vec!["nitm", "virus"]); + p + } + Three => { + let mut p = guard(Two); + p.append(&mut vec!["takeover"]); + p + } + } + } + + /// Compute nodes can sennd compute packets + pub fn compute() -> Vec<&'static str> { + let mut p = base(); + p.append(&mut vec!["compute"]); + p + } + + /// Relays only relay! + pub fn relay() -> Vec<&'static str> { + vec![] + } +} diff --git a/src/main.rs b/src/main.rs index 873a84e684a7..1b6a5773d25d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,7 @@ #![allow(warnings)] mod data; +mod gens; mod map; mod stats; diff --git a/src/stats.rs b/src/stats.rs index d679c3e7d38c..7755821e4742 100644 --- a/src/stats.rs +++ b/src/stats.rs @@ -5,12 +5,15 @@ //! Whenever there is some effect that can happen in the game, it's //! value (strength) will be derived from here. +pub type Money = u16; + /// The cost of doing business pub mod cost { + use super::Money; use crate::data::{Level, PacketType, Upgrade}; /// Takes the current node and desired upgrade level - pub fn upgrade(curr: &Upgrade, want: &Upgrade) -> u32 { + pub fn upgrade(curr: &Upgrade, want: &Upgrade) -> Money { use self::{Level::*, Upgrade::*}; match (curr, want) { // Base upgrades @@ -36,7 +39,7 @@ pub mod cost { } /// Sending certain packets costs money, let's find out how much - pub fn packets(node: &Upgrade, packet: &PacketType) -> u32 { + pub fn packets(node: &Upgrade, packet: &PacketType) -> Money { use { Level::*, PacketType::*, @@ -62,11 +65,13 @@ pub mod cost { (Guard(Two), Reset) => 32, (Guard(Three), Reset) => 48, - (Guard(One), Nitm) => 28, + (Guard(One), CNS) => 22, + (Guard(Two), CNS) => 40, + (Guard(Three), CNS) => 82, + (Guard(Two), Nitm) => 64, (Guard(Three), Nitm) => 148, - (Guard(One), Virus) => 18, (Guard(Two), Virus) => 40, (Guard(Three), Virus) => 60, @@ -74,7 +79,74 @@ pub mod cost { (Guard(Three), TakeOver) => 256, // Can't touch this - (_, _) => unreachable!() + (_, _) => unreachable!(), + } + } +} + +/// This is what capitalists are all the rage about +pub mod gains { + use super::Money; + use crate::data::{Level, PacketType, Upgrade}; + use std::sync::atomic::Ordering; + + /// This will tell you if you'll receive any money this week + pub fn parse_packet(node: &Upgrade, packet: &PacketType) -> Money { + use { + Level::*, + PacketType::*, + Upgrade::{Base, Compute as Cc, Guard, Relay}, + }; + + /// A utility function which increments the packet progress + /// + /// Depending on the node that is processing the incoming + /// packet, progress is either stepped by 1, 1.5, or 2 times + /// the advertised step rate, which is set by the spawning + /// node of the compute job. This means that stronger compute + /// nodes have a positive impact even in mostly low-level + /// systems. + /// + /// This function returns if it reached or overflowed the max + fn incr_compute(l: &Level, packet: &PacketType) -> bool { + match (l, packet) { + (lvl, Compute { max, curr, step }) => { + if curr.load(Ordering::Relaxed) < *max { + curr.fetch_add( + match lvl { + One => *step, + Two => (*step as f32 * 1.5) as u16, + Three => *step * 2, + }, + Ordering::Relaxed, + ); + } + + // Did we reach the target? + curr.load(Ordering::Relaxed) >= *max + } + (_, _) => unreachable!(), + } + } + + match (node, packet) { + // A basic income for all node and packets + (Base, Ping) => 4, + (Guard(One), Ping) | (Cc(One), Ping) | (Relay(One), Ping) => 6, + (Guard(Two), Ping) | (Cc(Two), Ping) | (Relay(Two), Ping) => 11, + (Guard(Three), Ping) | (Cc(Three), Ping) | (Relay(Three), Ping) => 17, + + // A compute node will always increment the packet + // reference. If it made it to "max", it will then also + // return an amount of money that can be gained + (Cc(ref lvl), Compute { ref max, .. }) if incr_compute(lvl, packet) => match lvl { + One => *max, + Two => max * 2, + Three => max * 3, + }, + + // If in doubt, nada! + (_, _) => 0, } } } -- cgit v1.2.3