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 :
Et voici ce que j'ai mis dans mon programme principal (fonction main) pour appeler NetAwale :