-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Homework 1 #4
base: master
Are you sure you want to change the base?
Homework 1 #4
Changes from 5 commits
a06e5bf
9d72824
94cf3b6
3780522
475c1cb
6c1c5fb
7f1fa8c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,19 +1,44 @@ | ||
#![no_std] | ||
|
||
#[allow(unused_imports)] | ||
use gstd::prelude::*; | ||
use gstd::{exec, msg, prelude::*}; | ||
use tamagotchi_io::*; | ||
|
||
static mut TAMAGOTCHI: Option<Tamagotchi> = None; | ||
|
||
#[no_mangle] | ||
extern fn init() { | ||
// TODO: 5️⃣ Initialize the Tamagotchi program | ||
let initname = msg::load().expect("unable to load name"); | ||
let birthdate = exec::block_timestamp(); | ||
let tmg = Tamagotchi { | ||
name: initname, | ||
date_of_birth: birthdate, | ||
}; | ||
unsafe { | ||
TAMAGOTCHI = Some(tmg); | ||
}; | ||
} | ||
|
||
#[no_mangle] | ||
extern fn handle() { | ||
// TODO: 6️⃣ Add handling of `Name` and `Age` actions | ||
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'"); | ||
} | ||
} | ||
} | ||
|
||
#[no_mangle] | ||
extern fn state() { | ||
// TODO: 7️⃣ Return the Tamagotchi state | ||
let tmg = unsafe { TAMAGOTCHI.take().expect("Unexpected error in taking state") }; | ||
msg::reply(tmg, 0).expect("Failed to share state"); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,39 @@ | ||
use gtest::{Program, System}; | ||
use gtest::{Log, Program, System}; | ||
use tamagotchi_io::*; | ||
|
||
#[test] | ||
fn smoke_test() { | ||
let sys = System::new(); | ||
sys.init_logger(); | ||
let _program = Program::current(&sys); | ||
let program = Program::current(&sys); | ||
let result = program.send(2, String::from("Goodmoring")); | ||
assert!(!result.main_failed()); | ||
let result = program.send(2, TmgAction::Name); | ||
let log = Log::builder() | ||
.dest(2) | ||
.payload(TmgEvent::Name(String::from("Goodmoring"))); | ||
assert!(result.contains(&log)); | ||
let _result = program.send(2, TmgAction::Age); | ||
// let log = Log::builder().dest(2).payload(TmgEvent::Age(sys.block_timestamp())); | ||
// assert!(result.contains(&log)); | ||
|
||
// TODO: 8️⃣ Test the program initialization and message handling | ||
//How to test the age? | ||
} | ||
|
||
#[test] | ||
fn negative_smoke_test() { | ||
let sys = System::new(); | ||
sys.init_logger(); | ||
let program = Program::current(&sys); | ||
let payload = vec![1, 2, 3]; | ||
let _result = program.send(2, payload); | ||
// assert!(result.main_failed()); | ||
// Why the assert is panic? | ||
|
||
// let result = program.send(1, TmgAction::Name); | ||
// let log = Log::builder().dest(2).payload(TmgEvent::Name("Goodmoring".to_string())); | ||
// assert!(!result.contains(&log)); | ||
// let result = program.send(1, TmgAction::Age); | ||
// let log = Log::builder().dest(2).payload(TmgEvent::Age(sys.block_timestamp())); | ||
// assert!(!result.contains(&log)); | ||
} |
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
@@ -1,18 +1,64 @@ | ||||||||||
#![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 { | ||||||||||
let a: u64 = | ||||||||||
self.fed - (HUNGER_PER_BLOCK as u64) * ((exec::block_height() as u64) - self.fed_block); | ||||||||||
a | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No need to create a var:
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||||||||
} | ||||||||||
fn current_entertained(&mut self) -> u64 { | ||||||||||
let b: u64 = self.entertained | ||||||||||
- (BOREDOM_PER_BLOCK as u64) * ((exec::block_height() as u64) - self.entertained_block); | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Using
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have fixed it. |
||||||||||
b | ||||||||||
} | ||||||||||
fn current_slept(&mut self) -> u64 { | ||||||||||
let c: u64 = self.slept | ||||||||||
- (ENERGY_PER_BLOCK as u64) * ((exec::block_height() as u64) - self.slept_block); | ||||||||||
c | ||||||||||
} | ||||||||||
} | ||||||||||
|
||||||||||
static mut TAMAGOTCHI: Option<Tamagotchi> = None; | ||||||||||
|
||||||||||
// TODO: 4️⃣ Define constants | ||||||||||
|
||||||||||
#[no_mangle] | ||||||||||
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; | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is no need to call There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||||||||
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 +70,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; | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is better to use named constants for numbers. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||||||||
tmg.fed_block = fedblock; | ||||||||||
tmg.entertained = tmg.current_entertained(); | ||||||||||
tmg.slept = tmg.current_slept(); | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The same code is in both There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||||||||
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(); | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Anyway, you can move the |
||||||||||
} 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] | ||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would be great to check the Tamagotchi's vital signs after spending various counts of blocks. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If
self.fed
is less thanHUNGER_PER_BLOCK * (exec::block_height() - self.fed_block)
, then subtraction results in the underflow.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.