Struggling with learning concepts.

Post Reply
User avatar
gorzak
Posts: 18
Joined: Fri May 18, 2007 2:25 pm

Struggling with learning concepts.

Post by gorzak »

I mentioned in earlier posts that I am teaching myself how to program so I can play this game.
I taught myself basic on a TI82 more than 10 years ago, well enough to make a little game for myself, so I know how to use booleans, logic and math. I don't feel like I am a lost cause. I do feel like I hit a wall though, in that things are getting complex enough that I can't wrap my mind around it all at once. The whole point of Object Oriented is to make things simple by encapsulating. I understand that, but I am having trouble putting that into practice.
I am hoping that someone will volunteer to help me. I would share a bot I have that is about 225 lines, and they would point out how I could break it down into seperate classes and assign them appropiately. It is functionally similar to the Herd example, with a bit more complexity in grouping up. I'd be in for alternative lessons, but the only context in which I have used programming is this game. I've read the Sun tutorials, but they just aren't sticking.
jos
Posts: 5
Joined: Sat Sep 06, 2008 11:47 pm

Post by jos »

I'll give it a try if you like :)
You can just post your source here (that way more people can look at it), though PM or mail to moc.liamgATjosbosmans (slightly munged for spam prevention) is fine too
User avatar
gorzak
Posts: 18
Joined: Fri May 18, 2007 2:25 pm

Post by gorzak »

My thought is have one class for "master" behavior, one for "servant", and this as the default. I can pick out what code belongs to which, but I can't figure out how to make each bot into one or the other.

Code: Select all

import java.util.Random;

public class MasterAndServant {
	
	// behavior modifying constants
	private final int MINIMUM_HERD_MEMBERS,PRECISION_MULTIPLIER;
	{
		MINIMUM_HERD_MEMBERS = 6;
		PRECISION_MULTIPLIER = 256 ;
	}
	// defined by the game rules
	private final int CITY , GRUNT , HOVER , ARTIL , NOUNIT;
	private final int NEUTRAL , MYTEAM, ENEMY;
	private final int GRASS , FOREST , SWAMP;
	private final int CONTINUE , MOVE , STOP;
	private double DX,DY;
	{
		CITY = 0;
		GRUNT = 1;
		HOVER = 2;
		ARTIL = 3;
		NOUNIT = 7;
		
		NEUTRAL = -1;	
		MYTEAM = 0;
		ENEMY = 1;
		
		GRASS = 0;
		FOREST = 1;
		SWAMP = 2;
		
		CONTINUE = 0;
		MOVE = 1;
		STOP = 2;
		
		DX=50;
		DY=50;
	}
	// author defined constants
	private final int  RADIO_ELEMENTS, SIGNAL , INDICATOR , RADIOX, RADIOY ; //outbound radio array elements
	private final int INCOMING_ID , INCOMING_SIGNAL , INCOMING_INDICATOR , INCOMING_RADIOX , INCOMING_RADIOY;//incoming radio array elements
	private final int COMMAND_SIGNAL, COLLECTING_GRUNTS, APPLYING_TO_MASTER, GRUNT_SLAVED ; //radio signals
	{
		//outbound radio array elements
		RADIO_ELEMENTS= 4 ; //number of outbound elements
		SIGNAL = 0;
		INDICATOR = 1;
		RADIOX = 2;
		RADIOY = 3;
		
		//incoming radio array elements
		INCOMING_ID = 0;
		INCOMING_SIGNAL = 1;
		INCOMING_INDICATOR = 2;
		INCOMING_RADIOX = 3;
		INCOMING_RADIOY = 4;
		
		//radio signals
		COMMAND_SIGNAL = 100;
		COLLECTING_GRUNTS = 101;
		APPLYING_TO_MASTER = 102;
		GRUNT_SLAVED = 103;
	}
	public int orderType; //the type of order sent
	public double destX,destY; //this is the destination of any move order
	public int[] radio = new int[RADIO_ELEMENTS]; // we'll use this to communicate with other bots
	
	Random r = new Random(); // help us randomize our actions
	private int lastCommandIndicator ; // we'll use this to see when the leader changes orders
	
	//METHODS
	
	void transmitLocation(double x1, double y1) {//stores a location in the outgoing radio with increased precision.
		radio[RADIOX] = (int) (PRECISION_MULTIPLIER * x1);
		radio[RADIOY] = (int) (PRECISION_MULTIPLIER * y1);
		return;
	}
	
	void followOrders(final int[][] incomingRadio, int leaderNumber){// assigns translated destination from the input array's identified element & updates lastCommandIndicator		
		orderType = MOVE;
		lastCommandIndicator = incomingRadio[leaderNumber][INCOMING_INDICATOR];
		destX = (incomingRadio[leaderNumber][INCOMING_RADIOX] / PRECISION_MULTIPLIER ) ;
		destY = (incomingRadio[leaderNumber][INCOMING_RADIOY] / PRECISION_MULTIPLIER ) ;
		return;
	}
	
	void destinationRandom(){// choose a random destination
		orderType = MOVE;
		destX = r.nextDouble() * (DX);
		destY = r.nextDouble() * (DY);
		return;
	}
	
 	public Object think(final double dx, final double dy, final double x, final double y, final boolean moving, final int terrain, final int ourID, final int ourType, final double hp, final double maxHP, final double range, final double time, final double[] objX, final double[] objY, final int[] objID, final int[] objFaction, final int[] objType, final int[][] incomingRadio) {
		if (ourType == CITY) {orderType = CONTINUE; return this;} // citys dont think
		
		//recon
		int slavesCollected = 0;
		int lowestRecruiterID = 100000;
		int recruiterReference = 100000;
		int commanderReference = 100000;
		if (radio[SIGNAL] == COLLECTING_GRUNTS) lowestRecruiterID = ourID;
		
		for (int i = 0; i < incomingRadio.length; i++) {//for each bot transmitting
			int[] ir = incomingRadio[i];// ir is the transmission of a single bot
			if ( (ir[INCOMING_SIGNAL] == COLLECTING_GRUNTS && (lowestRecruiterID > ir[INCOMING_ID]) ) ) { // thier ID is lower than the current recruiter
				lowestRecruiterID =  ir[INCOMING_ID];
				recruiterReference = i;
			}
			if ( (radio[SIGNAL] == APPLYING_TO_MASTER || radio[SIGNAL] == GRUNT_SLAVED ) && (//I'm looking for a commander
				ir[INCOMING_SIGNAL] == COMMAND_SIGNAL && ir[INCOMING_ID] == radio[INDICATOR]))
			{// and this is him
				commanderReference = i;
			}
			if ((ir[INCOMING_SIGNAL] == GRUNT_SLAVED || ir[INCOMING_SIGNAL] == APPLYING_TO_MASTER)//looking for a leader
				&& ir[INCOMING_INDICATOR] == ourID)
			{//that leader is me
				slavesCollected++;
			}
		} 
		
		if (radio[SIGNAL] == GRUNT_SLAVED && commanderReference >= 10000 ){//slaved but no commander
		radio[SIGNAL] = 0;
		radio[INDICATOR] = 0;
		radio[RADIOX] = 0;
		radio[RADIOY] = 0;
		}// radio set to zeros, like a newborn unit
		
		//orders assigned
		
		orderType = STOP;// default move
		//		if (moving) {orderType = 0; return this;}// debugging
		
		if (radio[SIGNAL] == GRUNT_SLAVED) {//slave
			if (incomingRadio[commanderReference][INCOMING_INDICATOR] == lastCommandIndicator ){// no new command
				{orderType = 0; return this;} 
			}//carry on
			else{//new command
				followOrders(incomingRadio, commanderReference);
				return this;
			}//follow orders
		}
		
		if ( radio[SIGNAL] == COMMAND_SIGNAL){// commander
			 
			if (slavesCollected < MINIMUM_HERD_MEMBERS){// with less than the minimum
			radio[SIGNAL] = COLLECTING_GRUNTS; 
			radio[INDICATOR] = 0;
			transmitLocation(x,y);
			//				return this // if this is in, he doesn't check for other collectors intitially
			}//collecting grunts at my location
			else{  //with more than the minimum
				if(moving) {orderType = 0; return this;}// keep going
				else{// pick,transmit, and go to a random location.
					destinationRandom();// choose a random destination
					radio[INDICATOR]++; // indicate a new order
					transmitLocation(destX,destY);// transmit the new order
					return this; //go there
				}
			}
		}
		
		if (radio[SIGNAL] == COLLECTING_GRUNTS){//collecting grunts
			if (ourID != lowestRecruiterID){// there is another recruiter with a lowerID, apply to him
				radio[SIGNAL] = APPLYING_TO_MASTER;
				radio[INDICATOR] = ourID;
				return this;
				
			}else
			
			{// our ID is lower/lowest
				if (slavesCollected < MINIMUM_HERD_MEMBERS) {// our herd fu is weak, waiting
					return this;
				}else{// our herd is strong, become a commander
					
				 
					radio[SIGNAL] = COMMAND_SIGNAL;
					radio[INDICATOR] = 1000;
					//	destinationRandom();// choose a random destination
					//	radio[INDICATOR]++; // indicate a new order
					//	transmitLocation(destX,destY);// transmit the new order
					return this; 
				}  
			}
		}
		
		if (radio[SIGNAL] == APPLYING_TO_MASTER){// supplicant
			
			 if(commanderReference < 10000){// application accepted
				radio[SIGNAL] = GRUNT_SLAVED;
				lastCommandIndicator = 0;
				return this;
			}
			else {//application pending
				
				
			 
				if (radio[INDICATOR] != lowestRecruiterID){// there is another recruiter with a lowerID, apply to him
					
					
					radio[INDICATOR] = lowestRecruiterID;
					followOrders(incomingRadio , recruiterReference); 
					return this;
					 
				}else{ //applied to the right recruiter
					if (moving) return null;
					else{orderType = 0; return this;}
				} 
			}  
		}
		
		if(radio[SIGNAL] == 0){//not participating
			radio[SIGNAL] = COLLECTING_GRUNTS;//collect grunts
			transmitLocation(x,y);
			return this;
		}
		
		
			destX = 25; destY = 25; orderType = MOVE; return this;
	}
	
	public int build(final double dx, final double dy, final double x, final double y, final int terrain, final int id, final int buildItem, final double hp, final double maxHP, final double time, final double[] objX, final double[] objY, final int[] objID, final int[] objFaction, final int[] objType, final int[][] incomingRadio) {
		if (buildItem != 0) return 0;
		return GRUNT;
	}
}
Rotekian
Posts: 3
Joined: Thu May 29, 2008 6:38 pm

Post by Rotekian »

The easiest way to do this is probably...

Code: Select all

private MasterAndServant myClass;
public MasterAndServant() {
    myClass = null;
}

public Object think(etc) {
    if(myClass != null) {
        return myClass.think(etc);
    } else {
        if(isCommander()) {
            myClass = new Commander();
        } else {
            myClass = new Servant();
        }
    }
}

// And make these classes
//class Commander extends MasterAndServant {  }
//class Servant extends MasterAndServant {  }
Lost in the Wyld
User avatar
gorzak
Posts: 18
Joined: Fri May 18, 2007 2:25 pm

Thanks

Post by gorzak »

I appreciate the input Rotekian, I look forward to giving it a try! Thanks so much.
Post Reply