<commit_before>import java.util.concurrent.LinkedBlockingQueue;
import java.util.Random;

static PApplet sketchApplet;
static final ImpendingDoom self = new ImpendingDoom();
static final Random prng = new Random();

static Board board;
static Button playButton;
static Button nextLevel;
static DifficultyButton difficultyButton;
static TowerButton currentTower;

static boolean gameStarted;
static boolean levelRunning = true; // prevent placing during title screen
static boolean levelGenerated;

static int currency;
static int score;

static final color BG = #5C00C6;
static final int INITIAL_DELAY = 3000;

static int difficulty = 2;
static int level = 1;
static int playerHealth = 10;
static int delay = INITIAL_DELAY;

static final int NUM_ENEMIES = 4;
static final int NUM_TOWERS = 4;
static final PImage[] enemyImages = new PImage[NUM_ENEMIES];
static final PImage[] towerImages = new PImage[NUM_TOWERS];
static final List<Enemy> enemyList = new ArrayList<Enemy>();
static final List<Tower> towerList = new ArrayList<Tower>();

static final LinkedBlockingQueue<Enemy> dqueue = new LinkedBlockingQueue<Enemy>();
static final ArrayList<Float[]> path = new ArrayList<Float[]>();

void setup() {
  sketchApplet = this;

  size(900, 900);
  background(BG);
  noStroke();
  textAlign(CENTER, CENTER);

  for ( int i = 0; i < NUM_ENEMIES; i++ ) {
    enemyImages[i] = loadImage("enemy" + (i + 1) + ".png");
    enemyList.add(
        (Enemy) Utilities.createObject("ImpendingDoom$Enemy" + (i + 1), self, delay, path));
  }

  for ( int i = 0; i < NUM_TOWERS; i++ ) {
    towerImages[i] = loadImage("tower" + (i + 1) + ".png");
    towerList.add(
        (Tower) Utilities.createObject("ImpendingDoom$Tower" + (i + 1), self, -1, -1));
  }

  playButton = new Button(width / 2, height / 2, 150, 75, "Play!");
  nextLevel = new Button(75, height - 37.5, 150, 75, "Next Level");
  difficultyButton = new DifficultyButton(width / 2, height / 3 * 2, 150, 75, "Normal");
  currentTower = new TowerButton(width - 75, 75, 150, 150, " ");


  // enemyImages[1] = loadImage("chicken.png");
  generatePath();
  board = new Board(path);
  board.boardMap = new Quadtree(0, 0, width);
}

void draw() {
  if ( ! levelGenerated ) {
    generateLevel();
    return;
  }

  if ( gameStarted ) {
    play();
  } else {
    fill(#809B85);
    textSize(50);

    text("Tower Defense", width / 2, height / 2 - 120);
    textSize(20);
    text("<NAME> + <NAME>", width / 2, height / 2 - 70);
    playButton.draw();
    difficultyButton.draw();
  }
}

void placeTowers() {
  Tower t = (Tower) Utilities.createObject(
      Utilities.getName(currentTower.current), self, (float) mouseX, (float) mouseY);
  if ( currency - t.cost < 0 ) {
    return;
  } else {
    board.addTower(t);
    currency -= t.cost;
  }
}

void generatePath() {
  //FIXME: Find a way to programically generate a random path
  float[] edge1 = new float[] {0, 0};
  float[] edge2 = new float[] {900, 900};
  float dy = (edge2[1] - edge1[1]) / edge2[1];
  float dx = (edge2[0] - edge1[0]) / edge2[0];

  for ( int i = 0; i < 900; i++ ) {
    path.add(new Float[] {edge1[0] + (dx * i), edge1[1] + (dy * i)});
  }
}

/** Generates a level.
 * First allocates a "budget" for the level. Enemies are added to the dqueue, with their health
 * values subtracted from the "budget".
 */
void generateLevel() {
  int threshold = level + ceil(random(level / 2, level * 10));

  while ( threshold > 0 ) {
    String className = Utilities.getName(enemyList.get(prng.nextInt(enemyList.size())));
    Enemy tmp = (Enemy) Utilities.createObject(className, self, delay, path);

    dqueue.add(tmp);
    threshold -= tmp.getHealth();
  }

  levelGenerated = true;
}

void play() {
  if ( playerHealth <= 0 ) {
    System.out.println("GAME OVER JERK");
    exit();
  }

  currentTower.draw();
  board.draw();

  if ( ! levelRunning ) {
    textSize(20);
    text("Please select where to place tower", width/2, 40);

    nextLevel.draw();
    currentTower.draw();
    return;
  }

  if ( dqueue.isEmpty() ) {
    if ( board.isEmpty() ) {
      levelRunning = false;
      levelGenerated = false;
      return;
    }

    board.update();
  } else {
    Enemy tmp = dqueue.peek();
    tmp.startDelay();

    if ( tmp.timeLeft() < 0 ) {
      board.addEnemy(dqueue.poll());
    }
  }
}

void mousePressed() {
  if ( playButton.clicked() ) {
    gameStarted = true;
    levelRunning = false;
    difficulty = difficultyButton.state;

    switch ( difficulty ) {
      case 1: currency = 500; playerHealth = 100; return;
      case 2: currency = 200; playerHealth =  50; return;
      case 3: currency = 100; playerHealth =  20; return;
    }
  }<commit_msg>Implement a game over screen<commit_after>import java.util.concurrent.LinkedBlockingQueue;
import java.util.Random;

static PApplet sketchApplet;
static final ImpendingDoom self = new ImpendingDoom();
static final Random prng = new Random();

static Board board;
static Button playButton;
static Button nextLevel;
static DifficultyButton difficultyButton;
static TowerButton currentTower;

static boolean gameStarted;
static boolean levelRunning = true; // prevent placing during title screen
static boolean levelGenerated;

static int currency;
static int score;

static final color BG = #5C00C6;
static final int INITIAL_DELAY = 3000;

static int difficulty = 2;
static int level = 1;
static int playerHealth = 10;
static int delay = INITIAL_DELAY;

static final int NUM_ENEMIES = 4;
static final int NUM_TOWERS = 4;
static final PImage[] enemyImages = new PImage[NUM_ENEMIES];
static final PImage[] towerImages = new PImage[NUM_TOWERS];
static final List<Enemy> enemyList = new ArrayList<Enemy>();
static final List<Tower> towerList = new ArrayList<Tower>();

static final LinkedBlockingQueue<Enemy> dqueue = new LinkedBlockingQueue<Enemy>();
static final ArrayList<Float[]> path = new ArrayList<Float[]>();

void setup() {
  sketchApplet = this;

  size(900, 900);
  background(BG);
  noStroke();
  textAlign(CENTER, CENTER);

  for ( int i = 0; i < NUM_ENEMIES; i++ ) {
    enemyImages[i] = loadImage("enemy" + (i + 1) + ".png");
    enemyList.add(
        (Enemy) Utilities.createObject("ImpendingDoom$Enemy" + (i + 1), self, delay, path));
  }

  for ( int i = 0; i < NUM_TOWERS; i++ ) {
    towerImages[i] = loadImage("tower" + (i + 1) + ".png");
    towerList.add(
        (Tower) Utilities.createObject("ImpendingDoom$Tower" + (i + 1), self, -1, -1));
  }

  playButton = new Button(width / 2, height / 2, 150, 75, "Play!");
  nextLevel = new Button(75, height - 37.5, 150, 75, "Next Level");
  difficultyButton = new DifficultyButton(width / 2, height / 3 * 2, 150, 75, "Normal");
  currentTower = new TowerButton(width - 75, 75, 150, 150, " ");


  // enemyImages[1] = loadImage("chicken.png");
  generatePath();
  board = new Board(path);
  board.boardMap = new Quadtree(0, 0, width);
}

void draw() {
  if ( ! levelGenerated ) {
    generateLevel();
    return;
  }

  fill(#809B85);
  background(BG);

  if ( gameStarted ) {
    if ( playerHealth > 0 ) {
      play();
    } else {
      textSize(50);
      text("GAME OVER", width / 2, height / 2 - 120);
      textSize(20);
      text(String.format("You died on level %s with a final score of %s.", level, score),
          width / 2,
          height / 2 - 70);
    }

    return;
  }

  textSize(50);
  text("Tower Defense", width / 2, height / 2 - 120);
  textSize(20);
  text("<NAME> + <NAME>", width / 2, height / 2 - 70);
  playButton.draw();
  difficultyButton.draw();
  return;
}

void placeTowers() {
  Tower t = (Tower) Utilities.createObject(
      Utilities.getName(currentTower.current), self, (float) mouseX, (float) mouseY);
  if ( currency - t.cost < 0 ) {
    return;
  } else {
    board.addTower(t);
    currency -= t.cost;
  }
}

void generatePath() {
  //FIXME: Find a way to programically generate a random path
  float[] edge1 = new float[] {0, 0};
  float[] edge2 = new float[] {900, 900};
  float dy = (edge2[1] - edge1[1]) / edge2[1];
  float dx = (edge2[0] - edge1[0]) / edge2[0];

  for ( int i = 0; i < 900; i++ ) {
    path.add(new Float[] {edge1[0] + (dx * i), edge1[1] + (dy * i)});
  }
}

/** Generates a level.
 * First allocates a "budget" for the level. Enemies are added to the dqueue, with their health
 * values subtracted from the "budget".
 */
void generateLevel() {
  int threshold = level + ceil(random(level / 2, level * 10));

  while ( threshold > 0 ) {
    String className = Utilities.getName(enemyList.get(prng.nextInt(enemyList.size())));
    Enemy tmp = (Enemy) Utilities.createObject(className, self, delay, path);

    dqueue.add(tmp);
    threshold -= tmp.getHealth();
  }

  levelGenerated = true;
}

void play() {
  currentTower.draw();
  board.draw();

  if ( ! levelRunning ) {
    textSize(20);
    text("Please select where to place tower", width/2, 40);

    nextLevel.draw();
    currentTower.draw();
    return;
  }

  if ( dqueue.isEmpty() ) {
    if ( board.isEmpty() ) {
      levelRunning = false;
      levelGenerated = false;
      level++;
      return;
    }

    board.update();
  } else {
    Enemy tmp = dqueue.peek();
    tmp.startDelay();

    if ( tmp.timeLeft() < 0 ) {
      board.addEnemy(dqueue.poll());
    }
  }
}

void mousePressed() {
  if ( playButton.clicked() ) {
    gameStarted = true;
    levelRunning = false;
    difficulty = difficultyButton.state;

    switch ( difficulty ) {
      case 1: currency = 500; playerHealth = 100; return;
      case 2: currency = 200; playerHealth =  50; return;
      case 3: currency = 100; playerHealth =  20; return;
    }
  }
{'fraction_non_alphanumeric': 0.144672429955213, 'fraction_numerical': 0.031559212582022704, 'mean_word_length': 3.2961968680089484, 'pattern_counts': {'":': 0, '<': 34, '<?xml version=': 0, '>': 26, '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': '5085063', 'n_tokens_mistral': 3492, 'n_tokens_neox': 3216, 'n_words': 931}