Ticket #5: Implement findPokemonById
Assigned to: Groups 8 & 9
Estimated time: 25 minutes
Difficulty: ⭐⭐⭐ Medium-Hard
What You're Doing Create a new function findPokemonById that finds a Pokemon by its ID number. This ticket focuses on error handling and robust function design.
Tasks
- ✍️ Write comprehensive tests FIRST (TDD)
- 💻 Implement the function with proper error handling
- 🚨 Handle edge cases gracefully
- ✅ Ensure all tests pass
Step 1: Write Tests First
describe('buildBalancedTeam', () => {
const largePokemonPool = [
{ id: 1, name: "Bulbasaur", type: "grass", hp: 45, attack: 49 },
{ id: 4, name: "Charmander", type: "fire", hp: 39, attack: 52 },
{ id: 7, name: "Squirtle", type: "water", hp: 44, attack: 48 },
{ id: 25, name: "Pikachu", type: "electric", hp: 35, attack: 55 },
{ id: 6, name: "Charizard", type: "fire", hp: 78, attack: 84 },
{ id: 9, name: "Blastoise", type: "water", hp: 79, attack: 83 }
];
test('should return team of exactly 3 Pokemon', () => {
const team = buildBalancedTeam(largePokemonPool);
expect(team).toHaveLength(3);
});
test('should have no duplicate types in team', () => {
const team = buildBalancedTeam(largePokemonPool);
const types = team.map(p => p.type);
const uniqueTypes = [...new Set(types)];
expect(types.length).toBe(uniqueTypes.length);
});
test('should have total attack of at least 150', () => {
const team = buildBalancedTeam(largePokemonPool);
const totalAttack = team.reduce((sum, pokemon) => sum + pokemon.attack, 0);
expect(totalAttack).toBeGreaterThanOrEqual(150);
});
test('should prefer higher HP when choosing between same type', () => {
const team = buildBalancedTeam(largePokemonPool);
const fireType = team.find(p => p.type === 'fire');
if (fireType) {
// Should pick Charizard (78 HP) over Charmander (39 HP)
expect(fireType.name).toBe('Charizard');
}
});
test('should return empty array when impossible to build team', () => {
const insufficientPokemon = [
{ id: 1, name: "Bulbasaur", type: "grass", hp: 45, attack: 30 },
{ id: 2, name: "Ivysaur", type: "grass", hp: 60, attack: 35 }
// Only 2 Pokemon, both same type, low attack
];
const team = buildBalancedTeam(insufficientPokemon);
expect(team).toEqual([]);
});
});Step 2: Implement Function
Add to utils.js:
export const buildBalancedTeam = (pokemonList) => {
// Strategy hints:
// 1. Group Pokemon by type
// 2. For each type, pick the one with highest HP
// 3. Sort these "best of type" by attack (highest first)
// 4. Try to pick 3 different types that meet attack requirement
// 5. Return empty array if impossible
// Helper: Group by type
// Helper: Find best Pokemon per type (highest HP)
// Helper: Check if team meets attack requirement
// Your code here
};Step 3: Import in Test File
// Step 1: Group by type and pick best of each
const bestByType = {};
// ... group Pokemon by type
// ... for each type, find Pokemon with highest HP
// Step 2: Convert to array and sort by attack
const candidates = Object.values(bestByType)
.sort((a, b) => b.attack - a.attack);
// Step 3: Try to build team that meets requirements
// ... pick top 3 different types
// ... check total attack >= 150
// ... return team or empty arrayGit Workflow
git checkout -b ticket-6-team-builder
git commit -m ":test_tube: test: add buildBalancedTeam structure tests"
git commit -m ":test_tube: test: add team constraints validation tests"
git commit -m ":sparkles: feat: implement Pokemon type grouping logic"
git commit -m ":sparkles: feat: implement team selection algorithm"
git commit -m ":test_tube: test: add edge case for impossible team building"
git push origin ticket-6-team-builder