Subversion Repositories AndroidProjects

Rev

Rev 673 | Rev 678 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

package com.gebauz.PonPonChun.game;

import com.badlogic.gdx.Gdx;
import com.gebauz.Bauzoid.math.RandomChooser;
import com.gebauz.PonPonChun.game.entities.Block;
import com.gebauz.PonPonChun.game.entities.PlayField;
import com.gebauz.PonPonChun.game.entities.PlayField.Cell;

public abstract class GameModeLogic extends GameLogicObject
{
        // Constants========================================================================================

        // Embedded Types===================================================================================

        // Members==========================================================================================
       
        private GameLogic.GameMode mGameMode;
       
        protected RandomChooser mBlockRandomizer = new RandomChooser();

        // Methods==========================================================================================
        public GameModeLogic(GameLogic gameLogic, GameLogic.GameMode mode)
        {
                super(gameLogic);
                mGameMode = mode;
        }
       
        public abstract void init(String param);
        public abstract void exit();
        public abstract void update(float deltaTime);
        public abstract void render();
       
        public abstract void restart();
       
        public void onPostPerformSwap()
        {
        }
       
        public void randomizeInitialLevel(int startRow)
        {
                PlayField pf = getGameLogic().getPlayField();
               
                pf.clearAllBlocks();
               
                // row by row randomization that prevents triplets
                int[] lastRow = null;
                int[] prevLastRow = null;
               
                for (int dy = (PlayField.NUM_CELLS_Y-startRow); dy < (PlayField.NUM_CELLS_Y); dy++)
                {
                        int[] row = generateRow(lastRow, prevLastRow);
                                               
                        for (int dx = 0; dx < row.length; dx++)
                        {
                                pf.spawnBlock(row[dx], dx, dy);
                        }
                       
                        if (lastRow != null)
                                prevLastRow = lastRow.clone();
                        lastRow = row.clone();
                }
               
                pf.setNextRow(generateRow(lastRow, prevLastRow));
        }
       
        /** Generate a row that does not have triplets. */
        public int[] generateRow(int[] lastRow, int[] prevLastRow)
        {
                int[] lastTypes = new int[] { -1, -1 };
                int[] row = new int[PlayField.NUM_CELLS_X];
               
                for (int dx = 0; dx < PlayField.NUM_CELLS_X; dx++)
                {
                        // prevent triplets along the row and along the upper rows
                        int type = getNewType();
                       
                        int compare1 = (lastRow == null) ? -1 : lastRow[dx];
                        int compare2 = (prevLastRow == null) ? -1 : prevLastRow[dx];
                       
                        //while (((type == lastTypes[0]) && (type == lastTypes[1])) ||
                        //              ((type == compare1) && (type == compare2)))
                       
                        int tries = 500;
                       
                        while (isTriplet(type, lastTypes[0], lastTypes[1]) ||
                                        isTriplet(type, compare1, compare2))
                        {
                                //type = getGameLogic().getGame().getRandomInt(0, Block.NUM_TYPES-1);
                                type = getNewType();
                               
                                tries--;
                               
                                // after 500 tries, just take any
                                if (tries <= 0)
                                {
                                        Gdx.app.log(GameConsts.LOG_TAG, "500 Tries broken");
                                        break;
                                }
                        }
                       
                        if ((type == compare1) && (type == compare2))
                                System.out.println("CANT BE");

                        lastTypes[1] = lastTypes[0];
                        lastTypes[0] = type;
                       
                        row[dx] = type;
                }
               
                return row;
        }
       
        public int getNewType()
        {
                PlayField pf = getGameLogic().getPlayField();
               
                int numCrystals = 0;
                int numCrystalized = 0;
                int numFruits = 0;
                int numJokers = 0;
                for (int i = 0; i < pf.getNumBlocks(); i++)
                {
                        Block block = pf.getBlock(i);
                        if ((block.getType() == Block.TYPE_CRYSTAL))
                                numCrystals++;
                        else if (block.isCrystalized())
                                numCrystalized++;
                        else if (block.isFruitType())
                                numFruits++;
                        else if (block.isJokerBlockType())
                                numJokers++;
                }
               
                for (int i = 0; i < PlayField.NUM_CELLS_X; i++)
                {
                        int n = pf.getNextRowType(i);
                        if ((n == Block.TYPE_CRYSTAL))
                                numCrystals++;
                        else if (Block.isFruitType(n))
                                numFruits++;
                        else if (Block.isJokerBlockType(n))
                                numJokers++;
                }
               
                int level = getDifficulty();
                int type = 0;
                int tries = 500;
                while (true)                   
                {
                        type = mBlockRandomizer.chooseEntry();
                       
                        tries--;
                        if (tries <= 0)
                        {
                                Gdx.app.log(GameConsts.LOG_TAG, "500 Tries broken");
                                break;
                        }
                       
                        if ((numCrystals > (GameLogic.MAX_CRYSTALS + level - 1)) && (type == Block.TYPE_CRYSTAL))
                        {
                                //System.out.println("Too many crystals!");
                                type = Block.TYPE_BOMB;
                                break;
                        }                      
                        if (((numCrystals+numCrystalized) > (GameLogic.MAX_CRYSTALS+GameLogic.MAX_CRYSTALIZED_BLOCKS + level - 1)) && (type == Block.TYPE_CRYSTAL))
                        {
                                //System.out.println("Too many crystals!");
                                type = Block.TYPE_BOMB;
                                break;
                        }
                        if ((numFruits > GameLogic.MAX_FRUITS) && (Block.isFruitType(type)))
                                continue;
                        if ((numJokers > GameLogic.MAX_JOKERS) && (Block.isJokerBlockType(type)))
                                continue;
                        break;                 
                }
               
                //if (type == Block.TYPE_CRYSTAL)
                //      System.out.println("Crystal spawned");
               
                return type;
        }
       
       
        public boolean isTriplet(int a, int b, int c)
        {
                if ((a == b) && (a == c))
                        return true;
               
                // possible cases:
                // a immovable, b == c -> return true
                // b immovable, a == c -> return true
                // c immovable, a == b -> return true
                //
                // a and b immovable and of same type -> return true
                // a and c immovable and of same type -> return true
                // b and c immovable and of same type -> return true
                //
                // else false          
               
                if ((Block.isSpecialBlockType(a) && (b == c)) ||
                        (Block.isSpecialBlockType(b) && (a == c)) ||
                        (Block.isSpecialBlockType(c) && (a == b)))
                        return true;
               
                if ((Block.isJokerBlockType(a) && (b == c)) ||
                        (Block.isJokerBlockType(b) && (a == c)) ||
                        (Block.isJokerBlockType(c) && (a == b)))
                        return true;
               
                if ((Block.isSpecialBlockType(a) && (Block.isSpecialBlockType(b) && (a == b))) ||
                        (Block.isSpecialBlockType(b) && (Block.isSpecialBlockType(c) && (b == c))) ||
                        (Block.isSpecialBlockType(a) && (Block.isSpecialBlockType(c) && (a == c))))
                        return true;
               
                if ((Block.isJokerBlockType(a) && (Block.isJokerBlockType(b))) ||
                        (Block.isJokerBlockType(b) && (Block.isJokerBlockType(c))) ||
                        (Block.isJokerBlockType(a) && (Block.isJokerBlockType(c))))
                        return true;
               
                if ((Block.isSpecialBlockType(a) && (Block.isJokerBlockType(b))) ||
                        (Block.isSpecialBlockType(a) && (Block.isJokerBlockType(c))) ||
                        (Block.isSpecialBlockType(b) && (Block.isJokerBlockType(a))) ||
                        (Block.isSpecialBlockType(b) && (Block.isJokerBlockType(c))) ||
                        (Block.isSpecialBlockType(c) && (Block.isJokerBlockType(a))) ||
                        (Block.isSpecialBlockType(c) && (Block.isJokerBlockType(b))))
                        return true;
               
                /*if (((a == Block.TYPE_BOMB) && (b == c)) ||
                        ((b == Block.TYPE_BOMB) && (a == c)) ||
                        ((c == Block.TYPE_BOMB) && (a == b)))
                        return true;
               
                if (((a == Block.TYPE_BOMB) && (b == Block.TYPE_BOMB)) ||
                        ((a == Block.TYPE_BOMB) && (c == Block.TYPE_BOMB)) ||
                        ((b == Block.TYPE_BOMB) && (c == Block.TYPE_BOMB)))
                        return true;*/


                return false;
        }
       
        /** Checks if there is still activity on the PlayField such as falling, animation, particles, etc. */
        public boolean isStillActivity()
        {
                PlayField pf = getGameLogic().getPlayField();
               
                boolean stillActivity = false;                         
                for (int i = 0; i < pf.getNumBlocks(); i++)
                {
                        Block block = pf.getBlock(i);
                        if (block.getState() != Block.State.NORMAL)
                        {
                                stillActivity = true;
                                break;
                        }
                }
               
                // check for holes
                if (!stillActivity)
                {
                        for (int i = 0; i < pf.getNumBlocks(); i++)
                        {
                                Block block = pf.getBlock(i);
                                Cell cell = block.getCell();
                                while (cell.below != null)
                                {
                                        cell = cell.below;
                                       
                                        if (cell.isEmpty())
                                        {
                                                stillActivity = true;
                                                break;
                                        }
                                }
                        }              
                }
               
                // also wait until particle systems are done
                if (!stillActivity)
                {
                        if (getGameLogic().getPlayField().getBlockBreakParticles().getNumParticles() > 0)
                                stillActivity = true;
                }
               
                if (!stillActivity)
                {
                        if (getGameLogic().getPlayField().getBombParticles().getNumParticles() > 0)
                                stillActivity = true;
                }
               
                return stillActivity;
        }
       
        public abstract int getDifficulty();
       
        // Getters/Setters==================================================================================
       
        public final GameLogic.GameMode getGameMode()
        {
                return mGameMode;
        }
       
        public boolean isGameFinished() { return false; }
}