Add game theory programming courses for Python and C

NEW ACTIVITIES:

activity46-game-theory-python.yaml - Game theory implementation in Python
- Representing games with dictionaries
- Payoff matrix as dict with tuple keys
- Query functions and game simulation
- One-shot and repeated games
- Tit-for-Tat strategy implementation
- Function composition and abstraction

activity47-game-theory-c.yaml - Game theory implementation in C
- Defining Payoff struct for outcomes
- 2D arrays for payoff matrices
- Memory-efficient game representation
- Strategy lookup functions
- Enum for self-documenting code
- Pointer and struct fundamentals

Both activities:
- Teach programming through game theory concepts
- Follow pedagogical best practice (concepts first, code examples in feedback)
- Validate with zero errors/warnings
- Progressive difficulty (structures → functions → simulation)
- Real-world application of abstract concepts
- Engage students with strategic thinking + coding
This commit is contained in:
Claude 2025-11-09 15:36:12 +00:00
parent b8bf7261cb
commit 4e72fed8be
No known key found for this signature in database
2 changed files with 1037 additions and 0 deletions

View file

@ -0,0 +1,509 @@
default_max_attempts_per_step: 3
classifier_model: "MODEL_1"
feedback_model: "MODEL_1"
tokens_for_ai_rubric: |
Evaluate the student's ability to implement game theory concepts in Python.
Consider:
- Correct Python syntax
- Understanding of game theory concepts
- Code logic and structure
- Use of appropriate data structures
- Ability to translate concepts to code
sections:
- section_id: introduction
title: Programming Game Theory in Python
steps:
- step_id: welcome
title: Code Meets Strategy
content_blocks:
- "# Game Theory Programming with Python 🐍🎮"
- ""
- "**Learn Python by implementing game theory!**"
- ""
- "You'll learn to:"
- "✓ Represent games as data structures"
- "✓ Implement payoff matrices"
- "✓ Code Prisoner's Dilemma simulations"
- "✓ Find Nash Equilibria programmatically"
- "✓ Simulate repeated games with strategies"
- ""
- "**Prerequisites:**"
- "- Basic Python knowledge (variables, functions, loops)"
- "- Understanding of basic game theory (Nash Equilibrium, Prisoner's Dilemma)"
- ""
- "**Why this matters:**"
- "- Learn to model strategic situations"
- "- Practice data structures (dictionaries, lists)"
- "- Build simulations and experiments"
- "- Apply theory to real code"
question: Ready to implement game theory in Python?
tokens_for_ai: Accept positive as 'ready', language preference as 'set_language', else 'off_topic'
buckets: [ready, set_language, off_topic]
transitions:
ready:
next_section_and_step: payoff_matrix:step_1
set_language:
metadata_add: {language: "the-users-response"}
counts_as_attempt: false
next_section_and_step: introduction:welcome
off_topic:
counts_as_attempt: false
next_section_and_step: introduction:welcome
- section_id: payoff_matrix
title: Representing Games as Data
steps:
- step_id: step_1
title: Payoff Matrix Structure
content_blocks:
- "## Representing Payoff Matrices in Python 📊"
- ""
- "**The challenge:**"
- "How do we represent a 2-player game in code?"
- ""
- "**Game structure:**"
- "- Two players (Row, Column)"
- "- Each has strategies (actions)"
- "- Each outcome has payoffs for both players"
- ""
- "**Conceptual approach:**"
- "A payoff matrix maps strategy pairs to payoff tuples"
- "- Input: (player1_strategy, player2_strategy)"
- "- Output: (player1_payoff, player2_payoff)"
- ""
- "**Data structure choice:**"
- "Python dictionaries are perfect!"
- "- Keys: tuples of strategy pairs"
- "- Values: tuples of payoffs"
- ""
- "**Example concept (Prisoner's Dilemma):**"
- "```"
- "Strategies: 'cooperate' or 'defect'"
- "Payoffs: (player1_years, player2_years)"
- "If both cooperate: (-1, -1)"
- "If both defect: (-2, -2)"
- "If one defects while other cooperates: (0, -3) or (-3, 0)"
- "```"
question: "Write Python code to create a dictionary representing the Prisoner's Dilemma payoff matrix. Use strategy pairs as keys (tuples like ('cooperate', 'defect')) and payoff tuples as values."
tokens_for_ai: |
Looking for Python dictionary with:
- Keys: tuples of (player1_strategy, player2_strategy)
- Values: tuples of (player1_payoff, player2_payoff)
- Four outcomes: (C,C), (C,D), (D,C), (D,D)
Correct payoffs (years in prison):
- ('cooperate', 'cooperate'): (-1, -1)
- ('cooperate', 'defect'): (-3, 0)
- ('defect', 'cooperate'): (0, -3)
- ('defect', 'defect'): (-2, -2)
Categorize as:
- correct: Proper dictionary with all 4 outcomes and correct payoffs
- correct_structure: Right structure, minor payoff errors
- uses_dictionary: Uses dict but wrong format
- wrong_approach: Different data structure
- needs_help: Very basic or confused
- set_language: Language preference
- off_topic: Unrelated
feedback_tokens_for_ai: |
If correct:
- Excellent! Dictionary maps strategy pairs to payoffs perfectly.
- This structure makes lookups easy.
- Show how to access: payoff_matrix[('cooperate', 'defect')] → (-3, 0)
If structure right but payoffs wrong:
- Great structure! But check payoffs:
- Both cooperate: (-1, -1) - best mutual outcome
- Both defect: (-2, -2) - mutual punishment
- One defects: (0, -3) or (-3, 0) - betrayal
If wrong approach:
- Show correct dictionary structure with example.
- Explain why dict with tuple keys is elegant for this.
buckets: [correct, correct_structure, uses_dictionary, wrong_approach, needs_help, set_language, off_topic]
transitions:
correct:
ai_feedback:
tokens_for_ai: |
Perfect implementation!
Your dictionary elegantly maps strategy pairs to payoffs.
Access is simple: matrix[('cooperate', 'defect')] gives (-3, 0).
This structure scales to more complex games!
metadata_add: {score: "n+2", concepts_mastered: "n+1"}
next_section_and_step: payoff_matrix:step_2
correct_structure:
ai_feedback:
tokens_for_ai: |
Great structure! Minor payoff correction needed:
- Both cooperate: (-1, -1)
- Both defect: (-2, -2)
- One defects: betrayer gets 0, cooperator gets -3
Show the corrected version.
metadata_add: {score: "n+1"}
next_section_and_step: payoff_matrix:step_2
uses_dictionary:
ai_feedback:
tokens_for_ai: |
Good use of dictionary!
For game matrices, use tuple keys:
payoff_matrix = {
('cooperate', 'cooperate'): (-1, -1),
('cooperate', 'defect'): (-3, 0),
...
}
next_section_and_step: payoff_matrix:step_1
wrong_approach:
ai_feedback:
tokens_for_ai: |
Python dictionaries with tuple keys work best!
Example format:
game = {('action1', 'action2'): (payoff1, payoff2)}
This allows easy lookup of any strategy combination.
next_section_and_step: payoff_matrix:step_1
needs_help:
content_blocks:
- "Start with: game = {}"
- "Add entries like: ('cooperate', 'cooperate'): (-1, -1)"
- "You need 4 entries total for all strategy combinations"
next_section_and_step: payoff_matrix:step_1
set_language:
metadata_add: {language: "the-users-response"}
counts_as_attempt: false
next_section_and_step: payoff_matrix:step_1
off_topic:
next_section_and_step: payoff_matrix:step_1
- step_id: step_2
title: Querying the Matrix
content_blocks:
- "## Using the Payoff Matrix 🔍"
- ""
- "**Now that you have a payoff matrix, let's use it!**"
- ""
- "**Task:** Write a function that determines outcomes"
- ""
- "**Function requirements:**"
- "- Name: `get_payoffs`"
- "- Parameters: `payoff_matrix`, `player1_action`, `player2_action`"
- "- Returns: tuple of (player1_payoff, player2_payoff)"
- ""
- "**What the function does:**"
- "Looks up the payoffs for the given strategy combination"
- ""
- "**Think about:**"
- "- How do you access dictionary values?"
- "- How do you create the lookup key from the two actions?"
question: "Write a Python function called `get_payoffs` that takes a payoff matrix dictionary and two player actions, then returns the payoff tuple for that strategy combination."
tokens_for_ai: |
Looking for function that:
- Takes 3 parameters: payoff_matrix (dict), player1_action, player2_action
- Creates tuple key: (player1_action, player2_action)
- Returns: payoff_matrix[(player1_action, player2_action)]
Acceptable variations:
- def get_payoffs(matrix, p1, p2): return matrix[(p1, p2)]
- def get_payoffs(payoff_matrix, action1, action2): ...
Categorize as:
- correct: Proper function with correct lookup
- correct_logic: Right idea, minor syntax issues
- missing_tuple: Tries to lookup without creating tuple key
- confused: Wrong approach
- set_language: Language preference
- off_topic: Unrelated
feedback_tokens_for_ai: |
If correct:
- Perfect! Your function correctly creates a tuple key and looks it up.
- Example: get_payoffs(game, 'cooperate', 'defect') → (-3, 0)
- Clean, simple, and reusable!
If correct logic but syntax issues:
- Right approach! Small syntax fix needed.
- Show corrected version.
- Explain the fix.
If missing tuple:
- Remember: dictionary keys are tuples!
- Need to create (player1_action, player2_action) first.
- Then look it up in the matrix.
buckets: [correct, correct_logic, missing_tuple, confused, set_language, off_topic]
transitions:
correct:
ai_feedback:
tokens_for_ai: |
Excellent function!
Your code cleanly creates the tuple key and returns the payoffs.
This abstraction makes game simulation much easier.
You can now query any strategy combination!
metadata_add: {score: "n+2", concepts_mastered: "n+1"}
next_section_and_step: simulation:step_1
correct_logic:
ai_feedback:
tokens_for_ai: |
Great logic! Minor syntax adjustment:
Show corrected function.
Explain what was fixed and why it matters.
metadata_add: {score: "n+1"}
next_section_and_step: simulation:step_1
missing_tuple:
ai_feedback:
tokens_for_ai: |
Close! Don't forget to create the tuple key:
def get_payoffs(payoff_matrix, p1_action, p2_action):
key = (p1_action, p2_action)
return payoff_matrix[key]
next_section_and_step: payoff_matrix:step_2
confused:
content_blocks:
- "A function that takes the matrix and both actions"
- "Creates a tuple from the two actions: (action1, action2)"
- "Uses that tuple to look up the payoffs in the dictionary"
next_section_and_step: payoff_matrix:step_2
set_language:
metadata_add: {language: "the-users-response"}
counts_as_attempt: false
next_section_and_step: payoff_matrix:step_2
off_topic:
next_section_and_step: payoff_matrix:step_2
- section_id: simulation
title: Simulating Strategic Interactions
steps:
- step_id: step_1
title: One-Shot Game Simulator
content_blocks:
- "## Simulating Game Outcomes 🎲"
- ""
- "**Building a simple game simulator**"
- ""
- "**Requirements:**"
- "- Function name: `play_game`"
- "- Parameters: `payoff_matrix`, `strategy1`, `strategy2`"
- "- Should call your `get_payoffs` function"
- "- Print the outcome in a readable format"
- "- Return the payoffs"
- ""
- "**Example output format:**"
- "```"
- "Player 1 chose: cooperate"
- "Player 2 chose: defect"
- "Payoffs: Player 1 = -3, Player 2 = 0"
- "```"
- ""
- "**Conceptual flow:**"
- "1. Get payoffs using your get_payoffs function"
- "2. Display what each player chose"
- "3. Display the resulting payoffs"
- "4. Return the payoffs for further use"
question: "Write a `play_game` function that simulates one round of a game, prints the outcome, and returns the payoffs. Use your `get_payoffs` function from earlier."
tokens_for_ai: |
Looking for function that:
- Calls get_payoffs(payoff_matrix, strategy1, strategy2)
- Prints player choices and payoffs
- Returns the payoff tuple
Should show understanding of:
- Function composition (using get_payoffs)
- Print statements for output
- Returning values
Categorize as:
- correct: Complete function with print and return
- missing_print: Has logic but doesn't print
- missing_return: Prints but doesn't return
- correct_concept: Right idea, minor issues
- confused: Wrong approach
- set_language: Language preference
- off_topic: Unrelated
feedback_tokens_for_ai: |
If correct:
- Excellent! Your simulator uses function composition nicely.
- The print statements make outcomes clear.
- Returning payoffs allows chaining simulations.
- This is how game theory research is done programmatically!
If missing print:
- Good logic! Add print statements to show:
- What each player chose
- The resulting payoffs
- Makes debugging and understanding easier!
If missing return:
- Good output! But also return the payoffs.
- This lets you use the function in larger simulations.
- return payoffs at the end.
Show complete example if needed.
buckets: [correct, missing_print, missing_return, correct_concept, confused, set_language, off_topic]
transitions:
correct:
ai_feedback:
tokens_for_ai: |
Perfect simulator!
You've built function composition (play_game uses get_payoffs).
Print statements provide visibility.
Return value enables further analysis.
You're ready for repeated game simulation!
metadata_add: {score: "n+2", concepts_mastered: "n+1"}
next_section_and_step: repeated_games:step_1
missing_print:
ai_feedback:
tokens_for_ai: |
Good structure! Add print statements:
print(f"Player 1 chose: {strategy1}")
print(f"Player 2 chose: {strategy2}")
print(f"Payoffs: Player 1 = {payoffs[0]}, Player 2 = {payoffs[1]}")
Makes the simulation observable!
metadata_add: {score: "n+1"}
next_section_and_step: repeated_games:step_1
missing_return:
ai_feedback:
tokens_for_ai: |
Great output! Just add:
return payoffs
This lets you accumulate results over many rounds!
metadata_add: {score: "n+1"}
next_section_and_step: repeated_games:step_1
correct_concept:
ai_feedback:
tokens_for_ai: |
Right approach! Small improvements:
Show polished version.
Explain the refinements.
next_section_and_step: repeated_games:step_1
confused:
content_blocks:
- "Your function should:"
- "1. Call get_payoffs to get the payoffs"
- "2. Print what each player chose"
- "3. Print the payoffs"
- "4. Return the payoffs tuple"
next_section_and_step: simulation:step_1
set_language:
metadata_add: {language: "the-users-response"}
counts_as_attempt: false
next_section_and_step: simulation:step_1
off_topic:
next_section_and_step: simulation:step_1
- section_id: repeated_games
title: Repeated Game Strategies
steps:
- step_id: step_1
title: Tit-for-Tat Strategy
content_blocks:
- "## Implementing Strategic Behavior 🔄"
- ""
- "**The Tit-for-Tat Strategy:**"
- "1. Start with cooperation"
- "2. Then copy opponent's previous move"
- ""
- "**Implementation challenge:**"
- "Create a function that implements Tit-for-Tat logic"
- ""
- "**Function requirements:**"
- "- Name: `tit_for_tat`"
- "- Parameter: `opponent_last_move` (or None for first move)"
- "- Returns: 'cooperate' or 'defect'"
- ""
- "**Logic:**"
- "- If it's the first move (opponent_last_move is None): return 'cooperate'"
- "- Otherwise: return whatever the opponent played last"
- ""
- "**Why this is powerful:**"
- "- Nice (starts with cooperation)"
- "- Retaliatory (punishes defection)"
- "- Forgiving (returns to cooperation)"
- "- Simple to understand and implement"
question: "Write a `tit_for_tat` function that takes an opponent's last move (or None for first round) and returns the appropriate strategy according to Tit-for-Tat logic."
tokens_for_ai: |
Correct logic:
- If opponent_last_move is None: return 'cooperate'
- Else: return opponent_last_move
Acceptable implementations:
- Simple if/else
- Ternary operator
- Return with 'or' default
Categorize as:
- correct: Proper Tit-for-Tat logic
- correct_logic: Right idea, minor syntax
- wrong_first_move: Doesn't handle None case
- always_cooperates: Ignores opponent's move
- confused: Wrong logic
- set_language: Language preference
- off_topic: Unrelated
feedback_tokens_for_ai: |
If correct:
- Perfect Tit-for-Tat implementation!
- First move: cooperate (nice)
- After: copy opponent (retaliatory & forgiving)
- This won Axelrod's tournament!
- Show usage example.
If correct logic:
- Great logic! Small syntax refinement:
- Show corrected version.
If wrong first move:
- Remember: Tit-for-Tat starts with cooperation!
- Check if opponent_last_move is None (first round).
- If None, return 'cooperate'.
If always cooperates:
- You need to copy the opponent's move!
- After first round, return opponent_last_move.
- That's what makes it "tit for tat"!
buckets: [correct, correct_logic, wrong_first_move, always_cooperates, confused, set_language, off_topic]
transitions:
correct:
ai_feedback:
tokens_for_ai: |
Excellent Tit-for-Tat implementation!
Your code captures the strategy perfectly:
- Nice: starts with cooperation
- Retaliatory: copies opponent's defection
- Forgiving: copies opponent's return to cooperation
This simple strategy is remarkably effective!
metadata_add: {score: "n+2", concepts_mastered: "n+1", activity_completed: "true"}
correct_logic:
ai_feedback:
tokens_for_ai: |
Great logic! Minor polish:
Show refined version.
Your understanding of the strategy is solid!
metadata_add: {score: "n+1", activity_completed: "true"}
wrong_first_move:
ai_feedback:
tokens_for_ai: |
Almost there! Handle the first move:
def tit_for_tat(opponent_last_move):
if opponent_last_move is None:
return 'cooperate' # Be nice first
return opponent_last_move # Then copy
next_section_and_step: repeated_games:step_1
always_cooperates:
ai_feedback:
tokens_for_ai: |
That's "always cooperate," not Tit-for-Tat!
Tit-for-Tat must COPY the opponent's last move.
Only the FIRST move is automatically cooperate.
next_section_and_step: repeated_games:step_1
confused:
content_blocks:
- "Tit-for-Tat logic:"
- "1. First move (when opponent_last_move is None): cooperate"
- "2. All other moves: copy opponent's last move"
- "Use an if statement to check for None"
next_section_and_step: repeated_games:step_1
set_language:
metadata_add: {language: "the-users-response"}
counts_as_attempt: false
next_section_and_step: repeated_games:step_1
off_topic:
metadata_add: {activity_completed: "true"}

View file

@ -0,0 +1,528 @@
default_max_attempts_per_step: 3
classifier_model: "MODEL_1"
feedback_model: "MODEL_1"
tokens_for_ai_rubric: |
Evaluate the student's ability to implement game theory concepts in C.
Consider:
- Correct C syntax
- Proper use of structs and pointers
- Memory management awareness
- Understanding of game theory concepts
- Code structure and organization
sections:
- section_id: introduction
title: Programming Game Theory in C
steps:
- step_id: welcome
title: Systems Programming Meets Strategy
content_blocks:
- "# Game Theory Programming with C ⚙️🎮"
- ""
- "**Learn C by implementing game theory!**"
- ""
- "You'll learn to:"
- "✓ Define game structures with structs"
- "✓ Use 2D arrays for payoff matrices"
- "✓ Work with pointers and memory"
- "✓ Implement strategy functions"
- "✓ Build game simulators in C"
- ""
- "**Prerequisites:**"
- "- Basic C knowledge (variables, functions, arrays)"
- "- Understanding of basic game theory concepts"
- ""
- "**Why C for game theory:**"
- "- Performance for large simulations"
- "- Memory efficiency"
- "- Understanding low-level implementation"
- "- Foundation for understanding algorithms"
question: Ready to implement game theory in C?
tokens_for_ai: Accept positive as 'ready', language preference as 'set_language', else 'off_topic'
buckets: [ready, set_language, off_topic]
transitions:
ready:
next_section_and_step: structures:step_1
set_language:
metadata_add: {language: "the-users-response"}
counts_as_attempt: false
next_section_and_step: introduction:welcome
off_topic:
counts_as_attempt: false
next_section_and_step: introduction:welcome
- section_id: structures
title: Defining Game Structures
steps:
- step_id: step_1
title: Payoff Structure
content_blocks:
- "## Representing Payoffs in C 📐"
- ""
- "**The challenge:**"
- "How do we represent a payoff (two player outcomes) in C?"
- ""
- "**Conceptual requirement:**"
- "Each outcome has TWO values:"
- "- Player 1's payoff"
- "- Player 2's payoff"
- ""
- "**C solution: struct**"
- "A struct groups related data together"
- ""
- "**What your struct needs:**"
- "- A name (like 'Payoff' or 'Outcome')"
- "- Two integer fields for the two payoffs"
- ""
- "**Struct syntax reminder:**"
- "```"
- "struct StructName {"
- " type field1;"
- " type field2;"
- "};"
- "```"
question: "Define a C struct called 'Payoff' that contains two integer fields: 'player1' and 'player2' for storing each player's payoff."
tokens_for_ai: |
Looking for struct definition with:
- Name: Payoff (or similar like Outcome, GameResult)
- Two int fields for the two player payoffs
Correct examples:
struct Payoff {
int player1;
int player2;
};
or
typedef struct {
int p1;
int p2;
} Payoff;
Categorize as:
- correct: Valid struct with two int fields
- correct_concept: Right idea, minor syntax
- missing_fields: Struct but wrong/missing fields
- no_struct: Doesn't use struct
- confused: Wrong approach
- set_language: Language preference
- off_topic: Unrelated
feedback_tokens_for_ai: |
If correct:
- Perfect struct definition!
- Your struct groups the two payoffs together.
- Now you can create: struct Payoff outcome;
- Access: outcome.player1 = -1; outcome.player2 = -1;
If correct concept:
- Right idea! Small syntax adjustment:
- Show corrected version.
- Explain the fix.
If missing fields:
- Remember: need TWO integer fields
- One for player1's payoff
- One for player2's payoff
If no struct:
- C structs group related data!
- Show example struct format.
buckets: [correct, correct_concept, missing_fields, no_struct, confused, set_language, off_topic]
transitions:
correct:
ai_feedback:
tokens_for_ai: |
Excellent struct definition!
Your Payoff struct elegantly groups both players' outcomes.
Usage: struct Payoff p = {-1, -2}; or p.player1 = 0;
This is the foundation for representing game outcomes!
metadata_add: {score: "n+2", concepts_mastered: "n+1"}
next_section_and_step: structures:step_2
correct_concept:
ai_feedback:
tokens_for_ai: |
Great concept! Minor syntax refinement:
Show corrected struct.
Explain the adjustment made.
metadata_add: {score: "n+1"}
next_section_and_step: structures:step_2
missing_fields:
ai_feedback:
tokens_for_ai: |
Need two int fields!
struct Payoff {
int player1;
int player2;
};
This stores both players' payoffs together.
next_section_and_step: structures:step_1
no_struct:
content_blocks:
- "Use a struct to group the two payoffs:"
- "struct Payoff { ... };"
- "Include two int fields inside the braces"
next_section_and_step: structures:step_1
confused:
content_blocks:
- "Define a struct with:"
- "- Name: Payoff"
- "- Two int fields (one for each player's payoff)"
- "Don't forget the semicolon at the end!"
next_section_and_step: structures:step_1
set_language:
metadata_add: {language: "the-users-response"}
counts_as_attempt: false
next_section_and_step: structures:step_1
off_topic:
next_section_and_step: structures:step_1
- step_id: step_2
title: Payoff Matrix with 2D Array
content_blocks:
- "## 2D Array for Game Matrix 🎯"
- ""
- "**Representing a 2x2 game:**"
- ""
- "**Prisoner's Dilemma has:**"
- "- 2 strategies per player: cooperate (0) or defect (1)"
- "- 4 possible outcomes: (0,0), (0,1), (1,0), (1,1)"
- ""
- "**Perfect for a 2D array!**"
- ""
- "**Array structure:**"
- "- First index: player 1's strategy (0 or 1)"
- "- Second index: player 2's strategy (0 or 1)"
- "- Value: Payoff struct with both payoffs"
- ""
- "**Conceptual mapping:**"
- "```"
- "matrix[0][0] = both cooperate"
- "matrix[0][1] = p1 cooperates, p2 defects"
- "matrix[1][0] = p1 defects, p2 cooperates"
- "matrix[1][1] = both defect"
- "```"
- ""
- "**Array declaration concept:**"
- "You declare a 2D array of your Payoff struct"
- "Then initialize it with the four outcomes"
question: "Declare and initialize a 2D array called 'prisoners_dilemma' of Payoff structs representing the Prisoner's Dilemma game. Use indices 0=cooperate, 1=defect. Payoffs: both cooperate (-1,-1), both defect (-2,-2), one defects (0,-3) or (-3,0)."
tokens_for_ai: |
Looking for 2D array declaration and initialization:
struct Payoff prisoners_dilemma[2][2] = {
{{-1, -1}, {-3, 0}}, // p1 cooperates
{{0, -3}, {-2, -2}} // p1 defects
};
Or similar valid initialization.
Categorize as:
- correct: Valid 2D array with proper payoffs
- correct_structure: Right format, payoff errors
- wrong_dimensions: Not 2x2
- syntax_errors: C syntax issues
- confused: Wrong approach
- set_language: Language preference
- off_topic: Unrelated
feedback_tokens_for_ai: |
If correct:
- Perfect 2D array implementation!
- prisoners_dilemma[0][0] = both cooperate = {-1,-1}
- prisoners_dilemma[1][1] = both defect = {-2,-2}
- prisoners_dilemma[0][1] = p1 cooperate, p2 defect = {-3,0}
- prisoners_dilemma[1][0] = p1 defect, p2 cooperate = {0,-3}
- Efficient memory layout for game representation!
If structure right:
- Great array structure! Payoff corrections:
- Show corrected initialization.
- Explain the Prisoner's Dilemma payoffs.
If wrong dimensions:
- Need 2x2 array (2 strategies per player)
- struct Payoff name[2][2] = {...};
If syntax errors:
- Show correct C array initialization syntax.
- Explain the nested braces structure.
buckets: [correct, correct_structure, wrong_dimensions, syntax_errors, confused, set_language, off_topic]
transitions:
correct:
ai_feedback:
tokens_for_ai: |
Excellent array implementation!
Your 2D array efficiently represents the payoff matrix.
Access is simple: prisoners_dilemma[i][j]
Memory layout is contiguous and cache-friendly.
This is how game theory simulations optimize performance!
metadata_add: {score: "n+2", concepts_mastered: "n+1"}
next_section_and_step: functions:step_1
correct_structure:
ai_feedback:
tokens_for_ai: |
Great structure! Payoff corrections for Prisoner's Dilemma:
Show corrected initialization with explanations.
Explain why these specific payoffs create the dilemma.
metadata_add: {score: "n+1"}
next_section_and_step: functions:step_1
wrong_dimensions:
ai_feedback:
tokens_for_ai: |
Need 2x2 for two-strategy game:
struct Payoff game[2][2] = {
{{-1,-1}, {-3,0}},
{{0,-3}, {-2,-2}}
};
next_section_and_step: structures:step_2
syntax_errors:
ai_feedback:
tokens_for_ai: |
C array initialization uses nested braces:
struct Payoff arr[2][2] = {
{row0_col0, row0_col1},
{row1_col0, row1_col1}
};
Each Payoff is {p1_payoff, p2_payoff}
next_section_and_step: structures:step_2
confused:
content_blocks:
- "Declare: struct Payoff prisoners_dilemma[2][2]"
- "Initialize with nested braces: {{...}, {...}}"
- "Four outcomes total (2x2 = 4 combinations)"
next_section_and_step: structures:step_2
set_language:
metadata_add: {language: "the-users-response"}
counts_as_attempt: false
next_section_and_step: structures:step_2
off_topic:
next_section_and_step: structures:step_2
- section_id: functions
title: Strategy Functions
steps:
- step_id: step_1
title: Lookup Function
content_blocks:
- "## Querying the Payoff Matrix 🔍"
- ""
- "**Create a function to get payoffs**"
- ""
- "**Function requirements:**"
- "- Name: `get_payoff`"
- "- Parameters: 2D array (pointer), two strategy indices"
- "- Returns: Payoff struct"
- ""
- "**C function concepts:**"
- "- Pass 2D array as pointer"
- "- Access with array indexing"
- "- Return struct by value"
- ""
- "**What it does:**"
- "Takes strategies (0 or 1 for each player)"
- "Returns the corresponding Payoff from the matrix"
question: "Write a C function called 'get_payoff' that takes a 2D Payoff array (as pointer) and two integer strategy indices, then returns the Payoff struct for that strategy combination."
tokens_for_ai: |
Acceptable function signatures:
- struct Payoff get_payoff(struct Payoff matrix[2][2], int s1, int s2)
- struct Payoff get_payoff(struct Payoff (*matrix)[2], int s1, int s2)
Function body should:
- Return matrix[s1][s2];
Categorize as:
- correct: Valid function with proper syntax
- correct_logic: Right idea, minor syntax
- wrong_return: Doesn't return Payoff struct
- pointer_confusion: Struggles with array parameter
- confused: Wrong approach
- set_language: Language preference
- off_topic: Unrelated
feedback_tokens_for_ai: |
If correct:
- Perfect function!
- Your function cleanly accesses the 2D array.
- Returning struct by value is simple and safe here.
- Usage: struct Payoff p = get_payoff(game, 0, 1);
If correct logic:
- Great logic! Minor syntax refinement:
- Show corrected version.
- Explain the C-specific details.
If wrong return:
- Function should return struct Payoff
- return matrix[s1][s2]; gives you the Payoff struct.
If pointer confusion:
- For small 2D arrays, can pass as: struct Payoff matrix[2][2]
- Or use pointer: struct Payoff (*matrix)[2]
- Show working example.
buckets: [correct, correct_logic, wrong_return, pointer_confusion, confused, set_language, off_topic]
transitions:
correct:
ai_feedback:
tokens_for_ai: |
Excellent function implementation!
Your get_payoff function cleanly retrieves outcomes.
C's struct return makes this straightforward.
You've encapsulated the lookup logic perfectly!
metadata_add: {score: "n+2", concepts_mastered: "n+1"}
next_section_and_step: simulation:step_1
correct_logic:
ai_feedback:
tokens_for_ai: |
Great logic! Small C syntax refinement:
Show polished version.
Explain the specific C conventions used.
metadata_add: {score: "n+1"}
next_section_and_step: simulation:step_1
wrong_return:
ai_feedback:
tokens_for_ai: |
Return type should be struct Payoff:
struct Payoff get_payoff(struct Payoff matrix[2][2], int s1, int s2) {
return matrix[s1][s2];
}
next_section_and_step: functions:step_1
pointer_confusion:
ai_feedback:
tokens_for_ai: |
For 2D array parameter, simple approach:
struct Payoff get_payoff(struct Payoff matrix[2][2], int s1, int s2) {
return matrix[s1][s2];
}
C automatically handles the array as pointer.
next_section_and_step: functions:step_1
confused:
content_blocks:
- "Function signature: struct Payoff get_payoff(struct Payoff matrix[2][2], int s1, int s2)"
- "Function body: return matrix[s1][s2];"
- "This returns the Payoff at position [s1][s2]"
next_section_and_step: functions:step_1
set_language:
metadata_add: {language: "the-users-response"}
counts_as_attempt: false
next_section_and_step: functions:step_1
off_topic:
next_section_and_step: functions:step_1
- section_id: simulation
title: Game Simulation
steps:
- step_id: step_1
title: Strategy Enumeration
content_blocks:
- "## Defining Strategies with Enum 🎲"
- ""
- "**Making code readable:**"
- "Instead of 0 and 1, use named constants!"
- ""
- "**C enum for strategies:**"
- "Enums give names to integer values"
- ""
- "**What you need:**"
- "- Enum name: Strategy (or similar)"
- "- Two values: COOPERATE = 0, DEFECT = 1"
- ""
- "**Why enums improve code:**"
- "- get_payoff(game, COOPERATE, DEFECT) is clearer"
- "- Better than get_payoff(game, 0, 1)"
- "- Self-documenting code"
- "- Type safety (to some degree)"
question: "Define a C enum called 'Strategy' with two values: COOPERATE (equals 0) and DEFECT (equals 1)."
tokens_for_ai: |
Looking for enum definition:
enum Strategy {
COOPERATE = 0,
DEFECT = 1
};
Or:
typedef enum {
COOPERATE = 0,
DEFECT = 1
} Strategy;
Categorize as:
- correct: Valid enum with both values
- correct_concept: Right idea, minor syntax
- missing_values: Enum but wrong values
- no_enum: Doesn't use enum
- confused: Wrong approach
- set_language: Language preference
- off_topic: Unrelated
feedback_tokens_for_ai: |
If correct:
- Perfect enum definition!
- Now you can write: enum Strategy s = COOPERATE;
- Much more readable than: int s = 0;
- Self-documenting code is maintainable code!
If correct concept:
- Great use of enum! Small refinement:
- Show corrected version.
If missing values:
- Need both COOPERATE = 0 and DEFECT = 1
- Show correct enum.
If no enum:
- C enums create named integer constants:
- Show enum syntax.
buckets: [correct, correct_concept, missing_values, no_enum, confused, set_language, off_topic]
transitions:
correct:
ai_feedback:
tokens_for_ai: |
Excellent enum!
Your code is now self-documenting.
COOPERATE and DEFECT are much clearer than 0 and 1.
This is professional C code style!
You've mastered game theory implementation in C!
metadata_add: {score: "n+2", concepts_mastered: "n+1", activity_completed: "true"}
correct_concept:
ai_feedback:
tokens_for_ai: |
Great enum concept! Small polish:
Show refined version.
You understand C enums well!
metadata_add: {score: "n+1", activity_completed: "true"}
missing_values:
ai_feedback:
tokens_for_ai: |
Need both strategies:
enum Strategy {
COOPERATE = 0,
DEFECT = 1
};
next_section_and_step: simulation:step_1
no_enum:
content_blocks:
- "Define enum with:"
- "enum Strategy { COOPERATE = 0, DEFECT = 1 };"
- "This creates named constants"
next_section_and_step: simulation:step_1
confused:
content_blocks:
- "Enum syntax: enum Name { VALUE1 = 0, VALUE2 = 1 };"
- "Creates named integer constants"
- "Don't forget the semicolon!"
next_section_and_step: simulation:step_1
set_language:
metadata_add: {language: "the-users-response"}
counts_as_attempt: false
next_section_and_step: simulation:step_1
off_topic:
metadata_add: {activity_completed: "true"}