Voici ma fonction qui s'appelle NetAwale :
package awele;
import java.net.*;
import java.io.*;
public class NetAwale {
public Awale awale; // lien vers le jeu awale
private byte req_size = 14; // taille des messages
private Socket s; // socket, ?o/c !c
private BufferedInputStream in; // flux entrant encapsulé dans un buffer
private BufferedOutputStream out; // flux sortant encapsulé dans un buffer
private byte[] b = new byte[req_size]; // jeu courant et commande de passage
private byte lui = 0,moi = 0; // pion ramassé
private float LastSend; // calcul du temps d'execution
private String[] endmessages = { // messages envoyés à la fin
"none", // ne pas utiliser
"perdu! :-/",
"gagné! :-D",
"draw",
"Jeux différents",
"timeout",
"coup sur case vide",
"coup invalide",
"abandon"
};
// creation de l'application réseau, prend awale en param
public NetAwale(Awale awale) {
super();
this.awale = awale;
}
// création serveur
public void listen(int port){
try{
// on tente de prendre le port
listening(new ServerSocket(port));
}
catch(IOException e){
log("pb écoute au port "+e.getMessage());
}
}
// attente de clients
private void listening(ServerSocket ss){
log("Ecoute au port "+ss.getLocalPort());
try
{
s = ss.accept(); // on attend un client / bloquant
log("nouveau client : "+s.getInetAddress().getHostAddress()+":"+s.getPort());
accepted((byte)0);
}
catch(IOException e){
log("pb écoute au port "+e.getMessage());
listening(ss);
}
}
// connexion à un serveur
public boolean connect(String addr,int port){
try{
s = new Socket(addr,port);
if( s.isConnected() ){
log("serveur : "+s.getInetAddress().getHostAddress()+":"+s.getPort());
accepted((byte)1);
return true;
}
}
catch(IOException e){
log("pb connexion à "+addr+":"+port+" "+e.getMessage());
}
return false;
}
// notification de la connexion d'un client ou à un serveur
private void accepted(byte k){
try{ // on récupère les streams
in = new BufferedInputStream(s.getInputStream());
out = new BufferedOutputStream(s.getOutputStream());
}
catch(IOException e){
log("pb accepté "+e.getMessage());
return;
}
// initialisation 1444444K (K=1 client)
b[0] = 1; // commande
b[13] = k; // param
for(int i=1;i<13;i++)
b[i] = 4; // tous les trous à 4
if( k == 1 ){
send(1,k); // trame d'initialisation
log("trame d'initialisation envoyée, attente du serveur...");
printgame(b);
}
receive(); // écoute du jeu
}
// envoyer un message
private boolean send(int cmd,int arg){ // int pour ne pas fatiguer mon clavier :/
b[13] = (byte)arg; // param
b[0] = (byte)cmd; // cmd
if( cmd == 3 ){
if( arg > 0 && arg < endmessages.length )
log("end message, envoi de ["+endmessages[arg]+"]");
if( arg == 1 )
log("VOUS AVEZ GAGNE!! Score : "+moi+" / "+lui);
else if( arg == 2 )
log("VOUS AVEZ PERDU.. Score : "+moi+" / "+lui);
else if( arg == 3 )
log("DRAW.. Score : "+moi+" / "+lui);
}
// fin explicite
// !todo le reste du tableau est à maj dans les 2 sens
// for(int i=0;i<b.length;i++) log("b["+i+"]="+b[i]);
try{
out.write(b,0,req_size);
out.flush();
LastSend = System.nanoTime();
return true;
}
catch(IOException e){
log("pb send; "+e.getMessage());
return false;
}
}
// recevoir un message
private void receive(){
try{
byte[] response = new byte[req_size];
in.read(response,0,req_size);
if( LastSend > 0 ){
log("Temps d'exécution adverse ["+(System.nanoTime()-LastSend)+" ns]");
LastSend = 0;
}
switch( response[0] ){
case (byte)1: // ini
if( checkGame(response) ){
if( response[13] == 1 ) // le serveur commence à jouer (reçu le 1 du client)
play(response); // appel de l'IA ou humain ici
else
log("initialisation : trame suspecte");
}
break;
case (byte)2: // play
if( updateGame(response) )
play(response); // appel de l'IA ou humain ici
break;
case (byte)3: // stop
if( response[13] > 0 && response[13] < endmessages.length )
log("end message de l'adversaire : "+endmessages[response[13]]);
endGame(true);
break;
default:
log("pb switch #1 "+response[0]);
break;
}
}
catch(IOException e){
log("pb receive "+e.getMessage());
}
}
// verifie le jeu
private boolean checkGame(byte[] a){
if( a.length != req_size ){
send(3,7);// coup invalide
return false;
}
for(int i=1;i<13;i++)
if( (i < 7 && a[i+6] != b[i]) || (i > 8 && a[i-6] != b[i]) ){
send(3,4); // jeux différents
log("jeu adverse:");
printgame(a);
log("mon jeu:");
printgame(b);
return false;
}
return true;
}
// mise à jour par rapport à ses propres coups
public void play(byte[] a){
if( a.length != req_size || a[13] < 1 || a[13] > 6 )
send(3,7); // coup invalide
else{
b[13] = a[13]; // on récupère le coup de l'adversaire
byte coup = play2(b);
if( coup < 1 || coup > 6 || b[coup] == 0 )
send(3,8); // give up
else{
// algo de semaison
byte c = coup,d = b[coup];
b[coup] = 0;
while( d > 0 ){
c++;
if( c == coup ) c++;
if( c > 12 ){
if( coup != 1 ) c = 1;
else c = 2;
}
b[c]++;
d--;
}
// algo de récolte
while( b[c] > 1 && b[c] < 4 && c > 6 && c < 13 ){
moi += b[c];
b[c] = 0;
c--;
}
// famine
if( (b[12]+b[11]+b[10]+b[9]+b[8]+b[7]) == 0 ){
lui += (b[1]+b[2]+b[3]+b[4]+b[5]+b[6]);
b[1]=0;b[2]=0;b[3]=0;b[4]=0;b[5]=0;b[6]=0;
log("famine!");
}
printgame(b);
send(2,coup);
if( !endGame(false) )
receive();
}
}
}
public byte play2(byte[] b){
boolean manuel = false;
printgame(b);
if( manuel ){
log("coup:");
try{
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
byte coup = Integer.decode(in.readLine()).byteValue();
if( coup < 1 || coup > 6 || b[coup] == 0 ){
log("coup errone");
return play2(b);
}
return coup;
}
catch(IOException e){
log("pb clavier #2, "+e.getMessage());
return 0;
}
}
//else
//return Awale.IA(b); // on interroge l'ia
return req_size;
}
// mise à jour par rapport aux coups adverses
public boolean updateGame(byte[] a){
if( a.length != req_size || a[13] < 1 || a[13] > 6 ){
log("updateGame, taille incorrecte "+a[13]+" "+a.length);
send(3,7); // cheat
return false;
}
// on inverse le coup (6 devient 12, 5 devient 11,... 1 devient 7)
byte coup = (byte)(a[13]+6);
if( b[coup] == 0 ){
log("case vide, paramètre incorrect #3 "+a[1]);
send(3,6); // cas vide
return false;
}
log("l'adversaire a joué : "+coup);
// algo de semaison
byte c = coup,d = b[coup];
b[coup] = 0;
while( d > 0 ){
c++;
if( c == coup ) c++;
if( c > 12 ){
if( coup != 1 ) c = 1;
else c = 2;
}
b[c]++;
d--;
}
// algo de récolte
while( b[c] > 1 && b[c] < 4 && c < 7 && c > 0 ){
lui += b[c];
b[c] = 0;
c--;
}
// famine
if( (b[1]+b[2]+b[3]+b[4]+b[5]+b[6]) == 0 ){
moi += (b[12]+b[11]+b[10]+b[9]+b[8]+b[7]);
b[12]=0;b[11]=0;b[10]=0;b[9]=0;b[8]=0;b[7]=0;
log("famine!");
}
return (!endGame(false) && checkGame(a));
}
private boolean endGame(boolean bAnnounced){
// lui/moi > 24
if( moi > 24 )
send(3,1); // you've lose!
else if( lui > 24 )
send(3,2); // you've won!
else if( lui == 24 && moi == 24 )
send(3,3); // draw
else if( bAnnounced )
log("fin inattendu, vous avez gagné");
else
return false;
return true;
}
// printgame() affiche le jeu en cours
private void printgame(byte[] b){
log("===== JEU EN COURS =====");
log("\t"+b[12]+"\t"+b[11]+"\t"+b[10]+"\t"+b[9]+"\t"+b[8]+"\t"+b[7]);
log("\t"+b[1]+"\t"+b[2]+"\t"+b[3]+"\t"+b[4]+"\t"+b[5]+"\t"+b[6]);
log("===== score: "+moi+" / "+lui);
}
/**
* affiche les messages
* peut être modifié pour afficher
* autre part que dans la console...
*/
public void log(String text){
System.out.println(text);
}
}
Et voici ce que j'ai mis dans mon programme principal (fonction main) pour appeler NetAwale :
//début fonction réseau
NetAwale na = new NetAwale(awale);
try{
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
na.log("AWALE MODE [1=IA,2=HUMAIN,*=SORTIE]");
switch(Integer.decode(in.readLine()).intValue()){
case 1: manuel = false; break;
case 2: manuel = true; break;
default: na.log("sortie"); return;
}
na.log("AWALE NET [1=SERVER,2=CLIENT,*=SORTIE]");
int port;
switch(Integer.decode(in.readLine()).intValue()){
case 1:
//na.log("Port local?");
port = 2222;
//port = Integer.decode(in.readLine()).intValue();
na.listen(port);
break;
case 2:
//na.log("Adresse?");
String adresse = "192.168.1.10";
//String adresse = in.readLine();
//na.log("Port distant?");
port = 2222;
//port = Integer.decode(in.readLine()).intValue();
na.connect(adresse,port);
break;
default:
na.log("sortie");
break;
}
}
catch(IOException e){
na.log("pb clavier #1, "+e.getMessage());
}
}
});
Voici ma fonction qui s'appelle NetAwale :
package awele; import java.net.*; import java.io.*; public class NetAwale { public Awale awale; // lien vers le jeu awale private byte req_size = 14; // taille des messages private Socket s; // socket, ?o/c !c private BufferedInputStream in; // flux entrant encapsulé dans un buffer private BufferedOutputStream out; // flux sortant encapsulé dans un buffer private byte[] b = new byte[req_size]; // jeu courant et commande de passage private byte lui = 0,moi = 0; // pion ramassé private float LastSend; // calcul du temps d'execution private String[] endmessages = { // messages envoyés à la fin "none", // ne pas utiliser "perdu! :-/", "gagné! :-D", "draw", "Jeux différents", "timeout", "coup sur case vide", "coup invalide", "abandon" }; // creation de l'application réseau, prend awale en param public NetAwale(Awale awale) { super(); this.awale = awale; } // création serveur public void listen(int port){ try{ // on tente de prendre le port listening(new ServerSocket(port)); } catch(IOException e){ log("pb écoute au port "+e.getMessage()); } } // attente de clients private void listening(ServerSocket ss){ log("Ecoute au port "+ss.getLocalPort()); try { s = ss.accept(); // on attend un client / bloquant log("nouveau client : "+s.getInetAddress().getHostAddress()+":"+s.getPort()); accepted((byte)0); } catch(IOException e){ log("pb écoute au port "+e.getMessage()); listening(ss); } } // connexion à un serveur public boolean connect(String addr,int port){ try{ s = new Socket(addr,port); if( s.isConnected() ){ log("serveur : "+s.getInetAddress().getHostAddress()+":"+s.getPort()); accepted((byte)1); return true; } } catch(IOException e){ log("pb connexion à "+addr+":"+port+" "+e.getMessage()); } return false; } // notification de la connexion d'un client ou à un serveur private void accepted(byte k){ try{ // on récupère les streams in = new BufferedInputStream(s.getInputStream()); out = new BufferedOutputStream(s.getOutputStream()); } catch(IOException e){ log("pb accepté "+e.getMessage()); return; } // initialisation 1444444K (K=1 client) b[0] = 1; // commande b[13] = k; // param for(int i=1;i<13;i++) b[i] = 4; // tous les trous à 4 if( k == 1 ){ send(1,k); // trame d'initialisation log("trame d'initialisation envoyée, attente du serveur..."); printgame(b); } receive(); // écoute du jeu } // envoyer un message private boolean send(int cmd,int arg){ // int pour ne pas fatiguer mon clavier :/ b[13] = (byte)arg; // param b[0] = (byte)cmd; // cmd if( cmd == 3 ){ if( arg > 0 && arg < endmessages.length ) log("end message, envoi de ["+endmessages[arg]+"]"); if( arg == 1 ) log("VOUS AVEZ GAGNE!! Score : "+moi+" / "+lui); else if( arg == 2 ) log("VOUS AVEZ PERDU.. Score : "+moi+" / "+lui); else if( arg == 3 ) log("DRAW.. Score : "+moi+" / "+lui); } // fin explicite // !todo le reste du tableau est à maj dans les 2 sens // for(int i=0;i<b.length;i++) log("b["+i+"]="+b[i]); try{ out.write(b,0,req_size); out.flush(); LastSend = System.nanoTime(); return true; } catch(IOException e){ log("pb send; "+e.getMessage()); return false; } } // recevoir un message private void receive(){ try{ byte[] response = new byte[req_size]; in.read(response,0,req_size); if( LastSend > 0 ){ log("Temps d'exécution adverse ["+(System.nanoTime()-LastSend)+" ns]"); LastSend = 0; } switch( response[0] ){ case (byte)1: // ini if( checkGame(response) ){ if( response[13] == 1 ) // le serveur commence à jouer (reçu le 1 du client) play(response); // appel de l'IA ou humain ici else log("initialisation : trame suspecte"); } break; case (byte)2: // play if( updateGame(response) ) play(response); // appel de l'IA ou humain ici break; case (byte)3: // stop if( response[13] > 0 && response[13] < endmessages.length ) log("end message de l'adversaire : "+endmessages[response[13]]); endGame(true); break; default: log("pb switch #1 "+response[0]); break; } } catch(IOException e){ log("pb receive "+e.getMessage()); } } // verifie le jeu private boolean checkGame(byte[] a){ if( a.length != req_size ){ send(3,7);// coup invalide return false; } for(int i=1;i<13;i++) if( (i < 7 && a[i+6] != b[i]) || (i > 8 && a[i-6] != b[i]) ){ send(3,4); // jeux différents log("jeu adverse:"); printgame(a); log("mon jeu:"); printgame(b); return false; } return true; } // mise à jour par rapport à ses propres coups public void play(byte[] a){ if( a.length != req_size || a[13] < 1 || a[13] > 6 ) send(3,7); // coup invalide else{ b[13] = a[13]; // on récupère le coup de l'adversaire byte coup = play2(b); if( coup < 1 || coup > 6 || b[coup] == 0 ) send(3,8); // give up else{ // algo de semaison byte c = coup,d = b[coup]; b[coup] = 0; while( d > 0 ){ c++; if( c == coup ) c++; if( c > 12 ){ if( coup != 1 ) c = 1; else c = 2; } b[c]++; d--; } // algo de récolte while( b[c] > 1 && b[c] < 4 && c > 6 && c < 13 ){ moi += b[c]; b[c] = 0; c--; } // famine if( (b[12]+b[11]+b[10]+b[9]+b[8]+b[7]) == 0 ){ lui += (b[1]+b[2]+b[3]+b[4]+b[5]+b[6]); b[1]=0;b[2]=0;b[3]=0;b[4]=0;b[5]=0;b[6]=0; log("famine!"); } printgame(b); send(2,coup); if( !endGame(false) ) receive(); } } } public byte play2(byte[] b){ boolean manuel = false; printgame(b); if( manuel ){ log("coup:"); try{ BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); byte coup = Integer.decode(in.readLine()).byteValue(); if( coup < 1 || coup > 6 || b[coup] == 0 ){ log("coup errone"); return play2(b); } return coup; } catch(IOException e){ log("pb clavier #2, "+e.getMessage()); return 0; } } //else //return Awale.IA(b); // on interroge l'ia return req_size; } // mise à jour par rapport aux coups adverses public boolean updateGame(byte[] a){ if( a.length != req_size || a[13] < 1 || a[13] > 6 ){ log("updateGame, taille incorrecte "+a[13]+" "+a.length); send(3,7); // cheat return false; } // on inverse le coup (6 devient 12, 5 devient 11,... 1 devient 7) byte coup = (byte)(a[13]+6); if( b[coup] == 0 ){ log("case vide, paramètre incorrect #3 "+a[1]); send(3,6); // cas vide return false; } log("l'adversaire a joué : "+coup); // algo de semaison byte c = coup,d = b[coup]; b[coup] = 0; while( d > 0 ){ c++; if( c == coup ) c++; if( c > 12 ){ if( coup != 1 ) c = 1; else c = 2; } b[c]++; d--; } // algo de récolte while( b[c] > 1 && b[c] < 4 && c < 7 && c > 0 ){ lui += b[c]; b[c] = 0; c--; } // famine if( (b[1]+b[2]+b[3]+b[4]+b[5]+b[6]) == 0 ){ moi += (b[12]+b[11]+b[10]+b[9]+b[8]+b[7]); b[12]=0;b[11]=0;b[10]=0;b[9]=0;b[8]=0;b[7]=0; log("famine!"); } return (!endGame(false) && checkGame(a)); } private boolean endGame(boolean bAnnounced){ // lui/moi > 24 if( moi > 24 ) send(3,1); // you've lose! else if( lui > 24 ) send(3,2); // you've won! else if( lui == 24 && moi == 24 ) send(3,3); // draw else if( bAnnounced ) log("fin inattendu, vous avez gagné"); else return false; return true; } // printgame() affiche le jeu en cours private void printgame(byte[] b){ log("===== JEU EN COURS ====="); log("\t"+b[12]+"\t"+b[11]+"\t"+b[10]+"\t"+b[9]+"\t"+b[8]+"\t"+b[7]); log("\t"+b[1]+"\t"+b[2]+"\t"+b[3]+"\t"+b[4]+"\t"+b[5]+"\t"+b[6]); log("===== score: "+moi+" / "+lui); } /** * affiche les messages * peut être modifié pour afficher * autre part que dans la console... */ public void log(String text){ System.out.println(text); } }Et voici ce que j'ai mis dans mon programme principal (fonction main) pour appeler NetAwale :
//début fonction réseau NetAwale na = new NetAwale(awale); try{ BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); na.log("AWALE MODE [1=IA,2=HUMAIN,*=SORTIE]"); switch(Integer.decode(in.readLine()).intValue()){ case 1: manuel = false; break; case 2: manuel = true; break; default: na.log("sortie"); return; } na.log("AWALE NET [1=SERVER,2=CLIENT,*=SORTIE]"); int port; switch(Integer.decode(in.readLine()).intValue()){ case 1: //na.log("Port local?"); port = 2222; //port = Integer.decode(in.readLine()).intValue(); na.listen(port); break; case 2: //na.log("Adresse?"); String adresse = "192.168.1.10"; //String adresse = in.readLine(); //na.log("Port distant?"); port = 2222; //port = Integer.decode(in.readLine()).intValue(); na.connect(adresse,port); break; default: na.log("sortie"); break; } } catch(IOException e){ na.log("pb clavier #1, "+e.getMessage()); } } });