Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Correct way in OOP. Game example. Player::walk or Map::playerWalk?

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".

like image 736
test201411 Avatar asked Sep 29 '22 11:09

test201411


2 Answers

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
like image 196
AlexanderBrevig Avatar answered Oct 07 '22 20:10

AlexanderBrevig


Your player instance doesn't have to "know" all those things. It can communicate with the Map instance through an interface. A person can look out at their surroundings and see some things, but not others (e.g. can see a wall, but not what's behind it). The Map instance can be in control of what is visible and what isn't.

Python-ish pseudo-code:

class Player:
    def __init__(self, Map, location):
        """Create a player, and tell them what Map they live on."""
        self.Map = Map
        self.location = location

    def walk(self, destination):
        """Try to walk to the destination."""
        path = self.Map.path_visible(location, destination)

        if path:
            self.location = destination

class Map:
    def path_visible(self, location, destination):
        """Can a player at location see how to get to the destination?"""
like image 36
Chris Avatar answered Oct 07 '22 20:10

Chris