I think that you could use local search for this, but let me give you a mathematical construction.
Divide the 16 teams into 8 A teams and 8 B teams. Each A team will play all but 2 B teams. Each B team will play all but 2 A teams.
This construction requires two mutually orthogonal 8x8 Latin squares, e.g.,
abcdehfg
badchegf
cdabgfhe
dcbafgeh
ehgfabdc
hefgbacd
fghedcab
gfehcdba
abcdefgh
cdabhgfe
efhgabdc
hgefcdba
dcbaghef
badcfehg
feghbacd
ghfedcab
Index the rows by A teams and the columns by B teams. The entries of the first Latin square specify the activity in which an A team will compete against a B team. Two of the letters are treated as rest. By the properties of Latin squares, each team completes each activity exactly once (and rests twice).
The entries of the second Latin square indicate when an A team competes against a B team (or both rest). By the properties of Latin squares, each team does one thing in each round. By the properties of mutually orthogonal Latin squares, each activity occurs exactly once in each round.
In Python 3:
import string
def latin8a(i, j):
return i ^ j
def latin8b(i, j):
b = i >> 2
return (i << 1) ^ (b << 3 | b << 1 | b) ^ j
a_teams = string.ascii_uppercase[:8]
b_teams = string.ascii_uppercase[8:16]
for i in range(8):
print()
print('Round', i + 1)
for j in range(6):
print(a_teams[latin8a(i, j)], 'vs', b_teams[latin8b(i, j)],
'in game type', string.ascii_lowercase[j])
Output:
Round 1
A vs I in game type a
B vs J in game type b
C vs K in game type c
D vs L in game type d
E vs M in game type e
F vs N in game type f
Round 2
B vs K in game type a
A vs L in game type b
D vs I in game type c
C vs J in game type d
F vs O in game type e
E vs P in game type f
Round 3
C vs M in game type a
D vs N in game type b
A vs O in game type c
B vs P in game type d
G vs I in game type e
H vs J in game type f
Round 4
D vs O in game type a
C vs P in game type b
B vs M in game type c
A vs N in game type d
H vs K in game type e
G vs L in game type f
Round 5
E vs L in game type a
F vs K in game type b
G vs J in game type c
H vs I in game type d
A vs P in game type e
B vs O in game type f
Round 6
F vs J in game type a
E vs I in game type b
H vs L in game type c
G vs K in game type d
B vs N in game type e
A vs M in game type f
Round 7
G vs P in game type a
H vs O in game type b
E vs N in game type c
F vs M in game type d
C vs L in game type e
D vs K in game type f
Round 8
H vs N in game type a
G vs M in game type b
F vs P in game type c
E vs O in game type d
D vs J in game type e
C vs I in game type f