-
Notifications
You must be signed in to change notification settings - Fork 61
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add logic to handle EstablishedPeer messages
- Loading branch information
Showing
5 changed files
with
322 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
from collections import defaultdict | ||
|
||
|
||
class ConnectionMatrix: | ||
def __init__(self, established_peers: dict[int, set[int]]): | ||
self.established_peers = established_peers | ||
|
||
def get_unconnected_peer_ids(self) -> set[int]: | ||
unconnected_peer_ids: set[int] = set() | ||
|
||
# Group players by number of connected peers | ||
players_by_num_peers = defaultdict(list) | ||
for player_id, peer_ids in self.established_peers.items(): | ||
players_by_num_peers[len(peer_ids)].append((player_id, peer_ids)) | ||
|
||
# Mark players with least number of connections as unconnected if they | ||
# don't meet the connection threshold. Each time a player is marked as | ||
# 'unconnected', remaining players need 1 less connection to be | ||
# considered connected. | ||
connected_peers = dict(self.established_peers) | ||
for num_connected, peers in sorted(players_by_num_peers.items()): | ||
if num_connected < len(connected_peers) - 1: | ||
for player_id, peer_ids in peers: | ||
unconnected_peer_ids.add(player_id) | ||
del connected_peers[player_id] | ||
|
||
return unconnected_peer_ids |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,246 @@ | ||
from server.game_connection_matrix import ConnectionMatrix | ||
|
||
|
||
def test_all_connected(): | ||
# One by hand example | ||
matrix = ConnectionMatrix( | ||
established_peers={ | ||
0: {1, 2, 3}, | ||
1: {0, 2, 3}, | ||
2: {0, 1, 3}, | ||
3: {0, 1, 2}, | ||
}, | ||
) | ||
assert matrix.get_unconnected_peer_ids() == set() | ||
|
||
# Check every fully connected grid, including the empty grid | ||
for num_players in range(0, 16 + 1): | ||
matrix = ConnectionMatrix( | ||
established_peers={ | ||
player_id: { | ||
peer_id | ||
for peer_id in range(num_players) | ||
if peer_id != player_id | ||
} | ||
for player_id in range(num_players) | ||
}, | ||
) | ||
assert matrix.get_unconnected_peer_ids() == set() | ||
|
||
|
||
def test_1v1_not_connected(): | ||
matrix = ConnectionMatrix( | ||
established_peers={ | ||
0: set(), | ||
1: set(), | ||
}, | ||
) | ||
assert matrix.get_unconnected_peer_ids() == {0, 1} | ||
|
||
|
||
def test_2v2_one_player_not_connected(): | ||
# 0 is not connected to anyone | ||
matrix = ConnectionMatrix( | ||
established_peers={ | ||
0: set(), | ||
1: {2, 3}, | ||
2: {1, 3}, | ||
3: {1, 2}, | ||
}, | ||
) | ||
assert matrix.get_unconnected_peer_ids() == {0} | ||
|
||
|
||
def test_2v2_two_players_not_connected(): | ||
# 0 is not connected to anyone | ||
# 1 is not connected to anyone | ||
matrix = ConnectionMatrix( | ||
established_peers={ | ||
0: set(), | ||
1: set(), | ||
2: {3}, | ||
3: {2}, | ||
}, | ||
) | ||
assert matrix.get_unconnected_peer_ids() == {0, 1} | ||
|
||
|
||
def test_2v2_not_connected(): | ||
# Not possible for only 3 players to be completely disconnected in a 4 | ||
# player game. Either 1, 2, or all can be disconnected. | ||
matrix = ConnectionMatrix( | ||
established_peers={ | ||
0: set(), | ||
1: set(), | ||
2: set(), | ||
3: set(), | ||
}, | ||
) | ||
assert matrix.get_unconnected_peer_ids() == {0, 1, 2, 3} | ||
|
||
|
||
def test_2v2_one_pair_not_connected(): | ||
# 0 and 1 are not connected to each other | ||
matrix = ConnectionMatrix( | ||
established_peers={ | ||
0: {2, 3}, | ||
1: {2, 3}, | ||
2: {0, 1, 3}, | ||
3: {0, 1, 2}, | ||
}, | ||
) | ||
assert matrix.get_unconnected_peer_ids() == {0, 1} | ||
|
||
|
||
def test_2v2_two_pairs_not_connected(): | ||
# 0 and 1 are not connected to each other | ||
# 1 and 2 are not connected to each other | ||
matrix = ConnectionMatrix( | ||
established_peers={ | ||
0: {2, 3}, | ||
1: {3}, | ||
2: {0, 3}, | ||
3: {0, 1, 2}, | ||
}, | ||
) | ||
assert matrix.get_unconnected_peer_ids() == {1} | ||
|
||
|
||
def test_2v2_two_disjoint_pairs_not_connected(): | ||
# 0 and 1 are not connected to each other | ||
# 2 and 3 are not connected to each other | ||
matrix = ConnectionMatrix( | ||
established_peers={ | ||
0: {2, 3}, | ||
1: {2, 3}, | ||
2: {0, 1}, | ||
3: {0, 1}, | ||
}, | ||
) | ||
assert matrix.get_unconnected_peer_ids() == {0, 1, 2, 3} | ||
|
||
|
||
def test_2v2_three_pairs_not_connected(): | ||
# 0 and 1 are not connected to each other | ||
# 1 and 2 are not connected to each other | ||
# 2 and 3 are not connected to each other | ||
matrix = ConnectionMatrix( | ||
established_peers={ | ||
0: {2, 3}, | ||
1: {3}, | ||
2: {0}, | ||
3: {0, 1}, | ||
}, | ||
) | ||
assert matrix.get_unconnected_peer_ids() == {1, 2} | ||
|
||
|
||
def test_3v3_one_player_not_connected(): | ||
# 0 is not connected to anyone | ||
matrix = ConnectionMatrix( | ||
established_peers={ | ||
0: set(), | ||
1: {2, 3, 4, 5}, | ||
2: {1, 3, 4, 5}, | ||
3: {1, 2, 4, 5}, | ||
4: {1, 2, 3, 5}, | ||
5: {1, 2, 3, 4}, | ||
}, | ||
) | ||
assert matrix.get_unconnected_peer_ids() == {0} | ||
|
||
|
||
def test_3v3_two_players_not_connected(): | ||
# 0 is not connected to anyone | ||
# 1 is not connected to anyone | ||
matrix = ConnectionMatrix( | ||
established_peers={ | ||
0: set(), | ||
1: set(), | ||
2: {3, 4, 5}, | ||
3: {2, 4, 5}, | ||
4: {2, 3, 5}, | ||
5: {2, 3, 4}, | ||
}, | ||
) | ||
assert matrix.get_unconnected_peer_ids() == {0, 1} | ||
|
||
|
||
def test_3v3_three_players_not_connected(): | ||
# 0 is not connected to anyone | ||
# 1 is not connected to anyone | ||
# 2 is not connected to anyone | ||
matrix = ConnectionMatrix( | ||
established_peers={ | ||
0: set(), | ||
1: set(), | ||
2: set(), | ||
3: {4, 5}, | ||
4: {3, 5}, | ||
5: {3, 4}, | ||
}, | ||
) | ||
assert matrix.get_unconnected_peer_ids() == {0, 1, 2} | ||
|
||
|
||
def test_3v3_four_players_not_connected(): | ||
# 0 is not connected to anyone | ||
# 1 is not connected to anyone | ||
# 2 is not connected to anyone | ||
# 3 is not connected to anyone | ||
matrix = ConnectionMatrix( | ||
established_peers={ | ||
0: set(), | ||
1: set(), | ||
2: set(), | ||
3: set(), | ||
4: {5}, | ||
5: {4}, | ||
}, | ||
) | ||
assert matrix.get_unconnected_peer_ids() == {0, 1, 2, 3} | ||
|
||
|
||
def test_3v3_not_connected(): | ||
matrix = ConnectionMatrix( | ||
established_peers={ | ||
0: set(), | ||
1: set(), | ||
2: set(), | ||
3: set(), | ||
4: set(), | ||
5: set(), | ||
}, | ||
) | ||
assert matrix.get_unconnected_peer_ids() == {0, 1, 2, 3, 4, 5} | ||
|
||
|
||
def test_3v3_one_pair_not_connected(): | ||
# 0 and 1 are not connected to each other | ||
matrix = ConnectionMatrix( | ||
established_peers={ | ||
0: {2, 3, 4, 5}, | ||
1: {2, 3, 4, 5}, | ||
2: {0, 1, 3, 4, 5}, | ||
3: {0, 1, 2, 4, 5}, | ||
4: {0, 1, 2, 3, 5}, | ||
5: {0, 1, 2, 3, 4}, | ||
}, | ||
) | ||
assert matrix.get_unconnected_peer_ids() == {0, 1} | ||
|
||
|
||
def test_3v3_one_player_and_one_pair_not_connected(): | ||
# 0 is not connected to anyone | ||
# 1 and 2 are not connected to each other | ||
matrix = ConnectionMatrix( | ||
established_peers={ | ||
0: set(), | ||
1: {3, 4, 5}, | ||
2: {3, 4, 5}, | ||
3: {1, 2, 4, 5}, | ||
4: {1, 2, 3, 5}, | ||
5: {1, 2, 3, 4}, | ||
}, | ||
) | ||
assert matrix.get_unconnected_peer_ids() == {0, 1, 2} |