Skip to content

Commit

Permalink
Merge pull request #1 from Polkadot-Blockchain-Academy/submit-start-c…
Browse files Browse the repository at this point in the history
…hange

Submit start change
  • Loading branch information
Flaxoos authored May 27, 2024
2 parents 366cfa5 + f63e82c commit fefef36
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 51 deletions.
61 changes: 51 additions & 10 deletions strategies/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@
* limitations under the License.
*/

pub mod submission_macro;
pub mod utils;

#[macro_use]
extern crate enum_display_derive;

Expand All @@ -33,6 +30,9 @@ pub use named::Named;

use crate::Move::{X, Y};

pub mod submission_macro;
pub mod utils;

/// This is the trait that needs to be implemented and submitted
pub trait Strategy: Named + Sync {
/// Determines the next move for the strategy, taking into account the strategy owner's favored move.
Expand Down Expand Up @@ -106,7 +106,7 @@ pub type ParticipantName = &'static str;
pub type ParticipantPubName = &'static str;

/// Represents a participant in the game.
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
#[derive(Clone, Debug, Eq, PartialEq, Hash, Copy)]
pub struct Participant {
/// The type of the participant (e.g., System, Remote, Onsite).
pub participant_type: ParticipantType,
Expand All @@ -117,7 +117,7 @@ pub struct Participant {
}

#[allow(dead_code)]
#[derive(Clone, Debug, Display, Eq, PartialEq, Hash)]
#[derive(Clone, Debug, Display, Eq, PartialEq, Hash, Copy)]
pub enum ParticipantType {
System,
Remote,
Expand All @@ -142,14 +142,15 @@ impl Participant {
impl Display for Participant {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
if let ParticipantType::System = self.participant_type {
f.write_str(format!("{}", self.participant_type).as_str())
f.write_str(format!("{:?}", self.participant_type).as_str())
} else {
f.write_str(self.pub_name.to_string().as_str())
}
}
}

/// Struct for holding a strategy and its owner.
#[derive(Clone)]
pub struct OwnedStrategy {
pub owner: Participant,
pub strategy: Rc<RefCell<Box<dyn Strategy>>>,
Expand All @@ -174,14 +175,15 @@ impl PartialEq<Self> for OwnedStrategy {
fn eq(&self, other: &Self) -> bool {
self.owner.eq(&other.owner)
&& self
.strategy
.borrow()
.name()
.eq(other.strategy.borrow().name())
.strategy
.borrow()
.name()
.eq(other.strategy.borrow().name())
}
}

impl Eq for OwnedStrategy {}

impl Hash for OwnedStrategy {
fn hash<H: Hasher>(&self, state: &mut H) {
self.owner.hash(state);
Expand All @@ -206,3 +208,42 @@ pub trait Named {
fn name(&self) -> &str;
}

#[cfg(test)]
mod tests {
use ParticipantType::Onsite;

use super::*;

#[derive(Named)]
struct MyStrategy {
pub moves: u8,
}

impl Strategy for MyStrategy {
fn play_for_favoured_move(&mut self, favoured_move: Move) -> Move {
let m = if self.moves % 2 == 0 { favoured_move } else { favoured_move.opposite() };
println!("Playing: {} because moves: {}", m, self.moves);
self.moves += 1;
m
}

fn handle_last_round(&mut self, round: Round, favoured_move: Move) {}
}

#[test]
fn test_submit_strategy_macro() {
submit_strategy!(MyStrategy { moves: 0 }, Onsite, "MyStrategy", "MyStrategy");
let (participant, get_strategy) = provide_strategy();
for matchup in 0..1 {
let s1 = Rc::new(RefCell::new(get_strategy()));
let s2 = Rc::new(RefCell::new(get_strategy()));
let s1_fm = if matchup % 2 == 0 { X } else { Y };
let s2_fm = if matchup % 2 == 0 { Y } else { X };
println!("matchup: {}: s1_fm: {} s2_fm: {}", matchup, s1_fm, s2_fm);
assert_eq!(s1.borrow_mut().play_for_favoured_move(s1_fm), X);
assert_eq!(s2.borrow_mut().play_for_favoured_move(s2_fm), Y);
assert_eq!(s1.borrow_mut().play_for_favoured_move(s1_fm), Y);
assert_eq!(s2.borrow_mut().play_for_favoured_move(s2_fm), X);
}
}
}
91 changes: 52 additions & 39 deletions strategies/src/submission_macro.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,55 +13,68 @@
* limitations under the License.
*/



use crate::{Move, Participant, Round, Strategy};

Check warning on line 16 in strategies/src/submission_macro.rs

View workflow job for this annotation

GitHub Actions / build_and_test

unused imports: `Move`, `Participant`, `Round`, `Strategy`
#[macro_export]
macro_rules! submit_strategy {
($strategy:expr, $participant_type:ident, $participant_name:literal, $participant_pub_name:literal) => {
pub fn provide_strategy() -> OwnedStrategy {
OwnedStrategy::new(
Participant::new($participant_type, $participant_name, $participant_pub_name),
Rc::new(RefCell::new(Box::new($strategy))),
)
}
pub fn provide_strategy() -> (Participant, impl Fn() -> Box<dyn Strategy>) {
(
Participant::new($participant_type, $participant_name, $participant_pub_name),
move || Box::new($strategy),
)
}

#[cfg(test)]
mod tests {
use super::*;
use std::time::{Duration, Instant};
mod tests {
use super::*;
use std::time::{Duration, Instant};

#[test]
fn test_participant_type() {
assert_ne!(ParticipantType::System, $participant_type, "participant type should not be System");
}
#[test]
fn test_participant_type() {
assert_ne!(
ParticipantType::System,
$participant_type,
"participant type should not be System"
);
}

#[test]
fn test_strategy_time() {
let max_move_time = Duration::from_millis(100);
let max_handle_round_time = Duration::from_millis(100);
let strategy = OwnedStrategy::new(
#[test]
fn test_strategy_time() {
let max_move_time = Duration::from_millis(100);
let max_handle_round_time = Duration::from_millis(100);
let strategy = OwnedStrategy::new(
Participant::new($participant_type, $participant_name, $participant_pub_name),
Rc::new(RefCell::new(Box::new($strategy))),
);

let start_time = Instant::now();
strategy.strategy.borrow_mut().play_for_favoured_move(X);
let elapsed = start_time.elapsed();
assert!(elapsed < max_move_time, "play_for_favoured_move exceeded timeout. elapsed:{:?}, max:{:?}", elapsed, max_move_time);
let start_time = Instant::now();
strategy.strategy.borrow_mut().play_for_favoured_move(X);
let elapsed = start_time.elapsed();
assert!(
elapsed < max_move_time,
"play_for_favoured_move exceeded timeout. elapsed:{:?}, max:{:?}",
elapsed,
max_move_time
);

let mut rounds = vec![];
for m1 in vec![X, Y, Z] {
for m2 in vec![X, Y, Z] {
rounds.push(Round::of(m1, m2));
}
}
for round in rounds {
let start_time = Instant::now();
strategy.strategy.borrow_mut().handle_last_round(round, X);
let elapsed = start_time.elapsed();
assert!(elapsed < max_handle_round_time, "handle_last_round exceeded timeout. elapsed:{:?}, max:{:?}", elapsed, max_handle_round_time);
}
}
}
}
let mut rounds = vec![];
for m1 in vec![X, Y, Z] {
for m2 in vec![X, Y, Z] {
rounds.push(Round::of(m1, m2));
}
}
for round in rounds {
let start_time = Instant::now();
strategy.strategy.borrow_mut().handle_last_round(round, X);
let elapsed = start_time.elapsed();
assert!(
elapsed < max_handle_round_time,
"handle_last_round exceeded timeout. elapsed:{:?}, max:{:?}",
elapsed,
max_handle_round_time
);
}
}
}
};
}
4 changes: 2 additions & 2 deletions strategies/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
pub use core::fmt::Debug;
pub use std::collections::VecDeque;

use urandom::Random;
use urandom::rng::Xoshiro256;
use urandom::Random;

use crate::Move;
use crate::Move::{X, Y, Z};
Expand Down Expand Up @@ -116,4 +116,4 @@ impl Default for RandomMove {
let third = 1f32 / 3f32;
RandomMove::new(third, third)
}
}
}

0 comments on commit fefef36

Please sign in to comment.