<commit_before>package wota.gameobjects;

import java.util.LinkedList;

import wota.utility.Vector;


/**
 * A hill of sugar. 
 * 
 * Sugar can be picked up by first come first serve principle.
 *
 */
public class SugarObject extends GameObject {
	
	private int amount;
	private int visibleAmount; // always at least as big as amount 
	private Sugar sugar;
	/** List of Ants which wait to receive sugar */
	private LinkedList<AntObject> serviceQueue = new LinkedList<AntObject>();
	/** number of ticks an ant will freeze when picking up */
	private int ticksToNextService;
	
	public SugarObject(Vector position, Parameters parameters) {
		super(position, parameters);
		ticksToNextService = parameters.TICKS_SUGAR_PICKUP;
		amount = parameters.INITIAL_SUGAR_IN_SOURCE;
		this.visibleAmount = amount;
	}
	
	public void createSugar() {
		this.sugar = new Sugar(this);
	}
	
	public Sugar getSugar() {
		return sugar;
	}
	
	public int getAmount() {
		return amount;
	}
	
	/** 
	 * @return the number of AntObjects waiting in the serviceQueue
	 */
	public int getQueueSize() {
		return serviceQueue.size();
	}
	
	public void tick() {
		if ( !serviceQueue.isEmpty() ) {
			ticksToNextService--;
			if (ticksToNextService == 0) {
				AntObject theServiced = serviceQueue.removeFirst();
				visibleAmount -= theServiced.getAmountPickedUpLastTime();
				theServiced.unsetSugarTarget();
				ticksToNextService = parameters.TICKS_SUGAR_PICKUP;
			}
		}
	}
	
	public void requestSugarPickup(AntObject antObject, int amountToPickUp) {
		serviceQueue.add(antObject);
		amount -= amountToPickUp;
	}
	
	/**
	 * removes antObject from serviceQueue
	 * @param antObject
	 */
	public void removeFromQueueEarly(AntObject antObject, int amountPickedUp) {
		if (serviceQueue.getFirst() == antObject) {
			ticksToNextService = parameters.TICKS_SUGAR_PICKUP;
		}
		amount += amountPickedUp;
		antObject.unsetSugarTarget();
		serviceQueue.remove(antObject);
	}
	
	public double getRadius() {
		return parameters.INITIAL_SUGAR_RADIUS * Math.sqrt((double) visibleAmount / parameters.INITIAL_SUGAR_IN_SOURCE);
	}

	/**
	 * Gets called by GameWorld when this SugarObject getsRemoved
	 */
	public void getsRemoved() {
		for (AntObject antObject : serviceQueue) {
			antObject.unsetSugarTarget();
		}
	}
}<commit_msg>Fixes #120 (ant killed during the last tick it spends waiting at sugar)<commit_after>package wota.gameobjects;

import java.util.LinkedList;

import wota.utility.Vector;


/**
 * A hill of sugar. 
 * 
 * Sugar can be picked up by first come first serve principle.
 *
 */
public class SugarObject extends GameObject {
	
	private int amount;
	private int visibleAmount; // always at least as big as amount 
	private Sugar sugar;
	/** List of Ants which wait to receive sugar */
	private LinkedList<AntObject> serviceQueue = new LinkedList<AntObject>();
	/** number of ticks an ant will freeze when picking up */
	private int ticksToNextService;
	
	public SugarObject(Vector position, Parameters parameters) {
		super(position, parameters);
		ticksToNextService = parameters.TICKS_SUGAR_PICKUP;
		amount = parameters.INITIAL_SUGAR_IN_SOURCE;
		this.visibleAmount = amount;
	}
	
	public void createSugar() {
		this.sugar = new Sugar(this);
	}
	
	public Sugar getSugar() {
		return sugar;
	}
	
	public int getAmount() {
		return amount;
	}
	
	/** 
	 * @return the number of AntObjects waiting in the serviceQueue
	 */
	public int getQueueSize() {
		return serviceQueue.size();
	}
	
	public void tick() {
		if ( !serviceQueue.isEmpty() ) {
			ticksToNextService--;
			if (ticksToNextService == 0) {
				AntObject theServiced = serviceQueue.removeFirst();
				visibleAmount -= theServiced.getAmountPickedUpLastTime();
				theServiced.unsetSugarTarget();
				ticksToNextService = parameters.TICKS_SUGAR_PICKUP;
			}
		}
	}
	
	public void requestSugarPickup(AntObject antObject, int amountToPickUp) {
		serviceQueue.add(antObject);
		amount -= amountToPickUp;
	}
	
	/**
	 * removes antObject from serviceQueue
	 * @param antObject
	 */
	public void removeFromQueueEarly(AntObject antObject, int amountPickedUp) {
		amount += amountPickedUp;
		antObject.unsetSugarTarget();
		
		// It is possible that the serviceQueue is empty, because the ant could be
		// killed during the tick it is done waiting.
		if (!serviceQueue.isEmpty()) { 
			if (serviceQueue.getFirst() == antObject) {
				ticksToNextService = parameters.TICKS_SUGAR_PICKUP;
			}
			serviceQueue.remove(antObject);
		}
	}
	
	public double getRadius() {
		return parameters.INITIAL_SUGAR_RADIUS * Math.sqrt((double) visibleAmount / parameters.INITIAL_SUGAR_IN_SOURCE);
	}

	/**
	 * Gets called by GameWorld when this SugarObject getsRemoved
	 */
	public void getsRemoved() {
		for (AntObject antObject : serviceQueue) {
			antObject.unsetSugarTarget();
		}
	}
}
{'fraction_non_alphanumeric': 0.09520833333333334, 'fraction_numerical': 0.0010416666666666667, 'mean_word_length': 4.053684210526316, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1994521', 'n_tokens_mistral': 1653, 'n_tokens_neox': 1468, 'n_words': 399}