Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
159 changes: 159 additions & 0 deletions backend/dojo_examples/combat_game/src/helpers/Experience_utils.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
use core::traits::Into;

#[generate_trait]
pub impl ExperienceCalculator of ExperienceCalculatorTrait {

fn calculate_exp_needed_for_level(level: u8) -> u16 {
let level_u16: u16 = level.into();
level_u16 * level_u16 * 10
}

fn should_level_up(current_level: u8, current_exp: u16) -> bool {
let exp_needed = Self::calculate_exp_needed_for_level(current_level);
current_exp >= exp_needed
}

fn remaining_exp_after_level_up(current_level: u8, current_exp: u16) -> u16 {
let exp_needed = Self::calculate_exp_needed_for_level(current_level);
if current_exp >= exp_needed {
current_exp - exp_needed
} else {
current_exp
}
}
}

#[cfg(test)]
mod experience_calculator_tests {
use super::{ExperienceCalculator};

#[test]
#[available_gas(1000000)]
fn test_calculate_exp_needed_for_level() {
// Test values for different levels to verify the formula level² × 10

// Level 1: 1² × 10 = 10
let exp_level_1 = ExperienceCalculator::calculate_exp_needed_for_level(1);
assert(exp_level_1 == 10, 'Level 1 should need 10 exp');

// Level 2: 2² × 10 = 40
let exp_level_2 = ExperienceCalculator::calculate_exp_needed_for_level(2);
assert(exp_level_2 == 40, 'Level 2 should need 40 exp');

// Level 5: 5² × 10 = 250
let exp_level_5 = ExperienceCalculator::calculate_exp_needed_for_level(5);
assert(exp_level_5 == 250, 'Level 5 should need 250 exp');

// Level 10: 10² × 10 = 1000
let exp_level_10 = ExperienceCalculator::calculate_exp_needed_for_level(10);
assert(exp_level_10 == 1000, 'Level 10 should need 1000 exp');

// Level 20: 20² × 10 = 4000
let exp_level_20 = ExperienceCalculator::calculate_exp_needed_for_level(20);
assert(exp_level_20 == 4000, 'Level 20 should need 4000 exp');
}

#[test]
#[available_gas(1000000)]
fn test_should_level_up() {
// Level 1 (needs 10 exp)

// 9 exp: should not level up
let should_level_up_1_9 = ExperienceCalculator::should_level_up(1, 9);
assert(!should_level_up_1_9, 'Level 1 with 9 exp not level up');

// 10 exp: should level up
let should_level_up_1_10 = ExperienceCalculator::should_level_up(1, 10);
assert(should_level_up_1_10, 'Level 1 with 10 exp level up');

// 15 exp: should level up
let should_level_up_1_15 = ExperienceCalculator::should_level_up(1, 15);
assert(should_level_up_1_15, 'Level 1 with 15 exp level up');

// Level 5 (needs 250 exp)

// 249 exp: should not level up
let should_level_up_5_249 = ExperienceCalculator::should_level_up(5, 249);
assert(!should_level_up_5_249, 'Level 5 249 exp not level up');

// 250 exp: should level up
let should_level_up_5_250 = ExperienceCalculator::should_level_up(5, 250);
assert(should_level_up_5_250, 'Level 5 with 250 exp level up');

// 300 exp: should level up
let should_level_up_5_300 = ExperienceCalculator::should_level_up(5, 300);
assert(should_level_up_5_300, 'Level 5 with 300 exp level up');
}

#[test]
#[available_gas(1000000)]
fn test_remaining_exp_after_level_up() {
// Level 1 (needs 10 exp)

// 9 exp: should remain at 9 (no level up)
let remaining_1_9 = ExperienceCalculator::remaining_exp_after_level_up(1, 9);
assert(remaining_1_9 == 9, 'Level 1 with 9 exp keep 9');

// 10 exp: should remain at 0 (level up)
let remaining_1_10 = ExperienceCalculator::remaining_exp_after_level_up(1, 10);
assert(remaining_1_10 == 0, 'Level 1 with 10 exp 0 remaining');

// 15 exp: should remain at 5 (level up)
let remaining_1_15 = ExperienceCalculator::remaining_exp_after_level_up(1, 15);
assert(remaining_1_15 == 5, 'Level 1 with 15 exp 5 remaining');

// Level 5 (needs 250 exp)

// 300 exp: should remain at 50 (level up)
let remaining_5_300 = ExperienceCalculator::remaining_exp_after_level_up(5, 300);
assert(remaining_5_300 == 50, 'Level 5 300 exp 50 remaining');
}

#[test]
#[available_gas(1000000)]
fn test_multiple_level_ups_simulation() {
// Simulate a scenario where a beast levels up multiple times

// Beast level 1 with 0 initial exp
let mut current_level = 1_u8;
let mut current_exp = 0_u16;

// Earned 20 exp
current_exp += 20;

// Validate if it should level up
let should_level = ExperienceCalculator::should_level_up(current_level, current_exp);
assert(should_level, 'Level up after more 20 exp');

// Level up and update remaining exp
if should_level {
current_exp = ExperienceCalculator::remaining_exp_after_level_up(current_level, current_exp);
current_level += 1;
}

// Verify final values
assert(current_level == 2, 'Should now be level 2');
assert(current_exp == 10, 'Should have 10 exp remaining');

// Earned 50 more exp
current_exp += 50;

// Validate if it should level up again
let should_level_again = ExperienceCalculator::should_level_up(current_level, current_exp);
assert(should_level_again, 'Level up 60 exp at level 2');

// Level up again
if should_level_again {
current_exp = ExperienceCalculator::remaining_exp_after_level_up(current_level, current_exp);
current_level += 1;
}

// Verify final values
assert(current_level == 3, 'Should now be level 3');
assert(current_exp == 20, 'Should have 20 exp remaining');

// Should not level up to level 4 yet
let not_enough_for_level4 = ExperienceCalculator::should_level_up(current_level, current_exp);
assert(!not_enough_for_level4, 'Should not reach level 4 yet');
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Mmesolove delete just this file

Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
use core::debug::PrintTrait;
use core::traits::Into;
use core::test::test_utils::assert_eq;

use combat_game::helpers::experience_utils::{ExperienceCalculator, ExperienceCalculatorTrait, ExperienceCalculatorImpl};

#[test]
fn test_calculate_exp_needed_for_level() {
// Test level 1
let exp_needed = ExperienceCalculatorImpl::calculate_exp_needed_for_level(1);
assert_eq(exp_needed, 10, 'Level 1 should need 10 exp');

// Test level 2
let exp_needed = ExperienceCalculatorImpl::calculate_exp_needed_for_level(2);
assert_eq(exp_needed, 40, 'Level 2 should need 40 exp');

// Test level 5
let exp_needed = ExperienceCalculatorImpl::calculate_exp_needed_for_level(5);
assert_eq(exp_needed, 250, 'Level 5 should need 250 exp');

// Test level 10
let exp_needed = ExperienceCalculatorImpl::calculate_exp_needed_for_level(10);
assert_eq(exp_needed, 1000, 'Level 10 should need 1000 exp');

// Test level 20
let exp_needed = ExperienceCalculatorImpl::calculate_exp_needed_for_level(20);
assert_eq(exp_needed, 4000, 'Level 20 should need 4000 exp');
}

#[test]
fn test_should_level_up() {
// Test level 1 with enough exp
let should_level = ExperienceCalculatorImpl::should_level_up(1, 10);
assert_eq(should_level, true, 'Should level up with exact exp needed');

// Test level 1 with not enough exp
let should_level = ExperienceCalculatorImpl::should_level_up(1, 9);
assert_eq(should_level, false, 'Should not level up with insufficient exp');

// Test level 2 with more than enough exp
let should_level = ExperienceCalculatorImpl::should_level_up(2, 50);
assert_eq(should_level, true, 'Should level up with excess exp');

// Test level 5 with exact exp needed
let should_level = ExperienceCalculatorImpl::should_level_up(5, 250);
assert_eq(should_level, true, 'Should level up with exact exp needed');
}

#[test]
fn test_remaining_exp_after_level_up() {
// Test level 1 with exact exp needed
let remaining = ExperienceCalculatorImpl::remaining_exp_after_level_up(1, 10);
assert_eq(remaining, 0, 'Should have 0 exp remaining after level up');

// Test level 1 with excess exp
let remaining = ExperienceCalculatorImpl::remaining_exp_after_level_up(1, 15);
assert_eq(remaining, 5, 'Should have 5 exp remaining after level up');

// Test level 2 with not enough exp
let remaining = ExperienceCalculatorImpl::remaining_exp_after_level_up(2, 30);
assert_eq(remaining, 30, 'Should keep current exp if not enough for level up');

// Test level 5 with excess exp
let remaining = ExperienceCalculatorImpl::remaining_exp_after_level_up(5, 300);
assert_eq(remaining, 50, 'Should have 50 exp remaining after level up');
}

#[test]
fn test_multiple_sequential_level_ups() {
let mut current_level: u8 = 1;
let mut current_exp: u16 = 100;

// First level up
let should_level = ExperienceCalculatorImpl::should_level_up(current_level, current_exp);
assert_eq(should_level, true, 'Should level up first time');
let remaining = ExperienceCalculatorImpl::remaining_exp_after_level_up(current_level, current_exp);
current_exp = remaining;
current_level += 1;

// Second level up
let should_level = ExperienceCalculatorImpl::should_level_up(current_level, current_exp);
assert_eq(should_level, true, 'Should level up second time');
let remaining = ExperienceCalculatorImpl::remaining_exp_after_level_up(current_level, current_exp);
current_exp = remaining;
current_level += 1;

// Check final state
assert_eq(current_level, 3, 'Should be level 3 after two level ups');
assert_eq(current_exp, 20, 'Should have 20 exp remaining after two level ups');
}