001package ca.bc.webarts.examples; 002/** 003 * From http://www.coderslexicon.com/a-beginner-tic-tac-toe-class-for-java/ 004 **/ 005public class TicTacToe 006{ 007 008 private char[][] board; 009 private char currentPlayerMark; 010 011 public TicTacToe() 012 { 013 board = new char[3][3]; 014 currentPlayerMark = 'x'; 015 initializeBoard(); 016 } 017 018 019 // Set/Reset the board back to all empty values. 020 public void initializeBoard() 021 { 022 023 // Loop through rows 024 for (int i = 0; i < 3; i++) 025 { 026 027 // Loop through columns 028 for (int j = 0; j < 3; j++) 029 { 030 board[i][j] = '-'; 031 } 032 } 033 } 034 035 036 // Print the current board (may be replaced by GUI implementation later) 037 public void printBoard() 038 { 039 System.out.println("-------------"); 040 041 for (int i = 0; i < 3; i++) 042 { 043 System.out.print("| "); 044 for (int j = 0; j < 3; j++) 045 { 046 System.out.print(board[i][j] + " | "); 047 } 048 System.out.println(); 049 System.out.println("-------------"); 050 } 051 } 052 053 054 // Loop through all cells of the board and if one is found to be empty (contains char '-') then return false. 055 // Otherwise the board is full. 056 public boolean isBoardFull() 057 { 058 boolean isFull = true; 059 060 for (int i = 0; i < 3; i++) 061 { 062 for (int j = 0; j < 3; j++) 063 { 064 if (board[i][j] == '-') 065 { 066 isFull = false; 067 } 068 } 069 } 070 071 return isFull; 072 } 073 074 075 // Returns true if there is a win, false otherwise. 076 // This calls our other win check functions to check the entire board. 077 public boolean isWinner() 078 { 079 return (checkRowsForWin() || checkColumnsForWin() || checkDiagonalsForWin()); 080 } 081 082 083 // Loop through rows and see if any are winners. 084 private boolean checkRowsForWin() 085 { 086 for (int i = 0; i < 3; i++) 087 { 088 if (checkRowCol(board[i][0], board[i][1], board[i][1]) == true) 089 { 090 return true; 091 } 092 } 093 return false; 094 } 095 096 097 // Loop through columns and see if any are winners. 098 private boolean checkColumnsForWin() 099 { 100 for (int i = 0; i < 3; i++) 101 { 102 if (checkRowCol(board[0][i], board[1][i], board[2][i]) == true) 103 { 104 return true; 105 } 106 } 107 return false; 108 } 109 110 111 // Check the two diagonals to see if either is a win. Return true if either wins. 112 private boolean checkDiagonalsForWin() 113 { 114 return ((checkRowCol(board[0][0], board[1][1], board[2][2]) == true) || (checkRowCol(board[0][2], board[1][1], board[2][0]) == true)); 115 } 116 117 118 // Check to see if all three values are the same (and not empty) indicating a win. 119 private boolean checkRowCol(char c1, char c2, char c3) 120 { 121 return ((c1 != '-') && (c1 == c2) && (c2 == c3)); 122 } 123 124 125 // Change player marks back and forth. 126 private void changePlayer() 127 { 128 if (currentPlayerMark == 'x') 129 { 130 currentPlayerMark = 'o'; 131 } 132 else 133 { 134 currentPlayerMark = 'x'; 135 } 136 } 137 138 139 // Places a mark at the cell specified by row and col with the mark of the current player. 140 public boolean placeMark(int row, int col) 141 { 142 143 // Make sure that row and column are in bounds of the board. 144 if ((row >= 0) && (row < 3)) 145 { 146 if ((col >= 0) && (col < 3)) 147 { 148 if (board[row][col] == '-') 149 { 150 board[row][col] = currentPlayerMark; 151 return true; 152 } 153 } 154 } 155 156 return false; 157 } 158 159 160 /** 161 * Toms Main method to show how to use this class in a simple console app. 162 **/ 163 public static void main(String[] args) 164 { 165 // Create game and initialize it. 166 // First player will be 'x' 167 TicTacToe game = new TicTacToe(); 168 game.initializeBoard(); 169 170 String player1Play = ""; 171 String player2Play = ""; 172 173 // Read commands from the console 174 //Loop Until "quit" 175 java.util.Scanner scanIn = new java.util.Scanner(System.in); 176 boolean validRead = false; 177 boolean quit = false; 178 String [] rowCol = null; 179 int currRow = 0; 180 int currCol = 0; 181 182 System.out.println("\nTic Tac Toe\n========="); 183 while (!quit) 184 { 185 // Player 1 Move 186 // ************ 187 validRead = false; 188 while (!quit && !validRead) 189 { 190 System.out.print("Player1 Place Your 'x': row,column ? "); 191 player1Play = scanIn.nextLine(); 192 rowCol = player1Play.split("\\,"); 193 System.out.println("player1Play="+player1Play); 194 System.out.println("rowCol.length="+rowCol.length); 195 196 try 197 { 198 if (rowCol.length == 2) 199 { 200 currRow = Integer.parseInt(rowCol[0]); 201 currCol = Integer.parseInt(rowCol[1]); 202 validRead = true; 203 } 204 else 205 if (rowCol.length == 1 && rowCol[0].equalsIgnoreCase("quit")) 206 quit = true; 207 else 208 System.out.println("Placemark must be 2 integers in the form: row,col"); 209 } 210 catch (Exception ex) 211 { 212 System.out.println("Placemark must be 2 integers."); 213 validRead = false; 214 } 215 } 216 217 if (!quit) 218 { 219 // Player 'x' places a mark in the top right corner row 0, column 2 220 // These values are based on a zero index array, so you may need to simply take in a row 1 and subtract 1 from it if you want that. 221 game.placeMark(currRow,currCol); 222 223 // print the board 224 game.printBoard(); 225 226 // Did we have a winner? 227 if (game.isWinner()) 228 { 229 System.out.println(" ! ! We have a winner! Congrats Player 1!\n\nPlay Again (type 'quit' to end)"); 230 game.initializeBoard(); 231 validRead = true;// this bypasses Player 2 and jumps straight to NEXT game 232 } 233 else if (game.isBoardFull()) 234 { 235 System.out.println(" > > Appears we have a draw!\n\nPlay Again (type 'quit' to end)"); 236 game.initializeBoard(); 237 validRead = true; // this bypasses Player 2 and jumps straight to NEXT game 238 } 239 else // just move to Player2 240 validRead = false; 241 242 game.changePlayer(); 243 244 // Player 2 Move 245 // ************ 246 while (!quit && !validRead) 247 { 248 System.out.print("Player2 Place Your 'y': row,column ? "); 249 player2Play = scanIn.nextLine(); 250 rowCol = player2Play.split("\\,"); 251 try 252 { 253 if (rowCol.length == 2) 254 { 255 currRow = Integer.parseInt(rowCol[0]); 256 currCol = Integer.parseInt(rowCol[1]); 257 validRead = true; 258 } 259 else 260 if (rowCol.length == 1 && rowCol[0].equalsIgnoreCase("quit")) 261 quit = true; 262 else 263 System.out.println("Placemark must be 2 integers in the form: row,col"); 264 } 265 catch (Exception ex) 266 { 267 System.out.println("Placemark must be 2 integers."); 268 validRead = false; 269 } 270 } 271 if (!quit) 272 { 273 // Player 'x' places a mark in the top right corner row 0, column 2 274 // These values are based on a zero index array, so you may need to simply take in a row 1 and subtract 1 from it if you want that. 275 game.placeMark(currRow,currCol); 276 277 // print the board 278 game.printBoard(); 279 280 // Did we have a winner? 281 if (game.isWinner()) 282 { 283 System.out.println(" ! ! We have a winner! Congrats Player 1!\n\nPlay Again (type 'quit' to end)"); 284 game.initializeBoard(); 285 validRead = true;// this bypasses Player 2 and jumps straight to NEXT game 286 } 287 else if (game.isBoardFull()) 288 { 289 System.out.println(" > > Appears we have a draw!\n\nPlay Again (type 'quit' to end)"); 290 game.initializeBoard(); 291 validRead = true; // this bypasses Player 2 and jumps straight to NEXT game 292 } 293 else // just move to Player2 294 validRead = false; 295 296 game.changePlayer(); 297 } 298 } 299 } // Repeat steps again for placing mark and checking game status... 300 301 302 System.out.println(" Bye."); 303 scanIn.close(); 304 }// main 305 306} 307