The prisoner’s dilemma in R: why defection dominates a single encounter and mutual cooperation collapses, the starting point for the evolution of cooperation.
Author
Tidy Ecology
Published
2026-08-07
Cooperation is a puzzle because cheating pays. Two animals that both help each other do better than two that both cheat, yet whatever the other one does, an individual gains by cheating. That tension has a canonical model: the prisoner’s dilemma. It is the foundation of everything in the evolution of cooperation, and this post builds it in a few lines of base R to show exactly why cooperation is hard.
The payoffs
Two players each choose to cooperate or defect. The four outcomes have standard names: mutual cooperation pays the reward R, mutual defection the punishment P, and a defector against a cooperator gets the temptation T while the cooperator gets the sucker’s payoff S. A prisoner’s dilemma is any game with T > R > P > S.
Tt <-5; R <-3; P <-1; S <-0# temptation, reward, punishment, sucker# focal player's payoff given (focal move, opponent move), C = cooperate, D = defectpayoff <-function(me, opp) {if (me =="C"&& opp =="C") R elseif (me =="C"&& opp =="D") S elseif (me =="D"&& opp =="C") Tt else P}cat(sprintf("T=%g > R=%g > P=%g > S=%g\n", Tt, R, P, S))
T=5 > R=3 > P=1 > S=0
Defection dominates
Ask the only question that matters to a selfish player: whatever my opponent does, am I better off cooperating or defecting?
cat(sprintf("opponent cooperates: D pays %g vs C pays %g -> defect\n", payoff("D", "C"), payoff("C", "C")))
opponent cooperates: D pays 5 vs C pays 3 -> defect
cat(sprintf("opponent defects: D pays %g vs C pays %g -> defect\n", payoff("D", "D"), payoff("C", "D")))
opponent defects: D pays 1 vs C pays 0 -> defect
Against a cooperator, defecting pays 5 instead of 3. Against a defector, defecting pays 1 instead of 0. Defection wins in both columns, so it is a dominant strategy: a rational player defects no matter what, and a population of defectors cannot be invaded by a lone cooperator. Defection is the only evolutionarily stable strategy of the one-shot game, the same logic that makes all-defect an equilibrium in any single social encounter.
The dilemma
Here is the catch that gives the game its name.
cat(sprintf("both defect (the ESS): %g each\n", payoff("D", "D")))
Two defectors earn 1 each; two cooperators would earn 3 each. Individual rationality drives everyone to the outcome that is worse for everyone. Nothing is wrong with the reasoning; the trap is real. This is why cooperation in nature demands an explanation, and why so much of social evolution is the search for what changes the payoffs or the structure enough to escape it.
library(ggplot2)d <-expand.grid(me =c("C", "D"), opp =c("C", "D"))d$pay <-mapply(payoff, d$me, d$opp)ggplot(d, aes(opp, me, fill = pay)) +geom_tile(colour ="white", linewidth =2) +geom_text(aes(label = pay), colour ="white", size =7) +scale_fill_gradient(low ="#93a87f", high ="#275139", guide ="none") +labs(x ="Opponent move", y ="Focal move") +theme_minimal(base_size =13)
Figure 1: The focal player’s payoff for each move against each opponent move. Defect (bottom row) beats cooperate (top row) in both columns, so defection dominates, even though mutual cooperation (3) beats mutual defection (1).
An honest limit
The one-shot dilemma is a starting point, not a description of most animal life. Its stark conclusion, always defect, rests on a specific and often false assumption: that the two players will never meet again and that nothing links this encounter to the next. Real interactions repeat, happen among relatives, are watched by others, and play out in space. Each of those changes the game, and each is a route out of the trap. The next posts follow the most studied one, repeated interaction, where the shadow of future encounters can make cooperation pay after all. The dilemma is worth understanding precisely because it sets the bar every explanation of cooperation has to clear.
Axelrod R, Hamilton WD 1981. Science 211(4489):1390-1396 (10.1126/science.7466396)
Trivers RL 1971. Quarterly Review of Biology 46(1):35-57 (10.1086/406755)
Newsletter
Get new tutorials by email
New R and QGIS tutorials for ecologists, straight to your inbox. No spam; unsubscribe anytime.
By subscribing you agree to receive these emails and confirm your address once. See the privacy policy.
Source Code
---title: "The prisoner's dilemma in R"description: "The prisoner's dilemma in R: why defection dominates a single encounter and mutual cooperation collapses, the starting point for the evolution of cooperation."date: "2026-08-07 09:00"categories: [evolutionary ecology, evolutionary game theory, social evolution, R, ecology tutorial]image: thumbnail.pngimage-alt: "A two-by-two payoff matrix showing defection paying more than cooperation against either opponent move"---Cooperation is a puzzle because cheating pays. Two animals that both help each other do better than two that both cheat, yet whatever the other one does, an individual gains by cheating. That tension has a canonical model: the prisoner's dilemma. It is the foundation of everything in [the evolution of cooperation](../direct-reciprocity-and-tit-for-tat/), and this post builds it in a few lines of base R to show exactly why cooperation is hard.## The payoffsTwo players each choose to cooperate or defect. The four outcomes have standard names: mutual cooperation pays the reward `R`, mutual defection the punishment `P`, and a defector against a cooperator gets the temptation `T` while the cooperator gets the sucker's payoff `S`. A prisoner's dilemma is any game with `T > R > P > S`.```{r}#| label: payoffsTt <-5; R <-3; P <-1; S <-0# temptation, reward, punishment, sucker# focal player's payoff given (focal move, opponent move), C = cooperate, D = defectpayoff <-function(me, opp) {if (me =="C"&& opp =="C") R elseif (me =="C"&& opp =="D") S elseif (me =="D"&& opp =="C") Tt else P}cat(sprintf("T=%g > R=%g > P=%g > S=%g\n", Tt, R, P, S))```## Defection dominatesAsk the only question that matters to a selfish player: whatever my opponent does, am I better off cooperating or defecting?```{r}#| label: dominancecat(sprintf("opponent cooperates: D pays %g vs C pays %g -> defect\n", payoff("D", "C"), payoff("C", "C")))cat(sprintf("opponent defects: D pays %g vs C pays %g -> defect\n", payoff("D", "D"), payoff("C", "D")))```Against a cooperator, defecting pays 5 instead of 3. Against a defector, defecting pays 1 instead of 0. Defection wins in both columns, so it is a dominant strategy: a rational player defects no matter what, and a population of defectors cannot be invaded by a lone cooperator. Defection is the only evolutionarily stable strategy of the one-shot game, the same logic that makes all-defect an equilibrium in any single social encounter.## The dilemmaHere is the catch that gives the game its name.```{r}#| label: dilemmacat(sprintf("both defect (the ESS): %g each\n", payoff("D", "D")))cat(sprintf("both cooperate: %g each\n", payoff("C", "C")))```Two defectors earn 1 each; two cooperators would earn 3 each. Individual rationality drives everyone to the outcome that is worse for everyone. Nothing is wrong with the reasoning; the trap is real. This is why cooperation in nature demands an explanation, and why so much of social evolution is the search for what changes the payoffs or the structure enough to escape it.```{r}#| label: fig-matrix#| fig-cap: "The focal player's payoff for each move against each opponent move. Defect (bottom row) beats cooperate (top row) in both columns, so defection dominates, even though mutual cooperation (3) beats mutual defection (1)."#| fig-alt: "A two-by-two grid of payoffs with the defect row shaded darker, showing 1 and 5 against 0 and 3."library(ggplot2)d <-expand.grid(me =c("C", "D"), opp =c("C", "D"))d$pay <-mapply(payoff, d$me, d$opp)ggplot(d, aes(opp, me, fill = pay)) +geom_tile(colour ="white", linewidth =2) +geom_text(aes(label = pay), colour ="white", size =7) +scale_fill_gradient(low ="#93a87f", high ="#275139", guide ="none") +labs(x ="Opponent move", y ="Focal move") +theme_minimal(base_size =13)```## An honest limitThe one-shot dilemma is a starting point, not a description of most animal life. Its stark conclusion, always defect, rests on a specific and often false assumption: that the two players will never meet again and that nothing links this encounter to the next. Real interactions repeat, happen among relatives, are watched by others, and play out in space. Each of those changes the game, and each is a route out of the trap. The next posts follow the most studied one, [repeated interaction](../direct-reciprocity-and-tit-for-tat/), where the shadow of future encounters can make cooperation pay after all. The dilemma is worth understanding precisely because it sets the bar every explanation of cooperation has to clear.## Related tutorials- [Direct reciprocity and tit-for-tat](../direct-reciprocity-and-tit-for-tat/)- [Network reciprocity on a lattice](../network-reciprocity-on-a-lattice/)- [Checking a reciprocity model](../checking-a-reciprocity-model/)- [The hawk-dove game and the ESS](../hawk-dove-and-the-ess/)## ReferencesAxelrod R, Hamilton WD 1981. Science 211(4489):1390-1396 (10.1126/science.7466396)Trivers RL 1971. Quarterly Review of Biology 46(1):35-57 (10.1086/406755)