knitr::opts_chunk$set(echo = TRUE)

This work extends that of curacao1962_threeplayers.R by including a rest monster.

library("hyper2")

a <- read.table("curacao1962_candidates.txt",header=FALSE)
colnames(a) <- c("W", "B", "result", "round")
head(a)

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
cumulative_collusive_games
cumulative_noncollusive_games

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)
tail(a)

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)
table(abs(diff))
cumsum(table(abs(diff)))

We can assess a null of no effect of fatigue:

table(a[,3],a[,5]-a[,6])

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

M <- table(b[,3],white_rested=b[,7])
M
fisher.test(M,alternative="greater")

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
summary(H)
mH <- maxp(H)
mH
pie(mH)

Now a hypothesis test

specificp.gt.test(H,"rest",0)
specificp.gt.test(H,"draw",0)
specificp.gt.test(H,"white",0)


RobinHankin/hyper2 documentation built on May 6, 2024, 4:25 p.m.