opencompletion.com/research/activity47-game-theory-c.yaml
Claude 4e72fed8be
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
2025-11-09 15:36:12 +00:00

528 lines
20 KiB
YAML

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"}