For turn based games like board games, I make clients that don't have any concept of the game rules at all. The server generates a complete list of all available actions to the player and sends an array of all actions along with the game state. When you take an action the only payload the client sends is the index into this array. In this way the client has no way to express a cheat whatsoever.
There can (and must) be compromises between the cost of enumerating moves in messages from the server and the cost of validating client commands; command validation should be straightforward enough to be obviously correct and complete (leaving no room for cheating) and sufficiently cheap, not trivially simple.
For example, if the client in a wargame says it would like to move a unit (by name) from place A to place B on the battlefield the possible moves are implicit (units and locations are known) and validation is nontrivial but easy (the unit is at A and it can move, it can reach B considering fog of war, etc.). Far cheaper than sending 50 different moves for each of 50 different units and validating all of them preemptively every turn.
Indeed it isn't a general solution, it's just really good for almost all board games.
Your example is one that it's not the best for and you could use a different approach or amend the approach to take a payload for some actions and have some client smarts for those actions.
Although even in your example of 50 units with 50 moves each, having 2500 moves is certainly not a disaster in a game where the server only does work in response to a player's move and players don't take multiple moves per second and more likely take seconds or even minutes between moves.
You don't need to be so literal. An action like "game action XYZ" with a client smart enough to know how to show a text field and enable submission is sufficient.
The point is just every bit of logic about when an action is enabled must be implemented on the backend for verification, so spelling that out to the client reduces duplication.
In that case you would probably add a payload which you would then have to check, you're correct. It just turns out you can implement most board games without that.
I do still like this system for some games with actions that aren't convenient to enumerate; it's safe and simple by default and you add validation only in exactly the places where you need a payload.
English words are enumerable. There’s just a few million of them. The dictionary is large, but it’s not like it changes frequently, so you can treat it like a static asset that gets downloaded once and only updated periodically out of band.
The specific example may be faulty but the general point absolutely is not. I've built turn based games where enumerating the space of actions grew at a x b x c and would have easily measured in the megabytes.
It's just not a practical general solution, but it sure works fine for something like Monopoly.