#include <cassert>
#include <cstddef>
#include <bitset>
using weapon_id = unsigned long long;
// Available weapons - reduced for brevity
// Ideally, adding a new weapon here wouldn't require editing anything below.
static const weapon_id WEAPON_HARSH_LANGUAGE = 0;
static const weapon_id WEAPON_SHARP_STICK = 1;
static const weapon_id WEAPON_KNIFE = 2;
static const weapon_id WEAPON_NUKE = 3;
static const std::size_t WEAPON_COUNT = 4; // Could potentially be > 64
using weapon_set = std::bitset< WEAPON_COUNT >;
// Select the next available weapon.
// If only one weapon is available, return that weapon.
// If the last weapon is currently selected then cycle back around to the first.
weapon_id next_weapon(const weapon_set& weapons, const weapon_id current_weapon)
{
assert(weapons.any());
if (weapons.count() == 1)
{
return current_weapon;
}
auto new_weapon = current_weapon;
// Insert magic here.
return new_weapon;
}
// Select the previous available weapon.
// If only one weapon is available, return that weapon.
// If the first weapon is currently selected then cycle back around to the last.
weapon_id prev_weapon(const weapon_set& weapons, const weapon_id current_weapon)
{
assert(weapons.any());
if (weapons.count() == 1)
{
return current_weapon;
}
auto new_weapon = current_weapon;
// Insert magic here
return new_weapon;
}
// Test cases I can think of. Have I missed any?
int main()
{
// Test 1 - One weapon
{
weapon_set weapons;
weapons.set(WEAPON_HARSH_LANGUAGE);
assert(next_weapon(weapons, WEAPON_HARSH_LANGUAGE) == WEAPON_HARSH_LANGUAGE);
assert(prev_weapon(weapons, WEAPON_HARSH_LANGUAGE) == WEAPON_HARSH_LANGUAGE);
}
// Test 2 - Two 'sequential' weapons
{
weapon_set weapons;
weapons.set(WEAPON_SHARP_STICK);
weapons.set(WEAPON_KNIFE);
assert(next_weapon(weapons, WEAPON_SHARP_STICK) == WEAPON_KNIFE);
assert(prev_weapon(weapons, WEAPON_SHARP_STICK) == WEAPON_KNIFE);
assert(next_weapon(weapons, WEAPON_KNIFE) == WEAPON_SHARP_STICK);
assert(prev_weapon(weapons, WEAPON_KNIFE) == WEAPON_SHARP_STICK);
}
// Test 3 - Two 'non sequential' weapons
{
weapon_set weapons;
weapons.set(WEAPON_HARSH_LANGUAGE);
weapons.set(WEAPON_KNIFE);
assert(next_weapon(weapons, WEAPON_HARSH_LANGUAGE) == WEAPON_KNIFE);
assert(prev_weapon(weapons, WEAPON_HARSH_LANGUAGE) == WEAPON_KNIFE);
assert(next_weapon(weapons, WEAPON_KNIFE) == WEAPON_HARSH_LANGUAGE);
assert(prev_weapon(weapons, WEAPON_KNIFE) == WEAPON_HARSH_LANGUAGE);
}
// Test 4 - All weapons
{
weapon_set weapons;
weapons.set(WEAPON_HARSH_LANGUAGE);
weapons.set(WEAPON_SHARP_STICK);
weapons.set(WEAPON_KNIFE);
weapons.set(WEAPON_NUKE);
assert(next_weapon(weapons, WEAPON_HARSH_LANGUAGE) == WEAPON_SHARP_STICK);
assert(prev_weapon(weapons, WEAPON_HARSH_LANGUAGE) == WEAPON_NUKE);
assert(next_weapon(weapons, WEAPON_NUKE) == WEAPON_HARSH_LANGUAGE);
assert(prev_weapon(weapons, WEAPON_NUKE) == WEAPON_KNIFE);
}
return 0;
}