Δευτέρα 15 Μαρτίου 2021

Good Java Tetris in 1300 lines Support 2 players Speed Col Rows and MagicTickets

 Use your magic tickets earned from Tetris x4 breakings! 

A little more efficient than 1st version (yesterday)









Download opensource .jar file from

https://drive.google.com/file/d/1dnXW_G0nbR66UxmORtxdpBevoc7W8r4p/view?usp=sharing



To be updated-programmed
-Speed may need range 1-1000 instead of 1/100 (for more slow till almost pause)

-Grammar correction Z and N is opposite !!  

/*

 * To change this license header, choose License Headers in Project Properties.

 * To change this template file, choose Tools | Templates

 * and open the template in the editor.

 */

package jimtetris;



import java.awt.BorderLayout;

import java.awt.Color;

import java.awt.Dimension;

import java.awt.Font;

import java.awt.Graphics;

import java.awt.Graphics2D;

import java.awt.GridLayout;

import java.awt.Insets;

import java.awt.Toolkit;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.awt.event.KeyEvent;

import java.awt.event.KeyListener;

import java.awt.event.MouseEvent;

import java.awt.event.MouseListener;

import java.util.Hashtable;

import java.util.Random;

import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JLabel;

import javax.swing.JPanel;

import javax.swing.JRadioButton;

import javax.swing.JSpinner;

import javax.swing.JTextField;

import javax.swing.JToggleButton;

import javax.swing.SpinnerNumberModel;

import javax.swing.event.ChangeEvent;

import javax.swing.event.ChangeListener;





/**

 *

 * @author jimakoskx

 */

public class JimTetris extends JFrame {

    

    static long millisOneHour=1000*60*60;

    static InterruptedException sl(long millis){

        try{

            Thread.sleep(millis);

        }catch(InterruptedException inter){

            //System.out.println(""+inter);

            return inter;

        }

        return null;

    }

    static Toolkit tk=Toolkit.getDefaultToolkit();

    static Dimension screen=tk.getScreenSize();

    

    

    static ActionListener secondPlayerOpener;

    static JimTetris pl1,pl0;

    /**

     * 

     * @param args 

     */

    public static void main(String[] args) {

        try{

            JimTetris pl1=new JimTetris();


            JButton jb2Players=new JButton("2 players");


            pl1.np.np.add(jb2Players,BorderLayout.CENTER);

            pl1.np.np.validate();

            pl1.repaint();


            jb2Players.addActionListener(secondPlayerOpener=new ActionListener() {

                @Override

                public void actionPerformed(ActionEvent e) {

                    JButton jbins=(JButton)e.getSource();

                    //pl1.np.np.remove(jbins);

                    jbins.setText("*");

                    jbins.removeActionListener(secondPlayerOpener);

                    jbins.addActionListener(new ActionListener() {

                        @Override

                        public void actionPerformed(ActionEvent e) {

                            pl0.setLocation(0,0);//for safety....

                        }

                    });

                    

                    

                    pl1.np.np.validate();

                    pl1.repaint();

                    

                    pl0=new JimTetris();

                    pl0.setBounds(pl1.getBounds());

                    pl0.jspSpeed.setValue(pl1.jspSpeed.getValue());

                    pl0.jspTetrisColumns.setValue(pl1.jspTetrisColumns.getValue());

                    pl0.jspTetrisRows.setValue(pl1.jspTetrisRows.getValue());

                    

                    pl0.setLocation(0, 0);

                    pl1.setLocation(screen.width-pl1.getWidth(), 0);

                    

                    pl1.setTitle("1_st Player");

                    pl0.setTitle("2_nd Player");

                    

                    pl1.keysToMeth.clear();

                    pl0.keysToMeth.clear();

                    

                    pl1.fillPlayer1Binds();

                    pl0.fillPlayer0Binds();

                    

                    pl1.opponent=pl0;

                    pl0.opponent=pl1;

                    

                    

                }

            });

            

            

            

        }catch(Throwable mainProblem){

            

        }

    }

    

    /**

     * 

     */

    boolean gameIsRunning;

    long score,tetrisAchieved,tetrisTickets;

    long constructed;

    long gameStartedAt;

    long seconds,minutes,hours;

    boolean continiusllyTetris;

    Color lostColor=null;

    boolean gameLost(){

        return lostColor!=null;

    }

    

    

    JSpinner jspSpeed=new JSpinner(new SpinnerNumberModel(70, 0, 100, 10));

    JToggleButton jtbSpeed=new JToggleButton("Speed",false);

    JPanel jpSpeed=new JPanel(new BorderLayout());

    int getSelectedSpeed(){return (Integer)jspSpeed.getValue();}

    long gameSpeed;

    long millisBetweenMovments;

    Thread thrGameMover=new Thread(){

        @Override

        public void run(){

            runGame();

        }

    };

    

    long millisBetweenRepaints=50;//20 frames per second

    Thread thrRepainter=new Thread(){

        @Override

        public void run(){

            runRepainter();

        }

    };

    

    

    //Thread for better left-right movement

    long millisBetweenKeys=100;

    boolean leftPressed,rightPressed;

    Thread thrPresser=new Thread(){

        @Override

        public void run(){

            runPresser();

        }

    };

    

    //

    Color palette[]={Color.WHITE,Color.GRAY,Color.CYAN,Color.YELLOW,Color.MAGENTA,Color.BLUE,Color.ORANGE,Color.GREEN,Color.RED};

    ArrayInt2 world=new ArrayInt2(1,1);//the tetris area world

    Random r=new Random();

    TetrisObject incoming=new TetrisObject(0);//a bar

    TetrisObject comingNext=new TetrisObject(1);//a square


    

    

    

    

    JPanel jpTetrisColumns=new JPanel(new BorderLayout());

    JLabel jlTetrisColumns=new JLabel("cols");

    JSpinner jspTetrisColumns=new JSpinner(new SpinnerNumberModel(10, 10, 30, 1));

    int getSelectedColumns(){return (Integer)jspTetrisColumns.getValue();}

    JPanel jpTetrisRows=new JPanel(new BorderLayout());

    JLabel jlTetrisRows=new JLabel("rows");

    JSpinner jspTetrisRows=new JSpinner(new SpinnerNumberModel(20,10, 60, 1));

    int getSelectedRows(){return (Integer)jspTetrisRows.getValue();}

    JPanel jpTetrisDim=new JPanel(new BorderLayout());

    ChangeListener tetrisDiomesionListener=(ChangeEvent e) -> {

        tetrisDimensionsChanged();

    };

    

    

    

    JButton jbbar=new JButton("----");

    JButton jbsquare=new JButton("sq");

    JButton jbcross=new JButton("cross");

    JButton jbel=new JButton("L");

    JButton jbgama=new JButton("Γ");

    JButton jbzet=new JButton("Z");

    JButton jbthunder=new JButton("thunder");

    JPanel jpMagics=new JPanel(new GridLayout(1,7));

    ActionListener ticketMagicAL=new ActionListener() {

        @Override

        public void actionPerformed(ActionEvent e) {

            ticketConsuming((JButton)e.getSource());

        }

    };

    

    

    

    JButton jbStart=new JButton(" Start ");

    

    

    JTextField jtfScore=new JTextField("score");

    Font fontScore=new Font("",Font.BOLD,24);

    Jbp jpScore=new Jbp();

    JToggleButton jtbFitSquares=new JToggleButton("fit",true);

    JPanel jpCanvas=new JPanel(){

        @Override

        public void paintComponent(Graphics gr){

            super.paintComponent(gr);

            paintingCanvas(gr);

        }

    };

    

    Jbp np=new Jbp();

    

    Jbp jp=new Jbp();

    

    

    

    

    /**

     * 

     */

    public JimTetris(){

        super();

        super.setTitle(getClass().getSimpleName()+" jimakoskx@all March 2021");

        super.setBounds(screen.width/4+0,0,screen.width/2,screen.height-100);

        super.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        super.setVisible(true);

        

        

        initilisingWindowsComponents();

        initilisingGameComponents();

        initilisingListeners();

        

        thrRepainter.setDaemon(true);

        thrGameMover.setDaemon(true);

        thrRepainter.start();

        thrGameMover.start();

        thrPresser.start();

        sl(666);

        setSize(Math.min(screen.width/2,world.ar.length*sqw+50), getHeight());

        

    }    

    void initilisingWindowsComponents(){

        jpTetrisColumns.add(jlTetrisColumns,BorderLayout.CENTER);

        jpTetrisColumns.add(jspTetrisColumns,BorderLayout.EAST);

        jpTetrisRows.add(jlTetrisRows,BorderLayout.CENTER);

        jpTetrisRows.add(jspTetrisRows,BorderLayout.EAST);

        jpTetrisDim.add(jpTetrisColumns,BorderLayout.WEST);

        jpTetrisDim.add(jtbFitSquares,BorderLayout.CENTER);

        jpTetrisDim.add(jpTetrisRows,BorderLayout.EAST);

        

        

        

        jpMagics.add(jbbar);

        jpMagics.add(jbsquare);

        jpMagics.add(jbcross);

        jpMagics.add(jbel);

        jpMagics.add(jbgama);

        jpMagics.add(jbzet);

        jpMagics.add(jbthunder);

        

        int i=0;

        Insets inszero=new Insets(0,0,0,0);

        JButton jb;

        long ticketsNeed;

        while(i<7){

            jb=((JButton)jpMagics.getComponent(i));

            jb.setForeground(palette[i+2]);

            if(i!=3){

                jb.setBackground(Color.BLACK);

            }

            jb.setMargin(inszero);

            if(i==0){ticketsNeed=4;}

            else if(i==1){ticketsNeed=3;}

            else {ticketsNeed=2;}

            jb.setToolTipText(" "+ticketsNeed+" Tickets for a "+jb.getText());

            jb.putClientProperty(Integer.class, i);

            jb.putClientProperty(Long.class, ticketsNeed);

            

            jb.addActionListener(ticketMagicAL);

            ++i;

        }

        

        

        

        jtbSpeed.setToolTipText("Speed is Free in this Version!");

        jtbSpeed.setEnabled(false);

        jpSpeed.add(jtbSpeed,BorderLayout.WEST);

        jpSpeed.add(jspSpeed,BorderLayout.EAST);

        

        np.np.add(jpTetrisDim,BorderLayout.EAST);

        np.np.add(jpSpeed,BorderLayout.WEST);

        np.sp.add(jbStart,BorderLayout.SOUTH);

        

        

        jp.np.add(np,BorderLayout.CENTER);

        jp.np.add(jpScore,BorderLayout.SOUTH);

        

        jtfScore.setFont(fontScore);

        jtfScore.setToolTipText("Use your Tetris Tickets if you can !!!");

        jpScore.cp.add(jtfScore,BorderLayout.CENTER);

        

        

        

        

        jp.cp.add(jpMagics,BorderLayout.NORTH);

        jp.cp.add(jpCanvas,BorderLayout.CENTER);

        

        getContentPane().add(jp,BorderLayout.CENTER);

        validate();

                

    }

    

    void initilisingGameComponents(){

        tetrisDimensionsChanged();

        speedChanged();

        //world.setAll(r,9,0);

    }

    

    

    Hashtable<Integer, Integer> keysToMeth=new Hashtable<>();

    JimTetris opponent=null;

    void fillDefaultBinds(){

        keysToMeth.clear();

        fillPlayer0Binds();

        fillPlayer1Binds();

    }

    void fillPlayer0Binds(){


        keysToMeth.put(KeyEvent.VK_Q,0);

        keysToMeth.put(KeyEvent.VK_W,0);

        keysToMeth.put(KeyEvent.VK_SPACE,0);



        keysToMeth.put(KeyEvent.VK_A,1);



        keysToMeth.put(KeyEvent.VK_D,2);


        keysToMeth.put(KeyEvent.VK_S,3);

    }

    void fillPlayer1Binds(){

        keysToMeth.put(KeyEvent.VK_UP,0);

        keysToMeth.put(KeyEvent.VK_NUMPAD5,0);

        keysToMeth.put(KeyEvent.VK_ENTER,0);


        keysToMeth.put(KeyEvent.VK_LEFT,1);

        keysToMeth.put(KeyEvent.VK_NUMPAD1,1);



        keysToMeth.put(KeyEvent.VK_RIGHT,2);

        keysToMeth.put(KeyEvent.VK_NUMPAD3,2);



        keysToMeth.put(KeyEvent.VK_DOWN,3);

        keysToMeth.put(KeyEvent.VK_NUMPAD2,3);


    }

    void initilisingListeners(){

        jspTetrisColumns.addChangeListener(tetrisDiomesionListener);

        jspTetrisRows.addChangeListener(tetrisDiomesionListener);

        jbStart.addActionListener(e->jbStart());

        jspSpeed.addChangeListener(e ->speedChanged());

        

        jtbFitSquares.addActionListener(e->repaintTheCanvas());

        fillDefaultBinds();

        jpCanvas.addKeyListener(new KeyListener() {

            @Override

            public void keyTyped(KeyEvent e) {

            }


            @Override

            public void keyPressed(KeyEvent e) {

                if(!checkingPressing(e.getKeyCode())){

                    if(opponent!=null){

                        opponent.checkingPressing(e.getKeyCode());

                    }

                }

            }


            @Override

            public void keyReleased(KeyEvent e) {

                if(!checkingReleasing(e.getKeyCode())){

                    if(opponent!=null){

                        opponent.checkingReleasing(e.getKeyCode());

                    }

                }

            }

        });

        jpCanvas.addMouseListener(new MouseListener() {

            @Override

            public void mouseClicked(MouseEvent e) {

            }


            @Override

            public void mousePressed(MouseEvent e) {

                jpCanvas.requestFocus();

            }


            @Override

            public void mouseReleased(MouseEvent e) {

            }


            @Override

            public void mouseEntered(MouseEvent e) {

            }


            @Override

            public void mouseExited(MouseEvent e) {

            }

        });

    }

    boolean mustRefreshScoreField;

    void ticketConsuming(JButton jb){

        if(gameIsRunning && tetrisTickets>=0){//>=0 for free tickets !!

            

            int jbType=(int)jb.getClientProperty(Integer.class);

            long ticketsNeedForThis=(long)jb.getClientProperty(Long.class);

            

            //comingNext.setType(jbType);//debug

            if(comingNext.type!=jbType){

                if(ticketsNeedForThis<=tetrisTickets){

                    comingNext.setType(jbType);

                    tetrisTickets-=ticketsNeedForThis;

                    refreshScore();

                }

                else{

                    jtfScore.setText("Not enough Tetris Tickets !!");

                    mustRefreshScoreField=true;

                }

            }

            else{

                jtfScore.setText("Already coming this . No worries");

                mustRefreshScoreField=true;

            }

        }

        jpCanvas.requestFocus();

    }

    

    

    boolean checkingPressing(int keycode){

        boolean konsumed=false;

        Integer key=keycode;

        Integer methodCode=keysToMeth.get(key);

        if(methodCode!=null){

            if(methodCode==0){

                space();

                konsumed=true;

            }

            else if(methodCode==1){

                leftPressed=true;

                thrPresser.interrupt();

                konsumed=true;


            }

            else if(methodCode==2){

                rightPressed=true;

                thrPresser.interrupt();

                konsumed=true;


            }

            else if(methodCode==3){

                down();

                konsumed=true;

            }

        }

        return konsumed;

    }

    boolean checkingReleasing(int keycode){

        boolean konsumed=false;

        Integer key=keycode;

        Integer methodCode=keysToMeth.get(key);

        if(methodCode!=null){

            if(methodCode==1){

                leftPressed=false;

                thrPresser.interrupt();

                konsumed=true;

            }

            else if(methodCode==2){

                rightPressed=false;

                thrPresser.interrupt();

                konsumed=true;

            }

        }

        return konsumed;

    }

    boolean obstaclePrevius=false;


    void space(){

        //System.out.println("space");

        if(gameIsRunning){

            int nextSub=incoming.nextSubtype();

            if(obstacleAtDifFromIncoming(0, 0, nextSub)){

                if(obstacleLeftOfIncoming(nextSub)){

                    //System.out.println("Roll forbitten from left");

                    if(obstacleRightOfIncoming(nextSub)){

                        //System.out.println("Roll forbitten from right");

                    }

                    else{

                        System.out.println("Roll may can fit +1 to the right");

                        incoming.relPosX++;

                        incoming.roll();

                        if(!obstacleLeftOfIncoming()){

                            incoming.relPosX--;

                            System.out.println("Moved back !!!");

                        }

                    }

                }

                else{

                    if(obstacleRightOfIncoming(nextSub)){

                        System.out.println("Roll may can fit -1 to the left");

                        incoming.relPosX--;

                        incoming.roll();

                        if(!obstacleRightOfIncoming()){

                            incoming.relPosX++;

                            System.out.println("Moved back !!!");

                        }

                    }

                    else{

                        //System.out.println("Roll is totally Free !!!");

                        incoming.roll();

                    }                

                }

            }

            else{

                //System.out.println("easy");

                incoming.roll();

            }

        }

    }

    void down(){

        if(gameIsRunning){

            if(!obstacleBelowIncoming()){

                incoming.relPosY++;

            }

        }

        

    }

    //left and right when first time pressed not too fast giving the second press

    //so i added a seperate thread for handle this

    void left0(){

        //if(gameIsRunning){

            if(obstacleLeftOfIncoming()){

                if(!obstaclePrevius){

                    //System.out.println("Can not move left");

                    tk.beep();

                }

                obstaclePrevius=true;

            }

            else{

                incoming.relPosX--;

                obstaclePrevius=false;

            }

            

        //}

    }

    void right0(){

        //if(gameIsRunning){

            if(obstacleRightOfIncoming()){

                if(!obstaclePrevius){

                    //System.out.println("Can not move right");

                    tk.beep();

                }

                obstaclePrevius=true;

            }

            else{

                incoming.relPosX++;

                obstaclePrevius=false;

            }

        //}

    }

    /**

     * 

     */

    void runPresser(){

        while(true){

            if(gameIsRunning && (leftPressed || rightPressed)){

                if(leftPressed){

                    left0();

                }

                else{

                    right0();

                }

                sl(millisBetweenKeys);

            }

            else{

                sl(millisOneHour);

            }

        }

    }

    

    

    

    

    void speedChanged(){

        gameSpeed=getSelectedSpeed();

        millisBetweenMovments=10+1010-gameSpeed*10;

        jspSpeed.setToolTipText("millisBetweenMovments : "+millisBetweenMovments);

        jpCanvas.requestFocus();

    }

    

    ArrayInt2 linesTroxiesShowingWhenBreak=new ArrayInt2(1,1);

    /**

     * must be adjusted to be visible for at least 1 seconds

     * =FPS *secondsWeWantToBeVisibleThe Oval Effect When breaking lines !!!

     */

    int linesTroxiesShowingWhenBreakStrenght=7;

    

    void tetrisDimensionsChanged(){

        if(gameIsRunning){

            jbStart();

        }

        world.setSize(getSelectedColumns()+2, getSelectedRows()+4+1);

        linesTroxiesShowingWhenBreak.setSize(1, getSelectedRows()+4+1);//metadata to showof!!!

        world.setAll(0);

        createWalls(1);

        jpCanvas.requestFocus();

        repaintTheCanvas();

    }

    void createWalls(int wallColorIndex){

        int i=0;

        int j=world.ar[0].length-1;

        while(i<world.ar.length){

            world.ar[i][j]=wallColorIndex;

            ++i;

        } 

        --i;

        while(j>3){

            world.ar[0][j]=wallColorIndex;

            world.ar[world.ar.length-1][j]=wallColorIndex;

            --j;

        } 

    }

   

    

    

    

    int nextInt(){

        return r.nextInt(7);

    }

    void jbStart(){

        if(gameIsRunning){

            System.out.println("Stopping");

            jbStart.setText("Start");

            gameIsRunning=false;

            refreshScore();

            

        }

        else{

            System.out.println("Starting");

            jbStart.setText("Abort");

            world.setAll(0);

            createWalls(1);

            linesTroxiesShowingWhenBreak.setAll(0);

            

            lostColor=null;

            score=0;

            tetrisAchieved=0;

            tetrisTickets=0;

            continiusllyTetris=false;

            constructed=0;

            

            incoming.setType(nextInt());

            comingNext.setType(nextInt());

            

            resetInitialPositions();

            

            gameStartedAt=System.currentTimeMillis();

            hours=0;

            minutes=0;

            seconds=0;

            jtfScore.setText("");

            mustRefreshScoreField=true;

            

            gameIsRunning=true;

        }

        jpCanvas.requestFocus();

        thrGameMover.interrupt();

        thrRepainter.interrupt();

        thrPresser.interrupt();

        repaintTheCanvas();

    }

    

    void resetInitialPositions(){

        incoming.relPosX=world.ar.length/2-2;

        incoming.relPosY=0;

        comingNext.relPosX=world.ar.length-4;

        comingNext.relPosY=0;        

    }

    

    

    /**

     * stupid repainter....

     */

    void runRepainter(){

        while(true){

            if(gameIsRunning){

                repaintTheCanvas();

                sl(millisBetweenRepaints);

            }

            else{

                sl(millisOneHour);

            }

        }

    }

    void repaintTheCanvas(){

        jpCanvas.repaint();

    }

    Graphics2D g;

    int canvasw,canvash,sqw,sqh;

    long paintingStartTime,paintingTime;

    Color linesColor=Color.BLACK;

    /**

     * stupid repainting all things every time instead to use buffer?

     * @param gr 

     */

    void paintingCanvas(Graphics gr){

        paintingStartTime=System.currentTimeMillis();

        g=(Graphics2D)gr;

        canvasw=jpCanvas.getWidth();

        canvash=jpCanvas.getHeight();

        sqw=canvasw/(world.ar.length);

        sqh=canvash/(world.ar[0].length);

        

        if(jtbFitSquares.isSelected()){

            int minsq=Math.min(sqw,sqh);

            sqw=minsq;

            sqh=minsq;

        }

        

        

        int col,row=0,colorValue,x,y=0;

        while(row<world.ar[0].length){

            col=0;

            x=0;

            while(col<world.ar.length){

                colorValue=world.ar[col][row];

                if(colorValue>0){

                    g.setColor(palette[colorValue]);

                    g.fillRect(x,y,sqw,sqh);

                    if(lostColor!=null){

                        g.setColor(lostColor);

                        if(colorValue>1){

                            g.drawLine(x,y,x+sqw,y+sqh);

                            g.drawLine(x+sqw,y,x,y+sqh);

                        }

                        else if((col+row)%2==0){

                            g.drawLine(x,y,x+sqw,y+sqh);

                        }

                        else{

                            g.drawLine(x+sqw,y,x,y+sqh);

                        }

                    }

                    if(linesColor!=null){

                        g.setColor(linesColor);

                        g.drawRect(x,y,sqw,sqh);

                    }

                }

                x+=sqw;

                ++col;

            }

            int j=linesTroxiesShowingWhenBreak.ar[0][row];

            if(j>0){

                //System.out.println("Drawing ovals on previuslly broken lines!");

                g.setColor(linesColor);

                int i=0;

                int lineWidth=world.ar.length*sqw;

                while(i<j){

                    g.drawOval(i*sqw,y,lineWidth,sqh);

                    ++i;

                }

                --linesTroxiesShowingWhenBreak.ar[0][row];

            }


            y+=sqh;

            ++row;

        }

        


        

        incoming.paintAt(g,palette[incoming.type+2], linesColor, sqw, sqh);

        comingNext.paintAt(g,palette[comingNext.type+2], linesColor, sqw, sqh);

        

        


        

        

        paintingTime=System.currentTimeMillis()-paintingStartTime;

        if(paintingTime>10){

            System.out.println("paintingTime>10 : "+paintingTime);

        }

    }

    

    void runGame(){

        while(true){

            if(gameIsRunning){

                sl(millisBetweenMovments);

                moveIncomingDown();

            }

            else{

                sl(millisOneHour);

            }

        }

    }

    void moveIncomingDown(){

        //System.out.println("Moving down");

        if(obstacleBelowIncoming()){

            

            if(incoming.relPosY<1){

                System.out.println("LOST");

                lostColor=Color.BLACK;

                jbStart();

            }

            else{

            

                storeIncomingToWorld();

                checkToBreak();


                TetrisObject temp=incoming;

                incoming=comingNext;

                comingNext=temp;

                comingNext.setType(nextInt());


                resetInitialPositions();

                ++constructed;

                jbStart.setText(constructed+" , abort");

            }

            

        }

        else{

            incoming.relPosY++;

        }

        

    }

    

    void storeIncomingToWorld(){

        int i=0,x,y,colorcode=incoming.type+2;

        while(i<incoming.xys[incoming.subtype][0].length){

            x=(incoming.xys[incoming.subtype][0][i]+incoming.relPosX);

            y=(incoming.xys[incoming.subtype][1][i]+incoming.relPosY);

            world.ar[x][y]=colorcode;

            ++i;

        }

        

    }

    

    /**

     * 

     * @return 

     */

    boolean obstacleBelowIncoming(){

        return obstacleBelowIncoming(incoming.subtype);

    }

    boolean obstacleBelowIncoming(int subtype){

        return obstacleAtDifFromIncoming(0,1,subtype);

    }

    /**

     * 

     * @return 

     */

    boolean obstacleLeftOfIncoming(){

        return obstacleLeftOfIncoming(incoming.subtype);

    }

    boolean obstacleLeftOfIncoming(int subtype){

        return obstacleAtDifFromIncoming(-1,0,subtype);

    }

    /**

     * 

     * @return 

     */

    boolean obstacleRightOfIncoming(){

        return obstacleRightOfIncoming(incoming.subtype);

    }

    boolean obstacleRightOfIncoming(int subtype){

        return obstacleAtDifFromIncoming(1,0,subtype);

    }

    

    

    /**

     * 

     * @param difx

     * @param dify

     * @return 

     */

    boolean obstacleAtDifFromIncoming(int difx,int dify){

        return obstacleBelowIncoming(incoming.subtype);

    }

    boolean obstacleAtDifFromIncoming(int difx,int dify,int subtype){

        int i=0,x,y;

        while(i<incoming.xys[subtype][0].length){

            x=(incoming.xys[subtype][0][i]+incoming.relPosX)+difx;

            y=(incoming.xys[subtype][1][i]+incoming.relPosY)+dify;

            try{

                if(world.ar[x][y]>0){

                    return true;

                }

            }catch(ArrayIndexOutOfBoundsException are){//can happen...without walls

                return true;

            }

            ++i;

        }

        return false;

    }

    

    

    

    void checkToBreak(){

        

        int line=world.ar[0].length-2;

        int originalLine=line;

        int linesFull=0;

        

        int i,iend=world.ar.length-1;

        int scoring=0,scoringPlus=0;

        while(line>3){

            i=1;

            while(i<iend){

                if(world.ar[i][line]<1){

                    break;

                }

                ++i;

            }

            if(i==iend){

                ++linesFull;

                System.out.println("Removing line : "+line);

                linesTroxiesShowingWhenBreak.ar[0][originalLine]+=linesTroxiesShowingWhenBreakStrenght;

                --i;

                while(i>0){

                    world.ar[i][line]=0;

                    --i;

                }

                BringDownAllAbove(line);

                ++line;

                scoring+=100;

                scoring+=scoringPlus;

                scoringPlus+=100;

            }

            

            

            --line;

            --originalLine;

        }

        if(linesFull>0){

            System.out.println(linesFull+ " Lines Removed for $ "+scoring);

            score+=scoring;

            if(linesFull==4){

                ++tetrisAchieved;

                ++tetrisTickets;

                System.out.println("new Tetris Achieved !");

                if(continiusllyTetris){

                    score+=1200;

                    System.out.println("+1200 from continiussly tetris !!!");

                }

                continiusllyTetris=true;

            }

            else{

                continiusllyTetris=false;

            }

            

            //jtfScore.setText(score+" , "+tetrisAchieved);

            refreshScore();

            mustRefreshScoreField=false;

        }

        if(mustRefreshScoreField){///may from ticket ordering!

            refreshScore();

            mustRefreshScoreField=false;

        }

    }

    

    void BringDownAllAbove(int line){

        int linePrev=line-1;

        while(line>0){

            int i=world.ar.length-2;

            while(i>0){

                world.ar[i][line]=world.ar[i][linePrev];

                --i;


            }

            --line;

            --linePrev;

        }

        

    }

    

    void refreshScore(){

        long time=System.currentTimeMillis();

        time-=gameStartedAt;

        time/=1000;

        seconds=time%60;

        time/=60;

        minutes=time%60;

        time/=24;

        hours=time%24;


        String hms=hours+":";  

        if(minutes<10){hms+="0"+minutes;}

        else{hms+=""+minutes;}

        if(seconds<10){hms+=":0"+seconds;}

        else{hms+=":"+seconds;}

        


        jtfScore.setText(" "+score+"  , Tickets: "+tetrisTickets+" / "+tetrisAchieved+" ,  "+hms);

        

        if(opponent!=null){

            if(opponent.score>score){

                jtfScore.setForeground(Color.RED);

            }

            else if(opponent.score<score){

                jtfScore.setForeground(Color.BLUE);

            }

            else{

                jtfScore.setForeground(Color.BLACK);

            }

        }


    }

    

}



class TetrisObject {

    

    int type;

    int subtype;

    int xys[][][];//subtype,0 for x, 1 for y,posIndex

    int relPosX=0;

    int relPosY=0;

    

    public TetrisObject(){

        this(0);

    }

    public TetrisObject(int type07){

        setType(type07);

    }

    void setType(int type07){

        type07%=7;

        if(type07==0){

            becomeBar();

        }

        else if(type07==1){

            becomeSquare();

        }

        else if(type07==2){

            becomeCross();

        }

        else if(type07==3){

            becomeEl();

        }

        else if(type07==4){

            becomeGamma();

        }

        else if(type07==5){

            becomeZetReversed();

        }

        else{// if(type07==6){

            becomeZet();

        }

        

    }

    void setSize(int subtypes,int len){

        xys=new int[subtypes][2][len];

    }

    public void becomeBar(){

        type=0;

        subtype=0;

        setSize(2,4);

        

        //vertical

        xys[0][0][0]=0;xys[0][1][0]=0;//p0(0,0)

        xys[0][0][1]=0;xys[0][1][1]=1;//p1(0,1)

        xys[0][0][2]=0;xys[0][1][2]=2;//p2(0,2)

        xys[0][0][3]=0;xys[0][1][3]=3;//p3(0,3)

        //horizontal

        xys[1][0][0]=0;xys[1][1][0]=0;//p0(0,0)

        xys[1][0][1]=1;xys[1][1][1]=0;//p1(1,0)

        xys[1][0][2]=2;xys[1][1][2]=0;//p2(2,0)

        xys[1][0][3]=3;xys[1][1][3]=0;//p3(3,0)

        

        

        

    }

    public void becomeSquare(){

        type=1;

        subtype=0;

        setSize(1,4);

        xys[0][0][0]=0;xys[0][1][0]=0;//p0(0,0)

        xys[0][0][1]=0;xys[0][1][1]=1;//p1(0,1)

        xys[0][0][2]=1;xys[0][1][2]=0;//p2(1,0)

        xys[0][0][3]=1;xys[0][1][3]=1;//p3(1,1)


    }

    public void becomeCross(){

        type=2;

        subtype=0;

        setSize(4,4);

        

        //vertical ->

        xys[0][0][0]=0;xys[0][1][0]=0;//p0(0,0)

        xys[0][0][1]=0;xys[0][1][1]=1;//p1(0,1)

        xys[0][0][2]=0;xys[0][1][2]=2;//p2(0,2)

        xys[0][0][3]=1;xys[0][1][3]=1;//p3(1,1)

        //horizontal v

        xys[1][0][0]=0;xys[1][1][0]=0;//p0(0,0)

        xys[1][0][1]=1;xys[1][1][1]=0;//p1(1,0)

        xys[1][0][2]=2;xys[1][1][2]=0;//p2(2,0)

        xys[1][0][3]=1;xys[1][1][3]=1;//p3(1,1)

        //vertical <-

        xys[2][0][0]=1;xys[2][1][0]=0;//p0(1,0)

        xys[2][0][1]=1;xys[2][1][1]=1;//p1(1,1)

        xys[2][0][2]=1;xys[2][1][2]=2;//p2(1,2)

        xys[2][0][3]=0;xys[2][1][3]=1;//p3(0,1)

        //horizontal ^

        xys[3][0][0]=0;xys[3][1][0]=1;//p0(0,1)

        xys[3][0][1]=1;xys[3][1][1]=1;//p1(1,1)

        xys[3][0][2]=2;xys[3][1][2]=1;//p2(2,1)

        xys[3][0][3]=1;xys[3][1][3]=0;//p3(1,0)

        

        

        

    }

    public void becomeEl(){

        type=3;

        subtype=0;

        setSize(4,4);

        

        //vertical ->

        xys[0][0][0]=0;xys[0][1][0]=0;//p0(0,0)

        xys[0][0][1]=0;xys[0][1][1]=1;//p1(0,1)

        xys[0][0][2]=0;xys[0][1][2]=2;//p2(0,2)

        xys[0][0][3]=1;xys[0][1][3]=2;//p3(1,2)

        //horizontal v

        xys[1][0][0]=0;xys[1][1][0]=0;//p0(0,0)

        xys[1][0][1]=1;xys[1][1][1]=0;//p1(1,0)

        xys[1][0][2]=2;xys[1][1][2]=0;//p2(2,0)

        xys[1][0][3]=0;xys[1][1][3]=1;//p3(0,1)

        //vertical <-

        xys[2][0][0]=1;xys[2][1][0]=0;//p0(1,0)

        xys[2][0][1]=1;xys[2][1][1]=1;//p1(1,1)

        xys[2][0][2]=1;xys[2][1][2]=2;//p2(1,2)

        xys[2][0][3]=0;xys[2][1][3]=0;//p3(0,0)

        //horizontal ^

        xys[3][0][0]=0;xys[3][1][0]=1;//p0(0,1)

        xys[3][0][1]=1;xys[3][1][1]=1;//p1(1,1)

        xys[3][0][2]=2;xys[3][1][2]=1;//p2(2,1)

        xys[3][0][3]=2;xys[3][1][3]=0;//p3(2,0)

        

        

        

    }

    public void becomeGamma(){

        type=4;

        subtype=0;

        setSize(4,4);

        

        //vertical ->

        xys[0][0][0]=0;xys[0][1][0]=0;//p0(0,0)

        xys[0][0][1]=0;xys[0][1][1]=1;//p1(0,1)

        xys[0][0][2]=0;xys[0][1][2]=2;//p2(0,2)

        xys[0][0][3]=1;xys[0][1][3]=0;//p3(1,0)

        //horizontal v

        xys[1][0][0]=0;xys[1][1][0]=0;//p0(0,0)

        xys[1][0][1]=1;xys[1][1][1]=0;//p1(1,0)

        xys[1][0][2]=2;xys[1][1][2]=0;//p2(2,0)

        xys[1][0][3]=2;xys[1][1][3]=1;//p3(2,1)

        //vertical <-

        xys[2][0][0]=1;xys[2][1][0]=0;//p0(1,0)

        xys[2][0][1]=1;xys[2][1][1]=1;//p1(1,1)

        xys[2][0][2]=1;xys[2][1][2]=2;//p2(1,2)

        xys[2][0][3]=0;xys[2][1][3]=2;//p3(0,2)

        //horizontal ^

        xys[3][0][0]=0;xys[3][1][0]=1;//p0(0,1)

        xys[3][0][1]=1;xys[3][1][1]=1;//p1(1,1)

        xys[3][0][2]=2;xys[3][1][2]=1;//p2(2,1)

        xys[3][0][3]=0;xys[3][1][3]=0;//p3(0,0)

        

        

        

    }

    

    public void becomeZetReversed(){

        type=5;

        subtype=0;

        setSize(2,4);

        

        //vertical  *

        //          * *

        //            *

        xys[0][0][0]=0;xys[0][1][0]=0;//p0(0,0)

        xys[0][0][1]=0;xys[0][1][1]=1;//p1(0,1)

        xys[0][0][2]=1;xys[0][1][2]=1;//p2(1,1)

        xys[0][0][3]=1;xys[0][1][3]=2;//p3(1,2)

        

        //horizontal    * *

        //            * *

        xys[1][0][0]=1;xys[1][1][0]=0;//p0(1,0)

        xys[1][0][1]=2;xys[1][1][1]=0;//p1(2,0)

        xys[1][0][2]=0;xys[1][1][2]=1;//p2(0,1)

        xys[1][0][3]=1;xys[1][1][3]=1;//p3(1,1)

        

    }

    

    public void becomeZet(){

        type=6;

        subtype=0;

        setSize(2,4);

        

        //vertical    *

        //          * *

        //          *

        xys[0][0][0]=1;xys[0][1][0]=0;//p0(1,0)

        xys[0][0][1]=0;xys[0][1][1]=1;//p1(0,1)

        xys[0][0][2]=1;xys[0][1][2]=1;//p2(1,1)

        xys[0][0][3]=0;xys[0][1][3]=2;//p3(0,2)

        

        //horizontal  * *

        //              * *

        xys[1][0][0]=0;xys[1][1][0]=0;//p0(0,0)

        xys[1][0][1]=1;xys[1][1][1]=0;//p1(1,0)

        xys[1][0][2]=1;xys[1][1][2]=1;//p2(1,1)

        xys[1][0][3]=2;xys[1][1][3]=1;//p3(2,1)


    }

    

    public void roll(){

        if(xys.length>1){

            ++subtype;

            subtype%=xys.length;

        }

    }

    public int nextSubtype(){

        int out=subtype;

        if(xys.length>1){

            ++out;

            out%=xys.length;

        }

        return out;

    }

    

    public void paintAt(Graphics2D g,Color c,Color linesColor,int sqw,int sqh){

        int i=0,x,y;

        g.setColor(c);

        while(i<xys[subtype][0].length){

            x=(xys[subtype][0][i]+relPosX)*sqw;

            y=(xys[subtype][1][i]+relPosY)*sqh;

            g.fillRect(x,y,sqw,sqh);

            if(linesColor!=null){

                g.setColor(linesColor);

                g.drawRect(x,y,sqw,sqh);

                g.setColor(c);

            }

            ++i;

        }

    }

    

    

}

class Jbp extends JPanel{

    public JPanel np=new JPanel(new BorderLayout());

    public JPanel wp=new JPanel(new BorderLayout());

    public JPanel cp=new JPanel(new BorderLayout());

    public JPanel ep=new JPanel(new BorderLayout());

    public JPanel sp=new JPanel(new BorderLayout());

    

    public Jbp(){

        super(new BorderLayout());

        super.add(np,BorderLayout.NORTH);

        super.add(wp,BorderLayout.WEST);

        super.add(cp,BorderLayout.CENTER);

        super.add(ep,BorderLayout.EAST);

        super.add(sp,BorderLayout.SOUTH);

    }

    

}


class ArrayInt2 {

    public int ar[][];

    public ArrayInt2(int w,int h){

        setSize(w, h);

    }

    public void setSize(int w,int h){

        ar=new int[w][h];

    }

    public void setAll(int value){

        int i=0,j;

        while(i<ar.length){

            j=0;

            while(j<ar[0].length){

                ar[i][j]=value;

                ++j;

            }

            ++i;

        }

    }    

    public void setAll(Random r,int bound,int beginAt){

        int i=0,j;

        while(i<ar.length){

            j=0;

            while(j<ar[0].length){

                ar[i][j]=r.nextInt(bound)+beginAt;

                ++j;

            }

            ++i;

        }

    }    

}


Δεν υπάρχουν σχόλια: