From 4e72fed8bef19e5cc4ec8373ad11f3839b7fa12e Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 9 Nov 2025 15:36:12 +0000 Subject: [PATCH] Add game theory programming courses for Python and C MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- research/activity46-game-theory-python.yaml | 509 +++++++++++++++++++ research/activity47-game-theory-c.yaml | 528 ++++++++++++++++++++ 2 files changed, 1037 insertions(+) create mode 100644 research/activity46-game-theory-python.yaml create mode 100644 research/activity47-game-theory-c.yaml diff --git a/research/activity46-game-theory-python.yaml b/research/activity46-game-theory-python.yaml new file mode 100644 index 0000000..d28a7c0 --- /dev/null +++ b/research/activity46-game-theory-python.yaml @@ -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"} diff --git a/research/activity47-game-theory-c.yaml b/research/activity47-game-theory-c.yaml new file mode 100644 index 0000000..bc79a27 --- /dev/null +++ b/research/activity47-game-theory-c.yaml @@ -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"}