Let's suppose there is a game. There is a map class and a player class. Map stores fields and fields stores players. Which would be a proper way to do in OOP. When method responsible for player walking would be Player::walk or Map::playerWalk?
Concerning first example (Player::walk), it seems that it is correct way to do and its like in real life - its player who walks, however it would have to access destination field through map instance, check if it can walk there, remove its from start field and add its on destination field, I have impression that Player would "know too much".
Ultimately this is a design question, both could fit well within the OOP paradigm.
I tend to place methods on the class that makes the most sense semantically. In this scenario, that means Player::walk
, unless the map does something to make "players" move (I.e. in a flippers game, the game board makes the ball [aka 'player'] move) and then it may be more semantic to have that entity call for instance Board::movePlayer
.
You should pass the map instance to the player if you go for the Player::walk
design. So you end up with Player::walk(Map &map /*more parameters here, maybe a direction or vector speed?*/)
.
The other thing to point out is that you should try to tell more than you ask. What this means is that rather than:
//in Player::walk
if (map.cells[wantToWalkTo] == 0) {
map.cells[wantToWalkTo] = this.playerId;
}
//TODO: handle failed moves
You should do something like:
bool moved = map.moveTo(position, this); //encapsulate the logic for moving a player to a position
//TODO: handle failed moves