Tic-tac-toe using a two-dimensional array

exercise No. 153

Q:

This exercise exclusively deals with the visualization and bookkeeping of two humans playing Tic-tac-toe against each other. For the sake of clarification: It is not about humans playing a computer. So you do not (yet) have to implement an algorithm finding a player's best possible moves. The following video shows the intended behaviour:

Figure 455. Two Tic-tac-toe players fighting each other.

Use a two-dimensional array to represent a game's state:

final char[][] board = new char[3][3];

Depending on your choice you may also use a class Player containing additional information like the player's name. In this case you'll probably need two instances representing both players and in turn a 3 x 3 array holding references to them:

final Player[][] board = new Player[3][3];

Discovering a win situation will be an essential part of this exercise. The following situations define a win state:

xxx
...
...
...
xxx
...
...
...
xxx
x..
x..
x..
.x.
.x.
.x.
..x
..x
..x
x..
.x.
..x
..x
.x.
x..

A:

Consider the following Maven project:

This implementation already uses a so called enum to be discussed later during an upcoming lecture:

public enum Player {

  PLAYER1("Jim", 'O'), PLAYER2("Eve", 'X');

  public final String nickname;
  public final char representation;

  Player(final String nickname, final char representation) {
    this.nickname = nickname;
    this.representation = representation;
  }

  public Player getOtherPlayer() {
    switch (this) {
      case PLAYER1:
        return PLAYER2;
      case PLAYER2:
        return PLAYER1;

      default:
            return null;
    }
  }

  @Override
  public String toString() {
    return "" + representation;
  }
}

A Java enum essentially is a specialized class. If you don't like this yet you may safely replace the given enum by the following class:

public class Player {

  final public static Player
    PLAYER1 = new Player ("Jim", 'O'),
    PLAYER2 = new Player("Eve", 'X');

    public final String nickname;
    public final char representation;

    Player(final String nickname, final char representation) {
      this.nickname = nickname;
      this.representation = representation;
    }

    public Player getOtherPlayer() {

      if (PLAYER1 == this) {
        return PLAYER2;
      } else if (PLAYER2 == this) {
        return PLAYER1;
      } else {
        return null;
      }
    }

    @Override
    public String toString() {
      return "" + representation;
    }
}

It is possible to wrap this solution into an executable Jar archive by adding:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-jar-plugin</artifactId>
  <version>2.6</version>
  <configuration>
    <archive>
      <manifest>
        <addClasspath>true</addClasspath>
        <!--  Class containing desired entry method public
               static void main(String[] args) -->
        <mainClass>de.hdm_stuttgart.mi.sd1.tictactoe.TicTacToe</mainClass>
      </manifest>
    </archive>
  </configuration>
</plugin>

This allows for console execution rather than using your IDE:

goik@mi-ESPRIMO-P910 V1> mvn install
[INFO] Scanning for projects...
...
-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running de.hdm_stuttgart.mi.sd1.connectfour.AppTest
Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.051 sec

Results :

Tests run: 2, Failures: 0, Errors: 0, Skipped: 0

[INFO]
[INFO] --- maven-jar-plugin:2.6:jar (default-jar) @ tictactoe ---
[INFO] Building jar: /.../P/Sd1/TicTacToe/V1/target/tictactoe-0.9.jar
[INFO]
[INFO] --- maven-install-plugin:2.5.2:install (default-install) @ tictactoe ---
[INFO] Installing /.../de/hdm-stuttgart/mi/sd1/tictactoe/0.9/tictactoe-0.9.jar
[INFO] Installing /ma/.../de/hdm-stuttgart/mi/sd1/tictactoe/0.9/tictactoe-0.9.pom
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.242s
[INFO] Finished at: Wed Sep 23 12:54:34 CEST 2015
[INFO] Final Memory: 18M/196M
[INFO] ------------------------------------------------------------------------

As you can see this creates /ma/goik/.m2/repository/de/hdm-stuttgart/mi/sd1/tictactoe/0.9/tictactoe-0.9.jar. This may be executed similar to a true binary executable:

goik@mi-ESPRIMO-P910 ~> java -jar /ma/goik/.m2/.../tictactoe-0.9.jar
Numbering scheme:

0|1|2
-+-+-
3|4|5
-+-+-
6|7|8

Jim, please enter next field's number: