import java.util.Random;

public class TicTacToe {
	public static final int SIZE = 3;

	private final Mark[][] fields_ = new Mark[SIZE][SIZE];
	private final Pair[][] lines_ = new Pair[][] {
			{new Pair(0,0), new Pair(0,1), new Pair(0,2)},
			{new Pair(1,0), new Pair(1,1), new Pair(1,2)},
			{new Pair(2,0), new Pair(2,1), new Pair(2,2)},
			{new Pair(0,0), new Pair(1,0), new Pair(2,0)},
			{new Pair(0,1), new Pair(1,1), new Pair(2,1)},
			{new Pair(0,2), new Pair(1,2), new Pair(2,2)},
			{new Pair(0,0), new Pair(1,1), new Pair(2,2)},
			{new Pair(2,2), new Pair(1,1), new Pair(0,0)},
	};


	public TicTacToe() {
		for (int x = 0; x < SIZE; x++) {
			for (int y = 0; y < SIZE; y++) {
				fields_[x][y] = Mark.E;
			}
		}
	}

	public Mark getMark(Pair pair) {
		return fields_[pair.x][pair.y];
	}
	public void setMark(Pair pair, Mark mark) {
		fields_[pair.x][pair.y] = mark;
	}

	public boolean nextStep(Pair pair, Mark mark) {
		if (getMark(pair) != Mark.E) return false;
		setMark(pair, mark);
		return true;
	}

	public Mark isEndGame() {
		for (Pair[] row: lines_) {
			Mark m = null;
			boolean isSame = true;
			for (Pair cell: row) {
				Mark mark = fields_[cell.x][cell.y];
				if (m == null) {
					m = mark;
					continue;
				}
				if (m != mark) {
					isSame = false;
					break;
				}
			}
			if (isSame) return m;
		}
		return Mark.E;
	}


	public static void main(String[] args) {
		Player player1 = new RandomPlayer(Mark.O, "Player1");
		Player player2 = new RandomPlayer(Mark.X, "Player2");

		int maxTurn = TicTacToe.SIZE * TicTacToe.SIZE;
		int[] result = new int[3];
		for (int round = 0; round < 10000; round++) {
			TicTacToe game = new TicTacToe();
			for (int turn = 0; turn <= maxTurn; turn++) {
				if (turn == maxTurn) {
					result[2]++;
					break;
				} else if (turn % 2 == 0) {
					player1.put(game);
				} else {
					player2.put(game);
				}
				Mark mark = game.isEndGame();
				if (mark == Mark.O) {
					result[0]++;
					break;
				} else if (mark == Mark.X) {
					result[1]++;
					break;
				}
			}
		}

		System.out.println("Result:");
		System.out.printf("%s won: %d%n", player1.name, result[0]);
		System.out.printf("%s won: %d%n", player2.name, result[1]);
		System.out.printf("draw game  : %d%n", result[2]);
	}
}

enum Mark {
	E { @Override public Mark getOpponent() { return E; } },
	O { @Override public Mark getOpponent() { return X; } },
	X { @Override public Mark getOpponent() { return O; } };

	public abstract Mark getOpponent();
}
class Pair {
	public final int x;
	public final int y;

	public Pair(int x, int y) {
		this.x = x;
		this.y = y;
	}
}


abstract class Player {
	public final Mark mark;
	public final String name;

	public Player(Mark mark, String name) {
		this.mark = mark;
		this.name = name;
	}

	public abstract void put(TicTacToe game);
}

class RandomPlayer extends Player {
	private final Random random_ = new Random();

	public RandomPlayer(Mark mark, String name) {
		super(mark, name);
	}

	@Override
	public void put(TicTacToe game) {
		for (;;) {
			Pair pair = getNextPair();
			boolean res = game.nextStep(pair, mark);
			if (res) break;
		}
	}
	private Pair getNextPair() {
		return new Pair(random_.nextInt(TicTacToe.SIZE), random_.nextInt(TicTacToe.SIZE));
	}
}
