1. Players in a game

A friend of yours is trying to create a simple game. The game consists of players and teams. A team is made up of a collection of players.

All players have a name and a value to denote their strength. Here is the code for Player that your friend has created.

Player.java
/**
 * Represents a player in the zombie game
 */
public class Player {
    private String name;
    private Integer strength;

    public Player(String name, Integer strength) {
        super();
        this.name = name;
        this.strength = strength;
    }

    /**
     * @return this Player's name
     */
    public String getName() {
        return this.name;
    }

    /**
     * @param name  the name to set
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * @return this Player's strength
     */
    public Integer getStrength() {
        return this.strength;

    }

    /**
     * @param strength
     *            the strength to set
     */
    public void setStrength(Integer strength) {
        this.strength = strength;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = (prime * result) + ((this.name == null) ? 0 : this.name.hashCode());
        result = (prime * result) + ((this.strength == null) ? 0 : this.strength.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        Player other = (Player) obj;
        if (this.name == null) {
            if (other.name != null) {
                return false;
            }
        } else if (!this.name.equals(other.name)) {
            return false;
        }
        if (this.strength == null) {
            if (other.strength != null) {
                return false;
            }
        } else if (!this.strength.equals(other.strength)) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "Player [name=" + this.name + ", strength=" + this.strength + "]";
    }

}

Your friend has attempted to create a class to represent a Team but they are stuck.

/**
 * Represents a team of players in the game
 */
public class Team {
    private PlayerList members;

    /**
     * @param members
     */
    public Team(PlayerList members) {
        this.members = members;
    }

    /**
     * @return this Platoon's members
     */
    public PlayerList getMembers() {
        return this.members;
    }

    /**
     * @param members
     *            the members to set
     */
    public void setMembers(PlayerList members) {
        this.members = members;
    }

    /**
     * Decreases the strengh of each player by {@code damage} units.
     *
     * @param damage units to decrease each players strength
     */
    public void takeHit(Integer damage) {
        // loop over members and decrease their
        // strength by damage.
        // Also if any player gets strength 0 or
        // less than 0 remove them from the list
    }

    /**
     * Increase the strengh of each player by {@code boost} units.
     *
     * @param boost units to increase each players strength
     */

    public void takeBoost(Integer boost) {
        // loop over members and increase their
        // strength by boost.
    }

}

They have not designed PlayerLists yet. They do however feel strongly about having the methods takeHit and takeBoost be void methods that update the members of the team using mutation.

Practise Exercises
  • 1) Design PlayerList for your friends game. Make sure you provide an interface for your PlayerList that will allow iterating over your list.

  • 2) Fill in the implementation of takeHit and takeBoost.

2. Singly Linked List

While reviewing your notes on singly linked lists with a friend, you realise that you can implement the same interface without using the SLList class. Instead you can use the Cell class. To convince yourself you wrote down the following ADT for List.

Operation Description

CreateEmpty() : List

Creates an empty list

add(String element) : void

Adds the given element to the start of the list (index 1)

add(String element, Integer index) : void

Adds the given element at index index. The index provided must be a positive integer greater than 0 and less than the size of the list. It the value passed for indes does not meet these criteria we should signal an error

size() : Integer

Returns the number of elements in the list

isEmpty() : Boolean

Returns true if the list has no elements, false otherwise

get(Integer index) : String

Returns the element at index index. The index provided must be a positive integer greater than 0 and less than the size of the list. It the value passed for indes does not meet these criteria we should signal an error

remove(Integer index) : void

Removes the element at index index. The index provided must be a positive integer greater than 0 and less than the size of the list. It the value passed for indes does not meet these criteria we should signal an error

You shared this ADT with the rest of the class and a classmate is stuck trying to implement this interface as a singly linked list using only an interface and one class. Your classmate has provided their code and added comments to indicate the locations where they are stuck. They are using // TODO comments to indicate these locations.

/**
 * The List ADT
 */
public interface List {

    public static List CreateEmpty() {

        return null; // TODO
    }

    void add(String element);

    void addAt(String element, Integer index);

    Integer size();

    Boolean isEmpty();

    String get(Integer index);

    void remove(Integer index);

}
public class Cell implements List {

    private String value;
    private List next;

    public Cell(String value, List next) {
        this.value = value;
        this.next = next;
    }

    @Override
    public void add(String element) {
        // TODO

    }

    @Override
    public void addAt(String element, Integer index) {
        // TODO

    }

    @Override
    public Integer size() {
        // TODO
        return null;
    }

    @Override
    public Boolean isEmpty() {
        // TODO
        return null;
    }

    @Override
    public String get(Integer index) {
        // TODO
        return null;
    }

    @Override
    public void remove(Integer index) {
        // TODO

    }

}
Practise Exercises
  • 3) Finish the implementation of Cell. Add method bodies and tests as appropriate.

  • 4) Make sure you provide implementations for toString(), equals() and hashCode().

3. Queue

Here is another ADT for a simple string StringQueue

Operation Description create() : StringQueue
  • Creates an empty StringQueue

isEmpty: Boolean

  • returns true if the StringQueue is empty

  • returns false if the StringQueue is non-empty

size() : Integer

  • returns 0 if the StringQueue is empty

  • returns the number of elements in the StringQueue

push(String element): void

  • adds the element x to the start of the queue

pop() : void * removes the first element in the StringQueue

peek() : String

  • if the StringQueue is empty peek throws an error

  • if the StringQueue is not empty then return the first element. The queue remains unchanged.

Practise Exercises
  • 5) Provide an implementation for StringQueue.

We would like to now implement a bounded string queue BSQ. A bounded queue works in the same way as your StringQueue but it has a maximum number of elements, called its capacity, that it can hold.

We will need

  1. The ability to pass the capacity (maximum number of elements) that the queue can hold when we create a BSQ

  2. The push operation must now throw an error when we try to add an element to a full BSQ. A full BSQ is a queue whose size is equal to its capacity.

  3. A method to check how many more elements we can add to the BSQ before it reaches maximum capacity.

Practise Exercises
  • 6) Provide an implementation for BSQ.

  • 7) Add the method push2 to BSQ that allows us to push 2 elements in succession, i.e., it is equivalent in effect to calling push twice.

  • 8) Add the method pop2 to BSQ that allows us to pop 2 elements in succession, i.e., it is equivalent in effect to calling pop twice.