This work extends that of curacao1962_threeplayers.R by
including a rest monster.
library("hyper2")
library("magrittr")
a <- read.table("curacao1962_candidates.txt",header=FALSE)
colnames(a) <- c("W", "B", "result", "round")
head(a)
## W B result round
## 1 Benko Fischer 1-0 1
## 2 Korchnoi Geller 1/2-1/2 1
## 3 Keres Filip 1/2-1/2 1
## 4 Petrosian Tal 1-0 1
## 5 Korchnoi Petrosian 1/2-1/2 2
## 6 Geller Fischer 1-0 2
specify the players:
players <-
c("Petrosian", "Keres", "Geller", "Fischer", "Korchnoi",
"Benko", "Tal", "Filip")
names(players) <- # accused of collusion or not
c("coll", "coll", "coll", "USA", "USSR", "USA", "USSR", "TCH")
collusive_players <- c("Petrosian", "Keres", "Geller")
d <- as.matrix(cbind(as.character(a$V1),as.character(a$V2)))
colnames(d) <- c("white","black")
stopifnot(all(c(d) %in% players))
jj <- matrix(0,28,8)
colnames(jj) <- players
cumulative_games <- jj
cumulative_collusive_games <- jj
cumulative_noncollusive_games <- jj
for(i in seq_len(28)){ # 'i' loops through rounds
for(j in seq_along(players)){
previous_games <- subset(a,a$round < i)
cg <- 0 # cumulative games
cncg <- 0 # cumulative noncollusive games
for(k in seq_len(nrow(previous_games))){
w <- previous_games$W[k] # white player
b <- previous_games$B[k] # black player
this_game <- c(w,b)
if((players[j] %in% this_game)){
if(players[j] %in% collusive_players){ # this player is collusive
if((w %in% collusive_players) & (b %in% collusive_players)){ # both players collusive
cg <- cg+1 # increment cm == cumulative games
} else { # non-collusive game
cncg <- cncg+1 # increment ncm == cumulative noncollusive games
}
} else { # noncollusive player
cncg <- cncg+1 # increment ncm == cumulative noncollusive games
}
}
} # k loop closes
cumulative_collusive_games[i,j] <- cg
cumulative_noncollusive_games[i,j] <- cncg
cumulative_games[i,j] <- cg + cncg
} # j loop closes
} # i loop closes
So we have three matrices cumulative_games,
cumulative_collusive_games and
cumulative_noncollusive_games:
cumulative_games
## Petrosian Keres Geller Fischer Korchnoi Benko Tal Filip
## [1,] 0 0 0 0 0 0 0 0
## [2,] 1 1 1 1 1 1 1 1
## [3,] 2 2 2 2 2 2 2 2
## [4,] 3 3 3 3 3 3 3 3
## [5,] 4 4 4 4 4 4 4 4
## [6,] 5 5 5 5 5 5 5 5
## [7,] 6 6 6 6 6 6 6 6
## [8,] 7 7 7 7 7 7 7 7
## [9,] 8 8 8 8 8 8 8 8
## [10,] 9 9 9 9 9 9 9 9
## [11,] 10 10 10 10 10 10 10 10
## [12,] 11 11 11 11 11 11 11 11
## [13,] 12 12 12 12 12 12 12 12
## [14,] 13 13 13 13 13 13 13 13
## [15,] 14 14 14 14 14 14 14 14
## [16,] 15 15 15 15 15 15 15 15
## [17,] 16 16 16 16 16 16 16 16
## [18,] 17 17 17 17 17 17 17 17
## [19,] 18 18 18 18 18 18 18 18
## [20,] 19 19 19 19 19 19 19 19
## [21,] 20 20 20 20 20 20 20 20
## [22,] 21 21 21 21 21 21 21 21
## [23,] 21 22 22 22 22 22 21 22
## [24,] 22 22 23 23 23 23 21 23
## [25,] 23 23 24 24 24 23 21 24
## [26,] 24 24 25 24 25 24 21 25
## [27,] 25 25 26 25 26 25 21 25
## [28,] 26 26 26 26 27 26 21 26
cumulative_collusive_games
## Petrosian Keres Geller Fischer Korchnoi Benko Tal Filip
## [1,] 0 0 0 0 0 0 0 0
## [2,] 0 0 0 0 0 0 0 0
## [3,] 0 0 0 0 0 0 0 0
## [4,] 1 0 1 0 0 0 0 0
## [5,] 2 1 1 0 0 0 0 0
## [6,] 2 2 2 0 0 0 0 0
## [7,] 2 2 2 0 0 0 0 0
## [8,] 2 2 2 0 0 0 0 0
## [9,] 2 2 2 0 0 0 0 0
## [10,] 2 2 2 0 0 0 0 0
## [11,] 3 2 3 0 0 0 0 0
## [12,] 4 3 3 0 0 0 0 0
## [13,] 4 4 4 0 0 0 0 0
## [14,] 4 4 4 0 0 0 0 0
## [15,] 4 4 4 0 0 0 0 0
## [16,] 4 4 4 0 0 0 0 0
## [17,] 4 4 4 0 0 0 0 0
## [18,] 5 4 5 0 0 0 0 0
## [19,] 6 5 5 0 0 0 0 0
## [20,] 6 6 6 0 0 0 0 0
## [21,] 6 6 6 0 0 0 0 0
## [22,] 6 6 6 0 0 0 0 0
## [23,] 6 6 6 0 0 0 0 0
## [24,] 6 6 6 0 0 0 0 0
## [25,] 7 6 7 0 0 0 0 0
## [26,] 8 7 7 0 0 0 0 0
## [27,] 8 8 8 0 0 0 0 0
## [28,] 8 8 8 0 0 0 0 0
cumulative_noncollusive_games
## Petrosian Keres Geller Fischer Korchnoi Benko Tal Filip
## [1,] 0 0 0 0 0 0 0 0
## [2,] 1 1 1 1 1 1 1 1
## [3,] 2 2 2 2 2 2 2 2
## [4,] 2 3 2 3 3 3 3 3
## [5,] 2 3 3 4 4 4 4 4
## [6,] 3 3 3 5 5 5 5 5
## [7,] 4 4 4 6 6 6 6 6
## [8,] 5 5 5 7 7 7 7 7
## [9,] 6 6 6 8 8 8 8 8
## [10,] 7 7 7 9 9 9 9 9
## [11,] 7 8 7 10 10 10 10 10
## [12,] 7 8 8 11 11 11 11 11
## [13,] 8 8 8 12 12 12 12 12
## [14,] 9 9 9 13 13 13 13 13
## [15,] 10 10 10 14 14 14 14 14
## [16,] 11 11 11 15 15 15 15 15
## [17,] 12 12 12 16 16 16 16 16
## [18,] 12 13 12 17 17 17 17 17
## [19,] 12 13 13 18 18 18 18 18
## [20,] 13 13 13 19 19 19 19 19
## [21,] 14 14 14 20 20 20 20 20
## [22,] 15 15 15 21 21 21 21 21
## [23,] 15 16 16 22 22 22 21 22
## [24,] 16 16 17 23 23 23 21 23
## [25,] 16 17 17 24 24 23 21 24
## [26,] 16 17 18 24 25 24 21 25
## [27,] 17 17 18 25 26 25 21 25
## [28,] 18 18 18 26 27 26 21 26
In the above three matrices, each row is a round, and the entries
show the number of games, collusive games, and noncollusive games played
up to and including that round for each of the 8 players. Each (named)
column corresponds to a player. Looking at the last row of
cumulative_noncollusive_games we see that in round 28,
players Petrosian, Keres, and Geller had played a total of 18
noncollusive games while the other players had played considerably more
and would be expected to be more fatigued at this point in the
tournament. Note that Tal retired after round 21 due to illness, which
explains why he had played fewer noncollusive games than Fischer,
Korchnoi, Benko, or Filip at this point.
## To justify the footnote "No game in the tournament is played
## between two players with cumulative game count (collusivitity
## ignored), differ by more than one" in jebo_chess_revision2.tex,
## replace `cumulative_noncollusive_games` with
## `cumulative_games` in this chunk.
##
a <- cbind(a,cncmp_white=0,cncmp_black=0)
for(i in seq_len(nrow(a))){
r <- a$round[i]
jj_w <- which(colnames(cumulative_noncollusive_games)==a$W[i])
jj_b <- which(colnames(cumulative_noncollusive_games)==a$B[i])
ncmp_w <- cumulative_noncollusive_games[r, jj_w]
ncmp_b <- cumulative_noncollusive_games[r, jj_b]
a$cncmp_white[i] <- ncmp_w
a$cncmp_black[i] <- ncmp_b
}
head(a)
## W B result round cncmp_white cncmp_black
## 1 Benko Fischer 1-0 1 0 0
## 2 Korchnoi Geller 1/2-1/2 1 0 0
## 3 Keres Filip 1/2-1/2 1 0 0
## 4 Petrosian Tal 1-0 1 0 0
## 5 Korchnoi Petrosian 1/2-1/2 2 1 1
## 6 Geller Fischer 1-0 2 1 1
tail(a)
## W B result round cncmp_white cncmp_black
## 100 Filip Korchnoi 0-1 27 25 26
## 101 Fischer Petrosian 1/2-1/2 27 25 17
## 102 Benko Keres 1-0 27 25 17
## 103 Keres Fischer 1/2-1/2 28 18 26
## 104 Geller Benko 1-0 28 18 26
## 105 Petrosian Filip 1/2-1/2 28 18 26
Thus the final match, between Petrosian and Filip was played in round 28, ended in a draw, and by that time Petrosian had played 18 noncollusive games and Filip had played 26.
We can see the differences between cumulative noncollusive games played between Black and White, summed over the whole tournament:
diff <- a$cncmp_white-a$cncmp_black # difference in each game
table(diff)
## diff
## -8 -7 -6 -5 -4 -2 -1 0 1 2 3 4 6 7 8
## 4 1 4 1 8 6 5 46 5 8 1 6 6 2 2
table(abs(diff))
##
## 0 1 2 3 4 5 6 7 8
## 46 10 14 1 14 1 10 3 6
cumsum(table(abs(diff)))
## 0 1 2 3 4 5 6 7 8
## 46 56 70 71 85 86 96 99 105
We can assess a null of no effect of fatigue:
table(a[,3],a[,5]-a[,6])
##
## -8 -7 -6 -5 -4 -2 -1 0 1 2 3 4 6 7 8
## 0-1 0 0 0 0 0 0 1 10 0 3 1 6 3 0 0
## 1-0 1 1 2 1 3 1 1 14 0 1 0 0 1 0 1
## 1/2-1/2 3 0 2 0 5 5 3 22 5 4 0 0 2 2 1
Then Fisher test:
b <- subset(a,a[,5] != a[,6])
b <- subset(b,abs(b[,5]-b[,6])>1)
b <- subset(b,b[,3] != "1/2-1/2")
b <- cbind(b,white_rested = b[,5] < b[,6])
b
## W B result round cncmp_white cncmp_black white_rested
## 24 Keres Benko 1-0 6 3 5 TRUE
## 25 Fischer Keres 1-0 7 6 4 FALSE
## 30 Tal Petrosian 0-1 8 7 5 FALSE
## 31 Filip Keres 0-1 8 7 5 FALSE
## 34 Fischer Geller 0-1 9 8 6 FALSE
## 41 Filip Geller 0-1 11 10 7 FALSE
## 50 Fischer Petrosian 0-1 13 12 8 FALSE
## 51 Tal Geller 0-1 13 12 8 FALSE
## 52 Benko Keres 0-1 13 12 8 FALSE
## 56 Petrosian Filip 1-0 14 9 13 TRUE
## 58 Korchnoi Geller 0-1 15 14 10 FALSE
## 60 Keres Filip 1-0 15 10 14 TRUE
## 61 Tal Keres 0-1 16 15 11 FALSE
## 62 Korchnoi Petrosian 0-1 16 15 11 FALSE
## 68 Keres Korchnoi 1-0 17 12 16 TRUE
## 69 Geller Filip 1-0 18 12 17 TRUE
## 75 Benko Petrosian 0-1 19 18 12 FALSE
## 79 Geller Tal 1-0 20 13 19 TRUE
## 80 Keres Benko 1-0 20 13 19 TRUE
## 81 Fischer Keres 0-1 21 20 14 FALSE
## 84 Filip Petrosian 0-1 21 20 14 FALSE
## 88 Petrosian Korchnoi 1-0 23 15 22 TRUE
## 89 Fischer Geller 1-0 23 22 16 FALSE
## 102 Benko Keres 1-0 27 25 17 FALSE
## 104 Geller Benko 1-0 28 18 26 TRUE
M <- table(b[,3],white_rested=b[,7])
M
## white_rested
## FALSE TRUE
## 0-1 13 0
## 1-0 3 9
fisher.test(M,alternative="greater")
##
## Fisher's Exact Test for Count Data
##
## data: M
## p-value = 0.00011
## alternative hypothesis: true odds ratio is greater than 1
## 95 percent confidence interval:
## 6.222 Inf
## sample estimates:
## odds ratio
## Inf
Highly signficant.
Now create a hyper2 object with appropriate reified monsters:
problem <- function(...){stop("must be a white win or a black win or a draw")}
H <- hyper2(pnames=c(players,"white","draw","rest"))
for(i in seq_len(nrow(a))){
white_player <- a[i,1]
black_player <- a[i,2]
collusive <- (white_player %in% collusive_players) & (black_player %in% collusive_players)
if(collusive){
drawmonster <- "draw"
} else {
drawmonster <- "draw"
}
white_player_rested <- a[i,6] - a[i,5] > 1
black_player_rested <- a[i,5] - a[i,6] > 1
result <- a[i,3]
if(white_player_rested){
if( result == "1-0"){
H[c(white_player, "white","rest" )] %<>% inc
} else if(result == "0-1"){
H[c( black_player )] %<>% inc
} else if(result == "1/2-1/2"){
H[c( drawmonster)] %<>% inc
} else { problem() }
H[c(white_player,black_player,"white","rest",drawmonster)] %<>% dec
} else if(black_player_rested){
if( result == "1-0"){
H[c(white_player, "white" )] %<>% inc
} else if(result == "0-1"){
H[c( black_player, "rest" )] %<>% inc
} else if(result == "1/2-1/2"){
H[c( drawmonster)] %<>% inc
} else { problem() }
H[c(white_player,black_player,"white","rest",drawmonster)] %<>% dec
} else { # neither player rested, rest monster inactive
if( result == "1-0"){
H[c(white_player, "white" )] %<>% inc
} else if(result == "0-1"){
H[c( black_player )] %<>% inc
} else if(result == "1/2-1/2"){
H[c( drawmonster)] %<>% inc
} else { problem() }
H[c(white_player,black_player,"white", drawmonster)] %<>% dec
}
}
H
## log( Benko * (Benko + Filip + draw + white)^-4 * (Benko + Fischer +
## draw + white)^-4 * (Benko + Geller + draw + rest + white)^-4 * (Benko +
## Keres + draw + rest + white)^-4 * (Benko + Korchnoi + draw + white)^-4
## * (Benko + Petrosian + draw + rest + white)^-4 * (Benko + Tal + draw +
## white)^-3 * (Benko + white)^5 * Filip * (Filip + Fischer + draw +
## white)^-4 * (Filip + Geller + draw + rest + white)^-3 * (Filip + Geller
## + draw + white)^-1 * (Filip + Keres + draw + rest + white)^-3 * (Filip
## + Keres + draw + white)^-1 * (Filip + Korchnoi + draw + white)^-4 *
## (Filip + Petrosian + draw + rest + white)^-4 * (Filip + Tal + draw +
## white)^-3 * (Filip + white) * Fischer * (Fischer + Geller + draw + rest
## + white)^-3 * (Fischer + Geller + draw + white)^-1 * (Fischer + Keres +
## draw + rest + white)^-4 * (Fischer + Korchnoi + draw + white)^-4 *
## (Fischer + Petrosian + draw + rest + white)^-4 * (Fischer + Tal + draw
## + white)^-3 * (Fischer + white)^7 * (Geller + Keres + draw + white)^-4
## * (Geller + Korchnoi + draw + rest + white)^-3 * (Geller + Korchnoi +
## draw + white)^-1 * (Geller + Petrosian + draw + white)^-4 * (Geller +
## Tal + draw + rest + white)^-3 * (Geller + rest)^4 * (Geller + rest +
## white)^3 * (Geller + white) * Keres * (Keres + Korchnoi + draw + rest +
## white)^-3 * (Keres + Korchnoi + draw + white)^-1 * (Keres + Petrosian +
## draw + white)^-4 * (Keres + Tal + draw + rest + white)^-2 * (Keres +
## Tal + draw + white)^-1 * (Keres + rest)^4 * (Keres + rest + white)^4 *
## Korchnoi^5 * (Korchnoi + Petrosian + draw + rest + white)^-3 *
## (Korchnoi + Petrosian + draw + white)^-1 * (Korchnoi + Tal + draw +
## white)^-3 * (Korchnoi + white)^2 * (Petrosian + Tal + draw + rest +
## white)^-2 * (Petrosian + Tal + draw + white)^-1 * (Petrosian + rest)^5
## * (Petrosian + rest + white)^2 * (Petrosian + white) * Tal^2 * (Tal +
## white) * draw^54)
summary(H)
## A hyper2 object of size 11.
## pnames: Petrosian Keres Geller Fischer Korchnoi Benko Tal Filip white draw rest
## Number of brackets: 56
## Sum of powers: 0
##
## Table of bracket lengths:
## 1 2 3 4 5
## 7 10 3 21 15
##
## Table of powers:
## -4 -3 -2 -1 1 2 3 4 5 7 54
## 15 11 2 8 8 3 1 3 3 1 1
mH <- maxp(H)
mH
## Petrosian Keres Geller Fischer Korchnoi Benko Tal
## 1.4589e-06 3.0603e-02 1.0342e-06 1.3502e-01 1.2654e-01 9.0446e-02 5.7880e-02
## Filip white draw rest
## 2.3301e-02 3.0598e-02 2.4399e-01 2.6162e-01
pie(mH)
Now a hypothesis test
specificp.gt.test(H,"rest",0)
##
## Constrained support maximization
##
## data: H
## null hypothesis: sum p_i=1, rest <= 0 (notional)
## null estimate:
## Petrosian Keres Geller Fischer Korchnoi Benko Tal
## 1.1964e-01 1.4987e-01 1.2279e-01 1.7566e-01 9.3549e-02 1.0895e-01 7.6281e-02
## Filip white draw rest
## 3.7118e-02 2.1287e-03 1.1400e-01 9.9997e-06
## (argmax, constrained optimization)
## Support for null: -110.84 + K
##
## alternative hypothesis: sum p_i=1
## alternative estimate:
## Petrosian Keres Geller Fischer Korchnoi Benko Tal
## 1.4589e-06 3.0603e-02 1.0342e-06 1.3502e-01 1.2654e-01 9.0446e-02 5.7880e-02
## Filip white draw rest
## 2.3301e-02 3.0598e-02 2.4399e-01 2.6162e-01
## (argmax, free optimization)
## Support for alternative: -96.676 + K
##
## degrees of freedom: 1
## support difference = 14.163
## p-value: 1.0247e-07 (one-sided)
specificp.gt.test(H,"draw",0)
##
## Constrained support maximization
##
## data: H
## null hypothesis: sum p_i=1, draw <= 0 (notional)
## null estimate:
## Petrosian Keres Geller Fischer Korchnoi Benko Tal
## 9.2626e-02 9.6422e-02 9.0492e-02 1.0239e-01 1.0796e-01 9.3799e-02 9.3990e-02
## Filip white draw rest
## 6.9649e-02 1.0979e-06 1.0000e-05 2.5266e-01
## (argmax, constrained optimization)
## Support for null: -578.21 + K
##
## alternative hypothesis: sum p_i=1
## alternative estimate:
## Petrosian Keres Geller Fischer Korchnoi Benko Tal
## 1.4589e-06 3.0603e-02 1.0342e-06 1.3502e-01 1.2654e-01 9.0446e-02 5.7880e-02
## Filip white draw rest
## 2.3301e-02 3.0598e-02 2.4399e-01 2.6162e-01
## (argmax, free optimization)
## Support for alternative: -96.676 + K
##
## degrees of freedom: 1
## support difference = 481.53
## p-value: 1.9143e-211 (one-sided)
specificp.gt.test(H,"white",0)
##
## Constrained support maximization
##
## data: H
## null hypothesis: sum p_i=1, white <= 0 (notional)
## null estimate:
## Petrosian Keres Geller Fischer Korchnoi Benko Tal
## 2.6870e-02 2.8619e-02 2.5928e-02 1.5030e-01 1.2017e-01 1.0610e-01 5.8616e-02
## Filip white draw rest
## 2.9354e-02 9.9950e-06 2.2352e-01 2.3051e-01
## (argmax, constrained optimization)
## Support for null: -97.152 + K
##
## alternative hypothesis: sum p_i=1
## alternative estimate:
## Petrosian Keres Geller Fischer Korchnoi Benko Tal
## 1.4589e-06 3.0603e-02 1.0342e-06 1.3502e-01 1.2654e-01 9.0446e-02 5.7880e-02
## Filip white draw rest
## 2.3301e-02 3.0598e-02 2.4399e-01 2.6162e-01
## (argmax, free optimization)
## Support for alternative: -96.676 + K
##
## degrees of freedom: 1
## support difference = 0.4758
## p-value: 0.32931 (one-sided)