RxTUDelft / RxJavaGames

10 games in RxJava + JavaFx
16 stars 5 forks source link

Tic tac toe #6

Closed rvanheest closed 10 years ago

rvanheest commented 10 years ago

TicTacToe for now is implemented as a multiplayer game (if we have time at the end of this period, we will probably implement an AI player) and was mainly created to explore how RxJava can handle the situation of an MVC architecture where the model has mutable state (i.e. programming with side effects). In the 'old days' people used the GoF Observer-Observable Pattern to let the model signal to its observers that it had changed. Since RxJava's Observables (which are quite different from the GoF's) are the new way to go, we have to figure out a way how to replace the 'old stuff'.

The main challenge here was to get the PublishSubject integrated into the model classes, since we cannot inherit from it (which after all makes a lot of sence) and also not use it as a field within the class, since this field is not initialized when we need it: at the time when the super-constructor is called. I therefore came up with the following:

public class A extends Observable<A> {

    private B b;
    private final PublishSubject<A> subject;

    public A(B b) {
        this(B b, PublishSubject.create());
    }

    private A(B b, PublishSubject<A> subject) {
        super(subscriber -> subject.subscribe(subscriber));
        this.b = b;
        this.subject = subject;
    }

    public void setB(B b) {
        this.b= b;

        this.subject.onNext(this);
    }

    //some other methods
}

This method of using the PublishSubject corresponds to the Rx Design Guidelines (item 5.10) although this reference was found a few days later than this solution.

Lars6 commented 10 years ago

@rvanheest I found a bug in the game. If you click on a non empty tile, the game switches turns. In this way, you can fill the board with only X's or only O's. You can also switch turns when the game has already finished in a draw. Maybe you can add a draw message, as you do when a player wins the game. This indicates that the game has finished.

For the restart and quit buttons, a mouse click observable is used. That's what I did as well, but in this game you can control the buttons with the keyboard too (by pressing the spacebar) but then it doesn't perform the action. You could disable the keyboard controls for the buttons, or maybe better, change the observable from a MouseEvent to an ActionEvent.

rvanheest commented 10 years ago

That's the kind of feedback one might expect from a software tester! Good job. All three comments were incorporated into the game in three separate commits. Hopefully this brings the game closer to finished!