Informatika gyűjtemény

Egy szinttel feljebb Aknakereso.java

2004050607080910

NézetNyomtat

Aknakereso.java (Vissza)
Az alábbi letöltési lehetőségek közül választhatsz: (segítség)
Karakterkódolás:
Sortörés:
Típus: text/plain
Tartalmaz szöveget
Karakterkódolás: utf-8
Méret: 18 KB
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package server;

import java.net.*;
import java.io.*;
import util.SocketUtil;

/**
 *
 * @author balint
 */
public class Client {

    private Socket cso;
    private String nickname;
    private String ip;
    private String host;
    
    public Game game = null;
    
    public BufferedReader is;
    public PrintWriter os;
    public boolean playRequest = false;
    public Client opponent;
    public ClientConnection connection;

    public volatile ChallengeObserver challengeObserver;    
    public class ChallengeObserver {
        public volatile boolean accepted;        
    }    
    
    
    public Client( Socket cso ) {        
        try {
            this.cso = cso;
            ip = cso.getInetAddress().getHostAddress();
            host = cso.getInetAddress().getHostName();

            is = SocketUtil.getBufferedReader(cso);
            os = SocketUtil.getPrintWriter(cso);
            
            challengeObserver = new ChallengeObserver();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
    
    public Socket getSocket()
    {
        return cso;
    }
    
    public String getHost()
    {
        return host;
    }

    public String getIP()
    {
        return ip;
    }    
    
    public void setNickname( String s )
    {
        nickname = s;
    }
    
    public String getNickname()
    {
        return nickname;
    }
    
    public void closeSocket() throws IOException {
        cso.close();
    }
    
    public void setReady() {
        synchronized( game.stateObserver ) {
            game.stateObserver.ready++;
            game.stateObserver.notify();
        }
    }

    public void closeStreams() throws IOException {
        is.close();
        os.close();
    }
    
    public void release()
    {
        try {
            closeStreams(); // bezárjuk a client socketet
            closeSocket(); // bezárjuk a client socketet
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    public void sendMessage(String string) {
        os.print(string+"\r\n");
        //System.out.println( "> "+string );                
        os.flush();
    }

    public String ask() {
        try {
            sendMessage("ASK");
            String s = is.readLine();
            if (s.startsWith("CLICK ")) {
                return s.substring(6);
            } else {
                return null;
            }
        } catch (IOException ex) {
            ex.printStackTrace();
            return null;
        }
    }

    void sendPlayRequest(Client player) {
        sendMessage("WANNAPLAY "+player.getNickname());
        playRequest = true;
        opponent = player;
    }
    
}

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package server;

import java.io.*;

/**
 *
 * @author balint
 */
public class ClientConnection extends Thread {

    public boolean should_run = true;
    private Client c;
    private ConnectionDispatcher dispatcher;
    public String click;
    
    public ClientConnection(Client c, ConnectionDispatcher dispatcher) {
        super("ClientConnection");
        this.= c;
        this.dispatcher = dispatcher;
        c.connection = this;
    }
    
    @Override
    public void run()
    {
        try {
            String s, cmd, arg;
            String[] tokens;
            
            // Üdvözlet
            c.sendMessage("HI");
            s = c.is.readLine();
            if( !s.startsWith("MYNAME ") ) return;
            c.setNickname( s.substring( 7 ) );
            
            moveToWaitingRoom();
            
            this.setName("ClientConnection-"+c.getNickname());
            
            // Most kezeljük a JOIN előtti parancsokat.
            while( should_run ) {
                s = c.is.readLine();
                if( s == null ) {
                    //megszakadt a kapcsolat
                    dispatcher.kick( this );
                    break;
                }
                tokens = s.split(" ");
                cmd = tokens[0];
                if( c.playRequest ) {
                    if( cmd.equals("ACCEPT") )
                    {
                        dispatcher.acceptToPlay( c );
                        should_run = false;
                        break;
                    } else
                    if( cmd.equals("REFUSE") )
                    {
                        dispatcher.refuseToPlay( c );
                    }
                } else {
                    if( cmd.equals("PLAYERLIST") )
                    {
                        dispatcher.sendPlayerListTo( c );
                    } else
                    if( cmd.equals("PLAY") )
                    {                    
                        arg = tokens[1];
                        dispatcher.wantToPlay( c, Integer.parseInt(arg) );
                        synchronized( c.challengeObserver )
                        {
                            c.challengeObserver.wait();
                        }
                        if( c.challengeObserver.accepted ) {
                            should_run = false;
                            break;
                        }
                    }   
                }
            }
            
        } catch (IOException ex) {
            ex.printStackTrace();
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }
    }
    
    public Client getClient()
    {
        return c;
    }

    private void moveToWaitingRoom() {
        dispatcher.moveToWaitingRoom( this );
    }

}

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package server;

import java.io.IOException;
import java.net.*;
import java.util.ArrayList;
import java.util.Iterator;

/**
 *
 * @author balint
 */
public class ConnectionDispatcher extends Thread {

    public boolean should_run = true;
    private ServerSocket sso;
    private ArrayList<ClientConnection> waitingRoom;
    private ArrayList<ClientConnection> newcomers;
    private ArrayList<Game> playingRooms;
    private int users = 0;
    
    public ConnectionDispatcher( ServerSocket sso ) {
        this.sso = sso;        
        
        waitingRoom = new ArrayList();
        newcomers = new ArrayList();
        playingRooms = new ArrayList();
    }
    
    @Override
    public void run()
    {        
        // gyűjtjük az embereket.
        while( should_run ) {
            try {
                Socket cso = sso.accept();
                Client c = new Client( cso );
                ClientConnection cc = new ClientConnection( c, this );
                newcomers.add( cc ); // hozzáadjuk a klienst a kliens listához.
                cc.start();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        
    }

    /*public void broadcast(String string) {
        
        Iterator<ClientConnection> itr = connections.iterator();
        while (itr.hasNext()) {
            ClientConnection connection = itr.next();
            if( !connection.isAlive() ) {
                // útközben leállt a szálunk (végetért a párbeszéd)
                // eltávolítjuk a connectiont és megyünk tovább!
                itr.remove();
                continue;
            }
            connectionsendMessage( string );
        }
        
        //System.out.println( "Messages have been sent to " + connections.size() + " client(s)." );
    }*/

    public int getWaitingPlayers() {
        return waitingRoom.size();
    }

    public void moveToWaitingRoom(ClientConnection cc) {
        ClientConnection waiter = newcomers.remove( newcomers.indexOf( cc ) );
        waitingRoom.add( waiter );
        Client c = waiter.getClient();
        c.sendMessage("OK"); // ha bent vagyunk a várószobában, akkor OK!
        System.out.println(c.getNickname()+" is in the waiting room.");
    }

    public void sendPlayerListTo(Client c) {
        StringBuffer sb = new StringBuffer();
        ArrayList<ClientConnection> room = (ArrayList<ClientConnection>) waitingRoom.clone();
        // clone-ozzuk, hogy ne zavarjon minket semmi, ha változik a room, akkor is egy konzisztens állapotot küldjünk ki.
        Iterator<ClientConnection> itr = room.iterator();
        sb.append( "+PLAYERLIST\r\n" );
        sb.append( room.size() );
        sb.append( "\r\n" );
        while( itr.hasNext() )
        {
            sb.append( itr.next().getClient().getNickname() );
            if( itr.hasNext() ) sb.append("\r\n");
        }        
        
        c.sendMessage( sb.toString() );
    }

    public void wantToPlay(Client player, int target) {
        // szeretnénk játszani a #target ID-jű játékossal. Lehet, hogy már kiléptt, vagy más van helyette
        // nem probléma.
        
        ClientConnection cc = waitingRoom.get( target );
        Client opponent = cc.getClient();
        
        // player vs. opponent
        opponent.sendPlayRequest( player );
    }

    public void kick(ClientConnection cc) {
        ClientConnection leaver = waitingRoom.remove( waitingRoom.indexOf( cc ) );
        leaver.getClient().release();
    }

    public void refuseToPlay(Client c) {
        c.opponent.sendMessage("REFUSED");
        c.playRequest = false;
        c.opponent.challengeObserver.accepted = false;
        synchronized( c.opponent.challengeObserver )
        {
            c.opponent.challengeObserver.notify();
        }
    }
    
    public void acceptToPlay(Client c)
    {
        c.opponent.sendMessage("ACCEPTED");
        c.playRequest = false;
        c.opponent.challengeObserver.accepted = true;
        synchronized( c.opponent.challengeObserver )
        {
            c.opponent.challengeObserver.notify();
        }
        
        // kivesszük őket a waitingRoom-ból
        waitingRoom.remove( waitingRoom.indexOf( c.connection ) );
        waitingRoom.remove( waitingRoom.indexOf( c.opponent.connection ) );
        
        // menjen a játék!
        Game g = new Game( c, c.opponent );
        playingRooms.add( g );
        g.start();
    }

    private void startNewGame() {
        //Game g = new Game( connections.remove(0).getClient(), connections.remove(0).getClient() );
        //g.start();
        // kezdjük a game-t.
    }

}

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package server;

import java.io.IOException;
import java.util.ArrayList;

/**
 *
 * @author 03cKrivan
 */
public class Game extends Thread {
    private Client p1;
    private Client p2;
    
    private Table t;

    private boolean should_run = true;
    private int PID = 1;
    
    public volatile StateObserver stateObserver;    
    public class StateObserver {
        public volatile int ready = 0;
    }    
    
    public Game(Client c1, Client c2) {
        // Játék inicializálása.
        super("Game"); // csak, hogy legyen neve :)
        p1 = c1;
        c1.game = this;
        p2 = c2;
        c2.game = this;
        
        stateObserver = new StateObserver();
        
        t = new Table();
        
        System.out.println("A game has been started: "+c1.getNickname()+" vs. "+c2.getNickname());
    }
    
    @Override
    public void run()
    {
        // elkezdődhet-e a játék? Tehát azonosították-e magukat?
        // Új specifikációnál már készen kell lenniük, hogy PLAY!
        /*while( true )
        {
            try {
                synchronized( stateObserver ) {
                    stateObserver.wait();
                }
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
            if( stateObserver.ready == 2 ) break;
        }*/
        
        String click;
        
        while( should_run )
        {            
            sendTable();
            click = getPlayer().ask(); // kérünk a playertől CLICK-et
            //System.out.println(click);
            // ha gond van a click-el, akkor E4
            if( click == null ) broadcast("E4");
            // ha nem volt jó a click akkor E3
            if( !t.clicked( click ) ) broadcast("E3");
            // csak akkor váltunk playert, ha nem aknára kapcsoltunk
            if( !t.last_is_mine ) changePlayer();
        }

        // elköszönünk a playerektől.
        p1.release();
        p2.release();
        
        /*while( should_run )
        {
            try {
                // játék :D
                p1c.sendTable(t.zip());
                p2c.sendTable(t.zip());                

                System.out.println( p1c.ask() );

                System.out.println( p2c.ask() );
                
                break;
            } catch (IOException ex) {
                ex.printStackTrace();
            }
            
        }*/
    }
    
    private Client getPlayer()
    {
        switch( PID )
        {
            case 1: return p1;                
            case 2: return p2;
            default: return null; // csak nem :)
        }
    }
    
    private void changePlayer() {
        PID = 3 - PID; // trükkös mi? :)
    }
    
    private void sendTable() {
        String s = "TABLE 0 0\r\n"+t.zip();
        p1.sendMessage( s );
        p2.sendMessage( s );
    }
    
    private void broadcast( String msg ) {
        p1.sendMessage( msg );
        p2.sendMessage( msg );
    }
    
}

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package server;

/**
 *
 * @author balint
 */
public class Mezo {

    public int value; // -1 -> 8 (-1 = akna)
    public boolean revealed = false; // felderített-e?
    
    public int x;
    public int y;
    
}

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package server;

import java.net.*;
import java.io.*;

/**
 *
 * @author balint
 */
public class Server {

    private int port;
    
    public static void main( String[] args )
    {
        
        if( args.length == 1 ) {
            // megadtunk portot
            
            Server server = new Server( Integer.parseInt( args[0] ) );            
            
        } else {
            System.out.println("Nem adtál meg paraméterként portot!");
            Server server = new Server( 12345 );
        }
        
    }

    public Server(int port) {
        this.port = port;
        
        System.out.println("The server has been started. It's waiting for clients on port "+port);
        
        try {
            ServerSocket serversocket = new ServerSocket(this.port, 10);
            
            new ConnectionDispatcher( serversocket ).start();
            
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        
    }
    
}

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package server;

import java.util.ArrayList;
import java.util.Random;

/**
 *
 * @author 03cKrivan
 */
public class Table {

    //
    
    private Mezo[][] table;
    public boolean last_is_mine = false;
    
    public Mezo[][] getTable()
    {
        return table;
    }
    
    public Table()
    {
        table = new Mezo[21][21];
        
        init();
    }
    
    public Table( boolean init )
    {
        table = new Mezo[21][21];
        
        if( !init )
        {
            for (int b = 0; b < 21; b++) {
                for (int a = 0; a < 21; a++) {
                    table[a][b] = new Mezo();
                    table[a][b].= a;
                    table[a][b].= b;
                }
            }            
        }
    }
    
    public void init()
    {
        for( int b=0; b<21; b++ )
        {
            for( int a=0; a<21; a++ )
            {
                table[a][b] = new Mezo();
                table[a][b].= a;
                table[a][b].= b;
            }
        }
        
        int[] t = new int[21*21];
        for( int i=0; i<t.length; i++ ) t[i] = i;
        
        int aknak = 0;
        int N = 21*21;
        int idx;
        Random r = new Random();
        while( aknak < 50 )
        {
            idx = r.nextInt( N );
            if( placeMine( idx % 21, (idx - idx % 21)/21 ) ) {
                aknak++;
            }                        
        }
    }
    
    public String zip()
    {       
        StringBuffer sb = new StringBuffer();
        for( int b=0; b<21; b++ )
        {
            for( int a=0; a<21; a++ )
            {
                if( table[a][b].revealed ) {
                    if( table[a][b].value == -1 ) sb.append( "*" );
                    else sb.append( table[a][b].value );
                } else {
                    sb.append("?");
                }
            }
            if( b != 20 ) sb.append( "\r\n" );
        }
        
        return sb.toString();
    }

    public boolean clicked(String click) {
        String[] s = click.split(" ");
        int x = Integer.parseInt(s[0])-1;
        int y = Integer.parseInt(s[1])-1;
        
        if( x>=0 && y>=0 && x<21 && y<21 )
        {
            
            if( table[x][y].revealed ) return false; // már felfedezett
            
            if( table[x][y].value == -1 ) last_is_mine = true; else last_is_mine = false;
            
            reveal( x, y );
            
        } else return false;
                
        return true;
    }

    private void mineNeighbourhood(int x, int y) {        
        for( int x0=x-1; x0<=x+1; x0++ )
        {
            for( int y0=y-1; y0<=y+1; y0++ )
            {
                if( x0 >= 0 && y0 >= 0 && x0 < 21 && y0 < 21 )
                    if( table[x0][y0].value != -1 ) table[x0][y0].value++;
            }
        }
    }

    private boolean placeMine(int x, int y) {       
       if( table[x][y].value != -1 ) {
                table[ x ][ y ].value = -1;
                mineNeighbourhood( x, y );
                return true;
       } else return false;
    }

    private void reveal(int x, int y) {
        // floodfill:
        ArrayList<Mezo> sor = new ArrayList<Mezo>();
        sor.add(table[x][y]);
        table[x][y].revealed = true;            
        Mezo m;
        while (!sor.isEmpty()) {
            // kivesszük az elsőt.
            m = sor.remove(0);
            //System.out.println( zip() );
            if (m.value == 0) {
                // berakjuk a szomszédokat, de csak azokat amik még nem felfedezettek
                for( int a=m.x-1; a<=m.x+1; a++ )
                {
                    for( int b=m.y-1; b<=m.y+1; b++ )
                    {
                        if( a>=0 && b>=0 && a<21 && b<21 )
                        {
                            if( !table[a][b].revealed ) {
                                sor.add( table[a][b] );
                                table[a][b].revealed = true;
                            }
                        }
                    }
                }
            }
        }
    }
    
}

(Vissza)