/*
* File name: TetrisEnvironment.java (package eas.users.lukas.demos.tetris2)
* Author(s): lko
* Java version: 7.0
* Generation date: 30.05.2013 (11:55:56)
*
* (c) This file and the EAS (Easy Agent Simulation) framework containing it
* is protected by Creative Commons by-nc-sa license. Any altered or
* further developed versions of this file have to meet the agreements
* stated by the license conditions.
*
* In a nutshell
* -------------
* You are free:
* - to Share -- to copy, distribute and transmit the work
* - to Remix -- to adapt the work
*
* Under the following conditions:
* - Attribution -- You must attribute the work in the manner specified by the
* author or licensor (but not in any way that suggests that they endorse
* you or your use of the work).
* - Noncommercial -- You may not use this work for commercial purposes.
* - Share Alike -- If you alter, transform, or build upon this work, you may
* distribute the resulting work only under the same or a similar license to
* this one.
*
* + Detailed license conditions (Germany):
* http://creativecommons.org/licenses/by-nc-sa/3.0/de/
* + Detailed license conditions (unported):
* http://creativecommons.org/licenses/by-nc-sa/3.0/deed.en
*
* This header must be placed in the beginning of any version of this file.
*/
package eas.users.demos.polytris;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import eas.math.geometry.LineSegment2D;
import eas.math.geometry.Polygon2D;
import eas.math.geometry.Rectangle2D;
import eas.math.geometry.Vector2D;
import eas.miscellaneous.useful.MP3Player;
import eas.plugins.standard.visualization.AllroundVideoPlugin;
import eas.simulation.ConstantsSimulation;
import eas.simulation.Wink;
import eas.simulation.agent.GenericSensor;
import eas.simulation.event.EASEvent;
import eas.simulation.spatial.sim2D.gridSimulation.standardEnvironments.AbstractGridEnvironment;
import eas.simulation.spatial.sim2D.gridSimulation.standardGridObjects.GridObject;
import eas.simulation.spatial.sim2D.standardAgents.PacmanAgent2D;
import eas.startSetup.ParCollection;
import eas.users.demos.polytris.agents.BombAgent;
import eas.users.demos.polytris.agents.DynamiteAgent;
import eas.users.demos.polytris.agents.FuseAgent;
import eas.users.demos.polytris.agents.PolytrisWholeAgent;
import eas.users.demos.polytris.agents.VectorVersionOfAgent;
import eas.users.demos.polytris.clocks.ConstantClock;
import eas.users.demos.polytris.clocks.PolytrisClock;
import eas.users.demos.polytris.fieldEvaluation.EvaluateCanyons;
import eas.users.demos.polytris.fieldEvaluation.EvaluateGaps;
import eas.users.demos.polytris.fieldEvaluation.EvaluateHeight;
import eas.users.demos.polytris.fieldEvaluation.EvaluateStone;
import eas.users.demos.polytris.fieldEvaluation.PolytrisEvaluation;
import eas.users.demos.polytris.highscore.Highscore;
import eas.users.demos.polytris.highscore.HighscoreEntry;
/**
* @author lko
*/
public class PolytrisEnvironment extends AbstractGridEnvironment<PacmanAgent2D> {
/**
*
*/
private static final long serialVersionUID = 1682524492848748384L;
private LinkedList<PolytrisEvaluation> evaluations = new LinkedList<PolytrisEvaluation>();
private PolytrisEvaluation stoneEvaluation;
private long score = 0;
private HashMap<Integer, PolytrisWholeAgent> agents;
private HashMap<Integer, PolytrisWholeAgent> pacmanToTetrisAgentMapping;
private Random rand;
private PolytrisClock clock;
private ArrayList<ArrayList<Vector2D>> possibleAgents = new ArrayList<ArrayList<Vector2D>>();
public long getScore() {
return this.score;
}
public PolytrisEnvironment(
ParCollection params,
int width,
int height,
PolytrisClock clock) {
this(params, width, height, clock, null);
}
private int level = -1;
private PolytrisStoneGenerator generator;
public PolytrisEnvironment(
ParCollection params,
int width,
int height,
PolytrisClock clock,
Collection<ArrayList<Vector2D>> possAgents) {
super(0, params, width, height, false);
this.rand = new Random();
this.generator = new PolytrisStoneGenerator(rand);
this.level = params.getParValueInt("Polytris.Level");
this.evaluations.add(new EvaluateCanyons());
this.evaluations.add(new EvaluateGaps());
this.evaluations.add(new EvaluateHeight());
this.stoneEvaluation = new EvaluateStone();
// Bombs.
this.bombPosition = new Vector2D(this.getGridWidth() / 2, 1);
this.bombAgent = new BombAgent(100000, this, this.getParCollection());
this.addAgent(this.bombAgent, bombPosition, 0);
this.bombClock = new ConstantClock(15);
this.clock = clock;
this.agents = new HashMap<Integer, PolytrisWholeAgent>();
this.pacmanToTetrisAgentMapping = new HashMap<Integer, PolytrisWholeAgent>();
this.possibleAgents.addAll(possAgents);
if (params.getParValueBoolean("Polytris.Ultimate")) {
this.scorezName = "scorez-ultimate";
} else {
this.scorezName = "scorez";
}
this.scorezName += "-" + params.getParValueInt("Polytris.Level") + ".dat";
this.scorez = new Highscore(new File("./sharedDirectory/Polytris/" + this.scorezName), params, 10);
}
private boolean addPolytrisAgent(
ArrayList<Vector2D> relativePositions,
Vector2D position,
String agentType) {
PolytrisWholeAgent wholeAgent = new PolytrisWholeAgent(null);
Color agentColor = new Color(rand.nextInt(256), rand.nextInt(256), rand.nextInt(256));
HashSet<Integer> successfullyAddedAgents = new HashSet<Integer>();
for (Vector2D v : relativePositions) {
if (v == null) {
return false;
}
}
if (agentType.equals("dynamite")) {
if (rand.nextBoolean() && rand.nextBoolean()) {
this.showText = "Heavy dynamite!";
this.dynamiteStrength = 2;
} else {
this.showText = "Dynamite!";
this.dynamiteStrength = 1;
}
this.dynamiteAgent = new HashSet<DynamiteAgent>();
}
if (agentType.equals("fuse")) {
this.showText = "Ignate!";
this.fuseAgent = new HashSet<FuseAgent>();
}
for (Vector2D v : relativePositions) {
PacmanAgent2D agent;
if (agentType.equals("dynamite")) {
DynamiteAgent da = new DynamiteAgent(0, this, this.getParCollection());
this.dynamiteAgent.add(da);
agent = da;
this.nextAgentType = "fuse";
} else if (agentType.equals("fuse")) {
FuseAgent fa = new FuseAgent(0, this, this.getParCollection());
this.fuseAgent.add(fa);
agent = fa;
this.nextAgentType = "normal";
} else {
agent = new PacmanAgent2D(0, this, this.getParCollection(), agentColor);
}
agent.addSensor(new GenericSensor<Long, PolytrisEnvironment, PacmanAgent2D>() {
/**
*
*/
private static final long serialVersionUID = -1927354872920066113L;
@Override
public Long sense(PolytrisEnvironment env,
PacmanAgent2D agent) {
return env.score;
}
@Override
public String id() {
return "YOUR SCORE";
}
});
agent.addSensor(new GenericSensor<Long, PolytrisEnvironment, PacmanAgent2D>() {
/**
*
*/
private static final long serialVersionUID = -219056252893169910L;
@Override
public Long sense(PolytrisEnvironment env,
PacmanAgent2D agent) {
return -1l;
}
private ArrayList<Vector2D> nextSensingAgent = null;
private VectorVersionOfAgent currentAgent;
@Override
public BufferedImage getSensorView(
PolytrisEnvironment env, PacmanAgent2D agent) {
try {
if (this.nextSensingAgent != PolytrisEnvironment.this.nextAgent) {
currentAgent = new VectorVersionOfAgent(
PolytrisEnvironment.this.nextAgent,
PolytrisEnvironment.this.getParCollection());
this.nextSensingAgent = PolytrisEnvironment.this.nextAgent;
}
return currentAgent.generateImage();
} catch (Exception e) {
return new BufferedImage(50, 50, BufferedImage.TYPE_3BYTE_BGR);
}
}
@Override
public String id() {
return "Next agent";
}
});
wholeAgent.addPartAgent(agent);
Vector2D pos = new Vector2D(position);
pos.translate(v);
float angle;
if (!agentType.equals("normal")) {
angle = 0;
} else {
angle = (float) ((rand.nextFloat() - 0.5) * 360);
}
if (!this.addCollidingAgent(agent, pos, angle)) {
for (int i : successfullyAddedAgents) {
this.removeAgent(i);
}
return false;
} else {
successfullyAddedAgents.add(agent.id());
}
this.pacmanToTetrisAgentMapping.put(agent.id(), wholeAgent);
}
this.agents.put(agents.size(), wholeAgent);
return true;
}
public PolytrisWholeAgent getTetrisAgent(int agentID) {
return this.agents.get(agentID);
}
private HashMap<Integer, Vector2D> prevPosOfPacmanAgents;
private void storeTempPositions(int agentID) {
this.prevPosOfPacmanAgents = new HashMap<Integer, Vector2D>();
for (PacmanAgent2D p : this.agents.get(agentID).getAgents()) {
this.prevPosOfPacmanAgents.put(p.id(), this.getAgentPosition(p.id()));
}
}
private void resetToTempPositions() {
for (int id : this.prevPosOfPacmanAgents.keySet()) {
this.setAgentPosition(id, this.prevPosOfPacmanAgents.get(id));
}
}
private boolean lowerAgent() {
return this.lowerAgent(this.getCurrentAgentID(), true);
}
private boolean lowerAgent(int agentID, boolean newAgent) {
this.storeTempPositions(agentID);
for (PacmanAgent2D p : this.agents.get(agentID).getAgents()) {
Vector2D pos = this.getAgentPosition(p.id());
if (!this.setAgentPosition(p.id(), new Vector2D(pos.x, pos.y + 1))) {
this.resetToTempPositions();
try {
if (newAgent) {
addScore += this.agents.get(this.getCurrentAgentID()).getAgents().size();
}
this.agentPos = this.getAgentPosition(this.agents.get(this.getCurrentAgentID()).getAgents().get(0).id());
} catch(Exception e) {}
if (newAgent) {
this.newRandomAgent(this.nextAgentType);
}
return false;
}
}
return true;
}
private boolean agentLeft() {
return this.agentLeft(this.getCurrentAgentID());
}
private boolean agentLeft(int agentID) {
this.storeTempPositions(agentID);
for (PacmanAgent2D p : this.agents.get(agentID).getAgents()) {
Vector2D pos = this.getAgentPosition(p.id());
if (!this.setAgentPosition(p.id(), new Vector2D(pos.x - 1, pos.y))) {
this.resetToTempPositions();
return false;
}
}
return true;
}
private boolean agentRight() {
return this.agentRight(this.getCurrentAgentID());
}
private boolean agentRight(int agentID) {
this.storeTempPositions(agentID);
for (PacmanAgent2D p : this.agents.get(agentID).getAgents()) {
Vector2D pos = this.getAgentPosition(p.id());
if (!this.setAgentPosition(p.id(), new Vector2D(pos.x + 1, pos.y))) {
this.resetToTempPositions();
return false;
}
}
return true;
}
private Vector2D getMiddle(int wholeAgentID) {
PolytrisWholeAgent agent = this.agents.get(wholeAgentID);
return this.getAgentPosition(agent.getAgents().get(0).id());
}
private boolean agentTurn() {
return this.agentTurn(this.getCurrentAgentID());
}
private boolean agentTurn(int agentID) {
this.storeTempPositions(agentID);
Vector2D middle = this.getMiddle(agentID);
for (PacmanAgent2D p : this.agents.get(agentID).getAgents()) {
Vector2D v = new Vector2D(this.getAgentPosition(p.id()));
v.rotate(middle, (float) (-Math.PI / 2));
if (!this.setAgentPosition(p.id(), v)) {
this.resetToTempPositions();
return false;
}
}
return true;
}
private final float heightGO = 5;
@Override
public BufferedImage getOutsideView() {
BufferedImage img = super.getOutsideView();
Graphics2D g = img.createGraphics();
int width = this.getGridWidth();
int height = this.getGridHeight();
float epsilon = (float) 0.5;
Rectangle2D r = new Rectangle2D(new Vector2D(0 - epsilon, 0 - epsilon), new Vector2D(width - epsilon, height - epsilon));
LineSegment2D l = new LineSegment2D(new Vector2D(0 - epsilon, heightGO + epsilon), new Vector2D(this.getWidth() - epsilon, heightGO + epsilon));
g.setColor(Color.red);
g.drawPolygon(this.getPolygonInVisualization(l.toPol2D()).toPol());
g.setStroke(new BasicStroke(5));
g.setColor(Color.orange);
g.drawPolygon(this.getPolygonInVisualization(r.toPol2D()).toPol());
g.setColor(Color.black);
g.setStroke(new BasicStroke(8));
float maxX = Float.NEGATIVE_INFINITY;
float minX = Float.POSITIVE_INFINITY;
for (PacmanAgent2D p : this.agents.get(this.getCurrentAgentID()).getAgents()) {
Vector2D pos = this.getAgentPosition(p.id());
try {
if (pos.x > maxX) {
maxX = (float) pos.x;
}
if (pos.x < minX) {
minX = (float) pos.x;
}
} catch (Exception e) {
e.printStackTrace();
}
}
LineSegment2D l2 = new LineSegment2D(
new Vector2D(minX - epsilon, this.getGridHeight() - epsilon),
new Vector2D(maxX + epsilon, this.getGridHeight() - epsilon));
g.drawPolygon(this.getPolygonInVisualization(l2.toPol2D()).toPol());
// Show text.
if (this.showText != null) {
this.showCyclesText = 20 + this.showText.length() * 2;
this.showNewText = this.showText;
this.showText = null;
maxSize = 30;
}
if (this.showCyclesText > 0) {
this.showCyclesText--;
Vector2D pos = new Vector2D(0, this.getGridHeight() / 2);
pos = this.getPointInVisualization(pos);
float size = 40 + this.showCyclesText;
g.setFont(new Font("MV Boli", Font.BOLD, (int) size));
Color fontColor = Color.red;
g.setColor(fontColor);
g.drawString("" + this.showNewText, (int) pos.x, (int) pos.y);
}
// Show score.
if (this.addScore > 0) {
this.showCyclesScore = 20 + this.addScore / 20;
this.newScore = addScore;
this.addScore = 0;
maxSize = Math.min(Math.max((this.newScore + this.showCyclesScore) / 2, 10), 500);
}
if (this.showCyclesScore > 0) {
this.showCyclesScore--;
Vector2D pos = new Vector2D(this.agentPos);
pos.y = Math.max(this.getGridHeight() / 2, pos.y);
Vector2D subVec = new Vector2D((float) Math.pow(this.newScore, 0.33), 0);
if (this.getVisualizationAngleCenterPoint() != null) {
subVec = Vector2D.NULL_VECTOR;
pos = new Vector2D(this.agentPos);
}
pos.sub(subVec);
pos = this.getPointInVisualization(pos);
float size = Math.max((Math.min(this.newScore, 500) + this.showCyclesScore) / 2, 10);
g.setFont(new Font("MV Boli", Font.BOLD, (int) size));
Color fontColor = new Color(
(int) Math.max(Math.min((maxSize - size) * 7 / maxSize * 255, 255), 0),
(int) Math.max(Math.min((maxSize - size) * 1 / maxSize * 255, 255), 0),
(int) Math.max(Math.min((maxSize - size) * 1 / maxSize * 255, 255), 0)
);
g.setColor(fontColor);
g.drawString("" + this.newScore, (int) pos.x, (int) pos.y);
}
if (this.bombRunning) {
Vector2D bombpos = this.getAgentPosition(this.bombAgent.id());
g.setColor(Color.red);
g.setStroke(new BasicStroke(2));
Polygon2D line1 = new Polygon2D();
line1.add(new Vector2D(-epsilon, bombpos.y + epsilon));
line1.add(new Vector2D(this.getGridWidth() - epsilon, bombpos.y + epsilon));
Polygon2D line2 = new Polygon2D();
line2.add(new Vector2D(-epsilon, bombpos.y - this.bombs + epsilon));
line2.add(new Vector2D(this.getGridWidth() - epsilon, bombpos.y - this.bombs + epsilon));
g.drawPolygon(this.getPolygonInVisualization(line1).toPol());
g.drawPolygon(this.getPolygonInVisualization(line2).toPol());
}
return img;
}
private int newScore;
private int showCyclesScore = 0;
private int showCyclesText = 0;
private String showNewText = null;
private float maxSize;
private boolean isRegularAgent(GridObject agent) {
return !BombAgent.class.isInstance(agent)
&& !DynamiteAgent.class.isInstance(agent)
&& !FuseAgent.class.isInstance(agent);
}
@Override
public boolean collides(PacmanAgent2D agent, Vector2D pos, double angle,
Vector2D scale) {
int x = this.getRealX(Math.round(pos.x));
int y = this.getRealY(Math.round(pos.y));
if (this.isCollidingAgent(agent.id())) {
for (GridObject g : this.getFieldPosition(x, y)) {
try {
PacmanAgent2D gridAgent = (PacmanAgent2D) g;
if (this.pacmanToTetrisAgentMapping.get(agent.id()) != this.pacmanToTetrisAgentMapping.get(gridAgent.id())) {
if (this.isCollidingAgent(gridAgent.id()) && gridAgent.id() != agent.id()) {
if (this.isRegularAgent(agent) || this.isRegularAgent(gridAgent)) {
return true;
}
}
}
} catch (Exception e) {
}
}
}
return false;
}
private void agentLowerCompletely(int agentID, boolean newAgent) {
boolean lowering = this.lowerAgent(agentID, newAgent);
while (lowering) {
lowering = this.lowerAgent(agentID, newAgent);
}
if (this.getFirstFullLine() < 0) {
new Thread(new MP3Player(new File("./sharedDirectory/Polytris/lower"))).start();
}
}
private int getFirstFullLine() {
for (int j = this.getGridHeight() - 1; j >= 0; j--) {
boolean full = true;
for (int i = 0; i < this.getGridWidth(); i++) {
boolean containsRegAgent = false;
for (GridObject g : this.getFieldPosition(i, j)) {
if (this.isRegularAgent(g)) {
containsRegAgent = true;
}
}
if (!containsRegAgent) {
full = false;
}
}
if (full) {
return j;
}
}
return -1;
}
public int getFirstFreeLine() {
for (int j = this.getGridHeight() - 1; j >= 0; j--) {
boolean full = false;
for (int i = 0; i < this.getGridWidth(); i++) {
for (GridObject g : this.getFieldPosition(i, j)) {
if (this.isRegularAgent(g)) {
full = true;
}
}
}
if (!full) {
return j;
}
}
return -1;
}
private int removeLine(int lineNo) {
int numberOfBricks = 0;
for (int j = lineNo; j >= 0; j--) {
for (int i = 0; i < this.getGridWidth(); i++) {
for (GridObject g : this.getFieldPosition(i, j)) {
try {
PacmanAgent2D pa = (PacmanAgent2D) g;
if (this.isRegularAgent(pa)
&& (this.canRemoveCurrentActiveAgent || !this.agents.get(this.getCurrentAgentID()).getAgents().contains(pa))) {
this.removeAgent(pa.id());
numberOfBricks++;
}
} catch (Exception e) {System.out.println(false);}
}
for (GridObject g : this.getFieldPosition(i, j - 1)) {
try {
PacmanAgent2D pa = (PacmanAgent2D) g;
if (this.isRegularAgent(pa)
&& (this.canRemoveCurrentActiveAgent || !this.agents.get(this.getCurrentAgentID()).getAgents().contains(pa))) {
this.setAgentPosition(pa.id(), new Vector2D(i, j));
}
} catch (Exception e) {System.out.println(false);}
}
}
}
return numberOfBricks;
}
private int removeLines() {
int firstFree = this.getFirstFullLine();
int counter = 0;
while (firstFree >= 0) {
counter++;
this.removeLine(firstFree);
firstFree = this.getFirstFullLine();
}
return counter;
}
private int getCurrentAgentID() {
return this.agents.size() - 1;
}
private ArrayList<Vector2D> nextAgent = null;
private int addScore = 0;
private Vector2D agentPos = new Vector2D(0, 0);
private boolean fieldEmpty() {
return this.getFirstFreeLine() == this.getGridHeight() - 1;
}
private int stoneNumberSinceEmptyField = -1;
private boolean canRemoveCurrentActiveAgent = false;
private int dynamiteNumber = 0;
private String nextAgentType = "normal";
private int agentNumber;
private static final int DYNAMITE_INTERVAL = 18;
private HashSet<DynamiteAgent> dynamiteAgent = null;
private HashSet<FuseAgent> fuseAgent = null;
private boolean removeRegularAgentFromField(int x, int y) {
for (GridObject g : this.getFieldPosition(x, y)) {
if (this.isRegularAgent(g)) {
this.removeAgent(((PacmanAgent2D) g).id());
return true;
}
}
return false;
}
private int explodeDynamite() {
int bricksRemoved = 0;
for (DynamiteAgent da : this.dynamiteAgent) {
for (FuseAgent fa : this.fuseAgent) {
Vector2D faPos = this.getAgentPosition(fa.id());
Vector2D daPos = this.getAgentPosition(da.id());
int xFa = (int) faPos.x;
int yFa = (int) faPos.y;
int xDa = (int) daPos.x;
int yDa = (int) daPos.y;
if (xFa == xDa && yFa == yDa) {
for (int i = xFa - this.dynamiteStrength; i <= xFa + this.dynamiteStrength; i++) {
for (int j = yFa - this.dynamiteStrength; j <= yFa + this.dynamiteStrength; j++) {
if (this.removeRegularAgentFromField(i, j)) {
bricksRemoved++;
}
}
}
}
}
}
if (bricksRemoved > 0) {
new Thread(new MP3Player(new File("./sharedDirectory/Polytris/dynamite"))).start();
} else {
new Thread(new MP3Player(new File("./sharedDirectory/Polytris/dynamiteBurnout"))).start();
}
return bricksRemoved;
}
private ArrayList<Vector2D> oldAgent;
private ArrayList<Vector2D> oldAgent2;
private void newRandomAgent(String type) {
// for (int j = 0; j < this.getGridHeight(); j++) {
// for (int i = 0; i < this.getGridWidth(); i++) {
// if (this.isBlockedByRegularStone(i, j)) {
// System.out.print("X");
// } else {
// System.out.print(" ");
// }
// }
// System.out.println();
// }
// Explode dynamite.
if (this.dynamiteAgent != null && this.fuseAgent != null) {
this.addScore += this.explodeDynamite() * 3;
for (PacmanAgent2D pa : this.dynamiteAgent) {
this.removeAgent(pa.id());
}
for (PacmanAgent2D pa : this.fuseAgent) {
this.removeAgent(pa.id());
}
this.dynamiteAgent = null;
this.fuseAgent = null;
}
// Set next agent type to dynamite.
if (this.nextAgentType.equals("normal") && this.agentNumber - this.dynamiteNumber > DYNAMITE_INTERVAL) {
this.nextAgentType = "dynamite";
this.dynamiteNumber = this.agentNumber;
}
this.agentNumber++;
stoneNumberSinceEmptyField++;
this.canRemoveCurrentActiveAgent = true;
int lines = this.removeLines();
this.canRemoveCurrentActiveAgent = false;
addScore += Math.pow(lines, 2) * 50;
this.score += addScore;
playDestroyedLinesSound(lines);
int firstFreeLine = this.getFirstFreeLine();
// Request warning sound or game over.
this.veryHigh = false;
if (firstFreeLine < heightGO || this.go) {
// float factor = (float) this.getParCollection().getParValueInt("Polytris.Level") / 4f;
this.go = true;
this.showText = "O-M-G!";
// this.score *= factor;
if (this.veryHighPlayer != null) {
this.veryHighPlayer.requestStop();
this.veryHighPlayer = null;
}
return;
} else if (firstFreeLine < heightGO + 1) {
this.veryHigh = true;
}
// Random agent.
if (this.nextAgent == null) {
this.nextAgent = this.generator.randomNTrisAgent(this.rand.nextInt(this.level) + 1);
}
while (!this.addPolytrisAgent(
this.nextAgent,
new Vector2D(this.getGridWidth() / 2, 4),
type)) {
this.nextAgent = this.generator.randomNTrisAgent(this.rand.nextInt(this.level) + 1);
}
oldAgent2 = oldAgent;
oldAgent = this.nextAgent;
if (!this.nextAgentType.equals("fuse")) {
this.nextAgent = this.generator.randomNTrisAgent(this.rand.nextInt(this.level) + 1);
}
if (this.getParCollection().getParValueBoolean("Polytris.Ultimate")) {
AllroundVideoPlugin vid = (AllroundVideoPlugin) this.getSimTime().getPluginObject(new AllroundVideoPlugin().id());
if (vid.getScale() > 50) {
vid.setZoom2DMinus();
vid.setZoom2DMinus();
} else if (vid.getScale() < 15) {
vid.setZoom2DPlus();
vid.setZoom2DPlus();
} else {
if (rand.nextBoolean()) {
vid.setZoom2DMinus();
vid.setZoom2DMinus();
} else {
vid.setZoom2DPlus();
vid.setZoom2DPlus();
}
}
}
float sum = 0;
for (PolytrisEvaluation e : this.evaluations) {
sum += e.evaluateField(this);
}
evaluationOld = evaluationCurrent;
evaluationCurrent = sum;
float stoneEval = this.stoneEvaluation.evaluateField(this);
if (evaluationCurrent - evaluationOld + stoneEval > 22) {
this.showText = "P E R F E C T !";
} else if (evaluationCurrent - evaluationOld + stoneEval > 12) {
this.showText = "Excellent!";
} else if (evaluationCurrent - evaluationOld + stoneEval > 7) {
this.showText = "Great";
} else if (evaluationCurrent - evaluationOld + stoneEval > 6) {
this.showText = "Good";
}
}
private float evaluationCurrent = Float.MAX_VALUE;
private float evaluationOld = Float.MAX_VALUE;
private void playDestroyedLinesSound(int lines) {
if (lines > 0) {
int linesTemp = lines;
File f = new File("./sharedDirectory/Polytris/line" + linesTemp);
while (!f.exists()) {
linesTemp--;
f = new File("./sharedDirectory/Polytris/line" + linesTemp);
}
new Thread(new MP3Player(new File("./sharedDirectory/Polytris/line" + linesTemp))).start();
// System.gc();
}
}
// Game Over.
private boolean go = false;
private boolean veryHigh = false;
private MP3Player veryHighPlayer;
private int bombs = 0;
private String showText = null;
private boolean bombRunning = false;
private PolytrisClock bombClock;
private BombAgent bombAgent;
private Vector2D bombPosition;
private int dynamiteStrength = 1;
public boolean isBombRunning() {
return this.bombRunning;
}
private void setBombsNumber(int value, int pointsEarnedByExplosion) {
this.bombs = value;
if (value > 0) {
if (value == 1) {
this.showText = this.bombs + "x bomb earned - 'b'";
} else {
this.showText = this.bombs + "x bomb earned - 'b'";
}
} else if (pointsEarnedByExplosion > 0) {
this.showText = pointsEarnedByExplosion + " points!";
} else {
this.showText = "No bombs";
}
if (!this.bombRunning) {
this.setAgentPosition(this.bombAgent.id(), bombPosition);
}
}
private void lowerBomb() {
Vector2D pos = new Vector2D(this.getAgentPosition(this.bombAgent.id()));
this.setAgentPosition(
this.bombAgent.id(),
pos.translate(new Vector2D(0, 1)));
}
private void agentLowerCompletelyRight() {
this.agentLowerCompletely(this.getCurrentAgentID(), false);
while (this.agentRight()) {
this.agentLowerCompletely(this.getCurrentAgentID(), false);
}
this.agentLowerCompletely(this.getCurrentAgentID(), true);
}
private void agentLowerCompletelyLeft() {
this.agentLowerCompletely(this.getCurrentAgentID(), false);
while (this.agentLeft()) {
this.agentLowerCompletely(this.getCurrentAgentID(), false);
}
this.agentLowerCompletely(this.getCurrentAgentID(), true);
}
private static final int MEGABONUS_EMPTY_FIELD = 123;
@Override
public void step(Wink simTime) {
super.step(simTime);
long startTime = System.currentTimeMillis();
long endTime;
long duration;
if (this.fieldEmpty() && stoneNumberSinceEmptyField > 0) {
int megabonus = MEGABONUS_EMPTY_FIELD * this.getParCollection().getParValueInt("Polytris.Level");
this.showText = "CLEARENCE -- " + megabonus + "!";
this.score += megabonus;
this.stoneNumberSinceEmptyField = 0;
}
// Lower bomb.
if (this.bombRunning && this.bombClock.pleaseLowerInCycle(simTime)) {
this.lowerBomb();
}
if (this.veryHigh) {
if (this.veryHighPlayer == null) {
this.veryHighPlayer = new MP3Player(new File("sharedDirectory/Polytris/warning"));
this.veryHighPlayer.setRepeat(true);
new Thread(this.veryHighPlayer).start();
}
} else {
if (this.veryHighPlayer != null) {
this.veryHighPlayer.requestStop();
this.veryHighPlayer = null;
}
}
// Faster sound.
if (this.clock.isAccelerating(simTime)) {
new Thread(new MP3Player(new File("./sharedDirectory/Polytris/faster"))).start();
this.addScore += 50;
this.score += this.addScore;
this.setBombsNumber(this.bombs + 1, 0);
}
if (e != null) {
if (e.getEventDescription().contains(ConstantsSimulation.KEY_EVENT_ARROW_KEY_ENCODING_RIGHT_SHIFT)) {
this.agentLowerCompletelyRight();
}
if (e.getEventDescription().contains(ConstantsSimulation.KEY_EVENT_ARROW_KEY_ENCODING_LEFT_SHIFT)) {
this.agentLowerCompletelyLeft();
}
if (e.getEventDescription().contains(ConstantsSimulation.ARROW_KEY_ENCODING_DOWN)) {
this.lowerAgent();
}
if (e.getEventDescription().contains(ConstantsSimulation.ARROW_KEY_ENCODING_LEFT)) {
this.agentLeft();
}
if (e.getEventDescription().contains(ConstantsSimulation.ARROW_KEY_ENCODING_RIGHT)) {
this.agentRight();
}
if (e.getEventDescription().contains(ConstantsSimulation.ARROW_KEY_ENCODING_UP)) {
this.agentTurn();
}
if (e.getEventDescription().equals(ConstantsSimulation.KEY_EVENT_IDENTIFIER + " ")) {
this.agentLowerCompletely(getCurrentAgentID(), true);
}
if (e.getEventDescription().equals(ConstantsSimulation.KEY_EVENT_IDENTIFIER + "p")) {
AllroundVideoPlugin vid = ((AllroundVideoPlugin) this.getSimTime().getPluginObject(new AllroundVideoPlugin().id()));
vid.pause();
}
if (e.getEventDescription().equals(ConstantsSimulation.KEY_EVENT_IDENTIFIER + "m")) {
MP3Player.turnOffAllSounds = !MP3Player.turnOffAllSounds;
if (MP3Player.turnOffAllSounds) {
for (MP3Player mp3 : MP3Player.activePlayers) {
mp3.requestStop();
}
}
}
if (e.getEventDescription().equals(ConstantsSimulation.KEY_EVENT_IDENTIFIER + "b")) {
if (this.bombs > 0 && !this.bombRunning) {
this.bombRunning = true;
this.showText = "Press 'b' for explosion";
} else {
Vector2D pos = new Vector2D(this.getAgentPosition(this.bombAgent.id()));
int bricksRemoved = 0;
for (int i = 0; i < this.bombs; i++) {
bricksRemoved += this.removeLine((int) pos.y);
}
if (bricksRemoved > 0) {
this.veryHigh = false;
}
int addPoints = bricksRemoved * 2 * this.bombs;
this.score += addPoints;
this.playDestroyedLinesSound(this.bombs);
this.bombRunning = false;
this.setBombsNumber(0, addPoints);
}
}
e = null;
}
if (simTime.getLastTick() == 0) {
this.newRandomAgent(this.nextAgentType);
}
if (this.clock.pleaseLowerInCycle(simTime)) {
this.lowerAgent();
((AllroundVideoPlugin) this.getSimTime().getPluginObject(
new AllroundVideoPlugin().id())).setMarkedAgentId(
this.agents.get(
this.getCurrentAgentID()).getAgents().get(0).id());
}
endTime = System.currentTimeMillis();
duration = Math.max(0, 25 - (endTime - startTime));
try {Thread.sleep(duration);} catch (InterruptedException e) {}
}
public ArrayList<ArrayList<Vector2D>> getPossibleAgents() {
return this.possibleAgents;
}
private EASEvent e = null;
@Override
public void handleEvent(EASEvent e, Wink lastTick) {
super.handleEvent(e, lastTick);
this.e = e;
}
public boolean isGo() {
return this.go;
}
private Highscore scorez;
private String scorezName;
public Highscore getScorez() {
return this.scorez;
}
public void addHighscore(long score, String name, int level) {
if (this.scorez.addEntry(new HighscoreEntry(score, name, level))) {
this.scorez.store();
}
}
public int getBombs() {
return this.bombs;
}
public boolean isBlockedByRegularStone(int x, int y) {
List<GridObject> pos = this.getFieldPosition(x, y);
for (GridObject g : pos) {
Class<?> goClass = g.getClass();
if (!FuseAgent.class.isAssignableFrom(goClass)
&& !DynamiteAgent.class.isAssignableFrom(goClass)
&& !BombAgent.class.isAssignableFrom(goClass)) {
// Ignore current agent.
if (!this.agents.get(this.getCurrentAgentID()).getAgents().contains(g)) {
return true;
}
}
}
return false;
}
public ArrayList<Vector2D> getOldAgent() {
return this.oldAgent2;
}
}