diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..6b8dde0
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,7 @@
+language: java
+jdk:
+ - oraclejdk8
+os:
+ - linux
+script:
+ - chmod +x buildscript.sh && ./buildscript.sh
diff --git a/02.TicTacToe/pom.xml b/02.TicTacToe/pom.xml
new file mode 100644
index 0000000..ead7aac
--- /dev/null
+++ b/02.TicTacToe/pom.xml
@@ -0,0 +1,36 @@
+
+
+ 4.0.0
+
+ 02
+ TicTacToe
+ 1.0-SNAPSHOT
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 1.8
+ 1.8
+
+
+
+
+
+
+ junit
+ junit
+ 4.12
+
+
+ junit
+ junit
+ 4.12
+
+
+
+
+
\ No newline at end of file
diff --git a/02.TicTacToe/src/main/java/ru/spbau/mit/alyokhina/TicTacToe/CreateElements.java b/02.TicTacToe/src/main/java/ru/spbau/mit/alyokhina/TicTacToe/CreateElements.java
new file mode 100644
index 0000000..b788eb6
--- /dev/null
+++ b/02.TicTacToe/src/main/java/ru/spbau/mit/alyokhina/TicTacToe/CreateElements.java
@@ -0,0 +1,201 @@
+package ru.spbau.mit.alyokhina.TicTacToe;
+
+
+import javafx.application.Platform;
+import javafx.geometry.Insets;
+import javafx.scene.control.Button;
+import javafx.scene.control.TextArea;
+import javafx.scene.layout.GridPane;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.Pane;
+
+import java.util.function.Consumer;
+
+/** Create UI elements */
+public class CreateElements {
+
+ /**
+ * Create button
+ *
+ * @param x abscissa coordinate
+ * @param y ordinate coordinate
+ * @param text this text will be on the button
+ * @return new button
+ */
+ public static Button createButton(GridPane gridPane, double height, double width, int x, int y, String text) {
+ Button button = new Button();
+ gridPane.add(button, x, y);
+ button.setText(text);
+ button.setPrefHeight(height);
+ button.setPrefWidth(width);
+ button.setLayoutX(x);
+ button.setLayoutY(y);
+ return button;
+ }
+
+
+ /**
+ * Create board for TicTacToe. Every cell is button
+ *
+ * @return array of buttons
+ */
+ public static Button[] createTableView(GridPane gridPane) {
+ Button[] buttons = new Button[9];
+ for (int i = 0; i < 9; i++) {
+ buttons[i] = createButton(gridPane, 60, 60, 210 + 60 * (i % 3), 110 + 60 * (i / 3), "");
+ }
+ return buttons;
+ }
+
+ /**Create Menu for Main Activity */
+ public static void createMainActivity(GridPane gridPane) {
+ Button buttonPlayWithComp = CreateElements.createButton(gridPane, 50, 200, 0, 0, "Играть с компьютером");
+ Button buttonPlayWithFriend = CreateElements.createButton(gridPane, 50, 200, 0, 1, "Играть с другом");
+ Button buttonExit = CreateElements.createButton(gridPane, 50, 200, 0, 2, "Выход");
+ buttonPlayWithComp.setOnAction(actionEvent -> {
+ GameWithComp gameWithComp = new GameWithComp(gridPane, new Statistics());
+ gameWithComp.menu();
+ });
+
+ buttonPlayWithFriend.setOnAction(actionEvent -> {
+ GameWithFriend gameWithFriend = new GameWithFriend(gridPane, new Statistics());
+ gameWithFriend.menu();
+ });
+ buttonExit.setOnAction(value -> Platform.exit());
+ }
+
+ /**
+ * Create button for new game
+ *
+ * @param statistics is parameter for consumer
+ * @param consumer will be accepted after clicking on the button
+ */
+ public static void createButtonReplay(GridPane gridPane, Statistics statistics, Consumer consumer) {
+ Button rePlay = CreateElements.createButton(gridPane, 50, 200, 400, 20, "Начать новую партию");
+ rePlay.setOnAction(actionEvent -> {
+ gridPane.getChildren().clear();
+ consumer.accept(statistics);
+ });
+ }
+
+
+ /** Create button to go to the main activity */
+ public static void createButtonToMainActivity(GridPane gridPane) {
+ Button buttonToMainActivity = CreateElements.createButton(gridPane, 50, 200, 400, 350, "В главное меню");
+ buttonToMainActivity.setOnAction(actionEvent -> {
+ gridPane.getChildren().clear();
+ createMainActivity(gridPane);
+ });
+ }
+
+
+ /**
+ * Create button to go to statistics for hot seat. After clicking go to new activity
+ *
+ * @param go will be accepted after clicking button back
+ */
+ public static void createButtonGetStatisticsForOnePlayers(GridPane gridPane, Statistics statistics, Consumer go) {
+ Button getStatistics = CreateElements.createButton(gridPane, 50, 200, 200, 270, "Статистика");
+ getStatistics.setOnAction(actionEvent -> {
+ gridPane.getChildren().clear();
+ CreateElements.createButtonToMainActivity(gridPane);
+ Button buttonBack = CreateElements.createButton(gridPane, 50, 200, 400, 20, "Назад");
+ buttonBack.setOnAction(actionEvent1 -> {
+ gridPane.getChildren().clear();
+ go.accept(statistics);
+ });
+ TextArea textArea = new TextArea();
+ textArea.setLayoutY(0);
+ textArea.setLayoutX(0);
+ textArea.setPrefHeight(600);
+ textArea.setPrefWidth(200);
+ gridPane.getChildren().add(textArea);
+ textArea.setText("количество побед: " + statistics.getCountWins().toString()
+ + "\nколичество поражений: " + statistics.getCountLose().toString()
+ + "\nколичество ничьих: " + statistics.getCountDraw().toString());
+
+ });
+ }
+
+
+ /**
+ * Create button to go to statistics for two players. After clicking go to new activity
+ *
+ * @param go will be accepted after clicking button back
+ */
+ public static void createButtonGetStatisticsForTwoPlayers(GridPane gridPane, Statistics statistics, Consumer go) {
+ Button getStatistics = CreateElements.createButton(gridPane, 50, 200, 200, 240, "Статистика");
+ getStatistics.setOnAction(actionEvent -> {
+ gridPane.getChildren().clear();
+ CreateElements.createButtonToMainActivity(gridPane);
+ Button button = CreateElements.createButton(gridPane, 50, 200, 400, 20, "Назад");
+ button.setOnAction(actionEvent1 -> {
+ gridPane.getChildren().clear();
+ go.accept(statistics);
+ });
+ TextArea textAreaForFirst = new TextArea();
+ //textAreaForFirst.setLayoutY(0);
+ //textAreaForFirst.setLayoutX(0);
+ textAreaForFirst.setPrefHeight(600);
+ textAreaForFirst.setPrefWidth(200);
+ gridPane.add(textAreaForFirst, 0, 0);
+ textAreaForFirst.setText("Х \nколичество побед: " + statistics.getCountLose().toString()
+ + "\nколичество поражений: " + statistics.getCountWins().toString()
+ + "\nколичество ничьих: " + statistics.getCountDraw().toString());
+
+
+ TextArea textAreaForSecond = new TextArea();
+ textAreaForSecond.setLayoutY(0);
+ textAreaForSecond.setLayoutX(200);
+ textAreaForSecond.setPrefHeight(600);
+ textAreaForSecond.setPrefWidth(200);
+ gridPane.add(textAreaForSecond, 5, 0);
+ textAreaForSecond.setText("О \nколичество побед: " + statistics.getCountWins().toString()
+ + "\nколичество поражений: " + statistics.getCountLose().toString()
+ + "\nколичество ничьих: " + statistics.getCountDraw().toString());
+ });
+ }
+
+ /** Print result on screen and update statistics */
+ public static void setResult(GridPane gridPane, Statistics statistics, String win) {
+ gridPane.getChildren().clear();
+ CreateElements.createButtonToMainActivity(gridPane);
+ switch (win) {
+ case "draw": {
+ TextArea textArea = new TextArea();
+ textArea.setLayoutY(150);
+ textArea.setLayoutX(250);
+ textArea.setPrefHeight(50);
+ textArea.setPrefWidth(100);
+ textArea.setText("draw");
+ gridPane.getChildren().add(textArea);
+ statistics.incDraw();
+ break;
+ }
+ case "X": {
+ TextArea textArea = new TextArea();
+ textArea.setLayoutY(150);
+ textArea.setLayoutX(250);
+ textArea.setPrefHeight(50);
+ textArea.setPrefWidth(100);
+ textArea.setText("X wins");
+ gridPane.getChildren().add(textArea);
+ statistics.incLose();
+ break;
+ }
+ default: {
+ TextArea textArea = new TextArea();
+ textArea.setLayoutY(150);
+ textArea.setLayoutX(250);
+ textArea.setPrefHeight(50);
+ textArea.setPrefWidth(100);
+ gridPane.getChildren().add(textArea);
+ textArea.setText("O wins");
+ statistics.incWins();
+ break;
+ }
+ }
+
+ }
+
+}
diff --git a/02.TicTacToe/src/main/java/ru/spbau/mit/alyokhina/TicTacToe/Game.java b/02.TicTacToe/src/main/java/ru/spbau/mit/alyokhina/TicTacToe/Game.java
new file mode 100644
index 0000000..bedd786
--- /dev/null
+++ b/02.TicTacToe/src/main/java/ru/spbau/mit/alyokhina/TicTacToe/Game.java
@@ -0,0 +1,138 @@
+package ru.spbau.mit.alyokhina.TicTacToe;
+
+import javafx.scene.control.Button;
+import javafx.scene.layout.GridPane;
+
+/**
+ * Class for key actions of game
+ */
+public class Game {
+ /**
+ * GridPane for current game
+ */
+ protected GridPane gridPane;
+ /**
+ * Number playing
+ */
+ protected int numberGames = 0;
+ /**
+ * Statistics for current game
+ */
+ protected Statistics statistics;
+
+ /**
+ * Constructor
+ */
+ public Game(GridPane gridPane, Statistics statistics) {
+ this.gridPane = gridPane;
+ this.statistics = statistics;
+ gridPane.getChildren().clear();
+ CreateElements.createButtonToMainActivity(gridPane);
+ }
+
+ /**
+ * Translated text from buttons array in string array
+ */
+ protected String[] toStringArray(Button[] table) {
+ String[] tableString = new String[table.length];
+ for (int i = 0; i < table.length; i++) {
+ tableString[i] = table[i].getText();
+ }
+ return tableString;
+ }
+
+ /**
+ * Check the state of the game
+ *
+ * @param tableString state board, "" - if cell is empty
+ * @return "X" - if X wins , "O" - if O wins, "" - if state is unknown, else - draw
+ */
+ public static String check(String[] tableString) {
+
+ boolean existEmpty = false;
+ for (int i = 0; i < tableString.length; i++) {
+ if (tableString[i].equals("")) {
+ existEmpty = true;
+ }
+ }
+
+ for (int i = 0; i < 9; i += 3) {
+ if (!tableString[i].equals("") && tableString[i].equals(tableString[i + 1]) && tableString[i + 1].equals(tableString[i + 2])) {
+ return tableString[i];
+ }
+ }
+
+ for (int i = 0; i < 3; i++) {
+ if (!tableString[i].equals("") && tableString[i].equals(tableString[i + 3]) && tableString[i + 3].equals(tableString[i + 6])) {
+ return tableString[i];
+ }
+ }
+
+ if (!tableString[0].equals("") && tableString[0].equals(tableString[4]) && tableString[4].equals(tableString[8])) {
+ return tableString[0];
+ }
+
+ if (!tableString[2].equals("") && tableString[2].equals(tableString[4]) && tableString[4].equals(tableString[6])) {
+
+ return tableString[2];
+ }
+ if (existEmpty) {
+ return "";
+ } else {
+ return "draw";
+ }
+ }
+
+ /**
+ * /**
+ * Check the state of the game
+ *
+ * @param tableString state board, "" - if cell is empty
+ * @param isPreliminaryCheck, true - if real state, false - if we want check move
+ * @return "X" - if X wins , "O" - if O wins, "" - if state is unknown, else - draw
+ */
+ protected String check(String[] tableString, boolean isPreliminaryCheck) {
+ String result = check(tableString);
+ if (!isPreliminaryCheck && !result.equals("")) {
+ setResult(result);
+ }
+ return result;
+ }
+
+ /**
+ * Print result games
+ */
+ private void setResult(String win) {
+ numberGames++;
+ CreateElements.setResult(gridPane, statistics, win);
+ CreateElements.createButtonReplay(gridPane, statistics, this::goBack);
+ }
+
+ /**
+ * For return in this activity
+ */
+ protected void goBack(Statistics statistics) {
+ this.statistics = statistics;
+ gridPane.getChildren().clear();
+ CreateElements.createButtonToMainActivity(gridPane);
+ menu();
+ }
+
+ /**
+ * Symbol to which the player move
+ */
+
+ public String getCompSymb(int player) {
+ return (numberGames % 2 == player) ? "X" : "O";
+ }
+
+
+ /**
+ * Before games we should choose characteristics game
+ */
+ public void menu() {
+ CreateElements.createButton(gridPane, 50, 200, 200, 70, "Легкий");
+ CreateElements.createButton(gridPane, 50, 200, 200, 170, "Сложный");
+ }
+
+}
diff --git a/02.TicTacToe/src/main/java/ru/spbau/mit/alyokhina/TicTacToe/GameWithComp.java b/02.TicTacToe/src/main/java/ru/spbau/mit/alyokhina/TicTacToe/GameWithComp.java
new file mode 100644
index 0000000..ea5fd07
--- /dev/null
+++ b/02.TicTacToe/src/main/java/ru/spbau/mit/alyokhina/TicTacToe/GameWithComp.java
@@ -0,0 +1,125 @@
+package ru.spbau.mit.alyokhina.TicTacToe;
+
+
+import javafx.scene.control.Button;
+import javafx.scene.layout.GridPane;
+
+import java.util.Random;
+import java.util.function.Consumer;
+
+public class GameWithComp extends Game {
+ /**
+ * Constructor
+ *
+ * @param statistics for collection information
+ */
+ public GameWithComp(GridPane gridPane, Statistics statistics) {
+ super(gridPane, statistics);
+ }
+
+
+ /**
+ * Menu.
+ * Choose level or get statistics
+ */
+ @Override
+ public void menu() {
+ CreateElements.createButtonGetStatisticsForOnePlayers(gridPane, statistics, value -> menu());
+ Button buttonEasyLevel = CreateElements.createButton(gridPane, 50, 200, 200, 70, "Легкий");
+ Button buttonHardLevel = CreateElements.createButton(gridPane, 50, 200, 200, 170, "Сложный");
+ buttonEasyLevel.setOnAction(value -> {
+ gridPane.getChildren().clear();
+ CreateElements.createButtonToMainActivity(gridPane);
+ playGame(this::moveCompEasyLevel);
+ });
+ buttonHardLevel.setOnAction(value -> {
+ gridPane.getChildren().clear();
+ CreateElements.createButtonToMainActivity(gridPane);
+ playGame(this::moveCompHardLevel);
+ });
+ }
+
+ /**
+ * Start game
+ *
+ * @param moveComp move computer
+ */
+ private void playGame(Consumer