APPENDIX C
MARBLES WORLD SERVER CODE
import
java.net.*;
import
java.io.*;
import
java.util.Date;
import
dtai.net.*;
public
class Connector extends NetServer
{
ConnectToClient c[]={null,null,null,null};
int connects=0;
int mode2=0;
int mode3=0;
int pieces = 0;
int maxpieces = 10;
int effects = 0;
int maxeffects = 0;
int goalx[] =
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int goaly[] =
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int roundno=100; //Keep track of questions and time reports
int count=0; //Keep track of reports in
long time[] = {0,0,0,0}; //time for last round
long report[] = {0,0,0,0}; //reporting time
int speed[] = {-9,-9,-9,-9}; //current speed
long maxturntime;
Date theDate;
long starttime;
String details = "";
String sim_type = "0";
int slowest=0;
public static void main ( String argv[] )
{
try {
int port
= 8765;
new
Connector( port,argv[0] );
}
catch ( Exception e ) {
e.printStackTrace();
}
}
public Connector( int portnum, String
st ) {
super ( portnum );
createGoals(10);
sim_type = st;
if (sim_type.charAt(0)=='0')
{roundno=103;}
}
public void createClientPort( Socket
socket )
{
try {
if(connects <4) {
addClient(new ConnectToClient
( this, socket ));
speed[connects]=-1;
c[connects++].start();
writeToAll("0" + connects + "" + sim_type);
//update player count & simulation_type
System.out.println("0" +
connects + "" + sim_type);
}
}
catch( IOException ioe )
{
ioe.printStackTrace();
}
}
public void addClient(ConnectToClient ctc)
{
if (connects<4) c[connects] = ctc;
System.out.println(connects);
}
public void writeToAll(String s) {
try {
for(int x=0;x<connects;x++) {
c[x].writeUTF(s);
c[x].flush();
}
}
catch( IOException ioe ) {
ioe.printStackTrace();
}
}
public void writeToOne(String s,int n) {
try {
c[n].writeUTF(s);
c[n].flush();
}
catch( IOException ioe ) {
ioe.printStackTrace();
}
}
public void writeDetails(String s,int m) {
try {
if(m==0) {
DataOutput s_out = new
DataOutputStream(new FileOutputStream("worldo.txt"));
s_out.writeUTF(s);
} else {
DataOutput s_out2 = new
DataOutputStream(new FileOutputStream("score.txt"));
s_out2.writeUTF(s);
}
}
catch( IOException ioe ) {
ioe.printStackTrace();
}
}
public void readDetails(int who) {
String line;
try {
DataInput s_in = new
DataInputStream(new FileInputStream("worldi.txt"));
line = s_in.readLine();
writeToOne("1103109" +
line,who);
line = s_in.readLine();
writeToOne("1109112" + line,who);
line = s_in.readLine();
writeToOne("1112113" +
line,who);
line = s_in.readLine();
writeToOne("1113114" +
line,who);
line = s_in.readLine();
writeToOne("1114115" +
line,who);
line = s_in.readLine();
writeToOne("1115116" +
line,who);
line = s_in.readLine();
writeToOne("1116117" +
line,who);
line = s_in.readLine();
writeToOne("1117200" +
line,who);
line = s_in.readLine(); //read the w
line = s_in.readLine(); //read first goal
while(line.charAt(0)!='y') {
writeToOne(line,who);
line = s_in.readLine();
}
line = s_in.readLine(); //read first obstacle
while(line.charAt(0)!='x') {
writeToOne(line,who);
line = s_in.readLine();
}
}
catch( IOException ioe ) {
ioe.printStackTrace();
}
}
public void checkMode2 () {
if (mode2==connects) {
writeToAll("92");
}
}
public void checkMode3 () {
if (mode3==connects) {
writeToAll("93");
writeDetails(details,0);
}
}
public void recalcSpeeds() {
long value=0;
long value1=0;
int catchup[]={0,0,0,0}; //additional added/subtracted to catchup for
reporting lags
if(connects<2) {return;} // no need
to recalc speed if just one participant
if(roundno==100) {
slowest=0;
for(int x=1;x<connects;x++){
if(time[x]>time[slowest]) {
slowest=x;
}
}
for(int x=0;x<connects;x++){
if(x==slowest) {
speed[x]=20;
} else {
speed[x]=(int)(20+((time[slowest]-time[x])/30)); //base initial speed
relative to slowest
}
writeToOne("8" +
speed[x],x);
System.out.println("speed
" + x + " " + speed[x]);
}
} else { //not the initial speed set, use performance to base
for(int x=0;x<connects;x++){ //recalculate speed for next 50 frames for
each participant
time[x]=time[x]-(catchup[x]*50);
//find true time discounting any additions for catch up
if((time[x]-time[slowest])>0
&& (report[x]-report[slowest])>0) { //running too slow
speed[x]=(int)(speed[x]+(time[slowest]-time[x])/200); //adjust for a
quarter of the difference
catchup[x]=(int)((report[slowest]-report[x])/50);
writeToOne("8" +
(speed[x]+catchup[x]),x);
} else if
((time[x]-time[slowest])<0 && (report[x]-report[slowest])<0) {
//running too fast
speed[x]=(int)(speed[x]+(time[slowest]-time[x])/200); //adjust for a
quarter of the difference
catchup[x]=(int)((report[slowest]-report[x])/50);
writeToOne("8" +
(speed[x]+catchup[x]),x); //send catch up correcter without updating speed
variable
} else {
catchup[x]=0;
}
System.out.println("speed
" + x + " " + (speed[x]+catchup[x]) + " time " +
time[x] + " report " + report[x]);
}
}
}
public void createGoals(int n) {
boolean valid;
for(int x=0;x<n;x++) {
valid=false;
while(!valid) {
goalx[x] =
(int)(Math.random()*1000);
goaly[x] = (int)(Math.random()*1000);
valid=true;
double p = goalx[x] - 100;
//i.mw.anim.ball[0]
double q = goaly[x] - 500;
double h2 = p*p + q*q;
double h = Math.sqrt(h2);
if (h < 50) { // too close
valid = false;
} else {
p = goalx[x] - 900;
q = goaly[x] - 500;
h2 = p*p + q*q;
h = Math.sqrt(h2);
if (h < 50) { // too
close
valid = false;
} else {
p = goalx[x] - 500;
q = goaly[x] - 100;
h2 = p*p + q*q;
h = Math.sqrt(h2);
if (h < 50) { // too
close
valid = false;
} else {
p = goalx[x] - 500;
q = goaly[x] - 900;
h2 = p*p + q*q;
h = Math.sqrt(h2);
if (h < 50) { //
too close
valid = false;
}
}
}
}
}
}
}
}
class
ConnectToClient extends NetPortToClient {
Connector conn;
int qno=103; //Question Number
int pno=-1; //Player Number
int value=0;
long value1=0;
int value2=0;
public ConnectToClient(Connector
server, Socket socket) throws IOException {
super( server, socket );
conn=server;
}
protected void readInput() throws
IOException {
String command =
readUTF();
if(command.charAt(0)=='1') {
qno=Integer.parseInt("" + command.charAt(1)+
command.charAt(2)+
command.charAt(3));
pno=Integer.parseInt("" + command.charAt(4));
value=Integer.parseInt("" + command.substring(5));
if(qno==103) {
conn.speed[pno-1]=value;
if(conn.speed[0]!=-1&&conn.speed[1]!=-1&&conn.speed[2]!=-1&&conn.speed[3]!=-1)
{
value=0;
for(int
x=0;x<conn.connects;x++) {
value=value+conn.speed[x];
conn.speed[x]=-1;
}
value=(int)(value/conn.connects);
if (value<1)
{conn.maxturntime=5000;}
else if (value<2)
{conn.maxturntime=10000;}
else if (value<3)
{conn.maxturntime=15000;}
else if (value<4)
{conn.maxturntime=20000;}
else if (value<5)
{conn.maxturntime=25000;}
else if (value<6)
{conn.maxturntime=30000;}
else if (value<7)
{conn.maxturntime=45000;}
else if (value<8)
{conn.maxturntime=60000;}
else
{conn.maxturntime=120000;}
System.out.println("Max Time " + conn.maxturntime);
value2=109;
conn.writeToAll("1" + qno + "" + value2 +
"" + value);
conn.details =
"" + value + "\n";
conn.theDate = new
Date();
conn.starttime =
conn.theDate.getTime();
}
} else if(qno==104) {
conn.maxpieces=value+1;
value2=qno+1;
} else if(qno==105) {
conn.maxeffects=value+1;
value2=qno+1;
} else if(qno==109) {
conn.theDate = new Date();
System.out.println("Against Time " + conn.theDate.getTime() +
" Start " + conn.starttime);
if((conn.theDate.getTime()-conn.starttime)>conn.maxturntime){
for(int
x=0;x<conn.connects;x++) {
if(conn.speed[x]==-1) {conn.speed[x]=-9;}
}
} else {
conn.speed[pno-1]=value;
}
if(conn.speed[0]!=-1&&conn.speed[1]!=-1&&conn.speed[2]!=-1&&conn.speed[3]!=-1){
value=0;
conn.roundno=0;
for(int
x=0;x<conn.connects;x++) {
if(conn.speed[x]!=-9) {
value=value+conn.speed[x];
conn.roundno++;
}
conn.speed[x]=-1;
}
if (conn.roundno==0)
{value=4;}
else {
value=(int)(value/conn.roundno);
}
value2=112;
conn.writeToAll("1" + qno + "" + value2 +
"" + value);
conn.details =
conn.details + value + "\n";
conn.theDate = new
Date();
conn.starttime = conn.theDate.getTime();
}
} else if(qno==200) {
conn.pieces++;
if(conn.pieces<conn.maxpieces) {
value2=200;
} else {
conn.pieces=0;
conn.maxpieces=40;
value2=qno+1;
}
} else if(qno==201) {
conn.effects++;
if(conn.effects<conn.maxeffects) {
value2=201;
} else {
conn.effects=0;
value2=999;
}
} else {
conn.theDate = new Date();
if((conn.starttime+conn.maxturntime)>conn.theDate.getTime()){
for(int
x=0;x<conn.connects;x++) {
if(conn.speed[x]==-1) {conn.speed[x]=-9;}
}
} else {
conn.speed[pno-1]=value;
}
if(conn.speed[0]!=-1&&conn.speed[1]!=-1&&conn.speed[2]!=-1&&conn.speed[3]!=-1){
value=0;
conn.roundno=0;
for(int
x=0;x<conn.connects;x++) {
if(conn.speed[x]!=-9) {
value=value+conn.speed[x];
conn.roundno++;
}
conn.speed[x]=-1;
}
if (conn.roundno==0)
{value=4;}
else {
value=(int)(value/conn.roundno);
}
value2=qno+1;
if(qno==117) {
conn.roundno=100;
for(int
x=0;x<conn.connects;x++) {
conn.speed[x]=0;
}
value2=999;
}
conn.writeToAll("1" + qno + "" + value2 +
"" + value);
conn.details =
conn.details + value + "\n";
if(qno==117) {
conn.details =
conn.details + "w" + "\n";
}
conn.theDate = new
Date();
conn.starttime =
conn.theDate.getTime();
}
}
conn.writeToAll("1" +
qno + "" + value2 + "" + value);
}
else
if(command.charAt(0)=='4') {
conn.pieces++;
value=Integer.parseInt("" +
command.charAt(1));
value++;
if(value>conn.connects) {value=1;}
//update whose turn it is
command = command.charAt(0) +
"" + value + command.substring(2);
conn.writeToAll(command);
conn.details = conn.details +
command + "\n";
if(conn.pieces>=conn.maxpieces) {
conn.details = conn.details
+ "x\n";
conn.writeToAll("92");
}
System.out.println(command);
}
else if(command.charAt(0)=='6') {
//load goals (and other objects)
value=Integer.parseInt("" +
command.charAt(1))-1;
if(conn.sim_type.charAt(0)=='1') {
conn.readDetails(value);
} else {
for(int x=0;x<10;x++) {
command="6"+(1000+conn.goalx[x])+(1000+conn.goaly[x]);
conn.writeToOne(command,value);
System.out.println(command);
if(value==0) {
conn.details = conn.details + command + "\n"; }
}
if(value==0) {conn.details =
conn.details + "y" + "\n";}
}
}
else if(command.charAt(0)=='8') { //reading a time report
System.out.println(command);
value2=Integer.parseInt("" + command.charAt(1)); //player
number
value=Integer.parseInt("" + command.charAt(2)+
command.charAt(3)+
command.charAt(4)); //round number
value1=Long.parseLong(""
+ command.substring(5)); //time for round
if(value==100) { //send initial time estimate
System.out.println("initial speed: " + value1);
conn.time[value2-1]=value1;
conn.count++;
if(conn.count==conn.connects
&& conn.connects>1) { //recalculate time and distribute new speeds
conn.recalcSpeeds();
conn.roundno++;
conn.count=0;
}
} else {
if(conn.connects>1
&& value!=conn.roundno) {
//someway ahead of the current round -- VERY BAD!
System.out.println("PARTICIPANT " + value2 + " WAY TOO
FAST");
}
conn.time[value2-1]=value1;
//store round time
conn.theDate = new Date();
conn.report[value2-1]=conn.theDate.getTime(); //store
report time
conn.count++;
if(conn.count==conn.connects
&& conn.connects>1) { //recalculate time and distribute new speeds
conn.recalcSpeeds();
conn.roundno++;
conn.count=0;
}
}
}
else if(command.charAt(0)=='9' && command.charAt(1)=='2') {
conn.mode2++;
conn.checkMode2();
}
else if(command.charAt(0)=='9' && command.charAt(1)=='3') {
conn.mode3++;
conn.checkMode3();
}
else if(command.charAt(0)=='9' && command.charAt(1)=='8') {
conn.details =
command.substring(2) + "\n";
conn.writeDetails(conn.details,1);
}
else if(command.charAt(0)=='9' && command.charAt(1)=='9') {
conn.details =
command.substring(2) + "\n";
conn.writeDetails(conn.details,1);
} else {
conn.writeToAll(command);
System.out.println(command);
}
}
}