tags:

views:

130

answers:

5

I am going to develop a Tic-Tac-Toe game using Java(or maybe other OO Languages). Now I have a picture in my mind about the general design.

Interface: Player, then I will be able to implement a couple of Player classes based on how I want the opponent to be, for example, random player, intelligent player, etc.

Classes: Board class, with a two-dimensional array of integers, 0 indicates open, 1 indicates me, -1 indicates opponent. The evaluation function will be in here as well, to return the next best move based on the current board arrangement and whose turn it is.

Referee class, which will create instance of the Board and two player instances, then get the game started.

This is a rough idea of my OO design. Could anybody give me any critiques please? I find this is really beneficial. Thank you very much.

+1  A: 

I would say that having using me and opponent for player moves isn't quite right. It should be either Xs and Os or first and second player. Beyond that, you've got a start. Where is input going to be handled? Referee or in the board square or somewhere else? Also, how about stat tracking that exists beyond 1 game?

Just some ideas.

Michael Dorgan
Cheers,Michael.I decided to use Referee class to handle user input(two integers to represent their desired next move).I decided to have another class,which is Move class.The last point you mentioned refers to the multi-player situation,doesn't it?
Robert
Yep - check out @Greelmo's input as well. He spent quite a bit more time on this and his answer is well thought out.
Michael Dorgan
+6  A: 

When I think of object structure, I think of my methods as doing one of two things:

1) asking an 'object' a question

2) commanding the 'object' to do something

That being said, it doesn't make sense to me to ask the 'board' what the next best move is. The board should simply hold values and tell you about its state.

I would probably have an object that is dedicated to determining the best next move for a given 'intelligence'. Let's call it the 'move_brain'. Then you can say, "hey move_brain, given this board and this level of intelligence, what's the next best move?"

The board class as you have outlined it now has many responsibilities: holding state, allowing users to move, AND thinking about how to move next. That's too much responsibility.

And after all that, I would say this: given that this program is not THAT massive, pretty much any solution will be okay.

Best of luck!

DexterW
Cheers,Greelmo.Really nice way of thinking all these problems.I might have put too many things in one object.
Robert
No worries. Check out this book for some really great design ideas.http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882
DexterW
+1  A: 

A general idea should be to make objects as self contained and single minded as possible. This will let you design things faster and tighter.

Also, do not be afraid of modelling even the smallest piece as its own class entity. Interactions are a lot simpler if you can model everything from a high level directly from the start.

Patrick
thanks!!Does that mean make every possible object as a class of its own?
Robert
+1  A: 

For one you'll want to use some symbolic values such as enums or constants to represent the state of the slots in your board.

Longpoke
Thanks,using enums for the board pieces?
Robert
Actually now that you say that, it would be much better to make a class for pieces and stick instances of them in the board. For example, you could make a class called `Piece`, and give it an attribute `Team`, and set that to represent the team of the piece. The board would just be a 2d array of `Piece`.
Longpoke
A: 

I'd define 3 interfaces:

  • Game interface
  • IPlayer interface
  • Board interface

Here's a quick sketch of what would each class have:

Game:

  • players (only could hold 2 players)
  • board (this could be other class or just a 2d matrix)
  • start();
  • nextTurn();
  • restart();
  • isEnded();

IPlayer:

  • onTurn() (this is the event that tells you its your turn to play)
  • play(int x, int y);
  • onWin() (this event tells you you won)
  • onLose() (you lost)
  • onTie(); (you tied)

You could run the code like the following:

IPlayer meAsAPlayer = new UserPlayer(); //you'd have to implement this
                                        //as an "empty" class that would let the user
                                        //specify the actions
IPlayer AIPlayer = new AIPlayer(); //one AI class you'd have implemented
Game game = new Game(meAsAPlayer, AIPlayer);
game.start(); //this would run one game to the end
game.start(); //this would be the second game already

It would be the Game class that'd decide which plays would be correct and which wouldn't.If a player tried to make an incorrect play, it'd block it and it'd call again that player's OnTurn() event.

That or instead of defining the IPlayer interface you could define an APlayer abstract class that'd only let you make correct movements.

devoured elysium