Commits

Jacek Bzdak  committed 27d9ea9

Initial commit

  • Participants

Comments (0)

Files changed (17)

+**/.idea/**
+sk/out/**
+**class
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="JAVA_MODULE" version="4">
+  <component name="NewModuleRootManager" inherit-compiler-output="true">
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>
+

File sk/src/pl/edu/pw/fizyka/sk/example/ClientSocket.java

+package pl.edu.pw.fizyka.sk.example;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.net.Socket;
+
+public class ClientSocket {
+    public static void main(String[] args) throws Exception{
+        Socket socket = new Socket("lfitj.if.pw.edu.pl", 80);
+        OutputStream outputStream = socket.getOutputStream();
+        PrintWriter printWriter = new PrintWriter(outputStream);
+        printWriter.print("GET /dydaktyka/sk/zaj2.html HTTP/1.0\n\n");
+        printWriter.flush();
+        BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
+        String line = reader.readLine();
+        while (line!=null){
+            System.out.println(line);
+            System.out.flush();
+            line = reader.readLine();
+        }
+    }
+}

File sk/src/pl/edu/pw/fizyka/sk/example/MultihreadedServerSocketExample.java

+package pl.edu.pw.fizyka.sk.example;
+
+import java.io.*;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+public class MultihreadedServerSocketExample {
+
+    public static void main(String[] args) throws IOException {
+        ServerSocket serverSocket = new ServerSocket(12347);
+        ExecutorService executorService = Executors.newFixedThreadPool(10);
+        while (true){
+            final Socket socket = serverSocket.accept();
+            Runnable connection = new Runnable() {
+                @Override
+                public void run() {
+
+                    try {
+                        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
+                        BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
+                        bufferedWriter.write("Napisz: \"END\" by zakończyć połączenie.");
+                        String line = bufferedReader.readLine();
+                        while (!line.contains("END")){
+                            bufferedWriter.write("Sever says: ");
+                            bufferedWriter.write(line);
+                            bufferedWriter.write("\n");
+                            bufferedWriter.flush();
+                            line = bufferedReader.readLine();
+                        }
+                        socket.close();
+                    } catch (IOException e) {
+                        e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
+                    }
+
+                }
+            };
+            executorService.submit(connection);
+        }
+    }
+}

File sk/src/pl/edu/pw/fizyka/sk/example/ServerSocketExample.java

+package pl.edu.pw.fizyka.sk.example;
+
+import java.io.*;
+import java.net.ServerSocket;
+import java.net.Socket;
+
+public class ServerSocketExample {
+
+    public static void main(String[] args) throws IOException {
+        ServerSocket serverSocket = new ServerSocket(12347);
+        while (true){
+            Socket socket = serverSocket.accept();
+            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
+            BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
+            bufferedWriter.write("Napisz: \"END\" by zakończyć połączenie.");
+            String line = bufferedReader.readLine();
+            while (!line.contains("END")){
+                bufferedWriter.write("Sever says: ");
+                bufferedWriter.write(line);
+                bufferedWriter.write("\n");
+                bufferedWriter.flush();
+                line = bufferedReader.readLine();
+            }
+            socket.close();
+        }
+    }
+}

File sk/src/pl/edu/pw/fizyka/sk/tictactoe/api/AbstractPlayer.java

+package pl.edu.pw.fizyka.sk.tictactoe.api;
+
+public abstract class AbstractPlayer implements Player {
+    protected State symbol;
+    protected State enemy;
+
+    @Override
+    public void notifyGameEnd(State[] board, State winner) {
+
+    }
+
+    @Override
+    public void setSymbol(State symbol) {
+        this.symbol = symbol;
+        if (symbol == State.X){
+            this.enemy = State.O;
+        }else {
+            this.enemy = State.X;
+        }
+
+    }
+}

File sk/src/pl/edu/pw/fizyka/sk/tictactoe/api/AiPlayer.java

+package pl.edu.pw.fizyka.sk.tictactoe.api;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Random;
+
+public class AiPlayer extends AbstractPlayer {
+
+    private final static int[] CORNERS = {4, 0, 2, 6 , 8};
+
+    private Random random = new Random();
+
+
+
+    @Override
+    /**
+     * Simple AI for tic tac toe game. It has following algorithm:
+     * <ul>
+     *     <li><p> If it has winning move it makes it
+     *     <li><p> If oponnent has winning move it blocks it
+     *     <li><p> If this is first move takes position 5
+     *     <li><p> Takes position in random corner if avilable
+     *     <li><p> Takes random position
+     * </ul>
+     */
+    public int nextMove(State[] board) {
+
+        List<Integer> empty = Board.emptyPlaces(board);
+
+        //Take middle if start
+        if (empty.size() == 9){
+            return 5;
+        }
+
+        // Make winning move
+        for (Integer place : empty){
+            State[] copy = Arrays.copyOf(board, board.length);
+            copy[place] = symbol;
+            if(Board.winner(copy, symbol)){
+                return place;
+            }
+        }
+
+        // Block opponent wining move
+        for (Integer place : empty){
+            State[] copy = Arrays.copyOf(board, board.length);
+            copy[place] = enemy;
+            if(Board.winner(copy, enemy)){
+                return place;
+            }
+        }
+
+        //Take corner or middle
+        for (int corner : CORNERS){
+            if (empty.contains(corner)){
+                return corner;
+            }
+        }
+        //Make random move
+        return empty.get(random.nextInt(empty.size()));
+    }
+}

File sk/src/pl/edu/pw/fizyka/sk/tictactoe/api/Board.java

+package pl.edu.pw.fizyka.sk.tictactoe.api;
+
+
+
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class Board {
+
+    private final State[] board = new State[9];
+
+    private static final int[][] WINNING_STATES = {
+            {0, 1, 2},
+            {3, 4, 5},
+            {6, 7, 8},
+            {0, 3, 6},
+            {1, 4, 7},
+            {2, 5, 8},
+            {0, 4, 8},
+            {2, 4, 6}
+    };
+
+    public State[] getBoard(){
+        return Arrays.copyOf(board, board.length);
+    }
+
+    /**
+     * Powoduje umieszczenie symbolu gracza na polu o ineksie
+     * @param index indeks w którym stawiamu znak (z zakresu 0 -- 9)
+     * @param player symbol gracza
+     */
+    public void play(int index, State player){
+        if (!legalMove(board, index)){
+            throw new IllegalStateException("Place where you put your mark must be empty");
+        }
+        board[index] = player;
+    }
+
+    /**
+     * Lista poprawnych ruchów
+     * @return
+     */
+    public List<Integer> getLegalMoves(){
+        return emptyPlaces(board);
+    }
+
+    /**
+     * Zwraca zwycięzcę, albo null jeśli nie ma zwycięzcy
+     * @return
+     */
+    public State winner(){
+        if (winner(board, State.X)){
+            return State.X;
+        }
+        if (winner(board, State.O)){
+            return State.O;
+        }
+        if (getLegalMoves().size()==0){
+            return State.DRAW;
+        }
+        return null;
+    }
+
+    /**
+     * Wyświetla planszę na OutputStream
+     * @param stream strumień do którego zapiszemy planszę
+     * @param board plansza do zapisania
+     */
+    public static void print(OutputStream stream, State[] board){
+        if (board.length !=9){
+            throw new IllegalStateException("Board.length must be equal to 9.");
+        }
+
+        PrintStream printStream;
+        if (stream instanceof  PrintStream){
+            printStream = (PrintStream) stream;
+        }else {
+            printStream = new PrintStream(stream);
+        }
+
+        for (int ii = 0;  ii < 3; ii++){
+            for(int jj = 0; jj < 3; jj++){
+                int index = ii * 3 + jj;
+                printStream.print(State.label(board[index], index));
+                if (jj <2){
+                    printStream.print("|");
+                }
+            }
+            printStream.print("\n");
+        }
+    }
+
+    public static boolean legalMove(State[] board, int index){
+        return board[index] == null;
+    }
+
+    public static List<Integer> emptyPlaces(State[] board){
+        List<Integer> result = new ArrayList<Integer>(9);
+        for (int ii = 0; ii < board.length; ii++){
+            if (board[ii] == null){
+                result.add(ii);
+            }
+        }
+        return result;
+    }
+
+    public static boolean winner(State[] board, State player){
+        /**
+         * Checks if player won the game
+         */
+        if (board.length !=9){
+            throw new IllegalStateException("Board.length must be equal to 9.");
+        }
+
+        for (int ii=0; ii < WINNING_STATES.length; ii++){
+            boolean won = true;
+            for (int index : WINNING_STATES[ii]){
+                if (board[index] != player){
+                    won = false;
+                    break;
+                }
+            }
+            if(won)
+                return true;
+        }
+        return false;
+    }
+
+
+
+}

File sk/src/pl/edu/pw/fizyka/sk/tictactoe/api/Game.java

+package pl.edu.pw.fizyka.sk.tictactoe.api;
+
+public class Game {
+
+    final Player playerA;
+    final Player playerB;
+    final Board board = new Board();
+
+    public Game(Player playerA, Player playerB) {
+        super();
+        this.playerA = playerA;
+        this.playerB = playerB;
+    }
+
+
+    /**
+     * Performs game and returns the winner
+     * @return
+     */
+    public State performGame(){
+        State winner = performGamePrivate();
+        playerA.notifyGameEnd(board.getBoard(), winner);
+        playerB.notifyGameEnd(board.getBoard(), winner);
+        return winner;
+    }
+
+    private State performGamePrivate(){
+        playerA.setSymbol(State.O);
+        playerB.setSymbol(State.X);
+        while (board.getLegalMoves().size()>0){
+            board.play(playerA.nextMove(board.getBoard()), State.O);
+            if (board.winner() != null){
+                return board.winner();
+            }
+            board.play(playerB.nextMove(board.getBoard()), State.X);
+            if (board.winner() != null){
+                return board.winner();
+            }
+        }
+        return null;
+    }
+}

File sk/src/pl/edu/pw/fizyka/sk/tictactoe/api/Player.java

+package pl.edu.pw.fizyka.sk.tictactoe.api;
+
+public interface Player {
+
+    /**
+     * Informuje gracza o zakończeniu rozgrywki
+     * @param board Końcowy stan planszy
+     * @param winner Zwycięzca
+     */
+    void notifyGameEnd(State[] board, State winner);
+
+    /**
+     * Zwraca następny ruch gracza
+     * @param board plansza
+     * @return następny ruch gracza
+     */
+    int nextMove(State[] board);
+
+    /**
+     * Ustawia symbol jakim gra dany gracz
+     * @param symbol
+     */
+    void setSymbol(State symbol);
+}

File sk/src/pl/edu/pw/fizyka/sk/tictactoe/api/State.java

+package pl.edu.pw.fizyka.sk.tictactoe.api;
+
+public enum State {
+    X, O, DRAW;
+
+    public static String label(State state, int index){
+        if(state == null){
+            return String.valueOf(index);
+        }
+        return state.name();
+    }
+}

File sk/src/pl/edu/pw/fizyka/sk/tictactoe/solution/AiConsoleGame.java

+package pl.edu.pw.fizyka.sk.tictactoe.solution;
+
+import pl.edu.pw.fizyka.sk.tictactoe.api.AiPlayer;
+import pl.edu.pw.fizyka.sk.tictactoe.api.Game;
+
+public class AiConsoleGame {
+
+    public static void main(String[] args){
+        Game game = new Game(new ConsolePlayer(), new AiPlayer());
+        game.performGame();
+    }
+}

File sk/src/pl/edu/pw/fizyka/sk/tictactoe/solution/ConsolePlayer.java

+package pl.edu.pw.fizyka.sk.tictactoe.solution;
+
+import java.io.PrintStream;
+
+public class ConsolePlayer extends TextHumanPlayer {
+
+    @Override
+    public PrintStream getOutputStream() {
+        return System.out;
+    }
+
+    @Override
+    public String getInputLine() {
+        return System.console().readLine();
+    }
+}

File sk/src/pl/edu/pw/fizyka/sk/tictactoe/solution/SocketGameClient.java

+package pl.edu.pw.fizyka.sk.tictactoe.solution;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.Socket;
+
+public class SocketGameClient {
+
+    public static void main(String[] args) throws IOException {
+        Socket s = new Socket("localhost", 12346);
+        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(s.getInputStream()));
+//        PrintStream stream = new PrintStream(s.getOutputStream());
+        while (true){
+            String line = bufferedReader.readLine();
+            System.out.println(line);
+            if (line.contains("Winner")){
+                return;
+            }
+            if (line.contains(TextHumanPlayer.YOUR_MOVE)){
+                System.out.println("Read");
+                String LINE = System.console().readLine();
+                System.out.println("READ " + LINE);
+                s.getOutputStream().write(LINE.getBytes());
+                s.getOutputStream().write("\n".getBytes());
+                s.getOutputStream().flush();
+            }
+
+        }
+
+    }
+}

File sk/src/pl/edu/pw/fizyka/sk/tictactoe/solution/SocketGameServer.java

+package pl.edu.pw.fizyka.sk.tictactoe.solution;
+
+import pl.edu.pw.fizyka.sk.tictactoe.api.AiPlayer;
+import pl.edu.pw.fizyka.sk.tictactoe.api.Game;
+
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+public class SocketGameServer  {
+
+    private static int PORT = 12346;
+
+    String host = "localhost";
+
+    public static void main(String[] args) throws Exception{
+        ExecutorService executor = Executors.newCachedThreadPool();
+
+        ServerSocket serverSocket = new ServerSocket(PORT);
+
+        while (true){
+            final Socket socket = serverSocket.accept();
+            System.out.printf("Accepting");
+            executor.submit(new Runnable() {
+                @Override
+                public void run() {
+                    Game game = null;
+                    try {
+                        game = new Game(new SocketPlayer(socket), new AiPlayer());
+                    } catch (IOException e) {
+                        throw new RuntimeException();
+                    }
+                    game.performGame();
+                }
+            });
+
+        }
+
+    }
+}

File sk/src/pl/edu/pw/fizyka/sk/tictactoe/solution/SocketPlayer.java

+package pl.edu.pw.fizyka.sk.tictactoe.solution;
+
+import pl.edu.pw.fizyka.sk.tictactoe.solution.TextHumanPlayer;
+
+import java.io.*;
+import java.net.Socket;
+
+public class SocketPlayer extends TextHumanPlayer {
+
+    final Socket socket;
+
+    final PrintStream printStream;
+
+    final BufferedReader reader;
+
+    public SocketPlayer(Socket socket) throws IOException {
+        this.socket = socket;
+        this.printStream = new PrintStream(socket.getOutputStream());
+        this.reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
+    }
+
+    @Override
+    public PrintStream getOutputStream() {
+        return printStream;
+    }
+
+    @Override
+    public String getInputLine() {
+        try {
+            return reader.readLine();
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}

File sk/src/pl/edu/pw/fizyka/sk/tictactoe/solution/TextHumanPlayer.java

+package pl.edu.pw.fizyka.sk.tictactoe.solution;
+
+import pl.edu.pw.fizyka.sk.tictactoe.api.AbstractPlayer;
+import pl.edu.pw.fizyka.sk.tictactoe.api.Board;
+import pl.edu.pw.fizyka.sk.tictactoe.api.State;
+
+import java.io.PrintStream;
+import java.util.List;
+
+public abstract class TextHumanPlayer extends AbstractPlayer {
+
+    public static final String GET_LEGAL_MOVE = "Please provide a legal move?";
+    public static final String YOUR_MOVE = "Your move?";
+
+    public abstract PrintStream getOutputStream();
+    
+    public abstract String getInputLine();
+
+    private void printBasicInfo(State[] board){
+        getOutputStream().println("Symbol: " + symbol);
+        getOutputStream().println("Board:");
+        Board.print(getOutputStream(), board);
+    }
+
+    @Override
+    public void notifyGameEnd(State[] board, State winner) {
+        printBasicInfo(board);
+        getOutputStream().println("Winner is: " + winner);
+    }
+
+    @Override
+    public int nextMove(State[] board) {
+        printBasicInfo(board);
+        getOutputStream().println("Legal moves:");
+        List<Integer> legalMoves = Board.emptyPlaces(board);
+        getOutputStream().print(legalMoves);
+        getOutputStream().println(YOUR_MOVE);
+        while (true){
+            String s = getInputLine().trim();
+            int move;
+            try{
+                move = Integer.parseInt(s);
+            }catch (NumberFormatException e){
+                getOutputStream().print("Wrong format");
+                continue;
+            }
+            if (!legalMoves.contains(move)){
+                getOutputStream().print(GET_LEGAL_MOVE);
+                continue;
+            }
+            return move;
+        }
+    }
+}