/* This is main code where the implementation is present. TicTacToe.java
1user vs computer game, bit of AI also implemented */
import java.io.IOException;
import java.util.Scanner;
class TicTacToe {
static final int EMPTY = 0;
static final int NONE = 0;
static final int USER = 1;
static final int COMPUTER = 20;
static final int STALEMATE = 3;
public static void main(String[] args) throws IOException {
// Data objects
// 1 = user, 2 = computer
int turn = USER;
// Console con = System.console();
Scanner sc = new Scanner(System.in);
// We will represent the board as nine cells
// 0 = empty, 1 = user, 20 = computer
int[][] board = new int[3][3];
// move: 1-9 representing ul through lr
int move;
// winner: 0 = none, 1 = user, 20 = computer, 3 = stalemate
int winner;
// Print Instructions
System.out.println("This is a tic-tac-toe game");
System.out.println("You are playing against the computer!");
System.out.println("Enter 1-9 to indicate your move");
// Print the board
print_board(board);
// While (game not over)
while (true) {
if (turn == USER) {
System.out.println("Your move");
move = -1;
while (move < 0 || move > 9
|| board[move / 3][move % 3] != EMPTY) {
System.out.println("Please enter your move(0-9): ");
// move = Integer.parseInt(con.readLine());
move = sc.nextInt();
System.out.println("move=" + move);
// System.in.read();
}
} else {
move = computer_move(board);
System.out.println("Computer move: " + move);
}
// Update the board
board[(int) (move / 3)][move % 3] = turn;
// Print the board
print_board(board);
// if game is over
winner = checkWinner(board);
if (winner != NONE)
break;
// switch turn
if (turn == USER) {
turn = COMPUTER;
} else {
turn = USER;
}
}
// Print out the outcome
switch (winner) {
case USER:
System.out.println("You won!");
break;
case COMPUTER:
System.out.println("Computer won!");
break;
default:
System.out.println("Tie!");
break;
}
}
// Print the board
public static void print_board(int[][] board) {
System.out.println("-------------");
for (int i = 0; i < 3; i++) {
System.out.print("| ");
for (int j = 0; j < 3; j++) {
System.out.print(printChar(board[i][j]) + " | ");
}
System.out.println();
System.out.println("-------------");
}
}
// Return an X or O, depending upon whose move it was
public static char printChar(int b) {
switch (b) {
case EMPTY:
return ' ';
case USER:
return 'X';
case COMPUTER:
return 'O';
}
return ' ';
}
// See if the game is over
public static int checkWinner(int[][] board) {
// Check if someone won
// Check horizontals
// top row
if ((board[0][0] == board[0][1]) && (board[0][1] == board[0][2]))
return board[0][0];
// middle row
if ((board[1][0] == board[1][1]) && (board[1][1] == board[1][2]))
return board[1][0];
// bottom row
if ((board[2][0] == board[2][1]) && (board[2][1] == board[2][2]))
return board[2][0];
// Check verticals
// left column
if ((board[0][0] == board[1][0]) && (board[1][0] == board[2][0]))
return board[0][0];
// middle column
if ((board[0][1] == board[1][1]) && (board[1][1] == board[2][1]))
return board[0][1];
// right column
if ((board[0][2] == board[1][2]) && (board[1][2] == board[2][2]))
return board[0][2];
// Check diagonals
// one diagonal
if ((board[0][0] == board[1][1]) && (board[1][1] == board[2][2]))
return board[0][0];
// the other diagonal
if ((board[0][2] == board[1][1]) && (board[1][1] == board[2][0]))
return board[0][2];
// Check if the board is full
if (board[0][0] == EMPTY || board[0][1] == EMPTY
|| board[0][2] == EMPTY || board[1][0] == EMPTY
|| board[1][1] == EMPTY || board[1][2] == EMPTY
|| board[2][0] == EMPTY || board[2][1] == EMPTY
|| board[2][2] == EMPTY)
return NONE;
return STALEMATE;
}
// Generate a random computer move
public static int computer_move(int[][] board) {
// int move = (int) (Math.random() * 9);
int move=0;
Coordinate c=possiblityComp(board);
if(c==null){
c=possiblityUser(board);
if(c==null){
if(board[1][1]==0)
move=4;
else
move=(int) (Math.random() * 9);
}
else
move=Coordinate.getMove(c);
}
else
move=Coordinate.getMove(c);
while (board[move / 3][move % 3] != EMPTY)
move = (int) (Math.random() * 9);
return move;
}
public static Coordinate possiblityUser(int b[][]) {
for (int i = 0; i < 3; i++) {
int c = b[0][i] + b[1][i] + b[2][i];
int r = b[i][0] + b[i][1] + b[i][2];
if (r == 2) {
for (int j = 0; j < 3; j++) {
if (b[i][j] == 0)
return new Coordinate(i, j);
}
}
if (c == 2) {
for (int j = 0; j < 3; j++) {
if (b[j][i] == 0)
return new Coordinate(j, i);
}
}
}
int d1 = b[0][0] + b[1][1] + b[2][2];
int d2 = b[0][2] + b[1][1] + b[2][0];
if (d1 == 2)
for (int i = 0, j = 0; i < 3 || j < 3; i++, j++) {
if (b[i][j] == 0)
return new Coordinate(i,j);
}
if (d2 == 2)
for (int i = 0, j = 2; i < 3 || j >=0 ; i++, j--) {
if (b[i][j] == 0)
return new Coordinate(i,j);
}
return null;
}
public static Coordinate possiblityComp(int b[][]) {
for (int i = 0; i < 3; i++) {
int c = b[0][i] + b[1][i] + b[2][i];
int r = b[i][0] + b[i][1] + b[i][2];
if (r == 40) {
for (int j = 0; j < 3; j++) {
if (b[i][j] == 0)
return new Coordinate(i, j);
}
}
if (c == 40) {
for (int j = 0; j < 3; j++) {
if (b[j][i] == 0)
return new Coordinate(j, i);
}
}
}
int d1 = b[0][0] + b[1][1] + b[2][2];
int d2 = b[0][2] + b[1][1] + b[2][0];
if (d1 == 40)
for (int i = 0, j = 0; i < 3 || j < 3; i++, j++) {
if (b[i][j] == 0)
return new Coordinate(i,j);
}
if (d2 == 40)
for (int i = 0, j = 2; i < 3 || j >=0 ; i++, j--) {
if (b[i][j] == 0)
return new Coordinate(i, j);
}
return null;
}
}
/* Add another class Coordinate.java*/
import java.util.HashMap;
public class Coordinate {
int x,y;
static HashMap<Coordinate, Integer> map = new HashMap<Coordinate, Integer>();
static { map.put(new Coordinate(0, 0), 0);
map.put(new Coordinate(0, 1), 1);
map.put(new Coordinate(0, 2), 2);
map.put(new Coordinate(1, 0), 3);
map.put(new Coordinate(1, 1), 4);
map.put(new Coordinate(1, 2), 5);
map.put(new Coordinate(2, 0), 6);
map.put(new Coordinate(2, 1), 7);
map.put(new Coordinate(2, 2), 8);
}
public Coordinate(int i,int j){
x=i;
y=j;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + x;
result = prime * result + y;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Coordinate other = (Coordinate) obj;
if (x != other.x)
return false;
if (y != other.y)
return false;
return true;
}
public boolean equals(Coordinate obj) {
return this.x==obj.x && this.y==obj.y;
}
public static int getMove(Coordinate c){
return map.get(c);
}
}