Main,java
/**
*
*/
package com.cfed.tiktactoe;
/**
* @author konzernites
* @since 1.0
*
*/
public class Main {
/**
* @param args
* @throws IllegalAccessException
*/
public static void main(String[] args) throws IllegalAccessException {
Matrix<Character> matrix = new Matrix<>(3, 3);
System.out.println(" **** INSTRUCTIONS **** ");
System.out.println(" User has to enter row and column ");
System.out.println(" Postion starts from (0,0) to (2,2) ");
TikTocToe tikTokToe = new TikTocToe(matrix);
tikTokToe.startGame();
System.out.println(" ***** GAME OVER ***** ");
System.out.println(" Developed by consumerfed I T Section ");
}
}
TicTacToe.java
/**
* Tic Tac Toe
* The main class
*
*/
package com.cfed.tiktactoe;
import java.util.Scanner;
/**
* @author konzernites
* @param <E>
* @since 1.0
*
*/
public class TikTocToe {
public static final int MATRIX_SIZE = 3;
public static final int MAX_MOVE = 9;
protected static int moveCount = 1;
public static final char USER_MOVE = 'X';
public static final char COMP_MOVE = 'O';
private ComputerMove computerMove = null;
private Matrix<Character> matrix = null;
public Character winner = null;
public TikTocToe() {
intialize();
}
public TikTocToe(Matrix matrix) {
this.matrix = matrix;
intialize();
}
private void intialize() {
computerMove = new ComputerMove(matrix);
}
private boolean checkWinner() {
if (findWinner() == USER_MOVE) {
return true;
} else if (findWinner() == COMP_MOVE) {
return true;
}
return false;
}
@SuppressWarnings("unused")
private char findWinner() {
Object[][] newMatrix = matrix.getMatrix();
if (moveCount < 5 || moveCount > MAX_MOVE) {
return Matrix.EMPTY_DATA;
} else if (null!= matrix.getValue(0, 0) && (TikTocToe.USER_MOVE == matrix.getValue(0, 0) || TikTocToe.COMP_MOVE == matrix.getValue(0, 0))) {
winner = (Character)matrix.getValue(0, 0);
if ((null!= matrix.getValue(0, 1) && winner.equals(newMatrix[0][1])) && (null!= matrix.getValue(0, 2) && winner.equals(newMatrix[0][2]))) {
return winner;
} else if ((null!= matrix.getValue(0, 1) && winner.equals(newMatrix[1][0])) && (null!= matrix.getValue(2, 0) && winner.equals(newMatrix[2][0]))) {
return winner;
} else if ((null!= matrix.getValue(1, 1) && winner.equals(newMatrix[1][1])) && ( null!= matrix.getValue(2, 2) && winner.equals(newMatrix[2][2]))) {
return winner;
}
} else if (null!= matrix.getValue(1, 1) && (TikTocToe.USER_MOVE == matrix.getValue(1, 1) || TikTocToe.COMP_MOVE == matrix.getValue(1, 1))) {
winner = (Character)newMatrix[1][1];
if ((null!= matrix.getValue(1, 0) && winner.equals(newMatrix[1][0])) && (null!= matrix.getValue(1, 2) && winner.equals(newMatrix[1][2]))) {
return winner;
} else if ((null!= matrix.getValue(0, 0) && winner.equals(newMatrix[0][0])) && (null!= matrix.getValue(1, 2) && winner.equals(newMatrix[1][2]))) {
return winner;
} else if ((null!= matrix.getValue(0, 2) && winner.equals(newMatrix[0][2])) && (null!= matrix.getValue(2, 0) && winner.equals(newMatrix[2][0]))) {
return winner;
}
} else if (null!= matrix.getValue(2, 2) && (TikTocToe.USER_MOVE == matrix.getValue(2, 2) || TikTocToe.COMP_MOVE == matrix.getValue(2, 2))) {
winner = (Character)newMatrix[2][2];
if ((null!= matrix.getValue(2, 0) && winner.equals(newMatrix[2][0])) && (null!= matrix.getValue(2, 1) && winner.equals(newMatrix[2][1]))) {
return winner;
} else if ((null!= matrix.getValue(0, 2) && winner.equals(newMatrix[0][2])) && (null!= matrix.getValue(1, 2) && winner.equals(newMatrix[1][2]))) {
return winner;
}
}
return Matrix.EMPTY_DATA;
}
/**
* @param args
* @throws IllegalAccessException
*/
public static void main(String[] args) throws IllegalAccessException {
System.out.println(" **** INSTRUCTION **** ");
System.out.println(" User has to enter row and column ");
System.out.println(" Postion starts from (0,0) to (2,2) ");
TikTocToe t = new TikTocToe();
t.startGame();
System.out.println(" **** GAME OVER ***** ");
System.out.println(" Developed by consumerfed I T section kozhikode ");
}
public void startGame() throws IllegalAccessException {
int rowMoved = 0;
int colMoved = 0;
Scanner scanner = new Scanner(System.in);
while (moveCount < MAX_MOVE) {
if (moveCount % 2 == 0) {
matrix = computerMove.computerMove(rowMoved, colMoved);
System.out.println("** COMPUTER MOVE **");
try {
Thread.sleep(3121);
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
System.out.println("** YOUR MOVE **");
System.out.println(" Enter the row (values from 0 to 2): ");
int row = scanner.nextInt();
validate(row);
System.out.println(" Enter the col (values from 0 to 2): ");
int col = scanner.nextInt();
validate(col);
matrix.add(row, col, USER_MOVE);
rowMoved = row;
colMoved = col;
}
matrix.print();
boolean isWon = checkWinner();
if (isWon) {
System.out.println("*** Congratulation *** ");
System.out.println(winner + " is the winner ");
break;
}
moveCount++;
}
}
Dimensions.java
/**
*
*/
package com.cfed.tiktactoe;
/**
* @author konzernites
* @since 1.0
*
*/
public class Dimensions {
private static final long serialVersionUID = 8683452581122892188L;
private int row = 0;
private int column = 0;
public int getRow() {
return row;
}
public void setRow(int row) {
this.row = row;
}
public int getColumn() {
return column;
}
public void setColumn(int column) {
this.column = column;
}
}
private void validate(int value) {
if (value < 0 || value > 2) {
throw new IllegalArgumentException(" This value is not permitted");
}
}
}
Matrix.java
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
* Copyright (c) 1997-2017 Javabelazy and/or its affiliates. All rights reserved.
*
*/
package com.cfed.tiktactoe;
import java.util.NoSuchElementException;
/**
* @author konzernites
* @since 1.0
*
*/
public class Matrix<E> extends AbstractMatrix<E> {
@SuppressWarnings("unused")
private static final long serialVersionUID = 8683452581122892189L;
private final int MAX_COLUMN;
private final int MAX_ROW;
private final int MAX_CAPACITY;
protected static final char EMPTY_DATA = '\0';
private static boolean isEditable = false;
private E elementData[][];
private int capacity = 0;
public Matrix(int row, int column) {
this.MAX_COLUMN = column;
this.MAX_ROW = row;
this.MAX_CAPACITY = MAX_ROW * MAX_COLUMN;
intialize();
}
@SuppressWarnings("unchecked")
private void intialize() {
this.elementData = (E[][]) new Object[MAX_ROW][MAX_COLUMN];
}
public Matrix() {
this(2, 2);
}
public void add(int row, int column, E value) throws IllegalAccessException {
if (row > MAX_ROW || column > MAX_COLUMN)
throw new IllegalAccessException("Illegal capacity");
else if (isFull() || isElementExist(row, column))
throw new IllegalAccessException("Value already exist");
else {
capacity++;
this.elementData[row][column] = value;
}
}
public E[][] getMatrix() {
if (isEmpty())
throw new NoSuchElementException("Matrix is empty");
else
return this.elementData;
}
public E getValue(int row, int column) {
if (isEmpty())
return null;
else if(isElementExist(row, column))
return this.elementData[row][column];
else
return null;
}
public void remove(int row, int column) {
if (isEmpty())
throw new NoSuchElementException("Cannot remove value from an empty matrix");
else {
this.elementData[row][column] = null;
capacity--;
}
}
public void removeAll() {
if (isEmpty())
throw new NoSuchElementException("Cannot remove value from an empty matrix");
else {
// TODO remove all elements from matrix
}
}
public void print() {
if (isEmpty())
throw new NoSuchElementException("Cannot display an empty matrix");
else {
for (int r = 0; r < MAX_ROW; r++) {
for (int c = 0; c < MAX_COLUMN; c++) {
if (null == elementData[r][c])
System.out.print(" | ");
else
System.out.print(elementData[r][c] + " | ");
}
System.out.println("");
}
}
}
public Dimensions dimension() {
Dimensions dimensions = new Dimensions();
dimensions.setRow(MAX_ROW);
dimensions.setColumn(MAX_COLUMN);
return dimensions;
}
private boolean isEmpty() {
if (capacity == 0)
return true;
else
return false;
}
public boolean isElementExist(int row, int column) {
if (isEmpty())
return false;
else if (null != elementData[row][column])
return true;
else
return false;
}
private boolean isFull() {
if (capacity >= MAX_CAPACITY)
return true;
else
return false;
}
public int size() {
return capacity;
}
}
ComputerMove.java
/**
* Computer Moves for user move in tik toc toe
* Developed by consumerfed kozhikode I T section
* Version 1.0
* consfedkozhikode@gmail.com
*
*/
package com.cfed.tiktactoe;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
/**
* @author konzernites
* @since 1.0
*
*/
public class ComputerMove {
private int MATRIX_SIZE = 3;
private static final char EMPTY_DATA = ' ';
private Map<String, Integer> priorityPosition = null;
private static final String techIssue = "EXPERIENCING SOME TECHNICAL ISSUE";
private Matrix<Character> matrix = null;
public ComputerMove(Matrix<Character> matrix) {
this.matrix = matrix;
}
public Matrix<Character> computerMove(int rowMoved, int colMoved) throws IllegalAccessException {
if (TikTocToe.moveCount <= 2) {
matrix = generateFirstCompMove();
} else {
matrix = generateCompMove(rowMoved, colMoved);
}
return matrix;
}
private Matrix<Character> generateCompMove(int rowMoved, int colMoved) throws IllegalAccessException {
priorityPosition = new HashMap<>();
boolean isInserted = false;
for (int row = 0; row < MATRIX_SIZE; row++) {
for (int col = 0; col < MATRIX_SIZE; col++) {
if (!matrix.isElementExist(row, col)) {
isInserted = findPriority(row, col);
if (isInserted)
return matrix;
}
}
}
if (!isInserted) {
String key = maxUsingCollectionsMaxAndLambda(priorityPosition);
int r = Integer.parseInt(key.substring(0, 1));
int c = Integer.parseInt(key.substring(1, 2));
if (!matrix.isElementExist(r, c))
matrix.add(r, c, TikTocToe.COMP_MOVE);
}
return matrix;
}
private Matrix<Character> generateFirstCompMove() throws IllegalAccessException {
int row = 0;
int col = 0;
if (matrix.getValue(1, 1).equals(EMPTY_DATA)) {
matrix.add(1, 1, TikTocToe.COMP_MOVE);
} else {
Random r = new Random();
row = r.nextInt(3);
col = r.nextInt(3);
col = (row == 1 && col == 1) ? col + 1 : col;
matrix.add(row, col, TikTocToe.COMP_MOVE);
}
return matrix;
}
private boolean findPriority(int row, int col) throws IllegalAccessException {
boolean isInserted = true;
if (diagonalOne(0, 0)) {
isInserted = true;
} else if (diagonalTwo(0, MATRIX_SIZE - 1)) {
isInserted = true;
} else if (rowCheck(row, col)) {
matrix.add(row, col, TikTocToe.COMP_MOVE);
} else if (colCheck(row, col)) {
matrix.add(row, col, TikTocToe.COMP_MOVE);
} else {
isInserted = false;
}
return isInserted;
}
private boolean colCheck(int row, int col) {
boolean isPrior = false;
boolean isSafe = false;
int loopCount = 1;
int value = 0;
int r = row;
int c = col;
while (loopCount < MATRIX_SIZE) {
if (r + 1 == MATRIX_SIZE) {
r = 0;
} else {
r++;
}
if (null != matrix.getValue(r, c) && TikTocToe.COMP_MOVE == matrix.getValue(r, c)) {
isSafe = true;
break;
} else if (null != matrix.getValue(r, c) && TikTocToe.USER_MOVE == matrix.getValue(r, c)) {
value++;
}
loopCount++;
}
if (!isSafe) {
String key = String.valueOf(row + "" + col);
priorityPosition.put(key, value);
}
if (value == 2 && !isSafe) {
isPrior = true;
}
return isPrior;
}
private boolean rowCheck(int row, int col) {
boolean isPrior = false;
boolean isSafe = false;
int loopCount = 1;
int value = 0;
int r = row;
int c = col;
while (loopCount < MATRIX_SIZE) {
c = (c + 1 == MATRIX_SIZE) ? 0 : c + 1;
if (null != matrix.getValue(r, c) && TikTocToe.COMP_MOVE == matrix.getValue(r, c)) {
isSafe = true;
break;
} else if (null != matrix.getValue(r, c) && TikTocToe.USER_MOVE == matrix.getValue(r, c)) {
value++;
}
loopCount++;
}
if (!isSafe) {
String key = String.valueOf(row + "" + col);
priorityPosition.put(key, value);
}
if (value == 2 && !isSafe) {
isPrior = true;
}
return isPrior;
}
private boolean diagonalTwo(int row, int col) throws IllegalAccessException {
boolean isPrior = false;
boolean isSafe = false;
int loopCount = 1;
int value = 0;
int r = 0;
int c = 0;
while (loopCount <= MATRIX_SIZE) {
if (null != matrix.getValue(row, col) && TikTocToe.COMP_MOVE == matrix.getValue(row, col)) {
isSafe = true;
break;
} else if (null != matrix.getValue(row, col) && TikTocToe.USER_MOVE == matrix.getValue(row, col)) {
value++;
}
if (!matrix.isElementExist(row, col)) {
r = row;
c = col;
}
row++;
col--;
loopCount++;
}
if (!isSafe) {
String key = String.valueOf(r + "" + c);
priorityPosition.put(key, value);
}
if (value == 2 && !isSafe) {
matrix.add(r, c, TikTocToe.COMP_MOVE);
isPrior = true;
}
return isPrior;
}
private boolean diagonalOne(int row, int col) throws IllegalAccessException {
boolean isPrior = false;
boolean isSafe = false;
int loopCount = 1;
int value = 0;
int r = 0;
int c = 0;
while (loopCount <= MATRIX_SIZE) {
if (null != matrix.getValue(row, col) && TikTocToe.COMP_MOVE == matrix.getValue(row, col)) {
isSafe = true;
break;
} else if (null != matrix.getValue(row, col) && TikTocToe.USER_MOVE == matrix.getValue(row, col)) {
value++;
}
if (!matrix.isElementExist(row, col)) {
r = row;
c = col;
}
row++;
col++;
loopCount++;
}
if (!isSafe) {
String key = String.valueOf(r + "" + c);
priorityPosition.put(key, value);
}
if (value == 2 && !isSafe) {
matrix.add(r, c, TikTocToe.COMP_MOVE);
isPrior = true;
}
return isPrior;
}
private <K, V extends Comparable<V>> K maxUsingCollectionsMaxAndLambda(Map<K, V> map) {
Entry<K, V> maxEntry = Collections.max(map.entrySet(),
(Entry<K, V> e1, Entry<K, V> e2) -> e1.getValue().compareTo(e2.getValue()));
return maxEntry.getKey();
}
}
Output
**** INSTRUCTIONS ****
User has to enter row and column
Postion starts from (0,0) to (2,2)
** YOUR MOVE **
Enter the row (values from 0 to 2):
1
Enter the col (values from 0 to 2):
1
| | |
| X | |
| | |
** COMPUTER MOVE **
| | O |
| X | |
| | |
** YOUR MOVE **
Enter the row (values from 0 to 2):
2
Enter the col (values from 0 to 2):
2
| | O |
| X | |
| | X |
** COMPUTER MOVE **
O | | O |
| X | |
| | X |
** YOUR MOVE **
Enter the row (values from 0 to 2):
1
Enter the col (values from 0 to 2):
2
O | | O |
| X | X |
| | X |
** COMPUTER MOVE **
O | | O |
O | X | X |
| | X |
** YOUR MOVE **
Enter the row (values from 0 to 2):
2
Enter the col (values from 0 to 2):
1
O | | O |
O | X | X |
| X | X |
** COMPUTER MOVE **
O | O | O |
O | X | X |
| X | X |
*** Congratulation ***
O is the winner
***** GAME OVER *****
Developed by consumerfed I T section kozhikode
O | O | O |
O | X | X |
| X | X |
User has to enter row and column
Postion starts from (0,0) to (2,2)
** YOUR MOVE **
Enter the row (values from 0 to 2):
1
Enter the col (values from 0 to 2):
1
| | |
| X | |
| | |
** COMPUTER MOVE **
| | O |
| X | |
| | |
** YOUR MOVE **
Enter the row (values from 0 to 2):
2
Enter the col (values from 0 to 2):
2
| | O |
| X | |
| | X |
** COMPUTER MOVE **
O | | O |
| X | |
| | X |
** YOUR MOVE **
Enter the row (values from 0 to 2):
1
Enter the col (values from 0 to 2):
2
O | | O |
| X | X |
| | X |
** COMPUTER MOVE **
O | | O |
O | X | X |
| | X |
** YOUR MOVE **
Enter the row (values from 0 to 2):
2
Enter the col (values from 0 to 2):
1
O | | O |
O | X | X |
| X | X |
** COMPUTER MOVE **
O | O | O |
O | X | X |
| X | X |
*** Congratulation ***
O is the winner
***** GAME OVER *****
Developed by consumerfed I T section kozhikode
O | O | O |
O | X | X |
| X | X |