summaryrefslogtreecommitdiff
path: root/c1/TicTacToe.java
blob: dd2343ac276356d6697cd74aeb58f719eea466c9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// **THIS IS AN EXAMPLE IMPLEMENTATION!**
// Brett Wortzman
// CSE 123
// C0: Abstract Strategy Games
//
// A class to represent a game of tic-tac-toe that implements the 
// AbstractStrategyGame interface.
import java.util.*;

public class TicTacToe extends AbstractStrategyGame {
    private char[][] board;
    private boolean isXTurn;

    // Constructs a new TicTacToe game.
    public TicTacToe() {
        board = new char[][]{{'-', '-', '-'},
                             {'-', '-', '-'},
                             {'-', '-', '-'}};
        isXTurn = true;
    }

    // Returns whether or not the game is over.
    public boolean isGameOver() {
        return getWinner() >= 0;
    }

    // Returns the index of the winner of the game.
    // 1 if player 1 (X), 2 if player 2 (O), 0 if a tie occurred,
    // and -1 if the game is not over.
    public int getWinner() {
        for (int i = 0; i < board.length; i++) {
            // check row i
            if (board[i][0] == board[i][1] && board[i][0] == board[i][2] && board[i][0] != '-') {
                return board[i][0] == 'X' ? 1 : 2;
            }

            // check col i
            if (board[0][i] == board[1][i] && board[0][i] == board[2][i] && board[0][i] != '-') {
                return board[0][i] == 'X' ? 1 : 2;
            }
        }

        // check diagonals
        if (board[0][0] == board[1][1] && board[0][0] == board[2][2] && board[0][0] != '-') {
            return board[0][0] == 'X' ? 1 : 2;
        }        
        if (board[0][2] == board[1][1] && board[0][2] == board[2][0] && board[0][2] != '-') {
            return board[0][2] == 'X' ? 1 : 2;
        }

        // check for tie
        for (int i = 0; i < board.length; i++) {
            for (int j = 0; j < board[i].length; j++) {
                if (board[i][j] == '-') {
                    // unfilled space; game not over
                    return -1;
                }
            }
        }

        // it's a tie!
        return 0;
    }

    // Returns the index of which player's turn it is.
    // 1 if player 1 (X), 2 if player 2 (O), -1 if the game is over
    public int getNextPlayer() {
        if (isGameOver()) {
            return -1;
        }
        return isXTurn ? 1 : 2;
    }

    // Given the input, places an X or an O where
    // the player specifies.
    // Throws an IllegalArgumentException if the position is
    // invalid, whether that be out of bounds or already occupied.
    // Board bounds are [0, 2] for both rows and cols.
    public void makeMove(Scanner input) {
        char currPlayer = isXTurn ? 'X' : 'O';

        System.out.print("Row? ");
        int row = input.nextInt();
        System.out.print("Column? ");
        int col = input.nextInt();

        makeMove(row, col, currPlayer);
        isXTurn = !isXTurn;
    }

    // Private helper method for makeMove.
    // Given a row and col, as well as player index,
    // places an X or an O in that row and col.
    // Throws an IllegalArgumentException if the position is
    // invalid, whether that be out of bounds or already occupied.
    // Board bounds are [0, 2] for both rows and cols.
    private void makeMove(int row, int col, char player) {
        if (row < 0 || row >= board.length ||
            col < 0 || col >= board[0].length) {
                throw new IllegalArgumentException("Invalid board position: " + row + "," + col);
        }

        if (board[row][col] != '-') {
            throw new IllegalArgumentException("Space already occupied: " + row + "," + col);
        }
        
        board[row][col] = player;
    }

    // Returns a String containing instructions to play the game.
    public String instructions() {
        String result = "";
        result += "Player 1 is X and goes first. Choose where to play by entering a row and\n";
        result += "column number, where (0, 0) is the upper left and (2, 2) is the lower right.\n";
        result += "Spaces show as a - are empty. The game ends when one player marks three spaces\n";
        result += "in a row, in which case that player wins, or when the board is full, in which\n";
        result += "case the game ends in a tie.";
        return result;
    }

    // Returns a String representation of the current state of the board.
    public String toString() {
        String result = "";
        for (int i = 0; i < board.length; i++) {
            for (int j = 0; j < board.length; j++) {
                result += board[i][j] + " ";
            }
            result += "\n";
        }
        return result;
    }
}