Package eas.users.demos.polytris

Source Code of eas.users.demos.polytris.PolytrisEnvironment

/*
* 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;
    }
}
TOP

Related Classes of eas.users.demos.polytris.PolytrisEnvironment

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.