Advertisement
Nattack

Untitled

Mar 31st, 2017
257
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 10.28 KB | None | 0 0
  1. /**
  2.  * Connect Four
  3.  *
  4.  * A gravity based game of what is more or less Tic-Tac-Toe
  5.  *
  6.  * @author RJ Trenchard, 100281657
  7.  *
  8.  */
  9.  
  10. public class AE8_20_100281657 {
  11.    
  12.     // Constants, States
  13.     public static enum Tile { EMPTY, RED, BLACK }
  14.     public static enum GameState { SETUP, DRAW, PLAY, CHECK, GAMEOVER, RESET, END }
  15.     public static final int SIZE_X = 7; // board size
  16.     public static final int SIZE_Y = 6;
  17.     public static final int WIN_CONDITION = 4; // how many need to match before a win
  18.    
  19.     /**
  20.      * initBoard
  21.      *
  22.      * initial setup of the game board
  23.      *
  24.      * @return      2-Dimensional array that holds the game board
  25.      */
  26.     public static Tile[][] initBoard() {
  27.         Tile[][] board = new Tile[SIZE_Y][SIZE_X];
  28.         board = resetBoard(board);
  29.         return board;
  30.     }
  31.    
  32.    
  33.     /**
  34.      * resetBoard
  35.      *
  36.      * resets the board to empty
  37.      *
  38.      * @param board     2-Dimensional array that holds the game board
  39.      * @return          Returns an empty board based on the board we fed it
  40.      */
  41.     public static Tile[][] resetBoard( Tile[][] board ) {
  42.         for (int i = 0; i < board.length; i++)
  43.             for (int j = 0; j < board[0].length; j++)
  44.                 board[i][j] = Tile.EMPTY;
  45.         return board;
  46.     }
  47.  
  48.     /**
  49.      * tileToString
  50.      *
  51.      * returns a string representation of the Tile enum.
  52.      *
  53.      * @param tile  The tile to represent
  54.      * @return      The string representation
  55.      */
  56.     public static String tileToString(Tile tile) {
  57.         switch (tile) {
  58.             case RED:            return "R";
  59.             case BLACK:          return "B";
  60.             case EMPTY: default: return " ";
  61.         }
  62.     }
  63.    
  64.     /**
  65.      * findTop
  66.      *
  67.      * retrieves the topmost tile of a particular index
  68.      *
  69.      * @param board     2-Dimensional array that holds the game board
  70.      * @param index     the index to check.
  71.      * @return          returns an int pointing to the topmost tile, or -1 if the tile is invalid.
  72.      */
  73.     public static int findTop(Tile[][] board, int index) {
  74.         if (index < board[0].length) {
  75.             for (int i = 0; i < board.length; i++)  // traverse down the board until we find something
  76.                 if (board[i][index] != Tile.EMPTY)
  77.                     return i - 1;
  78.             // if it is empty, return the top element index
  79.             return board.length -1;
  80.         }
  81.         // if it is out of bounds, return -1
  82.         return -1;
  83.     }
  84.    
  85.     /**
  86.      * playPuck
  87.      *
  88.      * attempts to play a puck on the game board
  89.      *
  90.      * @param board     2-Dimensional array that holds the game board
  91.      * @param index     which index we will play the puck
  92.      * @param player    which player is playing the puck
  93.      * @return          returns true if the puck can be played in that slot
  94.      */
  95.     public static boolean playPuck(Tile[][] board, int index, int player) {
  96.         Tile playerTile = (player == 0) ? Tile.RED:Tile.BLACK; //kind of messy, in the future lets use a struct-like object!
  97.         int top = findTop(board, index);
  98.         if (top < board.length && top > -1) {
  99.             board[top][index] = playerTile;
  100.             return true;
  101.         }
  102.         else return false;
  103.  
  104.     }
  105.    
  106.     /**
  107.      * checkWin
  108.      *
  109.      * Checks the board to see if a winner exists.
  110.      *
  111.      * @param board     2-Dimensional array that holds the game board
  112.      * @param index     the index to start checking
  113.      * @return          returns true if a winning combination has been found.
  114.      */
  115.     public static boolean checkWin(Tile[][] board, int index) {
  116.         if (    checkDirection(board, index, 1, 0) ||   // check x
  117.                 checkDirection(board, index, 0, 1) ||   // check y
  118.                 checkDirection(board, index, 1, 1) ||   // check x, y
  119.                 checkDirection(board, index, 1, -1)     // check x, -y
  120.             )
  121.             return true;
  122.         else return false;
  123.     }
  124.    
  125.     /**
  126.      * checkDirection
  127.      *
  128.      * Directional checking for matches
  129.      *
  130.      * @param board         2-Dimensional array that holds the game board
  131.      * @param index         which index we will check
  132.      * @param xDirection    the x direction to check, can be 1, 0, or -1
  133.      * @param yDirection    the y direction to check, can be 1, 0, or -1
  134.      * @return              returns true if four match.
  135.      */
  136.     public static boolean checkDirection(Tile[][] board, int index, int xDirection, int yDirection) {
  137.        
  138.         int top = findTop(board, index);
  139.         Tile last = board[top][index];
  140.         System.out.println(last);
  141.         int count = 0;
  142.         boolean isSame = true;
  143.         int xOpposite = xDirection * -1;
  144.         int yOpposite = yDirection * -1;
  145.         int x = top;
  146.         int y = index;
  147.  
  148.         System.out.println("y " + y + "  x " + x + "  Count " + count);
  149.         // find the first boundary
  150.         while ( isSame && count < 4 ) {
  151.             if (    y >= 0 && y < board.length &&
  152.                     x >= 0 && x < board[0].length &&
  153.                     last == board[y][x])
  154.             {
  155.                 count++;
  156.                 x+=xDirection;
  157.                 y+=yDirection;
  158.             } else isSame = false;
  159.         }
  160.        
  161.         if (!isSame) {
  162.             x+=xOpposite;
  163.             y+=xOpposite;
  164.         }
  165.        
  166.         isSame = true;
  167.         count = 0;
  168.  
  169.         // find the second boundary
  170.         while ( isSame ) {
  171.             System.out.println("y " + y + "  x " + x + "  Count " + count);
  172.             System.out.println(board[y][x]);
  173.             if (    y >= 0 && y < board.length &&
  174.                     x >= 0 && x < board[0].length &&
  175.                     last == board[y][x])
  176.             {
  177.                 count++;
  178.                 x+=xOpposite;
  179.                 y+=yOpposite;
  180.             } else isSame = false;
  181.             if ( count == 4 ) return true;
  182.         }      
  183.         // if nothing matches, return false
  184.         return false;
  185.     }
  186.    
  187.     /**
  188.      * drawOptions
  189.      *
  190.      * Prints all valid options
  191.      *
  192.      * @param player    The player that is going to play
  193.      */
  194.     public static void drawOptions(int player) {
  195.         System.out.println( "Options:\nQ - Quit\nD - Redraw\n1-7 - Play your coin\n");
  196.         System.out.print( "Player " + (player+1) + " select your option: ");
  197.     }
  198.    
  199.     /**
  200.      * drawTitle
  201.      *
  202.      * Prints the board header
  203.      */
  204.     public static void drawTitle() {
  205.         System.out.println("*********CONNECT FOUR*********");
  206.     }
  207.    
  208.     /**
  209.      * congratsPlayer
  210.      *
  211.      * Prints the winning message
  212.      *
  213.      * @param playerNum     The winner
  214.      * @param winCount      2 dimensional array of the winning numbers
  215.      */
  216.     public static void congratsPlayer( int playerNum, int[] winCount ) {
  217.         System.out.println(
  218.                 "Player " + (playerNum + 1) + " wins!\n\n"
  219.                 + "  Player 1: " + winCount[0] + "\n"
  220.                 + "  Player 2: " + winCount[1]);
  221.     }
  222.    
  223.     /**
  224.      * drawBoard
  225.      *
  226.      * Formats a board and prints a string to console
  227.      *
  228.      * @param board     A 2 dimensional array of type "Tile" that holds all the game pieces.
  229.      */
  230.     public static void drawBoard(Tile[][] board) {
  231.         StringBuilder strBoard = new StringBuilder();
  232.         StringBuilder strPlayBuilder = new StringBuilder();
  233.         StringBuilder strRowBuilder = new StringBuilder();
  234.         StringBuilder strIndexBuilderTop = new StringBuilder();
  235.         for (int i = 0; i < board.length; i++) {
  236.             for (int j = 0; j < board[0].length; j++) {
  237.                 strPlayBuilder.append("|" + tileToString( board[i][j]));
  238.                 strRowBuilder.append("--");
  239.                 strIndexBuilderTop.append(" " + Integer.toString(j+1));
  240.             }
  241.             strPlayBuilder.append("|\n");
  242.             strRowBuilder.append("-\n");
  243.             strIndexBuilderTop.append('\n');
  244.             if (i == 0) // use function currying to condense this. Should be safe since the form should never change.
  245.                 strBoard.append( strIndexBuilderTop ).append( strRowBuilder ).append( strPlayBuilder ).append( strRowBuilder );
  246.             else
  247.                 strBoard.append( strPlayBuilder ).append( strRowBuilder );
  248.             strPlayBuilder = new StringBuilder();
  249.             strRowBuilder = new StringBuilder();
  250.         }
  251.         System.out.println(strBoard);
  252.     }
  253.    
  254.     /**
  255.      * Connect Four
  256.      *
  257.      * This could be done in much less lines, surely,
  258.      * but for the sake of this assignment let's make
  259.      * things a bit more verbose
  260.      *
  261.      * @param args      does nothing!
  262.      */
  263.     public static void main(String[] args) {
  264.         // Connect four
  265.        
  266.         // initial declaration of variables
  267.         GameState state         =   GameState.SETUP;
  268.         java.util.Scanner input =   new java.util.Scanner ( System.in );
  269.         String parseBuffer      =   new String();
  270.         Tile[][] board          =   initBoard();
  271.         int[] winCount          =   {0,0};
  272.         int player              =   0;
  273.         boolean running         =   true;
  274.         int choice              =   0;
  275.        
  276.         // Main game loop
  277.         while (running) {
  278.             switch (state) {
  279.            
  280.                     // setup of the game board, also resets the score.
  281.                 case SETUP:
  282.                     board       =   initBoard();
  283.                     winCount[0] =   0;
  284.                     winCount[1] =   0;
  285.                     player      =   0;
  286.                     state       =   GameState.DRAW;
  287.                     break;
  288.                    
  289.                     // resets the game board for another game
  290.                 case RESET:
  291.                     board       =   resetBoard( board );
  292.                     player      =   0;
  293.                     state       =   GameState.DRAW;
  294.                     break;
  295.                    
  296.                     // draw the game board
  297.                 case DRAW:
  298.                     drawTitle();
  299.                     drawBoard(board);
  300.                     state = GameState.PLAY;
  301.                     break;
  302.                    
  303.                     // plays a puck, or gets a different option
  304.                 case PLAY:
  305.                     /*
  306.                      * Options:
  307.                      *  Q to quit
  308.                      *  D to redraw
  309.                      *  1-7 to play
  310.                      * */
  311.                     drawOptions( player );
  312.                     parseBuffer = input.nextLine();
  313.                     if (parseBuffer.isEmpty())
  314.                         System.out.println("Invalid input!");
  315.                     else if (parseBuffer.equalsIgnoreCase( "Q" ))
  316.                         state = GameState.END;
  317.                     else if (parseBuffer.equalsIgnoreCase( "D" ))
  318.                         state = GameState.DRAW;
  319.                     else if ( Character.isDigit( parseBuffer.charAt(0) ) ) {
  320.                         choice = Character.getNumericValue( parseBuffer.charAt(0) );
  321.                         if (choice < board[0].length || choice > 1)
  322.                             state = GameState.CHECK;
  323.                         else
  324.                             System.out.println("Invalid range!");
  325.                     }
  326.                     else System.out.println("Invalid input!");
  327.                     break;
  328.  
  329.                     // check if we can play that disk. If we can, play it, otherwise ask for input again                   
  330.                 case CHECK:
  331.                     if (playPuck(board, (choice -1), player))
  332.                     {
  333.                         if (checkWin( board, (choice -1) )) {
  334.                             winCount[player]++;
  335.                             congratsPlayer( player, winCount );
  336.                             state = GameState.GAMEOVER;
  337.                         } else {
  338.                             player ^= 1; // obligatory XOR player swap
  339.                             state = GameState.DRAW;
  340.                         }
  341.                     } else {
  342.                         System.out.println("That choice is invalid, try again.");
  343.                         state = GameState.PLAY;
  344.                     }
  345.                     break;
  346.                    
  347.                     // handle the end of game
  348.                 case GAMEOVER:
  349.                     System.out.print("Play again? (Y = Play again, N = Quit, R = Reset score): ");
  350.                     parseBuffer = input.nextLine();
  351.                     if (parseBuffer.equalsIgnoreCase( "Y" ))
  352.                         state = GameState.RESET;
  353.                     else if (parseBuffer.equalsIgnoreCase( "N" ))
  354.                         state = GameState.END;
  355.                     else if (parseBuffer.equalsIgnoreCase( "R"))
  356.                         state = GameState.SETUP;
  357.                     else System.out.println("Invalid Input!");
  358.                     break;
  359.                    
  360.                     // quit the game
  361.                 case END: default:
  362.                     System.out.println("Game ended.");
  363.                     input.close();
  364.                     running = false;
  365.                     break;
  366.                    
  367.             }
  368.         }
  369.     }
  370. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement