Introduction

For this assignment, we are asking you to implement a mini Pokédex in C. The task is split into 5 sections; each section is not weighted the same.

What is a Pokémon? What is a Pokédex?

Hello there! Welcome to the world of Pokémon! My name is Oak! People call me the Pokémon Prof! This world is inhabited by creatures called Pokémon! For some people, Pokémon are pets. Others use them for fights. Myself ... I study Pokémon as a profession. — Professor Oak

Pokémon are fictional creatures from the Pokémon franchise, most famously from the Pokémon games. The game revolves around the (questionably ethical) capturing of these creatures. Within the fiction of this universe, a device called the Pokédex is used to catalogue all the creatures a player finds and captures.

Where can we learn more about Pokédexes?

You can play the one of the original Pokémon games here. Quite early in the game you get introduced to the Pokédex.

There's some more information on the Pokémon Wikia.

In addition, Google will be a great resource, as the topic has been extensively written up about.


In addition, Google will be a great resource, as the topic has been extensively written up about.

What's Provided?

Supplied Code

New: you can run 1511 setup_pokedex to copy all of the files to your CSE account
This zip file contains the files that you need to get started with the assignment. It contains the following files:
pokedex.h
contains declarations for all functions you need to implement for this assignment. Don't change pokedex.h
pokedex.c
contains stubs for all the functions you need to implement for this assignment. Put all your Pokédex code in pokedex.c.
pokemon.h
contains declarations for all functions you must call to create and manipulate Pokémon. Don't change pokemon.h
pokemon.c
contains the functions you must call to create and manipulate Pokémon. Don't change pokemon.c
main.c
contains a main function and other functions that allow you to interactively test the functions you implement in pokedex.c Don't change main.c
test_pokedex.c
contains a main function and other functions which are your starting point for a test framework to automatically test the functions you implement in pokedex.c. As you implement functions in pokedex.c you should add tests to test_pokedex.c. Only put testing code in test_pokedex.c.


You can also link and copy the supplied files into your CSE account using commands like these:

mkdir ass2 

cd ass2 

cp -n /web/cs1511/19T3/activities/pokedex/pokedex.c . 

cp -n /web/cs1511/19T3/activities/pokedex/test_pokedex.c . 

ln -s /web/cs1511/19T3/activities/pokedex/pokemon.[ch] . 

ln -s /web/cs1511/19T3/activities/pokedex/main.c . 

ln -s /web/cs1511/19T3/activities/pokedex/pokedex.h .

The ln commands create symbolic links to a file in class account, so you are always using the latest version.

Reference implementation

A reference implementation 1511 pokedex_reference is available to help you understand the assignment.



1511 pokedex_reference ===========================[ Pokédex ]==========================
            Welcome to the Pokédex!  How can I help?
================================================================
Enter command: ? ============================[ Help ]============================
  a [pokemon_id] [name] [height] [weight] [type1] [type2]
    Add a Pokemon to the Pokedex
  p
    Print all of the Pokemon in the Pokedex (in the order they were added)
  g
    Print currently selected Pokemon
  d
    Display details of the currently selected Pokemon
  >
    Move the cursor to the next Pokemon in the Pokedex
  < Move the cursor to the previous Pokemon in the Pokedex m [pokemon_id] Move the cursor to the Pokemon with the specified pokemon_id r Remove the current Pokemon from the Pokedex y Show Pokemon types x Go exploring for Pokemon f Set the current Pokemon to be found c Print out the count of Pokemon who have been found t Print out the total count of Pokemon in the Pokedex e [pokemon_A] [pokemon_B] Add an evolution from Pokemon A to Pokemon B s Show evolutions of the currently selected Pokemon n Show next evolution of current selected Pokemon F Create a new Pokedex containing Pokemon that have previously been found S [string] Create a new Pokedex containing Pokemon that have the specified string in their name T [type] Create a new Pokedex containing Pokemon that have the specified type q Quit ? Show help ================================================================ Enter command: a 1 Bulbasaur 0.7 6.9 poison grass Added Bulbasaur to the Pokedex!

Your pokedex.c (compiled with the supplied pokemon.c and main.c) should match the behaviour of the reference implementation.

Provision of a reference implementation is a common method to provide an operational specification, and it's something you will likely need to do outside UNSW.

If you discover what you believe to be a bug in the reference implementation, report it in the class forum. We may fix the bug or indicate that you do not need to match the reference implementation's behaviour in this case.

The Tasks

For this assignment, we are asking you to implement a mini Pokédex in C. The task is split into 5 sections; each section is not weighted the same.

Stage 1: Adding and Printing

You can run the autotests for Stage 1 by running the following command:

1511 autotest-stage 01 pokedex
When you compile and run the given code, you will get the following message if you try to add a Pokemon:
dcc -o pokedex main.c pokedex.c pokemon.c ./pokedex ===========================[ Pokédex ]==========================
            Welcome to the Pokédex!  How can I help?
================================================================
Enter command: a 1 Bulbasaur 0.7 6.9 poison grass exiting because you have not implemented the add_pokemon function in pokedex.c
When you run the a command, this function in pokedex.c is called:
// Add a new Pokemon to the Pokedex. void add_pokemon(Pokedex pokedex, Pokemon pokemon) { // Note: you should use the new_pokenode function here, and add // the newly-created pokenode to the end of the linked list of // pokenodes in the Pokedex. fprintf(stderr, "exiting because you have not implemented the add_pokemon function\n"); exit(1); }
Your first task is to implement add_pokemon. All the functions you have to implement in pokedex.c have descriptions in pokedex.h:
// Add a new Pokemon to the Pokedex. // Note: just adding the Pokemon to the Pokedex does not mean it has // been 'found'. // // The new Pokemon should be added to the end of the Pokedex (i.e. // directly after the Pokemon that was added when add_pokemon was last // called). // // When the first Pokemon is added to the Pokédex, the currently // selected Pokemon becomes this Pokemon. // // The currently selected Pokemon remains the first Pokemon that was // inserted into the Pokedex, until the `change_current_pokemon`, // `next_pokemon`, or `prev_pokemon` functions are called. // // If there is already a Pokemon in the Pokedex with the same pokemon_id // as this Pokemon, the function should print an appropriate error // message and exit the program. // // Pokedex Order: // -------------- // The Pokemon in the Pokedex are stored in the order in which they were // added, i.e. the first Pokemon in the Pokedex will be the first // Pokemon that was added, the second Pokemon in the Pokedex will be the // second Pokemon that was added etc, and the last Pokemon in the // Pokedex will be the Pokemon that was added most recently. // // For example, if Pikachu (#025) was added into an empty Pokedex, the // Pokedex would now contain Pikachu at the start of the list, and // Pikachu would be the currently selected Pokemon. // // [Start of Pokedex] // #025: Pikachu <-- currently selected Pokemon // [End of Pokedex] // // If Squirtle (#007) was then added, it would be the second Pokemon in // the Pokedex, after Pikachu. The currently selected Pokemon would // remain Pikachu. // // [Start of Pokedex] // #025: Pikachu <-- currently selected Pokemon // #003: Squirtle // [End of Pokedex] // // If Diglett (#050) was then added, it would be the third Pokemon in the // Pokedex, after Squirtle. // // [Start of Pokedex] // #025: Pikachu <-- currently selected Pokemon // #003: Squirtle // #050: Diglett // [End of Pokedex] void add_pokemon(Pokedex pokedex, Pokemon pokemon);

You need to put code in the add_pokemon function to store the pokemon it is given into the pokedex it is given.

You don't need to know any details about what the Pokemon type is (i.e. the type of the Pokemon pokemon argument passed to add_pokemon) to implement add_pokemon or any other function in pokedex.c.

Pokemon Tip #0: Pokemon IDs

In the Pokemon game franchise, Pokemon IDs start at 1 and go up to 809 (at the time of writing this). The first Pokemon is Bulbasaur, who has a Pokemon ID of 1. This assignment, however, allows any Pokemon ID from 0 upwards (because programmers love counting from 0).

Throughout this spec we'll be making use of Bulbasaur (as well as some of the other official Pokemon) in our examples, but do note that you can make your own Pokemon with any ID from 0 to the maximum number that can be stored in an integer.

Hint: your code should also operate under the assumption that a pokemon_id of 0 is valid.

If you look in pokedex.h you will discover this definition: typedef struct pokedex *Pokedex

In other words the type Pokedex is the same as struct pokedex *.

struct pokedex is defined at the top of pokedex.c.

It already has one field: a pointer to struct pokenode which can be used to store a linked list.

Put in code in add_pokemon to add the pokemon it is given to the linked list whose head is in the pokedex it is given.

Hint: add code to the new_pokenode function to allocate a struct pokenode with malloc.

When you run your code you should see this:

dcc -o pokedex main.c pokedex.c pokemon.c ./pokedex ===========================[ Pokédex ]==========================
            Welcome to the Pokédex!  How can I help?
================================================================
Enter command: a 1 Bulbasaur 0.7 6.9 poison grass Added Bulbasaur to the Pokedex!
You'll need to implement 4 more functions to find out if add_pokemon really works:
void detail_pokemon(Pokedex pokedex); Pokemon get_current_pokemon(Pokedex pokedex); void find_current_pokemon(Pokedex pokedex); void print_pokemon(Pokedex pokedex);

See pokedex.h for information on each function.

detail_pokemon and print_pokemon need to call functions defined in pokemon.h to get the information about a Pokemon they need to print.

Note the information detail_pokemon and print_pokemon print about a Pokemon depends on whether it has been found.

Hint: add a field to struct pokenode to indicate if a Pokemon has been found.

Pokemon Tip #1: finding Pokemon.

Your Pokedex is like an encyclopedia that stores information about Pokemon.

But unlike a normal encyclopaedia, some of the information in your Pokedex is hidden until you've discovered a Pokemon of that kind.

Once you have "found" a certain kind of Pokemon, its details will become visible to you in your Pokedex.

You will need to keep track of whether a Pokemon has been found in your Pokedex implementation.

Hint: add a field to struct pokenode to indicate if a Pokemon has been found.

Pokemon Tip #2: the currently selected Pokemon.

Your Pokedex allows you to scroll through the Pokemon stored within, allowing you to see the details of a specific Pokemon of your choice. This means that there will always be one Pokemon that is currently selected by the Pokedex.

When you add the first Pokemon to the Pokedex, that Pokemon becomes the currently selected Pokemon. When you add additional Pokemon, the currently selected Pokemon does not change.

In Stage 2, you will implement functions to allow you to scroll back and forth between Pokemon. But for now, you won't need to change the currently selected Pokemon.

Hint: your currently selected Pokemon won't change in Stage 1, and so will always be the first Pokemon added to your Pokedex (for now).

Pokemon Tip #3: adding Pokemon to the Pokedex.

The Pokemon in your Pokedex are stored in the order that they were added (which is not necessarily by order of pokemon_id!).

For example, if you have an empty Pokedex and then add Pikachu (#025) to your Pokedex, your Pokedex now contains:

#025: Pikachu

If you next added Squirtle (#007), your Pokedex now contains:

#025: Pikachu -> #007: Squirtle

If you then added Diglett (#050), your Pokedex now contains:

#025: Pikachu -> #007: Squirtle -> #050: Diglett

Hint: every time you add a Pokemon to your Pokedex, add it to the end of your linked list.
When all four functions are working you should see something like this:
dcc -o pokedex main.c pokedex.c pokemon.c ./pokedex ===========================[ Pokédex ]==========================
            Welcome to the Pokédex!  How can I help?
================================================================
Enter command: a 1 Bulbasaur 0.7 6.9 poison grass Enter command: d ID: 001
Name: *********
Height: --
Weight: --
Type: --
Enter command: p --> #001: *********
Enter command: f Enter command: d ID: 001
Name: Bulbasaur
Height: 0.7m
Weight: 6.9kg
Type: Poison Grass
Enter command: p --> #001: Bulbasaur
Enter command: a 7 Squirtle 0.5 9 water none Added Squirtle to the Pokedex!
Enter command: p --> #001: Bulbasaur
    #007: ********
Enter command: d ID: 001
Name: Bulbasaur
Height: 0.7m
Weight: 6.9kg
Type: Poison Grass
Enter command:

Stage 2: Navigating the List And Destroying the List

You can run the autotests for Stage 2 by running the following command: