I’m currently teaching myself objective C. I’ve gone through the tutorials, but I find I learn best when slogging through a project of my own, so I’ve embarked on making a backgammon app.
Now that I’m partway in, I’m realizing there’s some overall architecture things I just don’t understand.
I’ve established a “player” class, a “piece” class, and a “board” class. A piece theoretically belongs to both a player and the board. For instance, a player has a color, and every turn makes a move; so the player owns his pieces. At the same time, when moving a piece, it has to check whether it’s a valid move, whether there are pieces on the board, etc.
From my reading it seems like it’s frowned upon to reach across classes. For instance, when a player makes a move, where should the function live that moves the piece? Should it exist on board? This would be my instinct, as the board should decide whether a move is valid or not; but the piece needs to initialize that query, as its the one being moved, no?
Any info to help a noob would be super appreciated. Thanks guys!
I think you’re probably over engineering your class hierarchy. A good rule of thumb is to start with a handful of classes whose functionality do not overlap, and then refactor your overall design, on demand, as you expand on your program.
A class to model each player may not be necessary at all. I would start by just having a board class manage the “state” of the backgammon game — namely whose turn it is, if the dice have been rolled, the dice roll if necessary, the state of all 24 points + bar + “off” for each player, the state of the doubling cube, the current match length and the current score for each player. (I wrote my MSc thesis on backgammon, including a command line shell program to play games, so I understand the domain here fairly well.)
@Mark Bessey I would certainly not have a design where the piece (checker) knows how to move itself.
@Felixyz Determining a legal move is actually a little more difficult in backgammon than it is in chess. This is especially true if you want to generate the complete list of legal moves on any given turn.