Calculate all the scenarios for a football group with 1 game played

Is there any function or way to calculate all the results (W/D/L) of the football matches for a group?

For example, I have this group with A vs D and B vs C being played:

 team  points
  <chr>  <dbl>
  A          4
  B          1
  C          1
  D          0

In the 2nd match play A vs B and C vs D and in the 3rd match play A vs C and B vs D.

I would like to know how to calculate what are all the possibilities of scenarios after the 2 remaining matches are played and in how many D is between the first 2?

[a win gives you 3 points, a draw 1 points and a loss 0 points].

Here is the solution I came up with.
You said , Team A played D and won; winning gets 3 points; so I ignored the 4 in your example table, as by your words it should be 3.

I calculated 81 possible timelines from the given starting point; of which D would be in the top 2 positions in 32 cases.

library(tidyverse)

(matches <- tibble(as.data.frame(t(combn(LETTERS[1:4],2)))))

(point_pos <- tibble(p1 = c(3,1,0), p2 =c(0,1,3)))

(possibility_groups <- crossing(matches,point_pos) |> 
    mutate(group=paste0(V1,V2)) |> split(f=~group))

# how many rows to expect (unfiltered) ?
3^6  # 729

filtered_possibility_groups <- possibility_groups

#can comment out these next two rows to have no filtering applied
filtered_possibility_groups$AD <- filtered_possibility_groups$AD |> filter(p1==1)
filtered_possibility_groups$BC <- filtered_possibility_groups$BC |> filter(p1==1)

(all_messy <- reduce(filtered_possibility_groups,crossing,.name_repair="universal"))

(cleanup1 <- all_messy |> rename_with(~str_replace_all(.x,fixed('...'),"_")) |>
    mutate(possible_timeline = row_number()) |> 
    relocate(possible_timeline))

#timelines post any filtering
nrow(cleanup1)
# 81 in given example filtering


make_points_frame_from_row <- function(row){
  timeid <- row$possible_timeline
  row$possible_timeline <- NULL
  groups <- (ncol(row)) /5
  starts <- seq_len(groups)*5 - 4
  ends <- starts + 3
  starts_and_ends <- map2(starts,ends,~seq(from=.x,to=.y))
  
  
  stacked <- map_dfr(starts_and_ends,
                     ~select(row,.x) |> set_names(c("V1","V2","P1","P2")))
  smry <- bind_rows(stacked |> select(V=V1,P=P1) ,
                    stacked |> select(V=V2,P=P2)) |> 
    group_by(V) |> 
    summarise(P=sum(P,na.rm=TRUE)) |> arrange(desc(P))
  bind_cols(t_id = timeid,smry)
}

time_lines <- map(seq_len(nrow(cleanup1)),
    ~make_points_frame_from_row(cleanup1 |> slice(.x)))

# count the subset of timelines for which D is in top 2 
map_int(time_lines,~{
  head(.x,n=2) |> filter(V == 'D') |> nrow()
}) |> sum()
# 32 for given example  filter