Package eas.users.demos.tetris

Source Code of eas.users.demos.tetris.TetrisEnvironment

/*
* Datei:            TetrisEnv.java
* Autor(en):        Lukas König
* Java-Version:     6.0
* Erstellt:         ??.06.2010
*
* (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.tetris;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Random;
import java.util.TreeMap;

import eas.math.geometry.Polygon2D;
import eas.math.geometry.Vector2D;
import eas.miscellaneous.StaticMethods;
import eas.plugins.standard.visualization.chartPlugin.ChartEvent;
import eas.simulation.ConstantsSimulation;
import eas.simulation.Wink;
import eas.simulation.agent.AbstractAgent;
import eas.simulation.event.EASEvent;
import eas.simulation.spatial.sim2D.standardEnvironments.AbstractEnvironment2D;
import eas.startSetup.ParCollection;

/**
* @author Lukas König
*/
public class TetrisEnvironment extends AbstractEnvironment2D<AbstractTetrisAgent> {

    /**
     *
     */
    private static final long serialVersionUID = -8699971734941326206L;
    private boolean[][] feld = new boolean[10][25];
    private long points = 0;
    final protected int fac = 25;
    private boolean gameOver = false;
    private ParCollection pars;
    private Random rand;
   
    /**
     * Miliseconds between tile drops.
     */
    private int pause;

    /**
     * Character pressed last (null if none).
     */
    private String pressed = null;

    @Override
    public synchronized BufferedImage getOutsideView(Graphics2D g2) {
        BufferedImage img = this.getOutsideView();
        g2.drawImage(img, 0, 0, null);
        return img;
    }
   
    @Override
    public BufferedImage getOutsideView() {
        BufferedImage img = new BufferedImage(feld.length * fac, feld[0].length
                * fac, BufferedImage.TYPE_INT_RGB);
        Graphics2D g = img.createGraphics();
       
        g.setColor(Color.white);
        g.fillRect(0, 0, img.getWidth(), img.getHeight());

        g.setColor(Color.ORANGE);
        g.drawLine(0, fac * 4, fac * feld.length, fac * 4);
        g.drawLine(0, fac * 4 - 1, fac * feld.length, fac * 4 - 1);
       
        for (int i = 0; i < feld.length; i++) {
            for (int j = 0; j < feld[0].length; j++) {
                if (this.getPix(i, j)) {
                    g.setColor(Color.DARK_GRAY);
                    g.drawRect(i * fac + 1, j * fac + 1, fac - 2, fac - 2);
                    g.setColor(Color.gray);
                    g.drawRect(i * fac + 0, j * fac + 0, fac - 2, fac - 2);
                    if (j == feld[0].length - 1) {
                        g.setColor(Color.black);
                        g.fillRect(i * fac + 1, j * fac + 1, fac - 2, fac - 2);
                    } else {
                        g.setColor(new Color(Math.min(255, j * 5 + 150), 0, 0));
                        g.fillRect(i * fac + 1, j * fac + 1, fac - 2, fac - 2);
                    }
                }
            }
        }
       
        g.setColor(Color.yellow);
        for (AbstractAgent<?> a : this.getAgents()) {
            g.drawString("" + a.id(), (int) this.getPositionInVisualization(a.id()).x - 6, (int) this.getPositionInVisualization(a.id()).y + 5);
        }
       
        return img;
    }
   
    @Override
    public Vector2D getPositionInVisualization(int agentID) {
        try {
            Vector2D pos = new Vector2D(this.getAgentPosition(agentID));
            pos.mult(this.fac);
            pos.translate(new Vector2D(this.fac / 2, this.fac / 2));
            return pos;
        } catch (Exception e) {
            return null;
        }
    }

    private synchronized boolean getPix(int x, int y) {
        return this.feld[StaticMethods.modZwischen(x, 0, this.feld.length - 1)]
                        [StaticMethods.modZwischen(y, 0, this.feld[0].length - 1)];
    }
   
    private synchronized void setPix(int x, int y, boolean color) {
        this.feld[StaticMethods.modZwischen(x, 0, this.feld.length - 1)]
                 [StaticMethods.modZwischen(y, 0, this.feld[0].length - 1)] = color;
    }

    /**
     * @param ident
     */
    public TetrisEnvironment(final int ident, final ParCollection params) {
        super(ident, params);
        this.pars = params;
        this.rand = new Random();
        this.reset();
        if (params != null) {
            this.readScorez();
        }
    }
   
    private TreeMap<Long, String> scorez;
   
    /**
     * @return Returns the scorez.
     */
    public TreeMap<Long, String> getScorez() {
        return this.scorez;
    }

    private LinkedList<String> pointHistory = new LinkedList<String>();
   
    private ArrayList<String> pointHistoryBest = new ArrayList<String>();
   
    private ArrayList<String> pointHistoryLast = new ArrayList<String>();
   
    private void readScorez() {
        LinkedList<String[]> scrz = new LinkedList<String[]>();
       
        try {
            scrz = StaticMethods.readCSVFile(
                    this.getParCollection().getStdDirectory(),
                    "scorez.dat",
                    ";",
                    this.getParCollection());
            pointHistoryBest = new ArrayList<String>(StaticMethods.liesTextArray(
                    this.getParCollection().getStdDirectory(),
                    "history.dat",
                    this.getParCollection()));
            pointHistoryLast = new ArrayList<String>(StaticMethods.liesTextArray(
                    this.getParCollection().getStdDirectory(),
                    "Last.dat",
                    this.getParCollection()));
        } catch (Exception e) {
            StaticMethods.speichereTextDatei(this.getParCollection().getStdDirectory(),
                    "scorez.dat", "", this.getParCollection());
        }
       
        scorez = new TreeMap<Long, String>();
        for (String[] line : scrz) {
            scorez.put(Long.parseLong(line[1]), line[0]);
        }
    }
   
    public void storeScorez() {
        ArrayList<String> scrz = new ArrayList<String>(this.scorez.size());
        for (long point : this.scorez.keySet()) {
            scrz.add(this.scorez.get(point) + ";" + point);
        }
        StaticMethods.speichereTextAusArray(
                this.getParCollection().getStdDirectory(),
                "scorez.dat",
                scrz,
                this.getParCollection());
       
        if (this.getPlace() == 1) {
            StaticMethods.speichereTextAusArray(
                    this.getParCollection().getStdDirectory(),
                    "history.dat",
                    pointHistory,
                    this.getParCollection());
        }
       
        StaticMethods.speichereTextAusArray(
                this.getParCollection().getStdDirectory(),
                "Last.dat",
                pointHistory,
                this.getParCollection());
    }

    /**
     * Note that the same score may only be stored once. Otherwise the older
     * entry is deleted.
     */
    private void gameOver() {
        this.gameOver = true;
        this.getSimTime().timeTerminate();
//        int i = this.scorez.size();
    }

    public String scorezString() {
        String s = "";
        int i = this.scorez.size();

        for (Long p : this.scorez.keySet()) {
            s += "(" + i-- + ") " + this.scorez.get(p) + " - " + p + "\n";
        }
       
        return s;
    }

    public int getPlace() {
        int place = 1;
       
        for (long p : this.scorez.keySet()) {
            if (this.points >= p) {
                place++;
            }
        }
       
        return this.scorez.size() - place + 2;
    }
   
    public void reset() {
        this.gameOver = false;
        this.lineCounter = 0;
        this.nextAgent = null;
        this.points = 0;
        this.pressed = null;

        if (this.getAgent(0) != null) {
            this.removeAgent(0);
        }
       
        for (int i = 0; i < this.feld.length; i++) {
            for (int j = 0; j < this.feld[0].length; j++) {
                this.setPix(i, j, false);
            }
        }
       
        for (int i = 0; i < this.getFeld().length; i++) {
            this.setPix(i, this.getFeld()[0].length - 1, true);
        }
        this.addRandomTile();
    }

    private AbstractTetrisAgent nextAgent;
   
    public AbstractTetrisAgent getNextAgent() {
        return this.nextAgent;
    }

    public void setNextAgent(int nextAgent) {
        switch (nextAgent) {
        case 0:
            this.nextAgent = new TetrisAgentI(0, this, this.pars);
            break;
        case 1:
            this.nextAgent = new TetrisAgentZ(0, this, this.pars);
            break;
        case 2:
            this.nextAgent = new TetrisAgentS(0, this, this.pars);
            break;
        case 3:
            this.nextAgent = new TetrisAgentL(0, this, this.pars);
            break;
        case 4:
            this.nextAgent = new TetrisAgentJ(0, this, this.pars);
            break;
        case 5:
            this.nextAgent = new TetrisAgentO(0, this, this.pars);
            break;
        case 6:
            this.nextAgent = new TetrisAgentT(0, this, this.pars);
            break;
        default:
            break;
        }
    }

    private synchronized void addRandomTile() {
        Vector2D pos = new Vector2D(this.feld.length / 2, 1);
       
        if (nextAgent == null) {
            switch (rand.nextInt(7)) {
            case 0:
                this.nextAgent = new TetrisAgentI(0, this, this.pars);
                break;
            case 1:
                this.nextAgent = new TetrisAgentZ(0, this, this.pars);
                break;
            case 2:
                this.nextAgent = new TetrisAgentS(0, this, this.pars);
                break;
            case 3:
                this.nextAgent = new TetrisAgentL(0, this, this.pars);
                break;
            case 4:
                this.nextAgent = new TetrisAgentJ(0, this, this.pars);
                break;
            case 5:
                this.nextAgent = new TetrisAgentO(0, this, this.pars);
                break;
            case 6:
                this.nextAgent = new TetrisAgentT(0, this, this.pars);
                break;
            default:
                break;
            }
        }
       
        this.addAgent(this.nextAgent, pos, Math.PI * 2);
       
        boolean full = false;
        for (int j = 0; j < this.feld.length && !full; j++) {
            if (this.feld[j][3]) {
                full = true;
            }
        }
        if (full) {
            this.gameOver();
            return;
        }
       
        switch (rand.nextInt(7)) {
        case 0:
            this.nextAgent = new TetrisAgentI(0, this, this.pars);
            break;
        case 1:
            this.nextAgent = new TetrisAgentZ(0, this, this.pars);
            break;
        case 2:
            this.nextAgent = new TetrisAgentS(0, this, this.pars);
            break;
        case 3:
            this.nextAgent = new TetrisAgentL(0, this, this.pars);
            break;
        case 4:
            this.nextAgent = new TetrisAgentJ(0, this, this.pars);
            break;
        case 5:
            this.nextAgent = new TetrisAgentO(0, this, this.pars);
            break;
        case 6:
            this.nextAgent = new TetrisAgentT(0, this, this.pars);
            break;
        default:
            break;
        }
       
        this.points += 50;
    }
   
    protected synchronized void drawTile(
            Polygon2D tile,
            Vector2D pos,
            double angle,
            boolean color) {
        Polygon2D tileTurned = new Polygon2D();
        for (Vector2D v : tile) {
            tileTurned.add(new Vector2D(v));
        }
        tileTurned.rotate(Vector2D.NULL_VECTOR, angle);
       
        for (Vector2D p : tileTurned) {
            Vector2D gesPos = new Vector2D(pos);
            gesPos.translate(p);
            this.setPix((int) Math.round(gesPos.x), (int) Math.round(gesPos.y), color);
        }
    }
   
    @Override
    public synchronized boolean setAgentPosition(int agentID, Vector2D newPosition) {
        Polygon2D tile = this.getAgent(agentID).getAgentShape();
        // Delete old position.
        this.drawTile(
                this.getAgent(agentID).getAgentShape(),
                this.getAgentPosition(agentID),
                this.getAgentAngle(agentID),
                false);
       
        // Try new position.
        Polygon2D newShape = new Polygon2D();
        for (Vector2D v : tile) {
            newShape.add(new Vector2D(v));
        }
        newShape.rotate(Vector2D.NULL_VECTOR, this.getAgentAngle(agentID));
        for (Vector2D p : newShape) {
            Vector2D reqPos = new Vector2D(newPosition);
            reqPos.translate(p);
            if (this.getPix((int) Math.round(reqPos.x), (int) Math.round(reqPos.y))) {
                // Redraw old position.
                this.drawTile(
                        this.getAgent(agentID).getAgentShape(),
                        this.getAgentPosition(agentID),
                        this.getAgentAngle(agentID),
                        true);
                return false;
            }
        }

        // Draw new position.
        this.drawTile(
                this.getAgent(agentID).getAgentShape(),
                newPosition,
                this.getAgentAngle(agentID),
                true);
        return super.setAgentPosition(agentID, newPosition);
    }

    @Override
    public synchronized void handleEvent(EASEvent e, Wink lastTick) {
        this.pressed = e.getEventDescription().replace(ConstantsSimulation.KEY_EVENT_IDENTIFIER, "");
//        for (Plugin<AbstractEnvironmentSpatial> visualizer : this.getVisualizers()) {
//            visualizer.runDuringSim(this, lastTick, this.pars);
//        }
    }

    private void deleteLine(final int num) {
        this.lineCounter++;
        for (int i = num; i > 0; i--) {
            for (int j = 0; j < this.feld.length; j++) {
                this.feld[j][i] = this.getPix(j, i - 1);
            }
        }
        for (int j = 0; j < this.feld.length; j++) {
            this.feld[j][0] = false;
        }
    }
   
    private int lineCounter;
   
    public int deleteLines() {
        boolean full;
        for (int i = this.feld[0].length - 2; i >= 0; i--) {
            full = true;
            for (int j = 0; j < this.feld.length; j++) {
                if (!this.feld[j][i]) {
                    full = false;
                }
            }
            if (full) {
                this.deleteLine(i);
                return this.deleteLines() + 1;
            }
        }
       
        return 0;
    }
   
    @Override
    public void step(Wink cyc) {
        if (gameOver) {
            return;
        }
       
//        if (stroke1 == null || stroke2 == null) {
//            stroke1 = new BasicStroke(4f);
//            stroke2 = new CompositeStroke(new BasicStroke(5f), new BasicStroke(0.5f));
//        }
       
        Vector2D aktPos = this.getAgentPosition(0);
        Vector2D newpos = new Vector2D(aktPos);
        Polygon2D pol = this.getAgentShape(0);
        double angle = this.getAgentAngle(0);
       
        newpos.translate(new Vector2D(0, 1));
        if (!this.setAgentPosition(0, newpos)) {
            this.removeAgent(0);
            this.drawTile(
                    pol,
                    aktPos,
                    angle,
                    true);
            this.lineCounter = 0;
            this.deleteLines();
            this.points += 250 * this.lineCounter * this.lineCounter;
            this.addRandomTile();
        }
       
        this.points--;
       
        ChartEvent event1 = new ChartEvent(
                "Tetris chart",
                "My points",
                this.points);
       
        if (cyc != null && cyc.getLastTick() == 1) {
            event1.setChartFramePos(new Vector2D(500, 0));
            event1.setChartFrameDim(new Vector2D(500, 600));
        }
       
        event1.setyAxisLabel("Points");
//        event1.setLineStroke(stroke1);
        event1.setLineColor(color1);
        this.getSimTime().broadcastEvent(event1);

        // Beste Punkte
        if (cyc != null && this.pointHistoryBest.size() > cyc.getLastTick()) {
            ChartEvent event2 = new ChartEvent(
                    "Tetris chart",
                    "Highscore",
                    Integer.parseInt(this.pointHistoryBest.get((int) cyc.getLastTick())));
           
//            event2.setLineStroke(stroke2);
            event2.setLineColor(color2);

            this.getSimTime().broadcastEvent(event2);
       
       
        // Letzte Punkte
        if (cyc != null && this.pointHistoryLast.size() > cyc.getLastTick()) {
            ChartEvent event3 = new ChartEvent(
                    "Tetris chart",
                    "Last run",
                    Integer.parseInt(this.pointHistoryLast.get((int) cyc.getLastTick())));
           
//            event2.setLineStroke(stroke2);
//            event2.setLineColor(color2);

            this.getSimTime().broadcastEvent(event3);
        }
       
        if (cyc != null) {
            pointHistory.add("" + this.points);
        }
    }

    public void broadcastRemainingChartEvents(Wink terminationTime) {
        for (long i = terminationTime.getLastTick(); i < pointHistoryBest.size(); i++) {
            ChartEvent event2 = new ChartEvent(
                    "Tetris chart",
                    "Highscore",
                    Integer.parseInt(this.pointHistoryBest.get((int) i)));
            event2.setXValue(i);
//            event2.setLineStroke(stroke2);
            event2.setLineColor(color2);
            this.getSimTime().broadcastEvent(event2);
        }
        for (long i = terminationTime.getLastTick(); i < pointHistoryLast.size(); i++) {
            ChartEvent event3 = new ChartEvent(
                    "Tetris chart",
                    "Last run",
                    Integer.parseInt(this.pointHistoryLast.get((int) i)));
            event3.setXValue(i);
            this.getSimTime().broadcastEvent(event3);
        }
    }
   
//    private transient Stroke stroke1 = new BasicStroke(4f);
//    private transient Stroke stroke2 = new CompositeStroke(new BasicStroke(5f), new BasicStroke(0.5f));
    private Color color1 = Color.blue;
    private Color color2 = Color.black;
   
    @Override
    public synchronized boolean removeAgent(int agentID) {
        try {
            this.drawTile(
                    this.getAgentShape(agentID),
                    this.getAgentPosition(agentID),
                    this.getAgentAngle(agentID),
                    false);
        } catch (Exception e) {}
       
        return super.removeAgent(agentID);
    }

    public String getPressed() {
        return this.pressed;
    }

    public boolean[][] getFeld() {
        return this.feld;
    }

    @Override
    public Vector2D getAgentPosition(int agentID) {
        Vector2D pos = super.getAgentPosition(agentID);
       
        try {
            pos.x = StaticMethods.modZwischen((int) Math.round(pos.x), 0, this.feld.length - 1);
            pos.y = StaticMethods.modZwischen((int) Math.round(pos.y), 0, this.feld[0].length - 1);
        } catch (Exception e) {
            return null;
        }
       
        return pos;
    }

    @Override
    public synchronized boolean setAgentAngle(int agentID, double angleNew) {
        Vector2D posOld = this.getAgentPosition(agentID);
        double angleOld = this.getAgentAngle(agentID);
        Polygon2D shapeOld = this.getAgentShape(agentID);
       
        // Delete old position.
        this.drawTile(
                shapeOld,
                posOld,
                angleOld,
                false);
       
        // Try new position.
        Polygon2D shapeNew = new Polygon2D();
        for (Vector2D v : shapeOld) {
            shapeNew.add(new Vector2D(v));
        }
        shapeNew.rotate(Vector2D.NULL_VECTOR, angleNew);
        for (Vector2D p : shapeNew) {
            if (this.getPix((int) Math.round(p.x + posOld.x), (int) Math.round(p.y + posOld.y))) {
                // Redraw old position.
                this.drawTile(
                        shapeOld,
                        posOld,
                        angleOld,
                        true);
                return false;
            }
        }

        // Draw new position.
        this.drawTile(
                shapeOld,
                posOld,
                angleNew,
                true);

        return super.setAgentAngle(agentID, angleNew);
    }

    @Override
    public String toString() {
        String s = "";
       
        for (int i = 0; i < this.feld[0].length; i++) {
            for (int j = 0; j < this.feld.length; j++) {
                if (this.feld[j][i]) {
                    s += "#";
                } else {
                    s += " ";
                }
            }
            s += "\n";
        }
       
        return s;
    }
   
    public synchronized void senkeAb() {
        Vector2D aktPos = this.getAgentPosition(0);
        Vector2D newpos = new Vector2D(aktPos);
        newpos.translate(new Vector2D(0, 1));
        while (this.setAgentPosition(0, newpos)) {
            aktPos = this.getAgentPosition(0);
            newpos = new Vector2D(aktPos);
            newpos.translate(new Vector2D(0, 1));
        }
        this.step(null);
    }
   
    /**
     * @return Returns the points.
     */
    public long getPoints() {
        return this.points;
    }
   
    /**
     * @return Returns the gameOver.
     */
    public boolean isGameOver() {
        return this.gameOver;
    }
   
    /**
     * @return Returns the pause.
     */
    public int getPause() {
        return this.pause;
    }

    /**
     * @param pause The pause to set.
     */
    public synchronized void setPause(int pause) {
        this.pause = pause;
    }
   
    @Override
    public synchronized Polygon2D getAgentShapeInVisualization(int agentID) {
        return null;
    }
}
TOP

Related Classes of eas.users.demos.tetris.TetrisEnvironment

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.