Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Missing import statements
- import java.util.Scanner;
- import java.util.Random;
- // Main class to run the game
- public class Solution {
- public static void main(String[] args) {
- GameBoard board = new GameBoard();
- Player player1 = new HumanPlayer('X');
- Player player2 = new HumanPlayer('O');
- GameController controller = new GameController(board, player1, player2);
- controller.startGame();
- }
- }
- // Interface for players (following Interface Segregation Principle)
- interface Player {
- Move makeMove(GameBoard board);
- char getSymbol();
- }
- // Board represents the game state (Single Responsibility Principle)
- class GameBoard {
- private static final int SIZE = 3;
- private char[][] board;
- public GameBoard() {
- board = new char[SIZE][SIZE];
- initializeBoard();
- }
- private void initializeBoard() {
- for (int i = 0; i < SIZE; i++) {
- for (int j = 0; j < SIZE; j++) {
- board[i][j] = ' ';
- }
- }
- }
- public boolean isCellEmpty(int row, int col) {
- return board[row][col] == ' ';
- }
- public void placeMove(Move move, char symbol) {
- if (isValidMove(move)) {
- board[move.getRow()][move.getCol()] = symbol;
- }
- }
- public boolean isValidMove(Move move) {
- int row = move.getRow();
- int col = move.getCol();
- return row >= 0 && row < SIZE &&
- col >= 0 && col < SIZE &&
- isCellEmpty(row, col);
- }
- public boolean isBoardFull() {
- for (int i = 0; i < SIZE; i++) {
- for (int j = 0; j < SIZE; j++) {
- if (board[i][j] == ' ') {
- return false;
- }
- }
- }
- return true;
- }
- public boolean checkWin(char symbol) {
- // Check rows
- for (int i = 0; i < SIZE; i++) {
- if (board[i][0] == symbol && board[i][1] == symbol && board[i][2] == symbol) {
- return true;
- }
- }
- // Check columns
- for (int i = 0; i < SIZE; i++) {
- if (board[0][i] == symbol && board[1][i] == symbol && board[2][i] == symbol) {
- return true;
- }
- }
- // Check diagonals
- if (board[0][0] == symbol && board[1][1] == symbol && board[2][2] == symbol) {
- return true;
- }
- if (board[0][2] == symbol && board[1][1] == symbol && board[2][0] == symbol) {
- return true;
- }
- return false;
- }
- public void printBoard() {
- System.out.println("-------------");
- for (int i = 0; i < SIZE; i++) {
- System.out.print("| ");
- for (int j = 0; j < SIZE; j++) {
- System.out.print(board[i][j] + " | ");
- }
- System.out.println();
- System.out.println("-------------");
- }
- }
- public void reset() {
- initializeBoard();
- }
- public int getSize() {
- return SIZE;
- }
- }
- // Value Object for move coordinates (Immutability)
- class Move {
- private final int row;
- private final int col;
- public Move(int row, int col) {
- this.row = row;
- this.col = col;
- }
- public int getRow() {
- return row;
- }
- public int getCol() {
- return col;
- }
- }
- // Human player implementation
- class HumanPlayer implements Player {
- private final char symbol;
- private final Scanner scanner;
- public HumanPlayer(char symbol) {
- this.symbol = symbol;
- this.scanner = new Scanner(System.in);
- }
- @Override
- public Move makeMove(GameBoard board) {
- int row, col;
- Move move;
- do {
- System.out.println("Player " + symbol + ", enter your move (row [0-2] column [0-2]): ");
- row = scanner.nextInt();
- col = scanner.nextInt();
- move = new Move(row, col);
- if (!board.isValidMove(move)) {
- System.out.println("Invalid move! Try again.");
- }
- } while (!board.isValidMove(move));
- return move;
- }
- @Override
- public char getSymbol() {
- return symbol;
- }
- }
- // Computer AI player implementation (easy to extend for different strategies)
- class ComputerPlayer implements Player {
- private final char symbol;
- private final MoveStrategy moveStrategy;
- public ComputerPlayer(char symbol, MoveStrategy moveStrategy) {
- this.symbol = symbol;
- this.moveStrategy = moveStrategy;
- }
- @Override
- public Move makeMove(GameBoard board) {
- System.out.println("Computer player " + symbol + " is making a move...");
- return moveStrategy.calculateMove(board, symbol);
- }
- @Override
- public char getSymbol() {
- return symbol;
- }
- }
- // Strategy pattern for different AI levels (Open/Closed Principle)
- interface MoveStrategy {
- Move calculateMove(GameBoard board, char symbol);
- }
- // Random move strategy implementation
- class RandomMoveStrategy implements MoveStrategy {
- private final Random random = new Random();
- @Override
- public Move calculateMove(GameBoard board, char symbol) {
- int size = board.getSize();
- int row, col;
- Move move;
- do {
- row = random.nextInt(size);
- col = random.nextInt(size);
- move = new Move(row, col);
- } while (!board.isValidMove(move));
- return move;
- }
- }
- // Game controller handles the game flow (Single Responsibility Principle)
- class GameController {
- private final GameBoard board;
- private final Player player1;
- private final Player player2;
- private Player currentPlayer;
- private GameState gameState;
- private final Scanner scanner;
- public GameController(GameBoard board, Player player1, Player player2) {
- this.board = board;
- this.player1 = player1;
- this.player2 = player2;
- this.currentPlayer = player1; // X goes first
- this.gameState = GameState.PLAYING;
- this.scanner = new Scanner(System.in);
- }
- public void startGame() {
- System.out.println("Welcome to Tic Tac Toe!");
- board.printBoard();
- while (gameState == GameState.PLAYING) {
- playTurn();
- checkGameState();
- switchPlayer();
- }
- announceResult();
- if (askForRematch()) {
- resetGame();
- startGame();
- } else {
- System.out.println("Thanks for playing!");
- }
- }
- private void playTurn() {
- System.out.println("Player " + currentPlayer.getSymbol() + "'s turn.");
- Move move = currentPlayer.makeMove(board);
- board.placeMove(move, currentPlayer.getSymbol());
- board.printBoard();
- }
- private void checkGameState() {
- if (board.checkWin(currentPlayer.getSymbol())) {
- gameState = GameState.WIN;
- } else if (board.isBoardFull()) {
- gameState = GameState.DRAW;
- }
- }
- private void switchPlayer() {
- currentPlayer = (currentPlayer == player1) ? player2 : player1;
- }
- private void announceResult() {
- if (gameState == GameState.WIN) {
- // Switch back to the winning player
- switchPlayer();
- System.out.println("Player " + currentPlayer.getSymbol() + " wins!");
- } else if (gameState == GameState.DRAW) {
- System.out.println("It's a draw!");
- }
- }
- private boolean askForRematch() {
- System.out.println("Would you like to play again? (y/n): ");
- String answer = scanner.next().toLowerCase();
- return answer.equals("y") || answer.equals("yes");
- }
- private void resetGame() {
- board.reset();
- currentPlayer = player1; // X always starts
- gameState = GameState.PLAYING;
- }
- }
- // Enum for game state (Type safety)
- enum GameState {
- PLAYING, WIN, DRAW
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement