10.2a — Card Jam Kickoff: Lists & Arrays
Second jam, new data structure: the LIST. Your coins were one number, your inventory was a few bools — a deck of cards is MANY things, in order, changing. The starter ships a card game skeleton (GameManager.cs) with a secret: two of its methods are EMPTY, waiting for you.
The starter's GameManager.cs declares six lists and hands you a deal that is only half a deal: Shuffle has two empty overloads, and Deal() reads player_deck[0] and ai_deck[0] and never once calls Add on player_hand or ai_hand. So the moment a deal finishes, both hands are still empty lists — and a loop over an empty list runs zero times and reports nothing at all. "How do I hold a hand of cards?" is not one problem. It is six, and each one is a single line: make the list exist, put a card in, read one back by index, take one out, ask how many are left, and walk the lot with a loop.
First, before anything else: cut that into parts small enough that you could look each one up on its own.
- Make the list exist: empty, before anything goes into itwhat does this part do?Read: the "Array vs List — same idea, one difference that matters" section of the Lists & Arrays reference, and the six list fields declared at the top of
Assets/Scripts/GameManager.cs - Put a card into it: APPENDwhat does this part do?Read: the APPEND row of the AP-pseudocode-versus-C# table in the Lists & Arrays reference
- Read one card back out: the indexwhat does this part do?Read: the
aList[i]row of that table, and "Bug 2 — the bounds", which is the crash that comes from reading one index too far - Take a card back out: REMOVEwhat does this part do?Read: the REMOVE row of that table, and "Bug 1 — remove while traversing forward", the bug the shift causes
- Ask how many are left: LENGTHwhat does this part do?Read: the LENGTH row of that table, and the
Countbound in "Bug 2 — the bounds" - Walk the whole hand: a loop over the listwhat does this part do?Read: patterns 1 and 2, "Traverse to total" and "Traverse with a filter", in the Lists & Arrays reference, and the
foreachyou ran over an area query in 8.3
The split is the lesson, and its shape is the giveaway: five of these six parts are a single line of C#. "Hold a hand of cards" sounds like a system; it is four list operations, one index and one loop, and the Unit 10 reference prints every one of them with its AP pseudocode beside it. The reason to write the split down anyway is what the starter has not done: the fields are declared, Shuffle is empty, and nothing has ever been added to a hand — so the honest answer to "where is my hand" is "nowhere yet", and knowing which of the six small things is missing is the whole job today.
The test for a finished split: can you look one part up in a single search, right now, and write it in one line? "How do I add a card to a list" can — the reference sheet prints the C# and the AP side by side. "How do I hold a hand of cards" cannot, because it is six of those questions wearing one name. A part that needs you to design something before you can write it is not a part of this problem; it is the next one.
Your turn
Pick two of the parts above and say in one line what each one actually does.
Deal() shuffles both decks, instantiates a card visual for each side and reads player_deck[0] and ai_deck[0] — and never once calls Add on player_hand or ai_hand. So the moment a deal finishes, both hands are still empty lists, and a loop over either one runs zero times and prints nothing. Where does the first Add go in your copy, and what would you print to prove the hand is no longer empty?
The decks and the hands do not hold the same type: player_deck and ai_deck are List<Card_data> — an asset, the card's numbers — while the hands and the two discard piles are List<Card>, the component sitting on a card object in the scene. Why does the deck want the asset type rather than the scene type, and what would you lose if you shuffled the visual objects instead?
This jam has five classes to ship and six lists to fill. Which of the six parts above would you write first if you wanted a card visible on screen inside ten minutes — and which one can wait until you have decided the rules of your game?
Open the starter's GameManager.cs (find it in the project — the card game scene). Two facts to verify with your own eyes:
- It is a singleton —
public static GameManager gm;set in Awake, behind a duplicate guard and aDontDestroyOnLoad. That is the shape you built yourself in 5.3; theStatManagerstub you met in 2.1 was left empty on purpose and only got filled in during that refactor, so this pattern is yours. The game manager is THE manager; everything finds it. - It holds exactly SIX Lists, and they are not all the same
kind. Count them: TWO decks —
List<Card_data>, the asset, the card's numbers — and TWO hands plus TWO discard piles, allList<Card>, the component on a card object. There is no play field and no score list; six is the whole inventory. THE WHOLE GAME IS LISTS.
List vocabulary (the exam's, exactly):
| Exam pseudocode | C# on a List | What it does |
|---|---|---|
| aList[i] | hand[i] | Access the item at index i (starts at 1 in AP, 0 in C#!) |
| APPEND(aList, item) | hand.Add(card) | Add at the end |
| REMOVE(aList, i) | hand.RemoveAt(i) | Remove item at index i |
| INSERT(aList, i, item) | hand.Insert(i, card) | Squeeze into position i |
| LENGTH(aList) | hand.Count | How many items |
Socratic
Your deck has 30 cards. You draw the top one: deck[0], REMOVE it, APPEND it to the hand. Why must the removal happen — what breaks at draw #31 if you never remove? (This is also why your coins could never be a List of coin objects — count what you keep, list what you ORDER.)
The jam task, read carefully: finish the starter's card game as YOUR version — your rules, your theme, your art swap — and ship it in five classes (10.2e build, 10.2f showcase). The skeleton handles setup; the EMPTY methods (Shuffle() and AI_Turn() — verify they are empty in your copy!) are your unit's final boss.
Pitch card (10 min to write, 30s to pitch):
- Theme sentence: "a card game about ___" (battles? cooking? dungeon crawling? dueling teachers?)
- The core loop: draw → play → resolve → repeat. Which part does the AI oppose?
- One twist that makes YOUR game not-just-war: costs? combos? a shared deck? one "cheat" card?
Vote + team (same rules as 10.1a): teams 1–3, everyone writes code, everyone's game has the deck-draw loop playable by 10.2e.
Checkpoint — before moving on, you must be able to:
- Explain the starter's six Lists and what each holds
- Translate AP pseudocode list ops to C# on sight
- Explain why draw = REMOVE from deck + APPEND to hand
- Pitch a card game with a loop, a twist, and an AI
- Break "hold a hand of cards" into parts small enough to look up one at a time, and say in one line what each part does
- Say which reference page or earlier lesson each part came from, and where you would reread it
Reference Docs
Need a deeper explanation? These pages cover the same concepts:
- Lists & Arrays — the full reference
- ScriptableObjects — tomorrow's tool
Saved on this device only — the Dashboard tracks your progress.