import java.awt.geom.Point2D;_x000D_
import java.io.*;_x000D_
import java.net.Socket;_x000D_
import java.util.Arrays;_x000D_
import java.util.stream.Collectors;_x000D_
_x000D_
public class HandleASession implements Runnable, Connect4Constants {_x000D_
        private Socket player1;_x000D_
        private Socket player2;_x000D_
_x000D_
        // Create and initialize cells_x000D_
        private char[][] cell =  new char[6][7];_x000D_
_x000D_
        private ObjectInputStream fromPlayer1;_x000D_
        private ObjectOutputStream toPlayer1;_x000D_
        private ObjectInputStream fromPlayer2;_x000D_
        private ObjectOutputStream toPlayer2;_x000D_
_x000D_
        // Continue to play_x000D_
        private boolean continueToPlay = true;_x000D_
_x000D_
        /** Construct a thread */_x000D_
        public HandleASession(Socket player1, Socket player2) {_x000D_
            this.player1 = player1;_x000D_
            this.player2 = player2;_x000D_
_x000D_
            // Initialize cells_x000D_
            for (int i = 0; i < 6; i++)_x000D_
                for (int j = 0; j < 7; j++)_x000D_
                    cell[i][j] = ' ';_x000D_
_x000D_
            printBoard();_x000D_
//            System.out.println(isRowFull(0)); wordt ook gecontroleerd in client -> als hij vol zit dan wordt hij niet gestuurd naar de server_x000D_
_x000D_
        }_x000D_
_x000D_
        private void printBoard(){_x000D_
            String result = Arrays_x000D_
                    .stream(cell)_x000D_
                    .map(Arrays::toString)_x000D_
                    .collect(Collectors.joining(System.lineSeparator()));_x000D_
            System.out.println(result);_x000D_
        }_x000D_
_x000D_
        /** Implement the run() method for the thread */_x000D_
        public void run() {_x000D_
            try {_x000D_
                // Create data input and output streams_x000D_
                 fromPlayer1 = new ObjectInputStream(_x000D_
                        player1.getInputStream());_x000D_
                 toPlayer1 = new ObjectOutputStream(_x000D_
                        player1.getOutputStream());_x000D_
                 fromPlayer2 = new ObjectInputStream(_x000D_
                        player2.getInputStream());_x000D_
                 toPlayer2 = new ObjectOutputStream(_x000D_
                        player2.getOutputStream());_x000D_
_x000D_
                 boolean isValid;_x000D_
_x000D_
                System.out.println("run() in HandleASession");_x000D_
_x000D_
_x000D_
                toPlayer1.writeInt(PLAYER1);_x000D_
                System.out.println("Send to player 1");_x000D_
                toPlayer1.flush();_x000D_
                toPlayer2.writeInt(PLAYER2);_x000D_
                toPlayer2.flush();_x000D_
                System.out.println("Send to player 2");_x000D_
_x000D_
                // Continuously serve the players and determine and report_x000D_
                // the game status to the players_x000D_
                while (true) {_x000D_
                    // Receive a move from player 1_x000D_
                    Point2D point = (Point2D) fromPlayer1.readObject();_x000D_
                    System.out.println("Reading point object from player 1");_x000D_
_x000D_
                    if(cell[(int) point.getY()][(int)(point.getX())] == ' ') {_x000D_
                        cell[(int) point.getY()][(int) point.getX()] = 'R';_x000D_
                        isValid = true;_x000D_
                    }_x000D_
                    else {_x000D_
                        toPlayer1.writeInt(INVALID_MOVE);_x000D_
                        isValid = false;_x000D_
                    }_x000D_
_x000D_
                    // Check if Player 1 wins_x000D_
                    if (isWon('R')) {_x000D_
                        System.out.println("PLAYER 1 WINS");_x000D_
                        toPlayer1.writeInt(PLAYER1_WON);_x000D_
                        toPlayer2.writeInt(PLAYER1_WON);_x000D_
                        toPlayer1.writeObject(point);_x000D_
                        toPlayer2.writeObject(point);_x000D_
                        break; // Break the loop_x000D_
                    }_x000D_
                    else if (isFull()) { // Check if all cells are filled_x000D_
                        System.out.println("NOBODY WINS, ITS A DRAW");_x000D_
                        toPlayer1.writeInt(DRAW);_x000D_
                        toPlayer2.writeInt(DRAW);_x000D_
                        toPlayer2.writeObject(point);_x000D_
                        break;_x000D_
                    }_x000D_
                    else if(isValid){_x000D_
//                      Notify player 2 to take the turn_x000D_
                        System.out.println("Notify player 2 to take the turn");_x000D_
                        toPlayer2.writeInt(CONTINUE);_x000D_
_x000D_
                        // Send player 1's selected row and column to player 2_x000D_
                        System.out.println("send move");_x000D_
                        toPlayer2.writeObject(point);_x000D_
                        isValid = false;_x000D_
                    }_x000D_
_x000D_
                    // Receive a move from Player 2_x000D_
                    point = (Point2D) fromPlayer2.readObject();_x000D_
                    System.out.println("Reading point object from player 1");_x000D_
                    if(cell[(int) point.getY()][(int)(point.getX())] == ' ') {_x000D_
                        cell[(int) point.getY()][(int) (point.getX())] = 'G';_x000D_
                        isValid = true;_x000D_
                    }_x000D_
                    else {_x000D_
                        toPlayer2.writeInt(INVALID_MOVE);_x000D_
                        isValid = false;_x000D_
                    }_x000D_
_x000D_
_x000D_
                    // Check if Player 2 wins_x000D_
                    if (isWon('G')) {_x000D_
                        System.out.println("PLAYER 2 WINS");_x000D_
                        toPlayer1.writeInt(PLAYER2_WON);_x000D_
                        toPlayer2.writeInt(PLAYER2_WON);_x000D_
                        toPlayer1.writeObject(point);_x000D_
                        toPlayer2.writeObject(point);_x000D_
                        break;_x000D_
                    }_x000D_
                    else if(isValid){_x000D_
                        System.out.println("Notify player 1 to take the turn");_x000D_
                        toPlayer1.writeInt(CONTINUE);_x000D_
_x000D_
                        // Send player 2's selected row and column to player 1_x000D_
                        System.out.println("send move");_x000D_
                        toPlayer1.writeObject(point);_x000D_
                        isValid = false;_x000D_
                    }_x000D_
                    printBoard();_x000D_
                }_x000D_
            }catch (IOException ioEx){_x000D_
//                ioEx.printStackTrace();_x000D_
                System.out.println("Player left.");_x000D_
_x000D_
            }catch (ClassNotFoundException classEx){_x000D_
                classEx.printStackTrace();_x000D_
            }_x000D_
        }_x000D_
_x000D_
        /** Determine if the cells are all occupied */_x000D_
        private boolean isFull() {_x000D_
            for (int i = 0; i < 6; i++)_x000D_
                for (int j = 0; j < 7; j++)_x000D_
                    if (cell[i][j] == ' ') {_x000D_
                        return false; // At least one cell is not filled_x000D_
                    }_x000D_
            // All cells are filled_x000D_
            return true;_x000D_
        }_x000D_
_x000D_
        private boolean isRowFull(int row){_x000D_
            return cell[5][row] != ' ';_x000D_
        }_x000D_
_x000D_
        /** Determine if the player with the specified token wins */_x000D_
        private boolean isWon(char token) {_x000D_
            // TEST BOARD VALUES_x000D_
            for (int x = 0; x < 5; x++) {_x000D_
                for (int y = 0; y < 6; y++) {_x000D_
                    System.out.print(cell[x][y]);_x000D_
                }_x000D_
                System.out.println();_x000D_
            }_x000D_
_x000D_
_x000D_
            // Check all rows_x000D_
            for (int x = 0; x < 6; x++) {_x000D_
                for (int y = 0; y < 3; y++) {_x000D_
                    if (cell[x][y] == token && cell[x][y+1] == token && cell[x][y+2] == token && cell[x][y+3] == token) {_x000D_
                        return true;_x000D_
                    }_x000D_
                }_x000D_
            }_x000D_
            ///Vert_x000D_
_x000D_
            for (int x = 0; x < 3; x++) {_x000D_
                for (int y = 0; y < 7; y++) {_x000D_
                    if (cell[x][y] == token && cell[x+1][y] == token && cell[x+2][y] == token && cell[x+3][y] == token) {_x000D_
                        return true;_x000D_
                    }_x000D_
                }_x000D_
            }_x000D_
_x000D_
            //Diagonal wins_x000D_
            //0 to 1_x000D_
            //0 to 3_x000D_
            for (int x = 0; x < 3; x++) {_x000D_
                for (int y = 0; y < 6; y++) {_x000D_
                    if (cell[x][y] == token && cell[x+1][y+1] == token && cell[x+2][y+2] == token && cell[x+3][y+3] == token) {_x000D_
                        return true;_x000D_
                    }_x000D_
                }_x000D_
            }_x000D_
_x000D_
            //Other diagonal wins_x000D_
            for (int x = 0; x < 3; x++) {_x000D_
                for (int y = 3; y < 7; y++) {_x000D_
                    if (cell[x][y] == token && cell[x+1][y-1] == token && cell[x+2][y-2] == token && cell[x+3][y-3] == token) {_x000D_
                        return true;_x000D_
                    }_x000D_
                }_x000D_
            }_x000D_
            return false;_x000D_
        }_x000D_
    }_x000D_

//            System.out.println(isRowFull(0)); wordt ook gecontroleerd in client -> als hij vol zit dan wordt hij niet gestuurd naar de server_x000D_
import java.awt.geom.Point2D;_x000D_
import java.io.*;_x000D_
import java.net.Socket;_x000D_
import java.util.Arrays;_x000D_
import java.util.stream.Collectors;_x000D_
_x000D_
public class HandleASession implements Runnable, Connect4Constants {_x000D_
        private Socket player1;_x000D_
        private Socket player2;_x000D_
_x000D_
        // Create and initialize cells_x000D_
        private char[][] cell =  new char[6][7];_x000D_
_x000D_
        private ObjectInputStream fromPlayer1;_x000D_
        private ObjectOutputStream toPlayer1;_x000D_
        private ObjectInputStream fromPlayer2;_x000D_
        private ObjectOutputStream toPlayer2;_x000D_
_x000D_
        // Continue to play_x000D_
        private boolean continueToPlay = true;_x000D_
_x000D_
        /** Construct a thread */_x000D_
        public HandleASession(Socket player1, Socket player2) {_x000D_
            this.player1 = player1;_x000D_
            this.player2 = player2;_x000D_
_x000D_
            // Initialize cells_x000D_
            for (int i = 0; i < 6; i++)_x000D_
                for (int j = 0; j < 7; j++)_x000D_
                    cell[i][j] = ' ';_x000D_
_x000D_
            printBoard();_x000D_
//            System.out.println(isRowFull(0)); wordt<SUF>
_x000D_
        }_x000D_
_x000D_
        private void printBoard(){_x000D_
            String result = Arrays_x000D_
                    .stream(cell)_x000D_
                    .map(Arrays::toString)_x000D_
                    .collect(Collectors.joining(System.lineSeparator()));_x000D_
            System.out.println(result);_x000D_
        }_x000D_
_x000D_
        /** Implement the run() method for the thread */_x000D_
        public void run() {_x000D_
            try {_x000D_
                // Create data input and output streams_x000D_
                 fromPlayer1 = new ObjectInputStream(_x000D_
                        player1.getInputStream());_x000D_
                 toPlayer1 = new ObjectOutputStream(_x000D_
                        player1.getOutputStream());_x000D_
                 fromPlayer2 = new ObjectInputStream(_x000D_
                        player2.getInputStream());_x000D_
                 toPlayer2 = new ObjectOutputStream(_x000D_
                        player2.getOutputStream());_x000D_
_x000D_
                 boolean isValid;_x000D_
_x000D_
                System.out.println("run() in HandleASession");_x000D_
_x000D_
_x000D_
                toPlayer1.writeInt(PLAYER1);_x000D_
                System.out.println("Send to player 1");_x000D_
                toPlayer1.flush();_x000D_
                toPlayer2.writeInt(PLAYER2);_x000D_
                toPlayer2.flush();_x000D_
                System.out.println("Send to player 2");_x000D_
_x000D_
                // Continuously serve the players and determine and report_x000D_
                // the game status to the players_x000D_
                while (true) {_x000D_
                    // Receive a move from player 1_x000D_
                    Point2D point = (Point2D) fromPlayer1.readObject();_x000D_
                    System.out.println("Reading point object from player 1");_x000D_
_x000D_
                    if(cell[(int) point.getY()][(int)(point.getX())] == ' ') {_x000D_
                        cell[(int) point.getY()][(int) point.getX()] = 'R';_x000D_
                        isValid = true;_x000D_
                    }_x000D_
                    else {_x000D_
                        toPlayer1.writeInt(INVALID_MOVE);_x000D_
                        isValid = false;_x000D_
                    }_x000D_
_x000D_
                    // Check if Player 1 wins_x000D_
                    if (isWon('R')) {_x000D_
                        System.out.println("PLAYER 1 WINS");_x000D_
                        toPlayer1.writeInt(PLAYER1_WON);_x000D_
                        toPlayer2.writeInt(PLAYER1_WON);_x000D_
                        toPlayer1.writeObject(point);_x000D_
                        toPlayer2.writeObject(point);_x000D_
                        break; // Break the loop_x000D_
                    }_x000D_
                    else if (isFull()) { // Check if all cells are filled_x000D_
                        System.out.println("NOBODY WINS, ITS A DRAW");_x000D_
                        toPlayer1.writeInt(DRAW);_x000D_
                        toPlayer2.writeInt(DRAW);_x000D_
                        toPlayer2.writeObject(point);_x000D_
                        break;_x000D_
                    }_x000D_
                    else if(isValid){_x000D_
//                      Notify player 2 to take the turn_x000D_
                        System.out.println("Notify player 2 to take the turn");_x000D_
                        toPlayer2.writeInt(CONTINUE);_x000D_
_x000D_
                        // Send player 1's selected row and column to player 2_x000D_
                        System.out.println("send move");_x000D_
                        toPlayer2.writeObject(point);_x000D_
                        isValid = false;_x000D_
                    }_x000D_
_x000D_
                    // Receive a move from Player 2_x000D_
                    point = (Point2D) fromPlayer2.readObject();_x000D_
                    System.out.println("Reading point object from player 1");_x000D_
                    if(cell[(int) point.getY()][(int)(point.getX())] == ' ') {_x000D_
                        cell[(int) point.getY()][(int) (point.getX())] = 'G';_x000D_
                        isValid = true;_x000D_
                    }_x000D_
                    else {_x000D_
                        toPlayer2.writeInt(INVALID_MOVE);_x000D_
                        isValid = false;_x000D_
                    }_x000D_
_x000D_
_x000D_
                    // Check if Player 2 wins_x000D_
                    if (isWon('G')) {_x000D_
                        System.out.println("PLAYER 2 WINS");_x000D_
                        toPlayer1.writeInt(PLAYER2_WON);_x000D_
                        toPlayer2.writeInt(PLAYER2_WON);_x000D_
                        toPlayer1.writeObject(point);_x000D_
                        toPlayer2.writeObject(point);_x000D_
                        break;_x000D_
                    }_x000D_
                    else if(isValid){_x000D_
                        System.out.println("Notify player 1 to take the turn");_x000D_
                        toPlayer1.writeInt(CONTINUE);_x000D_
_x000D_
                        // Send player 2's selected row and column to player 1_x000D_
                        System.out.println("send move");_x000D_
                        toPlayer1.writeObject(point);_x000D_
                        isValid = false;_x000D_
                    }_x000D_
                    printBoard();_x000D_
                }_x000D_
            }catch (IOException ioEx){_x000D_
//                ioEx.printStackTrace();_x000D_
                System.out.println("Player left.");_x000D_
_x000D_
            }catch (ClassNotFoundException classEx){_x000D_
                classEx.printStackTrace();_x000D_
            }_x000D_
        }_x000D_
_x000D_
        /** Determine if the cells are all occupied */_x000D_
        private boolean isFull() {_x000D_
            for (int i = 0; i < 6; i++)_x000D_
                for (int j = 0; j < 7; j++)_x000D_
                    if (cell[i][j] == ' ') {_x000D_
                        return false; // At least one cell is not filled_x000D_
                    }_x000D_
            // All cells are filled_x000D_
            return true;_x000D_
        }_x000D_
_x000D_
        private boolean isRowFull(int row){_x000D_
            return cell[5][row] != ' ';_x000D_
        }_x000D_
_x000D_
        /** Determine if the player with the specified token wins */_x000D_
        private boolean isWon(char token) {_x000D_
            // TEST BOARD VALUES_x000D_
            for (int x = 0; x < 5; x++) {_x000D_
                for (int y = 0; y < 6; y++) {_x000D_
                    System.out.print(cell[x][y]);_x000D_
                }_x000D_
                System.out.println();_x000D_
            }_x000D_
_x000D_
_x000D_
            // Check all rows_x000D_
            for (int x = 0; x < 6; x++) {_x000D_
                for (int y = 0; y < 3; y++) {_x000D_
                    if (cell[x][y] == token && cell[x][y+1] == token && cell[x][y+2] == token && cell[x][y+3] == token) {_x000D_
                        return true;_x000D_
                    }_x000D_
                }_x000D_
            }_x000D_
            ///Vert_x000D_
_x000D_
            for (int x = 0; x < 3; x++) {_x000D_
                for (int y = 0; y < 7; y++) {_x000D_
                    if (cell[x][y] == token && cell[x+1][y] == token && cell[x+2][y] == token && cell[x+3][y] == token) {_x000D_
                        return true;_x000D_
                    }_x000D_
                }_x000D_
            }_x000D_
_x000D_
            //Diagonal wins_x000D_
            //0 to 1_x000D_
            //0 to 3_x000D_
            for (int x = 0; x < 3; x++) {_x000D_
                for (int y = 0; y < 6; y++) {_x000D_
                    if (cell[x][y] == token && cell[x+1][y+1] == token && cell[x+2][y+2] == token && cell[x+3][y+3] == token) {_x000D_
                        return true;_x000D_
                    }_x000D_
                }_x000D_
            }_x000D_
_x000D_
            //Other diagonal wins_x000D_
            for (int x = 0; x < 3; x++) {_x000D_
                for (int y = 3; y < 7; y++) {_x000D_
                    if (cell[x][y] == token && cell[x+1][y-1] == token && cell[x+2][y-2] == token && cell[x+3][y-3] == token) {_x000D_
                        return true;_x000D_
                    }_x000D_
                }_x000D_
            }_x000D_
            return false;_x000D_
        }_x000D_
    }_x000D_
