From 30da4dc7fd2a4789e2444eeac7e1b9e476db69e2 Mon Sep 17 00:00:00 2001 From: Theodore Turocy Date: Mon, 17 Nov 2025 13:24:40 +0000 Subject: [PATCH] Fix regression in GUI not properly numbering actions at a new information set. Due to a previous refactoring the GUI was not generating distinct labels at new information sets created by drag-and-drop of the player icon. Instead, the label "1" was assigned to all actions. This restores the correct behaviour. Internally, the action generation option has been refactored to be part of the game operation itself, in anticipation of future developments on the rules on action labels. Closes #618. --- ChangeLog | 2 ++ src/games/game.h | 6 ++++-- src/games/gametree.cc | 14 ++++++++++++-- src/games/gametree.h | 6 ++++-- src/gui/gamedoc.cc | 5 +---- 5 files changed, 23 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9c7b10cc2..5af871f2d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7,6 +7,8 @@ when changing the number of strategies in the game (#571) - Fixed improper shared pointer handling when writing a .nfg file based on a game in extensive form. +- Fixed a regression in the GUI in which unique action labels were not being generated when + adding a move via drag-and-drop of a player icon (#618) ## [16.3.2] - unreleased diff --git a/src/games/game.h b/src/games/game.h index 529dbc507..112b68d38 100644 --- a/src/games/game.h +++ b/src/games/game.h @@ -743,7 +743,8 @@ class GameRep : public std::enable_shared_from_this { { throw UndefinedException(); } - virtual GameInfoset AppendMove(GameNode p_node, GamePlayer p_player, int p_actions) + virtual GameInfoset AppendMove(GameNode p_node, GamePlayer p_player, int p_actions, + bool p_generateLabels = false) { throw UndefinedException(); } @@ -751,7 +752,8 @@ class GameRep : public std::enable_shared_from_this { { throw UndefinedException(); } - virtual GameInfoset InsertMove(GameNode p_node, GamePlayer p_player, int p_actions) + virtual GameInfoset InsertMove(GameNode p_node, GamePlayer p_player, int p_actions, + bool p_generateLabels = false) { throw UndefinedException(); } diff --git a/src/games/gametree.cc b/src/games/gametree.cc index de0c008a2..4fbebf5c5 100644 --- a/src/games/gametree.cc +++ b/src/games/gametree.cc @@ -569,7 +569,8 @@ GameInfoset GameTreeRep::LeaveInfoset(GameNode p_node) return node->m_infoset->shared_from_this(); } -GameInfoset GameTreeRep::AppendMove(GameNode p_node, GamePlayer p_player, int p_actions) +GameInfoset GameTreeRep::AppendMove(GameNode p_node, GamePlayer p_player, int p_actions, + bool p_generateLabels) { GameNodeRep *node = p_node.get(); if (p_actions <= 0 || !node->m_children.empty()) { @@ -583,6 +584,10 @@ GameInfoset GameTreeRep::AppendMove(GameNode p_node, GamePlayer p_player, int p_ auto newInfoset = std::make_shared(this, p_player->m_infosets.size() + 1, p_player.get(), p_actions); p_player->m_infosets.push_back(newInfoset); + if (p_generateLabels) { + std::for_each(newInfoset->m_actions.begin(), newInfoset->m_actions.end(), + [act = 1](const GameAction &a) mutable { a->SetLabel(std::to_string(act++)); }); + } return AppendMove(p_node, newInfoset); } @@ -609,7 +614,8 @@ GameInfoset GameTreeRep::AppendMove(GameNode p_node, GameInfoset p_infoset) return node->m_infoset->shared_from_this(); } -GameInfoset GameTreeRep::InsertMove(GameNode p_node, GamePlayer p_player, int p_actions) +GameInfoset GameTreeRep::InsertMove(GameNode p_node, GamePlayer p_player, int p_actions, + bool p_generateLabels) { if (p_actions <= 0) { throw UndefinedException(); @@ -622,6 +628,10 @@ GameInfoset GameTreeRep::InsertMove(GameNode p_node, GamePlayer p_player, int p_ auto newInfoset = std::make_shared(this, p_player->m_infosets.size() + 1, p_player.get(), p_actions); p_player->m_infosets.push_back(newInfoset); + if (p_generateLabels) { + std::for_each(newInfoset->m_actions.begin(), newInfoset->m_actions.end(), + [act = 1](const GameAction &a) mutable { a->SetLabel(std::to_string(act++)); }); + } return InsertMove(p_node, newInfoset); } diff --git a/src/games/gametree.h b/src/games/gametree.h index 085cd557b..8695bb3f3 100644 --- a/src/games/gametree.h +++ b/src/games/gametree.h @@ -120,9 +120,11 @@ class GameTreeRep : public GameExplicitRep { /// @name Modification //@{ - GameInfoset AppendMove(GameNode p_node, GamePlayer p_player, int p_actions) override; + GameInfoset AppendMove(GameNode p_node, GamePlayer p_player, int p_actions, + bool p_generateLabels = false) override; GameInfoset AppendMove(GameNode p_node, GameInfoset p_infoset) override; - GameInfoset InsertMove(GameNode p_node, GamePlayer p_player, int p_actions) override; + GameInfoset InsertMove(GameNode p_node, GamePlayer p_player, int p_actions, + bool p_generateLabels = false) override; GameInfoset InsertMove(GameNode p_node, GameInfoset p_infoset) override; void CopyTree(GameNode dest, GameNode src) override; void MoveTree(GameNode dest, GameNode src) override; diff --git a/src/gui/gamedoc.cc b/src/gui/gamedoc.cc index 326e5f0b9..2b17fa9fe 100644 --- a/src/gui/gamedoc.cc +++ b/src/gui/gamedoc.cc @@ -639,10 +639,7 @@ void gbtGameDocument::DoAppendMove(GameNode p_node, GameInfoset p_infoset) void gbtGameDocument::DoInsertMove(GameNode p_node, GamePlayer p_player, unsigned int p_actions) { - const GameInfoset infoset = m_game->InsertMove(p_node, p_player, p_actions); - auto actions = infoset->GetActions(); - std::for_each(actions.begin(), actions.end(), - [act = 1](const GameAction &a) mutable { a->SetLabel(std::to_string(act)); }); + m_game->InsertMove(p_node, p_player, p_actions, true); m_game->SortInfosets(); UpdateViews(GBT_DOC_MODIFIED_GAME); }