Advertisement
adityasuman100

tic tac toe

Apr 14th, 2025
319
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 8.31 KB | None | 0 0
  1.  
  2. // Missing import statements
  3. import java.util.Scanner;
  4. import java.util.Random;
  5. // Main class to run the game
  6. public class Solution {
  7.     public static void main(String[] args) {
  8.         GameBoard board = new GameBoard();
  9.         Player player1 = new HumanPlayer('X');
  10.         Player player2 = new HumanPlayer('O');
  11.         GameController controller = new GameController(board, player1, player2);
  12.        
  13.         controller.startGame();
  14.     }
  15. }
  16.  
  17. // Interface for players (following Interface Segregation Principle)
  18. interface Player {
  19.     Move makeMove(GameBoard board);
  20.     char getSymbol();
  21. }
  22.  
  23. // Board represents the game state (Single Responsibility Principle)
  24. class GameBoard {
  25.     private static final int SIZE = 3;
  26.     private char[][] board;
  27.    
  28.     public GameBoard() {
  29.         board = new char[SIZE][SIZE];
  30.         initializeBoard();
  31.     }
  32.    
  33.     private void initializeBoard() {
  34.         for (int i = 0; i < SIZE; i++) {
  35.             for (int j = 0; j < SIZE; j++) {
  36.                 board[i][j] = ' ';
  37.             }
  38.         }
  39.     }
  40.    
  41.     public boolean isCellEmpty(int row, int col) {
  42.         return board[row][col] == ' ';
  43.     }
  44.    
  45.     public void placeMove(Move move, char symbol) {
  46.         if (isValidMove(move)) {
  47.             board[move.getRow()][move.getCol()] = symbol;
  48.         }
  49.     }
  50.    
  51.     public boolean isValidMove(Move move) {
  52.         int row = move.getRow();
  53.         int col = move.getCol();
  54.        
  55.         return row >= 0 && row < SIZE &&
  56.                col >= 0 && col < SIZE &&
  57.                isCellEmpty(row, col);
  58.     }
  59.    
  60.     public boolean isBoardFull() {
  61.         for (int i = 0; i < SIZE; i++) {
  62.             for (int j = 0; j < SIZE; j++) {
  63.                 if (board[i][j] == ' ') {
  64.                     return false;
  65.                 }
  66.             }
  67.         }
  68.         return true;
  69.     }
  70.    
  71.     public boolean checkWin(char symbol) {
  72.         // Check rows
  73.         for (int i = 0; i < SIZE; i++) {
  74.             if (board[i][0] == symbol && board[i][1] == symbol && board[i][2] == symbol) {
  75.                 return true;
  76.             }
  77.         }
  78.        
  79.         // Check columns
  80.         for (int i = 0; i < SIZE; i++) {
  81.             if (board[0][i] == symbol && board[1][i] == symbol && board[2][i] == symbol) {
  82.                 return true;
  83.             }
  84.         }
  85.        
  86.         // Check diagonals
  87.         if (board[0][0] == symbol && board[1][1] == symbol && board[2][2] == symbol) {
  88.             return true;
  89.         }
  90.        
  91.         if (board[0][2] == symbol && board[1][1] == symbol && board[2][0] == symbol) {
  92.             return true;
  93.         }
  94.        
  95.         return false;
  96.     }
  97.    
  98.     public void printBoard() {
  99.         System.out.println("-------------");
  100.         for (int i = 0; i < SIZE; i++) {
  101.             System.out.print("| ");
  102.             for (int j = 0; j < SIZE; j++) {
  103.                 System.out.print(board[i][j] + " | ");
  104.             }
  105.             System.out.println();
  106.             System.out.println("-------------");
  107.         }
  108.     }
  109.    
  110.     public void reset() {
  111.         initializeBoard();
  112.     }
  113.    
  114.     public int getSize() {
  115.         return SIZE;
  116.     }
  117. }
  118.  
  119. // Value Object for move coordinates (Immutability)
  120. class Move {
  121.     private final int row;
  122.     private final int col;
  123.    
  124.     public Move(int row, int col) {
  125.         this.row = row;
  126.         this.col = col;
  127.     }
  128.    
  129.     public int getRow() {
  130.         return row;
  131.     }
  132.    
  133.     public int getCol() {
  134.         return col;
  135.     }
  136. }
  137.  
  138. // Human player implementation
  139. class HumanPlayer implements Player {
  140.     private final char symbol;
  141.     private final Scanner scanner;
  142.    
  143.     public HumanPlayer(char symbol) {
  144.         this.symbol = symbol;
  145.         this.scanner = new Scanner(System.in);
  146.     }
  147.    
  148.     @Override
  149.     public Move makeMove(GameBoard board) {
  150.         int row, col;
  151.         Move move;
  152.        
  153.         do {
  154.             System.out.println("Player " + symbol + ", enter your move (row [0-2] column [0-2]): ");
  155.             row = scanner.nextInt();
  156.             col = scanner.nextInt();
  157.             move = new Move(row, col);
  158.            
  159.             if (!board.isValidMove(move)) {
  160.                 System.out.println("Invalid move! Try again.");
  161.             }
  162.         } while (!board.isValidMove(move));
  163.        
  164.         return move;
  165.     }
  166.    
  167.     @Override
  168.     public char getSymbol() {
  169.         return symbol;
  170.     }
  171. }
  172.  
  173. // Computer AI player implementation (easy to extend for different strategies)
  174. class ComputerPlayer implements Player {
  175.     private final char symbol;
  176.     private final MoveStrategy moveStrategy;
  177.    
  178.     public ComputerPlayer(char symbol, MoveStrategy moveStrategy) {
  179.         this.symbol = symbol;
  180.         this.moveStrategy = moveStrategy;
  181.     }
  182.    
  183.     @Override
  184.     public Move makeMove(GameBoard board) {
  185.         System.out.println("Computer player " + symbol + " is making a move...");
  186.         return moveStrategy.calculateMove(board, symbol);
  187.     }
  188.    
  189.     @Override
  190.     public char getSymbol() {
  191.         return symbol;
  192.     }
  193. }
  194.  
  195. // Strategy pattern for different AI levels (Open/Closed Principle)
  196. interface MoveStrategy {
  197.     Move calculateMove(GameBoard board, char symbol);
  198. }
  199.  
  200. // Random move strategy implementation
  201. class RandomMoveStrategy implements MoveStrategy {
  202.     private final Random random = new Random();
  203.    
  204.     @Override
  205.     public Move calculateMove(GameBoard board, char symbol) {
  206.         int size = board.getSize();
  207.         int row, col;
  208.         Move move;
  209.        
  210.         do {
  211.             row = random.nextInt(size);
  212.             col = random.nextInt(size);
  213.             move = new Move(row, col);
  214.         } while (!board.isValidMove(move));
  215.        
  216.         return move;
  217.     }
  218. }
  219.  
  220. // Game controller handles the game flow (Single Responsibility Principle)
  221. class GameController {
  222.     private final GameBoard board;
  223.     private final Player player1;
  224.     private final Player player2;
  225.     private Player currentPlayer;
  226.     private GameState gameState;
  227.     private final Scanner scanner;
  228.    
  229.     public GameController(GameBoard board, Player player1, Player player2) {
  230.         this.board = board;
  231.         this.player1 = player1;
  232.         this.player2 = player2;
  233.         this.currentPlayer = player1; // X goes first
  234.         this.gameState = GameState.PLAYING;
  235.         this.scanner = new Scanner(System.in);
  236.     }
  237.    
  238.     public void startGame() {
  239.         System.out.println("Welcome to Tic Tac Toe!");
  240.         board.printBoard();
  241.        
  242.         while (gameState == GameState.PLAYING) {
  243.             playTurn();
  244.             checkGameState();
  245.             switchPlayer();
  246.         }
  247.        
  248.         announceResult();
  249.        
  250.         if (askForRematch()) {
  251.             resetGame();
  252.             startGame();
  253.         } else {
  254.             System.out.println("Thanks for playing!");
  255.         }
  256.     }
  257.    
  258.     private void playTurn() {
  259.         System.out.println("Player " + currentPlayer.getSymbol() + "'s turn.");
  260.         Move move = currentPlayer.makeMove(board);
  261.         board.placeMove(move, currentPlayer.getSymbol());
  262.         board.printBoard();
  263.     }
  264.    
  265.     private void checkGameState() {
  266.         if (board.checkWin(currentPlayer.getSymbol())) {
  267.             gameState = GameState.WIN;
  268.         } else if (board.isBoardFull()) {
  269.             gameState = GameState.DRAW;
  270.         }
  271.     }
  272.    
  273.     private void switchPlayer() {
  274.         currentPlayer = (currentPlayer == player1) ? player2 : player1;
  275.     }
  276.    
  277.     private void announceResult() {
  278.         if (gameState == GameState.WIN) {
  279.             // Switch back to the winning player
  280.             switchPlayer();
  281.             System.out.println("Player " + currentPlayer.getSymbol() + " wins!");
  282.         } else if (gameState == GameState.DRAW) {
  283.             System.out.println("It's a draw!");
  284.         }
  285.     }
  286.    
  287.     private boolean askForRematch() {
  288.         System.out.println("Would you like to play again? (y/n): ");
  289.         String answer = scanner.next().toLowerCase();
  290.         return answer.equals("y") || answer.equals("yes");
  291.     }
  292.    
  293.     private void resetGame() {
  294.         board.reset();
  295.         currentPlayer = player1; // X always starts
  296.         gameState = GameState.PLAYING;
  297.     }
  298. }
  299.  
  300. // Enum for game state (Type safety)
  301. enum GameState {
  302.     PLAYING, WIN, DRAW
  303. }
  304.  
  305.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement