diff --git a/contracts/01-tamagotchi/Cargo.toml b/contracts/01-tamagotchi/Cargo.toml deleted file mode 100644 index ce867ab7..00000000 --- a/contracts/01-tamagotchi/Cargo.toml +++ /dev/null @@ -1,16 +0,0 @@ -[package] -name = "tamagotchi" -version.workspace = true -edition.workspace = true -publish.workspace = true - -[dependencies] -gstd.workspace = true -tamagotchi-io.workspace = true - -[build-dependencies] -gear-wasm-builder.workspace = true -tamagotchi-io.workspace = true - -[dev-dependencies] -gtest.workspace = true diff --git a/contracts/01-tamagotchi/build.rs b/contracts/01-tamagotchi/build.rs deleted file mode 100644 index 96f5ca8d..00000000 --- a/contracts/01-tamagotchi/build.rs +++ /dev/null @@ -1,5 +0,0 @@ -use tamagotchi_io::ProgramMetadata; - -fn main() { - gear_wasm_builder::build_with_metadata::(); -} diff --git a/contracts/01-tamagotchi/io/Cargo.toml b/contracts/01-tamagotchi/io/Cargo.toml deleted file mode 100644 index 2418cac1..00000000 --- a/contracts/01-tamagotchi/io/Cargo.toml +++ /dev/null @@ -1,9 +0,0 @@ -[package] -name = "tamagotchi-io" -version.workspace = true -edition.workspace = true -publish.workspace = true - -[dependencies] -gmeta.workspace = true -gstd.workspace = true diff --git a/contracts/01-tamagotchi/io/src/lib.rs b/contracts/01-tamagotchi/io/src/lib.rs deleted file mode 100644 index 394f418f..00000000 --- a/contracts/01-tamagotchi/io/src/lib.rs +++ /dev/null @@ -1,39 +0,0 @@ -#![no_std] - -use codec::{Decode, Encode}; -use gmeta::Metadata; -use gstd::prelude::*; -use scale_info::TypeInfo; - -#[derive(Default, Encode, Decode, TypeInfo)] -#[codec(crate = gstd::codec)] -#[scale_info(crate = gstd::scale_info)] -pub struct Tamagotchi { - // TODO: 1️⃣ Add `name` and `age` fields -} - -#[derive(Encode, Decode, TypeInfo)] -#[codec(crate = gstd::codec)] -#[scale_info(crate = gstd::scale_info)] -pub enum TmgAction { - // TODO: 2️⃣ Add `Name` and `Age` actions that set the name and age -} - -#[derive(Encode, Decode, TypeInfo)] -#[codec(crate = gstd::codec)] -#[scale_info(crate = gstd::scale_info)] -pub enum TmgEvent { - // TODO: 3️⃣ Add `Name` and `Age` events that return the name and age -} - -pub struct ProgramMetadata; - -// TODO: 4️⃣ Fill `Init`, `Handle`, and `State` types -impl Metadata for ProgramMetadata { - type Init = (); - type Handle = (); - type State = (); - type Reply = (); - type Others = (); - type Signal = (); -} diff --git a/contracts/01-tamagotchi/src/lib.rs b/contracts/01-tamagotchi/src/lib.rs deleted file mode 100644 index 85f152bd..00000000 --- a/contracts/01-tamagotchi/src/lib.rs +++ /dev/null @@ -1,19 +0,0 @@ -#![no_std] - -#[allow(unused_imports)] -use gstd::prelude::*; - -#[no_mangle] -extern fn init() { - // TODO: 5️⃣ Initialize the Tamagotchi program -} - -#[no_mangle] -extern fn handle() { - // TODO: 6️⃣ Add handling of `Name` and `Age` actions -} - -#[no_mangle] -extern fn state() { - // TODO: 7️⃣ Return the Tamagotchi state -} diff --git a/contracts/01-tamagotchi/tests/smoke.rs b/contracts/01-tamagotchi/tests/smoke.rs deleted file mode 100644 index 5dd29f16..00000000 --- a/contracts/01-tamagotchi/tests/smoke.rs +++ /dev/null @@ -1,10 +0,0 @@ -use gtest::{Program, System}; - -#[test] -fn smoke_test() { - let sys = System::new(); - sys.init_logger(); - let _program = Program::current(&sys); - - // TODO: 8️⃣ Test the program initialization and message handling -} diff --git a/contracts/02-tamagotchi-interaction/io/src/lib.rs b/contracts/02-tamagotchi-interaction/io/src/lib.rs index 621d1338..a5b88eda 100644 --- a/contracts/02-tamagotchi-interaction/io/src/lib.rs +++ b/contracts/02-tamagotchi-interaction/io/src/lib.rs @@ -1,8 +1,8 @@ #![no_std] use codec::{Decode, Encode}; -use gmeta::{Metadata,In,InOut,Out}; -use gstd::prelude::*; +use gmeta::{In, InOut, Metadata, Out}; +use gstd::{prelude::*, ActorId}; #[derive(Default, Encode, Decode, TypeInfo)] #[codec(crate = gstd::codec)] @@ -12,6 +12,13 @@ pub struct Tamagotchi { pub name: String, pub date_of_birth: u64, // TODO: 1️⃣ Add new fields + pub owner: ActorId, + pub fed: u64, + pub fed_block: u64, + pub entertained: u64, + pub entertained_block: u64, + pub slept: u64, + pub slept_block: u64, } #[derive(Encode, Decode, TypeInfo)] @@ -22,6 +29,9 @@ pub enum TmgAction { Name, Age, // TODO: 2️⃣ Add new actions + Feed, + Entertain, + Sleep, } #[derive(Encode, Decode, TypeInfo)] @@ -32,6 +42,9 @@ pub enum TmgEvent { Name(String), Age(u64), // TODO: 3️⃣ Add new events + Fed, + Entertained, + Slept, } pub struct ProgramMetadata; @@ -45,3 +58,15 @@ impl Metadata for ProgramMetadata { type Others = (); type Signal = (); } + +pub const HUNGER_PER_BLOCK: u64 = 1; +pub const BOREDOM_PER_BLOCK: u64 = 2; +pub const ENERGY_PER_BLOCK: u64 = 2; + +pub const FILL_PER_FEED: u64 = 1000; +pub const FILL_PER_ENTERTAINMENT: u64 = 1000; +pub const FILL_PER_SLEEP: u64 = 1000; + +pub const MAX_FED: u64 = 10000; +pub const MAX_ENTERTAINED: u64 = 10000; +pub const MAX_SLEPT: u64 = 10000; \ No newline at end of file diff --git a/contracts/02-tamagotchi-interaction/src/lib.rs b/contracts/02-tamagotchi-interaction/src/lib.rs index 35987cd0..ba4d00df 100644 --- a/contracts/02-tamagotchi-interaction/src/lib.rs +++ b/contracts/02-tamagotchi-interaction/src/lib.rs @@ -1,7 +1,57 @@ #![no_std] #[allow(unused_imports)] -use gstd::prelude::*; +use gstd::{exec, msg, prelude::*, ActorId}; +use tamagotchi_interaction_io::*; + +#[derive(Default, Encode, Decode, TypeInfo)] +#[codec(crate = gstd::codec)] +#[scale_info(crate = gstd::scale_info)] +pub struct Tamagotchi { + pub name: String, + pub date_of_birth: u64, + pub owner: ActorId, + pub fed: u64, + pub fed_block: u64, + pub entertained: u64, + pub entertained_block: u64, + pub slept: u64, + pub slept_block: u64, +} + +impl Tamagotchi { + fn current_fed(&mut self) -> u64 { + self.fed - (HUNGER_PER_BLOCK as u64) * ((exec::block_height() as u64) - self.fed_block) + } + fn current_entertained(&mut self) -> u64 { + self.entertained + - (BOREDOM_PER_BLOCK as u64) * ((exec::block_height() as u64) - self.entertained_block) + } + fn current_slept(&mut self) -> u64 { + self.slept - (ENERGY_PER_BLOCK as u64) * ((exec::block_height() as u64) - self.slept_block) + } + fn is_alive(&mut self) -> bool { + if self.current_fed() > 0 && self.current_entertained() > 0 && self.current_slept() > 0 { + true + } else { + panic!("Your tamagotchi is dead"); + } + } + fn feedaction(&mut self) { + self.entertained = self.current_entertained(); + self.slept = self.current_slept(); + } + fn entertainaction(&mut self) { + self.fed = self.current_fed(); + self.slept = self.current_slept(); + } + fn selptaction(&mut self) { + self.fed = self.current_fed(); + self.entertained = self.current_entertained(); + } +} + +static mut TAMAGOTCHI: Option = None; // TODO: 4️⃣ Define constants @@ -9,10 +59,17 @@ use gstd::prelude::*; extern fn init() { // TODO: 0️⃣ Copy the `init` function from the previous lesson and push changes to the master branch let initname = msg::load().expect("unable to load name"); - let birthdate = exec::block_timestamp(); + let current_block_height = exec::block_height() as u64; let tmg = Tamagotchi { name: initname, - date_of_birth: birthdate, + date_of_birth: current_block_height, + owner: msg::source(), + fed: 1000, + fed_block: current_block_height, + entertained: 5000, + entertained_block: current_block_height, + slept: 2000, + slept_block: current_block_height, }; unsafe { TAMAGOTCHI = Some(tmg); @@ -24,17 +81,67 @@ extern fn handle() { // TODO: 0️⃣ Copy the `handle` function from the previous lesson and push changes to the master branch let action: TmgAction = msg::load().expect("unable to load action"); let tmg = unsafe { TAMAGOTCHI.get_or_insert(Default::default()) }; - match action { - TmgAction::Name => { - msg::reply(TmgEvent::Name(tmg.name.clone()), 0) - .expect("Error in a reply'tamagotchi::name'"); - } - TmgAction::Age => { - let age = exec::block_timestamp() - tmg.date_of_birth; - msg::reply(TmgEvent::Age(age), 0).expect("Error in a reply'tamagotchi::age'"); + if msg::source() == tmg.owner { + match action { + TmgAction::Name => { + msg::reply(TmgEvent::Name(tmg.name.clone()), 0) + .expect("Error in a reply'tamagotchi::name'"); + } + TmgAction::Age => { + let age = exec::block_timestamp() - tmg.date_of_birth; + msg::reply(TmgEvent::Age(age), 0).expect("Error in a reply'tamagotchi::age'"); + } + TmgAction::Feed => { + if (tmg.current_fed() <= 9000) && tmg.is_alive() { + let fed = tmg.fed + FILL_PER_FEED; + msg::reply(TmgEvent::Fed, 0).expect("Error in a reply'tamagotchi::fed'"); + tmg.fed = fed; + tmg.fed_block = exec::block_height() as u64; + tmg.feedaction(); + } else if tmg.current_entertained() >= 9000 { + let fedblock = exec::block_height() as u64; + tmg.fed = MAX_FED; + tmg.fed_block = fedblock; + tmg.feedaction(); + msg::reply(TmgEvent::Fed, 1).expect("Error in a reply'tamagotchi::fed'"); + } + } + TmgAction::Entertain => { + if (tmg.current_entertained() <= 9000) && tmg.is_alive() { + let entertained = tmg.entertained + FILL_PER_ENTERTAINMENT; + msg::reply(TmgEvent::Entertained, 0) + .expect("Error in a reply'tamagotchi::entertained'"); + tmg.entertained = entertained; + tmg.entertained_block = exec::block_height() as u64; + tmg.entertainaction(); + } else if tmg.current_entertained() >= 9000 { + let entertainedblock = exec::block_height() as u64; + tmg.entertained = MAX_ENTERTAINED; + tmg.entertained_block = entertainedblock; + tmg.entertainaction(); + msg::reply(TmgEvent::Entertained, 1) + .expect("Error in a reply'tamagotchi::entertained'"); + } + } + TmgAction::Sleep => { + if (tmg.current_slept() <= 9000) && tmg.is_alive() { + let slept = tmg.slept + FILL_PER_SLEEP; + msg::reply(TmgEvent::Slept, 0).expect("Error in a reply'tamagotchi::slept'"); + tmg.slept = slept; + tmg.slept_block = exec::block_height() as u64; + tmg.selptaction() + } else if tmg.current_entertained() >= 9000 { + let sleptblock = exec::block_height() as u64; + tmg.slept = MAX_SLEPT; + tmg.slept_block = sleptblock; + tmg.selptaction(); + msg::reply(TmgEvent::Slept, 1).expect("Error in a reply'tamagotchi::slept'"); + } + } } + } else { + panic!("You are not the owner of this tamagotchi"); } - // TODO: 5️⃣ Add new logic for calculating the `fed`, `entertained` and `slept` levels } #[no_mangle] diff --git a/contracts/02-tamagotchi-interaction/tests/interaction.rs b/contracts/02-tamagotchi-interaction/tests/interaction.rs index a8cdc2a0..60b40945 100644 --- a/contracts/02-tamagotchi-interaction/tests/interaction.rs +++ b/contracts/02-tamagotchi-interaction/tests/interaction.rs @@ -1,4 +1,5 @@ -use gtest::{Program, System}; +use gtest::{Log, Program, System}; +use tamagotchi_interaction_io::*; // TODO: 0️⃣ Copy tests from the previous lesson and push changes to the master branch @@ -43,6 +44,20 @@ fn negative_smoke_test() { fn interaction_test() { let sys = System::new(); sys.init_logger(); - let _program = Program::current(&sys); - // TODO: 6️⃣ Test new functionality + let program = Program::current(&sys); + let result = program.send(2, String::from("Goodmoring")); + assert!(!result.main_failed()); + let result = program.send(2, TmgAction::Feed); + let log = Log::builder().dest(2).payload(TmgEvent::Fed); + assert!(result.contains(&log)); + let result = program.send(2, TmgAction::Entertain); + let log = Log::builder().dest(2).payload(TmgEvent::Entertained); + assert!(result.contains(&log)); + let result = program.send(2, TmgAction::Sleep); + let log = Log::builder().dest(2).payload(TmgEvent::Slept); + assert!(result.contains(&log)); + + let _result = program.send(1, TmgAction::Sleep); + //how to test the panic result? + //negetive test } diff --git a/contracts/Cargo.lock b/contracts/Cargo.lock index b112d757..5c4e29ab 100644 --- a/contracts/Cargo.lock +++ b/contracts/Cargo.lock @@ -5644,16 +5644,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "tamagotchi" -version = "0.3.3" -dependencies = [ - "gear-wasm-builder", - "gstd", - "gtest", - "tamagotchi-io", -] - [[package]] name = "tamagotchi-army" version = "0.3.3" @@ -5707,14 +5697,6 @@ dependencies = [ "gstd", ] -[[package]] -name = "tamagotchi-io" -version = "0.3.3" -dependencies = [ - "gmeta", - "gstd", -] - [[package]] name = "tamagotchi-nft" version = "0.3.3" diff --git a/contracts/Cargo.toml b/contracts/Cargo.toml index 70a1424d..c8575493 100644 --- a/contracts/Cargo.toml +++ b/contracts/Cargo.toml @@ -9,7 +9,6 @@ publish = false [workspace] resolver = "2" members = [ - "01-tamagotchi", "02-tamagotchi-interaction", "03-tamagotchi-nft", "04-tamagotchi-shop", @@ -29,7 +28,6 @@ gstd = { git = "https://github.com/gear-tech/gear", tag = "v1.0.2" } gtest = { git = "https://github.com/gear-tech/gear", tag = "v1.0.2" } sharded-fungible-token-io = { git = "https://github.com/gear-foundation/dapps", tag = "v1.0.2" } -tamagotchi-io.path = "01-tamagotchi/io" tamagotchi-interaction-io.path = "02-tamagotchi-interaction/io" tamagotchi-nft-io.path = "03-tamagotchi-nft/io" tamagotchi-shop-io.path = "04-tamagotchi-shop/io"