mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-11-13 13:30:00 -08:00
[Server] Keep player ids stable across seat shuffles
This commit is contained in:
parent
cc9847c33b
commit
00c0b2c96b
3 changed files with 129 additions and 74 deletions
|
|
@ -1,4 +1,5 @@
|
|||
#include "game/game_config.h"
|
||||
#include "game/role_info.h"
|
||||
#include "game/server_abstract_participant.h"
|
||||
#include "game/server_game.h"
|
||||
#include "server_abstractuserinterface.h"
|
||||
|
|
@ -70,19 +71,18 @@ namespace
|
|||
QStringList participantNamesInOrder(const Server_Game &game)
|
||||
{
|
||||
QStringList names;
|
||||
for (const auto *participant : game.getParticipants()) {
|
||||
names.append(QString::fromStdString(participant->getUserInfo()->name()));
|
||||
for (int id : game.getSeatOrder()) {
|
||||
const auto *participant = game.getParticipants().value(id, nullptr);
|
||||
if (participant) {
|
||||
names.append(QString::fromStdString(participant->getUserInfo()->name()));
|
||||
}
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
QList<int> participantIdsInOrder(const Server_Game &game)
|
||||
{
|
||||
QList<int> ids;
|
||||
for (int id : game.getParticipants().keys()) {
|
||||
ids.append(id);
|
||||
}
|
||||
return ids;
|
||||
return game.getSeatOrder();
|
||||
}
|
||||
} // namespace
|
||||
|
||||
|
|
@ -129,9 +129,9 @@ TEST_F(PlayerOrderTest, JoinOrderIsSeatOrder)
|
|||
Server_Game game(config, &room);
|
||||
ResponseContainer rc(0);
|
||||
|
||||
game.addPlayer(&uiA, rc, false, false);
|
||||
game.addPlayer(&uiB, rc, false, false);
|
||||
game.addPlayer(&uiC, rc, false, false);
|
||||
game.addPlayer(&uiA, rc, RoleInfo{}, false);
|
||||
game.addPlayer(&uiB, rc, RoleInfo{}, false);
|
||||
game.addPlayer(&uiC, rc, RoleInfo{}, false);
|
||||
|
||||
EXPECT_EQ(participantNamesInOrder(game), QStringList({"A", "B", "C"}));
|
||||
EXPECT_EQ(participantIdsInOrder(game), QList<int>({0, 1, 2}));
|
||||
|
|
@ -164,27 +164,25 @@ TEST_F(PlayerOrderTest, ReorderPlayerSeats)
|
|||
Server_Game game(config, &room);
|
||||
ResponseContainer rc(0);
|
||||
|
||||
game.addPlayer(&uiA, rc, false, false);
|
||||
game.addPlayer(&uiB, rc, false, false);
|
||||
game.addPlayer(&uiC, rc, false, false);
|
||||
game.addPlayer(&uiA, rc, RoleInfo{}, false);
|
||||
game.addPlayer(&uiB, rc, RoleInfo{}, false);
|
||||
game.addPlayer(&uiC, rc, RoleInfo{}, false);
|
||||
|
||||
game.reorderPlayerSeats({"C", "A", "B"});
|
||||
|
||||
const QList<int> ids = participantIdsInOrder(game);
|
||||
// player ids are stable; only the seat order changes
|
||||
EXPECT_EQ(participantNamesInOrder(game), QStringList({"C", "A", "B"}));
|
||||
EXPECT_EQ(ids.size(), 3);
|
||||
EXPECT_GE(ids.at(0), 3); // re-seated players get fresh ids
|
||||
EXPECT_LT(ids.at(0), ids.at(1));
|
||||
EXPECT_LT(ids.at(1), ids.at(2));
|
||||
EXPECT_EQ(participantIdsInOrder(game), QList<int>({2, 0, 1}));
|
||||
EXPECT_EQ(game.getParticipants().size(), 3);
|
||||
|
||||
// the host seat follows the creator
|
||||
EXPECT_EQ(game.getHostId(), ids.at(1));
|
||||
// the host keeps its seat: creator A is still in the game, so host stays 0
|
||||
EXPECT_EQ(game.getHostId(), 0);
|
||||
|
||||
// every user interface's game list is updated to the new player id
|
||||
// no re-keying means every mapping keyed by player id stays valid
|
||||
const int gameId = game.getGameId();
|
||||
EXPECT_EQ(uiA.getGames().value(gameId).second, ids.at(1));
|
||||
EXPECT_EQ(uiB.getGames().value(gameId).second, ids.at(2));
|
||||
EXPECT_EQ(uiC.getGames().value(gameId).second, ids.at(0));
|
||||
EXPECT_EQ(uiA.getGames().value(gameId).second, 0);
|
||||
EXPECT_EQ(uiB.getGames().value(gameId).second, 1);
|
||||
EXPECT_EQ(uiC.getGames().value(gameId).second, 2);
|
||||
}
|
||||
|
||||
TEST_F(PlayerOrderTest, ReorderPlayerSeatsKeepsPlayerCount)
|
||||
|
|
@ -212,16 +210,17 @@ TEST_F(PlayerOrderTest, ReorderPlayerSeatsKeepsPlayerCount)
|
|||
Server_Game game(config, &room);
|
||||
ResponseContainer rc(0);
|
||||
|
||||
game.addPlayer(&uiA, rc, false, false);
|
||||
game.addPlayer(&uiB, rc, false, false);
|
||||
game.addPlayer(&uiC, rc, false, false);
|
||||
game.addPlayer(&uiA, rc, RoleInfo{}, false);
|
||||
game.addPlayer(&uiB, rc, RoleInfo{}, false);
|
||||
game.addPlayer(&uiC, rc, RoleInfo{}, false);
|
||||
|
||||
// listing only a subset appends the remaining players in their current order
|
||||
game.reorderPlayerSeats({"C"});
|
||||
|
||||
EXPECT_EQ(participantNamesInOrder(game), QStringList({"C", "A", "B"}));
|
||||
EXPECT_EQ(participantIdsInOrder(game), QList<int>({2, 0, 1}));
|
||||
EXPECT_EQ(game.getPlayerCount(), 3);
|
||||
EXPECT_EQ(game.getHostId(), participantIdsInOrder(game).at(1));
|
||||
EXPECT_EQ(game.getHostId(), 0);
|
||||
}
|
||||
|
||||
TEST_F(PlayerOrderTest, ShufflePlayerSeatsIsAPermutation)
|
||||
|
|
@ -249,9 +248,9 @@ TEST_F(PlayerOrderTest, ShufflePlayerSeatsIsAPermutation)
|
|||
Server_Game game(config, &room);
|
||||
ResponseContainer rc(0);
|
||||
|
||||
game.addPlayer(&uiA, rc, false, false);
|
||||
game.addPlayer(&uiB, rc, false, false);
|
||||
game.addPlayer(&uiC, rc, false, false);
|
||||
game.addPlayer(&uiA, rc, RoleInfo{}, false);
|
||||
game.addPlayer(&uiB, rc, RoleInfo{}, false);
|
||||
game.addPlayer(&uiC, rc, RoleInfo{}, false);
|
||||
|
||||
// fisher-yates on [A, B, C]: rand(0, 2) -> 1 (take B), rand(0, 1) -> 0 (take A), rand(0, 0) -> 0 (take C)
|
||||
auto *scriptedRng = new ScriptedRng;
|
||||
|
|
@ -261,9 +260,9 @@ TEST_F(PlayerOrderTest, ShufflePlayerSeatsIsAPermutation)
|
|||
game.shufflePlayerSeats();
|
||||
|
||||
EXPECT_EQ(participantNamesInOrder(game), QStringList({"B", "A", "C"}));
|
||||
const QList<int> ids = participantIdsInOrder(game);
|
||||
EXPECT_EQ(ids.size(), 3);
|
||||
QSet<int> idSet(ids.cbegin(), ids.cend());
|
||||
EXPECT_EQ(participantIdsInOrder(game), QList<int>({1, 0, 2}));
|
||||
QSet<int> idSet(participantIdsInOrder(game).cbegin(), participantIdsInOrder(game).cend());
|
||||
EXPECT_EQ(idSet.size(), 3); // ids are unique
|
||||
EXPECT_EQ(game.getHostId(), ids.at(1));
|
||||
// ids are stable, so the host (creator A, id 0) is unchanged
|
||||
EXPECT_EQ(game.getHostId(), 0);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue