Skip to content

Commit

Permalink
Reset to latest commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Flaxoos committed Apr 30, 2024
0 parents commit ebaec7e
Show file tree
Hide file tree
Showing 9 changed files with 447 additions and 0 deletions.
27 changes: 27 additions & 0 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: Build

on:
push:
branches: [ main ]
pull_request:
branches: [ main ]

jobs:
build_and_test:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2

- name: Install Rust
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true

- name: Build and Test
uses: actions-rs/cargo@v1
with:
command: build --release
args: --verbose --workspace
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/target/
**/*.rs.bk
Cargo.lock
/node_modules/
.env
*.idea
.DS_STORE
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
workspace = { members = [ "named", "strategies"] }
11 changes: 11 additions & 0 deletions named/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[package]
name = "named"
version = "0.1.0"
edition = "2021"

[lib]
proc-macro = true

[dependencies]
quote = "1.0.35"
syn = "2.0.48"
35 changes: 35 additions & 0 deletions named/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright (C) 2024 Polkadot Blockchain Academy
* See the LICENSE.md file distributed with this work for additional
* information regarding copyright ownership.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

extern crate proc_macro;

use proc_macro::TokenStream;

use quote::quote;
use syn::{DeriveInput, parse_macro_input};

#[proc_macro_derive(Named)]
pub fn named_derive(input: TokenStream) -> TokenStream {
let ast = parse_macro_input!(input as DeriveInput);
let name = &ast.ident;
let gen = quote! {
impl Named for #name {
fn name(&self) -> &str {
stringify!(#name)
}
}
};
gen.into()
}
13 changes: 13 additions & 0 deletions strategies/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[package]
name = "strategies"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
named = { path = "../named" }
urandom = "0.1.1"
itertools = "0.12.1"
serde = { version = "1.0.198", features = ["derive"] }
enum-display-derive = "0.1.1"
208 changes: 208 additions & 0 deletions strategies/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
/*
* Copyright (C) 2024 Polkadot Blockchain Academy
* See the LICENSE.md file distributed with this work for additional
* information regarding copyright ownership.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

pub mod submission_macro;
pub mod utils;

#[macro_use]
extern crate enum_display_derive;

use core::fmt::{Debug, Display};
use std::cell::RefCell;
use std::hash::*;
use std::rc::Rc;
pub use std::sync::{Arc, Mutex};

use serde::Serialize;
pub use urandom::rng::Xoshiro256;

use Move::Z;
pub use named::Named;

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

/// 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.
///
/// # Arguments
///
/// * `favoured_move` - A move that might be favored by the opponent or game conditions.
///
/// # Returns
///
/// The move that the strategy chooses to play.
fn play_for_favoured_move(&mut self, favoured_move: Move) -> Move;

/// Handles the last round of the game, taking into account the strategy owner's favored move.
///
/// # Arguments
///
/// * `round` - The last round of the game
/// * `favoured_move` - The strategy owner's favored move
fn handle_last_round(&mut self, round: Round, favoured_move: Move);
}

#[derive(Eq, PartialEq, Clone, Copy, Debug, Hash, Named, Ord, PartialOrd, Serialize, Display)]
pub enum Move {
X,
Y,
Z,
}

/// Return the opposite of a `Move` such that:
///
/// `X` -> `Y`
///
/// `Y` -> `X`
///
/// `Z` -> `Z`
///
pub trait Opposite {
fn opposite(self) -> Self;
}

impl Opposite for Move {
fn opposite(self) -> Self {
match self {
X => Y,
Y => X,
Z => Z,
}
}
}

/// The result of a round
#[derive(Clone, Copy, Debug)]
pub struct Round {
/// The move that the participant made
pub my_move: Move,
/// The move that the opponent made
pub opponent_move: Move,
}

impl Round {
pub fn of(my_move: Move, opponent_move: Move) -> Self {
Round {
my_move,
opponent_move,
}
}
}

pub type ParticipantName = &'static str;
pub type ParticipantPubName = &'static str;

/// Represents a participant in the game.
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub struct Participant {
/// The type of the participant (e.g., System, Remote, Onsite).
pub participant_type: ParticipantType,
/// The internal, unique name of the participant.
pub name: ParticipantName,
/// The public-facing name of the participant.
pub pub_name: ParticipantPubName,
}

#[allow(dead_code)]
#[derive(Clone, Debug, Display, Eq, PartialEq, Hash)]
pub enum ParticipantType {
System,
Remote,
Onsite,
}

impl Participant {
/// Creates a new participant.
pub fn new(
participant_type: ParticipantType,
name: ParticipantName,
pub_name: ParticipantPubName,
) -> Self {
Self {
participant_type,
name,
pub_name,
}
}
}

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())
} else {
f.write_str(self.pub_name.to_string().as_str())
}
}
}

/// Struct for holding a strategy and its owner.
pub struct OwnedStrategy {
pub owner: Participant,
pub strategy: Rc<RefCell<Box<dyn Strategy>>>,
}

impl Debug for OwnedStrategy {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("OwnedStrategy")
.field("owner", &self.owner)
.field("strategy", &self.strategy.borrow().name())
.finish()
}
}

impl Display for OwnedStrategy {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str(format!("{}: {}", self.owner.name, self.strategy.borrow().name()).as_str())
}
}

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())
}
}

impl Eq for OwnedStrategy {}
impl Hash for OwnedStrategy {
fn hash<H: Hasher>(&self, state: &mut H) {
self.owner.hash(state);
self.strategy.borrow().name().hash(state);
}
}

impl OwnedStrategy {
pub fn new(owner: Participant, strategy: Rc<RefCell<Box<dyn Strategy>>>) -> Self {
OwnedStrategy { owner, strategy }
}

/// Returns the an ID for the strategy
pub fn id(&self) -> String {
self.to_string()
}
}

/// Something that has a name
pub trait Named {
/// Return the name of `self`
fn name(&self) -> &str;
}

26 changes: 26 additions & 0 deletions strategies/src/submission_macro.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright (C) 2024 Polkadot Blockchain Academy
* See the LICENSE.md file distributed with this work for additional
* information regarding copyright ownership.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#[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))),
)
}
}
}
Loading

0 comments on commit ebaec7e

Please sign in to comment.