question (player, field, entity and base.java codes given) Random Walker Player
ID: 3776022 • Letter: Q
Question
question (player, field, entity and base.java codes given)
Random Walker Player
Create a class called RandomWalker that extends the Player class. Your RandomWalker player will continually walk in the playing eld. When it reaches a border of the playing eld, it should “bounce” o the wall and continue walking and bouncing o the borders. Your player does not have to move in straight lines (but it is OK if does).
player class;
public abstract class Player extends Entity{
/** this player's team name */
protected String team;
/** this player's name */
protected String name;
/** this player's number */
protected int number;
/** gets this player's team name
*
* @return the team name that this player is on
*/
public final String getTeam(){ return this.team; }
/** gets this player's name
*
* @return the name of this player
*/
public final String getName(){ return this.name; }
/** gets this player's number
*
* @return the number of this player
*/
public final int getNumber(){ return this.number; }
/** creates a player with specified symbol at specified position
*
* @param f is the field the player will be playing on
* @param side is the side of the field the player will play on
* @param name is this name of the player
* @param number is this player's number
* @param team is this player's team name
* @param symbol is a character (char) representation of this player
* @param x is the x-coordinate of this player
* @param y is the y-coordinate of this player
*/
public Player(Field f, int side, String name, int number, String team, char symbol, double x, double y){
super(symbol, x, y);
this.name = name;
this.number = number;
this.team = team;
f.registerPlayer(this, this.id, side); // register the player on the field
}
/** attempt to catch an opponent player
*
* @param opponent a player on the opponent's team that you are trying to catch
* @param field is the field the game is being played on
* @return true if this player successfully catches the opponent player, false otherwise
*/
public final boolean catchOpponent(Player opponent, Field field){
return field.catchOpponent(this, opponent);
}
/** Informs this player that they have been caught by another player.
* <p>
* This method should only be called from within the Field class.
*
* @param opponent is the player that caught this player
* @param id should be the id of the this player
*/
public void beenCaught(Player opponent, int id){
/* check if the caller knows this entity's id */
if( this.id != id ){
throw new SecurityException("Unauthorized attempt to call beenCaught ");
}
}
/** attempt to free a teammate from jail
*
* @param teammate is another player on this player's team
* @param field is the field the game is being played on
* @return true if the <code>teammate</code> is successfully freed from jail, false otherwise
*/
public final boolean freeTeammate(Player teammate, Field field){
return field.freeTeammate(this, teammate);
}
/** Informs this player that they have been freed by a teammate
* <p>
* This method should only be called from within the Field class.
*
* @param teammate is the player that caught this player
* @param id should be the id of the this player
*/
public void hasBeenFreed(Player teammate, int id){
/* check if the caller knows this entity's id */
if( this.id != id){
throw new SecurityException("Unauthorized attempt to call hasBeenFreed ");
}
}
/** attempt to pick up the opponent's flag
*
* @param field is the field the game is being played on
* @return true if this player successfully picked up the opponent's flag, false otherwise
*/
public final boolean pickUpFlag(Field field){
return field.pickUpFlag(this);
}
/** Informs this player that they have picked up the flag
* <p>
* This method should only be called from with the Field class.
*
* @param id should be the id of the this player
*/
public void hasPickedUpFlag(int id){
/* check if the caller knows this entity's id */
if( this.id != id ){
throw new SecurityException("Unauthorized attempt to call hasPickedUpFlag ");
}
}
/** Informs this player that they have dropped the flag
* <p>
* This method should only be called from within the Field class.
*
* @param id should be the id of the this player
*/
public void hasDroppedFlag(int id){
/* check if the caller knows this entity's id */
if( this.id != id ){
throw new SecurityException("Unauthorized attempt to call hasDroppedFlag ");
}
}
/** attempt to win the game
*
* @param field is the field the game is being played on
* @return true if this player successfully brings the opponent's flag back to this player's base, false otherwise
*/
public final boolean winGame(Field field){
return field.winGame(this);
}
}
field.java
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Arrays;
/** This is the field that a game of Capture the Flag plays on.
* <p>
* The field also acts as a moderator (umpire) for the game to
* try and prevent players from cheating.
* <p>
* A field will have some width (x directions) and a height (y direction).
* The upper left-hand corner is the [0,0] coordinate.
*
* The values of x increase as you move to the right
* The values of y increase as you move down
*/
public class Field{
/** determines if players start at base or not */
public static boolean START_FROM_BASE = true;
/** constant scaling for moving */
protected static long SCALE = 30;
/** determines if the game has been won (completed) */
protected static boolean GAME_IS_WON = false;
/** distance between entities to be considered touching (from centre to centre) */
public static Double ARMS_LENGTH = 12.0;
/** max x-coordinate for entity on field */
final int maxX;
/** max y-coordinate for entity on field */
final int maxY;
/** min x-coordinate for entity on field */
final int minX;
/** min y-coordinate for entity on field */
final int minY;
/** the graphical view of the game */
final View view;
/* */
/* teams in the game */
/* */
/** the team for territory 1 */
protected ArrayList<Entity> team1 = new ArrayList<Entity>();
/** the team for territory 2 */
protected ArrayList<Entity> team2 = new ArrayList<Entity>();
/** getter for the players in team 1
*
* @return the players in team 1
*/
public ArrayList<Entity> getTeam1(){ return this.team1; }
/** getter for the players in team 2
*
* @return the players in team 2
*/
public ArrayList<Entity> getTeam2(){ return this.team2; }
/* */
/* basic entities that all games need */
/* */
/** A look-up table for players and their ids */
protected Hashtable<Entity, Integer> getID = new Hashtable<Entity, Integer>();
/** things for territory 1 */
protected final Entity flag1;
protected final Entity jail1;
protected final Entity base1;
/** things for territory 2 */
protected final Entity flag2;
protected final Entity jail2;
protected final Entity base2;
/** the flag for territory 2 */
/** the jail for territory 1 */
/** the jail for territory 2 */
/** the base for territory 1 */
/** the base for territory 2 */
/** holds the "things" in a game: flags, bases and jails */
ArrayList<Entity> things = new ArrayList<Entity>();
/** A look-up table that maps entity's to the team (territory) they belong to */
protected Hashtable<Entity, Integer> getTeam = new Hashtable<Entity, Integer>();
/** gets the x and y coordinates of flag 1
*
* @return [x,y], the x and y coordinates of the flag 1 on this field
*/
public int[] getFlag1Position(){ return new int[]{ flag1.getX(), flag1.getY() }; }
/** gets the x and y coordinates of flag 2
*
* @return [x,y], the x and y coordinates of the flag 2 on this field
*/
public int[] getFlag2Position(){ return new int[]{ flag2.getX(), flag2.getY() }; }
/** gets the x and y coordinates of jail 1
*
* @return [x,y], the x and y coordinates of the jail 1 on this field
*/
public int[] getJail1Position(){ return new int[]{ jail1.getX(), jail1.getY() }; }
/** gets the x and y coordinates of jail 2
*
* @return [x,y], the x and y coordinates of the jail 2 on this field
*/
public int[] getJail2Position(){ return new int[]{ jail2.getX(), jail2.getY() }; }
/** gets the x and y coordinates of base 1
*
* @return [x,y], the x and y coordinates of the base 1 on this field
*/
public int[] getBase1Position(){ return new int[]{ base1.getX(), base1.getY() }; }
/** gets the x and y coordinates of base 2
*
* @return [x,y], the x and y coordinates of the base 2 on this field
*/
public int[] getBase2Position(){ return new int[]{ base2.getX(), base2.getY() }; }
/** getter for all the "things" in the game: flags, bases and jails
*
* @return an arraylist containing both flags, bases and jails in this field
*/
public ArrayList<Entity> getThings(){
/* hard-coded list of all things in the game. Change this if you want to add more things */
Entity[] allThings = new Entity[]{ flag1, flag2, base1, base2, jail1, jail2 };
return new ArrayList<Entity>( Arrays.asList(allThings) );
}
/* */
/* methods that the game will use */
/* */
/** update all entities on the field
* <p>
* update the position of all entity's on this field
*/
public void update(){
for(Entity en: team1){
try{
en.updatePosition(SCALE*1, this, getID.get(en));
}catch(EntityOutOfBoundsException e){
// add code here
}
}
for(Entity en: team2){
try{
en.updatePosition(SCALE*1, this, getID.get(en));
}catch(EntityOutOfBoundsException e){
// add code here
}
}
for(Entity en: things){
try{
en.updatePosition(SCALE*1, this, getID.get(en));
}catch(EntityOutOfBoundsException e){
// add code here
}
}
}
/** have all entities on this field "play" (perform their own logic) */
public void play(){
for(Entity e: team1){
e.play(this);
}
for(Entity e: team2){
e.play(this);
}
for(Entity e: things){
e.play(this);
}
}
/** draw the current state of the game */
public void draw(){
view.update();
view.draw(team1, team2, things);
}
/** Assigns a player to given territory on the field
* <p>
* Registers a player to a side (territory) on the field. If <code>START_FROM_BASE</code> is
* true, a registered player will have its position set be the same as the base for
* territory they are being registered to.
* <p>
* Side effects: registers a player with a territory. Assigns a sprite (image) to the player.
* Players position is set to their base if START_FROM_BASE is true.
*
* @param a is a player
* @param id is the player's id number
* @param territory is either 1 or 2 (representing a territory)
* @return true if <code>a</code> is not already registered, <code>territory</code> is 1 or 2,
* and the player's coordinates are not on the other territory. False, otherwise.
*/
public boolean registerPlayer(Player a, int id, int territory){
if( getTeam.containsKey(a) || territory < 1 || territory > 2){
return false;
}
if( territory == 1 ){
if (a.getX() > maxX/2){
/* player must be on the correct side of the field */
return false;
}
a.setSprite("sprites/blue.png", id);
if(START_FROM_BASE){
a.setX(base1.getX(), id);
a.setY(base1.getY(), id);
}
team1.add(a);
}else{
if (a.getX() < maxX/2){
/* player must be on the correct side of the field */
return false;
}
a.setSprite("sprites/red.png", id);
if(START_FROM_BASE){
a.setX(base2.getX(), id);
a.setY(base2.getY(), id);
}
team2.add(a);
}
getTeam.put(a, territory);
getID.put(a, id);
return true;
}
/** Assigns a non-player entity to given territory on the field
* <p>
* Side effects: registers a non-player entity with a territory.
* Assigns a sprite (image) to the entity.
* Remembers the entity's id.
*
* @param a is an entity (non-player)
* @param id is the entity's id number
* @param territory is either 1 or 2 (representing a territory)
*/
public boolean registerThing(Entity a, int id, int territory){
if( territory < 1 || territory > 2){
return false;
}
// currently only remembers the thing's id
getID.put(a, id);
return true;
}
/* */
/* methods that players use */
/* */
/** Attempt to catch a player
*
* @param a is a player trying to catch player <code>b<code>
* @param b is a player
* @return true if <code>a</code> and <code>b</code> on are on different teams
* and are within ARMS_LENGTH of each other. False otherwise.
*/
public boolean catchOpponent(Player a, Player b){
if( a.getTeam().equals(b.getTeam()) ){
return false;
}
if( Math.hypot( a.getX() - b.getX(), a.getY() - b.getY() ) <= ARMS_LENGTH ){
return true;
}
return false;
}
/** attempt to free a player from jail
*
* @param a is a player trying to free a teammate from jail
* @param b is a player
* @return true if <code>a</code> and <code>b</code> are on the same team,
* <code<b</code> is in jail, and <code>a</code> is within ARMS_REACH of
* the jail where <code>b</code> is located. False otherwise.
*/
public boolean freeTeammate(Player a, Player b){
//
// need to add some code here
//
return false;
}
/** attempt to pick up a flag
*
* @param a is a player trying to pick up a flag
* @return true if <code>a</code> is within ARMS_REACH of
* the opposing team's flag and it is not being carried by anyone else.
* Returns false otherwise.
*/
public boolean pickUpFlag(Player a){
Entity b = flag1;
if( getTeam.get(a).equals(new Integer(1)) ){
b = flag2;
}
if( Math.hypot( a.getX() - b.getX(), a.getY() - b.getY() ) <= ARMS_LENGTH ){
return true;
}
return false;
}
/** attempt to win the game
*
* @param a is a player
* @return true if <code>a</code> is carrying its opponent's flag
* and is with ARMS_REACH of its own base. False otherwise.
*/
public boolean winGame(Player a){
Entity b = base1;
if( getTeam.get(this).equals(new Integer(1)) ){
b = base2;
}
//
// needs some code to determine if a is carrying the flag
//
if( Math.hypot( a.getX() - b.getX(), a.getY() - b.getY() ) <= ARMS_LENGTH ){
GAME_IS_WON = true;
return true;
}
return false;
}
/** Asks if the game is still running (no winner yet)
*
* @return true if the game is still running (the game has not been won) and false otherwise.
*/
public boolean gameStillRunning(){
return !GAME_IS_WON;
}
/** create the default playing field
* <p>
* width of field = 800 pixels
* height of field = 600 pixels
*/
public Field(){
// initialize field dimensions (hardcoded for now)
maxX = 810; minX = 10;
maxY = 610; minY = 10;
// initialize all the "things" in the game
flag1 = new Flag(this, 1, 'f', 34+minX, 191+minY, "sprites/blueFlag.png");
jail1 = new Jail(this, 1, 'j', 29+minX, 399+minY, "sprites/jail.png");
base1 = new Base(this, 1, 'b', 29+minX, 199+minY, "sprites/blueBase.png");
getTeam.put(base1, 1); getTeam.put(jail1,1); getTeam.put(flag1, 1);
things.add(base1); things.add(jail1); things.add(flag1);
flag2 = new Flag(this, 2, 'F', 754+minX, 391+minY, "sprites/redFlag.png");
jail2 = new Jail(this, 2, 'J', 749+minX, 199+minY, "sprites/jail.png");
base2 = new Base(this, 2, 'B', 749+minX, 399+minY, "sprites/redBase.png");
getTeam.put(base2, 2); getTeam.put(jail2,2); getTeam.put(flag2, 2);
things.add(base2); things.add(jail2); things.add(flag2);
// initialize the view
view = new View(minX, minY, maxX, maxY);
}
}
Entity class
/**
* Entity class to represent "things" in the game: players, flags, jails, bases, etc.
*/
public abstract class Entity{
/** time scaling factor. Will be more important when View is graphics based */
public static double TIME_SCALE = 50;
/** character representation of this entity */
protected char symbol;
/** current x-coordinate of this entity */
protected double x;
/** current y-coordinate of this entity */
protected double y;
/** current speed in x-direction of this entity */
protected double speedX;
/** current speed in y-direction of this entity */
protected double speedY;
/** unique ID for entity */
protected int id;
protected static int ID = 0; // used to generate unique id's
/** maximum speed for a player for use in tournament */
public static final int MAX_SPEED = 10;
/** creates an entity (for players) with specified symbol at specified position
*
* @param symbol is a character (char) representation of the entity
* @param x is the x-coordinate of the entity
* @param y is the y-coordinate of the entity
*/
public Entity(char symbol, double x, double y){
this.symbol = symbol;
this.x = x;
this.y = y;
this.id = ID; // set the ID for the entity
ID +=1; // update the ID counter for the next entity created
}
/** constructor for non-player things
*
* @param symbol is a character (char) representation of the entity
* @param x is the x-coordinate of the entity
* @param y is the y-coordinate of the entity
*/
public Entity(Field f, int side, char symbol, double x, double y, String ref){
this(symbol, x, y);
f.registerThing(this, this.id, side); // register with the field
this.sprite = SpriteStore.get().getSprite(ref);
}
/** gets this entity's symbol
*
* @return the symbol of this entity (char)
*/
public char getSymbol(){ return this.symbol; }
/** gets the current speed in the x-direction of this entity
*
* @return the current x-direction speed of this entity
*/
public double getSpeedX(){ return this.speedX; }
/** gets the current speed in the y-direction of this entity
*
* @return the current y-direction speed of this entity
*/
public double getSpeedY(){ return this.speedY; }
/** gets the current x-coordinate of this entity
*
* @return the current x-coordinate of this entity
*/
public int getX() { return (int) this.x; }
/** gets the current y-coordinate of this entity
*
* @return the current y-coordinate of this entity
*/
public int getY() { return (int) this.y; }
/** update the position of this entity using basic physics
* <p>
* In each direction, we have
* new_position = current_position + speed * time_elapsed
* <p>
* Note: TIME_SCALE will need to be manually adjusted to a value that allows good game play
*
* @param time is a length of time
* @param field is the current field
* @param id is supposed to the entity's id value
*/
public final void updatePosition(long time, Field field, int id)
throws SecurityException, EntityOutOfBoundsException
{
if( id != this.id ){
throw new SecurityException("Unauthorized change of position");
}
/* need to add logic of when to actually throw this */
if(false){
throw new EntityOutOfBoundsException("out of bounds");
}
this.x += (time * this.speedX) / TIME_SCALE;
this.y += (time * this.speedY) / TIME_SCALE;
checkCoordinates(field);
}
/** checks that this player is within the field boundaries
*
* @param field is the field that this entity is on
*/
protected void checkCoordinates(Field field) throws EntityOutOfBoundsException{
// check if this entity is out of the playing field
// if they are throw the exception
// if they are not, do nothing
}
/** logic for this entity (change direction/speed)
* <p>
* logic is based on current playing field (which holds information about
* all entities on the field) and possibly state of this entity. Do NOT
* update the entity's position here, just update speed.
*
* @param field is the current playing field
*/
public abstract void play(Field field);
/** update this entity for any changes to it
* <p>
* For example, if this entity is moved by another entity, this entity's
* positions need to be updated.
*
* @param field is the current playing field
*/
public abstract void update(Field field);
/** override the equals method from Object
* <p>
* This needs to be implemented in a child class
*
* @param o is an object to be tested for equality with this
* @return throws an exception
*/
@Override
public boolean equals(Object o){
if(this == o){return true;}
if(o==null){return false;}
if( o instanceof Entity){
return this.id == ((Entity)o).id;
}
return false;
}
/* Setter methods
*
* We don't want a player of one team to be able to change the
* position or movement of a player on another team.
* The caller needs to know the entity's id number.
*/
/** sets the x-coordinate of this entity
*
* @param x is the new x-coordinate
* @param id should be the entity's id
*/
protected final void setX(double x, int id){
/* check if the caller knows this entity's id */
if( id != this.id ){
throw new SecurityException("Unauthorized change of entity x coordinate");
}
this.x = x;
}
/** sets the y-coordinate of this entity
*
* @param y is the new y-coordinate
* @param id should be the entity's id
*/
protected final void setY(double y, int id){
/* check if the caller knows this entity's id */
if( id != this.id ){
throw new SecurityException("Unauthorized change of entity y coordinate");
}
this.y = y;
}
/** sets the speed in the x-direction of this entity
*
* @param speedX is the new x-direction speed
* @param id should be the entity's id
*/
protected final void setSpeedX(double speedX, int id){
/* check if the caller knows this entity's id */
if( id != this.id ){
throw new SecurityException("Unauthorized change of entity x-direction speed");
}
this.speedX = speedX;
}
/** sets the current speed in the y-direction of this entity
*
* @param speedY is the new y-direction speed
* @param id should be the entity's id
*/
protected final void setSpeedY(double speedY, int id){
/* check if the caller knows this entity's id */
if( id != this.id ){
throw new SecurityException("Unauthorized change of entity y-direction speed");
}
this.speedY = speedY;
}
//
// this is used for graphical representations
//
/** the sprite that will represent this entity */
protected Sprite sprite;
public Sprite getSprite(){ return this.sprite; }
public void setSprite(String ref, int id){
/* check if the caller knows this entity's id */
if( id != this.id ){
throw new SecurityException("Unauthorized change of entity's sprite");
}
this.sprite = SpriteStore.get().getSprite(ref);
}
}
Base.java
public class Base extends Entity{
@Override
public void play(Field field){}
@Override
public void update(Field field){}
@Override
public boolean equals(Object o){
if(o == null) return false;
if(o instanceof Base && this.getSymbol() == ((Base)o).getSymbol()){
return true;
}
return false;
}
public Base(char symbol, int x, int y){
super(symbol, x, y);
speedX = speedY = 0;
}
public Base(Field f, int side, char symbol, int x, int y, String ref){
super(f, side, symbol, x, y, ref);
speedX = speedY = 0;
}
}
Explanation / Answer
public class RandomWalkers {
public static void main(String[] args) {
int n = Integer.parseInt(args[0]);
int[] x = new int[n]; // x positions
int[] y = new int[n]; // y positions
int cellsToVisit = n*n; // cells left to visit
int steps = 0; // number of steps taken
double r;
boolean[][] visited = new boolean[n][n]; // has the i-j been visited?
// start at center
for (int i = 0; i < n; i++) {
x[i] = n/2;
y[i] = n/2;
}
visited[n/2][n/2] = true;
cellsToVisit--;
// repeat until all cells have been visited
while (cellsToVisit > 0) {
steps++;
// move random walker i
for (int i = 0; i < n; i++) {
r = Math.random();
if (r <= 0.25) x[i]++;
else if (r <= 0.50) x[i]--;
else if (r <= 0.75) y[i]++;
else if (r <= 1.00) y[i]--;
// check if (x[i], y[i]) is inside N-by-N boundary and has been visited
if (x[i] < n && y[i] < n && x[i] >= 0 && y[i] >= 0 && !visited[x[i]][y[i]]) {
cellsToVisit--;
visited[x[i]][y[i]] = true;
}
}
}
System.out.println(steps);
}
}
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.