From 37805220e26a20cd035b0b93f8d436b1f424b2da Mon Sep 17 00:00:00 2001 From: Jackliu-miaozi <71253778+Jackliu-miaozi@users.noreply.github.com> Date: Wed, 13 Dec 2023 17:41:44 +0800 Subject: [PATCH] second commit --- .../02-tamagotchi-interaction/io/src/lib.rs | 25 +++- .../02-tamagotchi-interaction/src/lib.rs | 119 ++++++++++++++++-- .../tests/interaction.rs | 21 +++- 3 files changed, 149 insertions(+), 16 deletions(-) diff --git a/contracts/02-tamagotchi-interaction/io/src/lib.rs b/contracts/02-tamagotchi-interaction/io/src/lib.rs index 621d1338..dd1e025e 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,11 @@ 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; \ 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..0419a62d 100644 --- a/contracts/02-tamagotchi-interaction/src/lib.rs +++ b/contracts/02-tamagotchi-interaction/src/lib.rs @@ -1,7 +1,38 @@ #![no_std] #[allow(unused_imports)] -use gstd::prelude::*; +use gstd::{exec, prelude::*}; +use tamagotchi_interaction_io::*; + +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(&self) -> u64 {} + fn current_entertained(&self) -> u64 {} + fn current_slept(&self) -> u64 {} +} + +fn current_fed(&self) -> u64 { + self.fed - HUNGER_PER_BLOCK * (exec::block_height() as u64 - self.fed_block) +} +fn current_entertained(&self) -> u64 { + self.entertained - BOREDOM_PER_BLOCK * (exec::block_height() as u64 - self.entertained_block) +} +fn current_slept(&self) -> u64 { + self.slept - ENERGY_PER_BLOCK * (exec::block_height() as u64 - self.slept_block) +} + +static mut TAMAGOTCHI: Option = None; // TODO: 4️⃣ Define constants @@ -9,10 +40,20 @@ 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 birthdate = exec::block_height() as u64; + let fedblock = exec::block_height() as u64; + let entertainedblock = exec::block_height() as u64; + let sleptblock = exec::block_height() as u64; let tmg = Tamagotchi { name: initname, date_of_birth: birthdate, + owner: msg::source(), + fed: 1000, + fed_block: fedblock, + entertained: 5000, + entertained_block: entertainedblock, + slept: 2000, + slept_block: sleptblock, }; unsafe { TAMAGOTCHI = Some(tmg); @@ -24,17 +65,73 @@ 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 { + 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.entertained = tmg.current_entertained(); + tmg.slept = tmg.current_slept(); + } else { + let fedblock = exec::block_height() as u64; + tmg.fed = 10000; + tmg.fed_block = fedblock; + tmg.entertained = tmg.current_entertained(); + tmg.slept = tmg.current_slept(); + msg::reply(TmgEvent::Fed, 1).expect("Error in a reply'tamagotchi::fed'"); + } + } + TmgAction::Entertain => { + if tmg.current_entertained() <= 9000 { + 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.fed = tmg.current_fed(); + tmg.slept = tmg.current_slept(); + } else { + let entertainedblock = exec::block_height() as u64; + tmg.entertained = 10000; + tmg.entertained_block = entertainedblock; + tmg.fed = tmg.current_fed(); + tmg.slept = tmg.current_slept(); + msg::reply(TmgEvent::Entertained, 1) + .expect("Error in a reply'tamagotchi::entertained'"); + } + } + TmgAction::Sleep => { + if tmg.current_slept() <= 9000 { + 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.fed = tmg.current_fed(); + tmg.entertained = tmg.current_entertained(); + } else { + let sleptblock = exec::block_height() as u64; + tmg.slept = 10000; + tmg.slept_block = sleptblock; + tmg.fed = tmg.current_fed(); + tmg.entertained = tmg.current_entertained(); + 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..e90872cc 100644 --- a/contracts/02-tamagotchi-interaction/tests/interaction.rs +++ b/contracts/02-tamagotchi-interaction/tests/interaction.rs @@ -43,6 +43,21 @@ 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); + assert!(result.main_failed()); + //negetive test +} \ No newline at end of file