Logic Number with GTGE

package com.golden.maximize;

// JFC
import java.awt.*;
import java.awt.event.KeyEvent;
import java.util.*;

// GTGE
import com.golden.gamedev.Game;
import com.golden.gamedev.GameLoader;
import com.golden.gamedev.object.GameFont;
import com.golden.gamedev.util.Utility;
import com.golden.gamedev.funbox.*;

// GTGE GUI
import com.golden.gamedev.gui.*;
import com.golden.gamedev.gui.toolkit.FrameWork;


/**
 * Logic Number Game, a mind game.
 * The game objective is to guess the hidden number.
 */
public class LogicNumber extends Game {

    public static void main(String[] args) {
        GameLoader game = new GameLoader();
        game.setup(new LogicNumber(), new Dimension(640, 480), false);
        game.start();
    }

    { distribute = true; }

 /****************************** MISCELLANEOUS *******************************/

    private ResourceBundle     res;        // language support
    private StringBuffer     debugTrace;    // for debugging value to console

    private GameFont          f, f2;        // used font
    private Color             bgColor;    // background color


 /********************************* G U I ************************************/

    private FrameWork         frame;        // the frame work
    private TTextField      text;       // textfield for input the guess
    private TButton[]       btnNumber,  // number button for click the guess
                            btnDest;       // destination button

    private TButton         btnOK,      // execute button (OK)
                            btnLevel;   // change level button

    private TFloatPanel        paneHowToPlay,    // info panel:
                            paneWinInfo,    // how to play, win, lose
                            paneLoseInfo;


 /***************************** LEVEL VARIABLES ******************************/

    private int             gameState;    // game state :
                                        // 1-play, 2-win, 3-lose

    private int             level;      // current game level


 /************************* OBJECT NUMBER TO GUESS ***************************/

    private int[]           logicNumber;    // the number to guess
    private int             totalNumber;
    private int             totalLogic;
    private boolean[]       btnPos;         // true, the position has been occupied


 /***************************** GUESS VARIABLES ******************************/

    private int[]           playerGuess;
    private String          logicNumberStr;
    private int             chance;     // current guess, max 20 times
    private String[]        result;     // guess result (star and circle)


 /******************************* UTILITIES **********************************/

    private KeyCapture        keyFPS,        // toggle on/off show fps
                            keySpeed;    // maximum fps

    private boolean         showFPS = false;


 /****************************************************************************/
 /*************************** INIT GAME RESOURCES ****************************/
 /****************************************************************************/

    public void initResources() {
        setMaskColor(Color.GREEN);
        showCursor();

        ///////// language support /////////
        Locale[] locale = new Locale[] {
            new Locale("in","ID"),     // indonesian language
            new Locale("en","US")     // english
        };
        // always use english
        Locale lang = locale[1];
        res = ResourceBundle.getBundle("com.golden.maximize.resource.Res", lang);

        bgColor = new Color(255, 128, 64);
        f = fontManager.getFont(getImages("ocrfont.png", 20, 5));
        f2 = fontManager.getFont(getImages("ocrfont2.png", 10, 3));

        initGUI();             // init gui

        gameState = 1;
        level = 1;
        initLevel();

        // key capture
        // toggle on/off show fps: [ctrl] + [shift] + F
        keyFPS = new KeyCapture(bsInput, "F", 500) {
            public void keyCaptured() {
                showFPS = !showFPS;
                bgColor = (showFPS) ? new Color(128, 128, 64) :
                                            new Color(255, 128, 64);

                // debug trace the input
                System.out.println(debugTrace.toString());
            }
        };
        keyFPS.setModifiers(new int[] {KeyEvent.VK_CONTROL, KeyEvent.VK_SHIFT});

        // force fps to 300 -> HYPERSPEED
        keySpeed = new KeyCapture(bsInput, "HYPERSPEED", 500) {
            public void keyCaptured() {
                setFPS(3000);
            }
        };
    }

    private void initGUI() {
        frame = new FrameWork(bsInput, getWidth(), getHeight());

        // modify titlebar renderer default color
        frame.getTheme().getUIRenderer("TitleBar").put("Background Color", Color.RED);
        frame.getTheme().getUIRenderer("TitleBarButton").put("Background Color", new Color(204, 204, 204));
        frame.getTheme().getUIRenderer("TitleBarButton").put("Background Border Color", Color.BLACK);

        // main panel
        TPanel pane = new TPanel(0, getHeight()-180, getWidth(), 180);

        // coloring the main panel, orange color without border
        pane.UIResource().put("Background Color", Color.ORANGE);
        pane.UIResource().put("Background Border Color", null);
            // destination button
            btnDest = new TButton[7];
            for (int i=0;i < btnDest.length;i++) {
                btnDest[i] = new TButton("", 50+(i*30), 40, 25, 30);
            }

            // button for number to guess
            btnNumber = new TButton[9];
            for (int i=0;i < btnNumber.length;i++) {
                btnNumber[i] = new TButton(String.valueOf(i+1),
                                           50+(i*30), 80, 25, 30) {
                    public void doAction() {
                        int num = Integer.parseInt(getText())-1;
                        if (getY() == 40) {
                            // clicking button that has been on guess position
                            // will make the button return to its initial position
                            btnPos[(getX()-50)/30] = false;
                            setLocation(50+(num*30),80);
                            return;
                        }

                        // clicking button that on initial position
                        // will fill the empty guess position
                        for (int i=0;i < totalLogic;i++) {
                            if (btnPos[i] == false) {
                                // checking is the button is empty or not
                                setLocation(50+(i*30),40);
                                btnPos[i] = true;
                                playerGuess[i] = Integer.parseInt(getText());
                                break;
                            }
                        }
                    }
                };
            }

            // text field for input the guess
            text = new TTextField("", 50, 125, 80, 20) {
                public boolean insertString(int offset, String st) {
                    // accept only numeric value
                    try { Integer.parseInt(st);
                    } catch (Exception e) { return false; }
                    return super.insertString(offset, st);
                }

                public void doAction() {
                    String st = getText();
                    text.setText("");

                    // validating textfield length
                    if (st.length() != totalLogic) {
                        return;
                    }

                    // validating for double values
                    for (int i=0;i < totalNumber;i++) {
                        String num = String.valueOf(i);
                        int found = st.indexOf(num, 0);
                        if (found != -1 && st.indexOf(num, found+1) != -1) {
                            // double values!!
                            return;
                        }
                    }

                    // validating the values is still in limit value
                    int[] values = new int[totalLogic];
                    boolean[] valid = new boolean[btnNumber.length];
                    for (int i=0;i < totalLogic;i++) {
                        values[i] = Character.getNumericValue(st.charAt(i));

                        if (values[i] > totalNumber || values[i] == 0) {
                            // invalid value (0 or bigger than limit)
                            return;
                        }

                        // array is starting from 0, so decrease the value by 1
                        values[i]--;
                    }

                    // VALID values!
                    // proceed with the values

                    // return back all the guess number to its position
                    for (int i=0;i < btnNumber.length;i++) {
                        btnNumber[i].setLocation(50+(i*30), 80);
                    }

                    // and send to new position
                    for (int i=0;i < totalLogic;i++) {
                        btnPos[i] = true; // all position filled
                        btnNumber[values[i]].setLocation(50+(i*30),40);

                        // tebakan user, ditambah satu karna tadi dikurang satu, utk array
                        playerGuess[i] = values[i] + 1;
                    }

                    // now send the event to button OK
                    btnOK.doClick(15);
                }
            };
            text.setToolTipText(res.getString("masukkan_angka"));

            // OK button
            btnOK = new TButton(res.getString("OK"), 138, 125, 30, 20) {
                public void doAction() {
                    if (text.getText().length() > 0) {
                        text.doAction(); // let the text do its job
                        if (text.getText().length() == 0) {
                            return;
                        }
                    }

                    checkValue();
                }
            };
            btnOK.setToolTipText(res.getString("ok_klik"));
            btnOK.UIResource().put("Text Font", fontManager.getFont(new Font("Verdana",Font.BOLD,12)));

            // level chooser button
            btnLevel = new TButton("", pane.getWidth()-76, 7, 69, 22) {
                public void doAction() {
                    if (++level > 8) level = 1;
                    initLevel();
                }
            };
            btnLevel.setToolTipText(res.getString("ubah_level"));
            btnLevel.UIResource().put("Background Color", new Color(231,227,231));

            // how to play button
            TButton btnCredits = new TButton(res.getString("Cara_Bermain"),
                                             pane.getWidth()-115, 34, 108, 22) {
                public void doAction() {
                    paneHowToPlay.setVisible(!paneHowToPlay.isVisible());
                }
            };
            btnCredits.setToolTipText(res.getString("papan_cara"));
            btnCredits.UIResource().put("Background Color", new Color(231,227,231));

        // add all main panel UI to the frame work
        for (int i=0;i < btnDest.length;i++) {
            pane.add(btnDest[i]);
        }
        for (int i=0;i < btnNumber.length;i++) {
            pane.add(btnNumber[i]);
        }
        pane.add(text);
        pane.add(btnOK);
        pane.add(btnLevel);
        pane.add(btnCredits);
        frame.add(pane);
        //======================================================================

        GameFont labelFont = fontManager.getFont(new Font("DIALOG",Font.BOLD,15));
        ///////// win panel /////////
        paneWinInfo = new TFloatPanel("", false, true, 0, 0, 240, 104);
            // win info
            TLabel lbWinInfo = new TLabel(res.getString("Anda_berhasil"),
                                          28, 8, 200, 20);
            lbWinInfo.UIResource().put("Text Font", labelFont);

            // continue
            TButton btnContinue = new TButton(res.getString("Lanjut"),
                                            22, 46, 75, 22) {
                public void doAction() { initLevel(); }
            };

            // next level
            TButton btnNextLevel = new TButton(res.getString("Naik_Level"),
                                          120, 46, 100, 22) {
                public void doAction() {
                    if (++level > 8) level = 8;
                    initLevel();
                }
            };
        // add all winner panel UI to the frame work
        paneWinInfo.add(lbWinInfo);
        paneWinInfo.add(btnContinue);
        paneWinInfo.add(btnNextLevel);
        frame.add(paneWinInfo);


        ///////// lose panel /////////
        paneLoseInfo = new TFloatPanel("", false, true, 0, 0, 240, 104);
            // lose info
            TLabel lbLoseInfo = new TLabel(res.getString("Anda_gagal"),
                                           28, 8, 200, 20);
            lbLoseInfo.UIResource().put("Text Font", labelFont);

            // try again
            TButton btnTryAgain = new TButton(res.getString("Coba_Lagi"),
                                                 20, 46, 100, 22) {
                public void doAction() { initLevel(); }
            };

            // exit game
            TButton btnExit = new TButton(res.getString("Keluar"),
                                          145, 46, 75, 22) {
                public void doAction() { finish(); }
            };
        // add all lose panel UI to the frame work
        paneLoseInfo.add(lbLoseInfo);
        paneLoseInfo.add(btnTryAgain);
        paneLoseInfo.add(btnExit);
        frame.add(paneLoseInfo);


        ///////// example panel /////////
        final PanelSample paneSample = new PanelSample(res, f,
                                                       (getWidth()/2)-275, (getHeight()/2)-110,
                                                       550, 160);
        paneSample.setVisible(false);
        frame.add(paneSample);


        ///////// how to play panel /////////
        paneHowToPlay = new PanelHowToPlay(res,
                                              fontManager.getFont(new Font("Verdana",Font.PLAIN,12)),
                                              fontManager.getFont(getImages("ocrfont3.png",20,3)),
                                           (getWidth()/2)-240, (getHeight()/2)-150,
                                           480, 270);
            TButton btnSample = new TButton(res.getString("contoh"),
                                            152,157,80,22) {
                public void doAction() {
                    paneSample.setVisible(!paneSample.isVisible());
                }
            };
        paneHowToPlay.add(btnSample);
        paneHowToPlay.setVisible(false);
        frame.add(paneHowToPlay);


        text.requestFocus();
    }


 /****************************************************************************/
 /************************* LEVEL INITIALIZATION *****************************/
 /****************************************************************************/

    private void initLevel() {
        gameState = 1;    // play state

        // hide win and lose info panel
        paneWinInfo.setVisible(false);
        paneLoseInfo.setVisible(false);

        result = new String[20];
        chance = 0;
        btnLevel.setText(res.getString("Level") + level);
        text.setText(""); // clear user input text field

        totalNumber = 0; totalLogic = 0;
        switch (level) {
            case 1: totalNumber = 6; totalLogic = 4; break;
            case 2: totalNumber = 7; totalLogic = 4; break;
            case 3: totalNumber = 7; totalLogic = 5; break;
            case 4: totalNumber = 8; totalLogic = 5; break;
            case 5: totalNumber = 8; totalLogic = 6; break;
            case 6: totalNumber = 9; totalLogic = 5; break;
            case 7: totalNumber = 9; totalLogic = 6; break;
            case 8: totalNumber = 9; totalLogic = 7; break;
        }
        btnPos = new boolean[totalLogic];
        playerGuess = new int[totalLogic];
        logicNumber = new int[totalLogic];
        text.setMaxLength(totalLogic);

        // reset status
        for (int i=0;i < btnDest.length;i++) {
            // show destination button as many as totalLogic
            btnDest[i].setVisible((i < totalLogic));
        }
        for (int i=0;i < btnNumber.length;i++) {
            // return to initial position
            btnNumber[i].setLocation(50 + (i*30), 80);

            // show number as many as totalNumber
            btnNumber[i].setVisible((i < totalNumber));
        }

        // fill and scramble the logic number
        int[] allNumber = new int[totalNumber];
        for (int i=0;i < totalNumber;i++) {
            allNumber[i] = i+1;
        }
        Utility.mixElements(allNumber);

        debugTrace = new StringBuffer();
        debugTrace.append("==================\nno: ");
        logicNumberStr = "\"";
        for (int i=0;i < totalLogic;i++) {
            // fill the logic number
            logicNumber[i] = allNumber[i];

            logicNumberStr += String.valueOf(logicNumber[i]);
            if (i != totalLogic-1) {
                logicNumberStr += " ";
            }
            debugTrace.append(logicNumber[i]).append("  ");
        }
        logicNumberStr += "\"";
        debugTrace.append("\n");


        // insert wrong guesses as many as 'num' amount
        // (for testing purpose)
//        int num = 19;
//        String st = "";
//        for (int i=0;i < btnPos.length;i++) {
//            st += String.valueOf(i+1); // the guess is always 1234...
//        }
//        st += " = **00"; // the dummy result :)
//        for (int k=0;k < num;k++) {
//            result[chance] = st;
//            chance++;
//        }
    }

 /****************************************************************************/
 /************** CHECKING IS THE USER GUESS IS RIGHT OR NOT ******************/
 /****************************************************************************/

    private void checkValue() {
        // validating guess number

        // first all position must be occupied!
        for (int i=0;i < totalLogic;i++) {
            if (btnPos[i] == false) {
                return;
            }
        }

        // star and circle counter
        int star = 0,
            circle = 0;

        // debug trace
        if (chance + 1 < 10) {
            debugTrace.append("0");
        }
        debugTrace.append(chance + 1).append(". ");

        for (int i=0;i < totalLogic;i++) {
            if (playerGuess[i] == logicNumber[i]) {
                // right value in the right position (got star)
                star++;
                debugTrace.append(playerGuess[i]).append("* ");

            } else {
                boolean exists = false;
                for (int j=0;j < btnPos.length;j++) {
                    if (playerGuess[i] == logicNumber[j]) {
                        // right value in wrong position (got circle)
                        circle++; exists = true;
                        debugTrace.append(playerGuess[i]).append("0 ");
                        break;
                    }
                }

                if (!exists) debugTrace.append(playerGuess[i]+"  ");
            }
        }
        debugTrace.append("\n");

        // info guess to show the player
        StringBuffer buff = new StringBuffer();
        for (int i=0;i < btnPos.length;i++) {
            // write the guess
            buff.append(playerGuess[i]);
        }
        buff.append(" = ");
        for (int i=0;i < star;i++) buff.append("*");     // add the star
        for (int i=0;i < circle;i++) buff.append("0");  // add the circle

        result[chance] = buff.toString();
        chance++;


        if (star == totalLogic) {
            // win!! show win panel
            gameState = 2;
//            playSound("clear.wav");

            paneWinInfo.setLocation((getWidth()/2)-120,getHeight()-290);
            paneWinInfo.setIcon(false);
            paneWinInfo.setVisible(true);

            // set as modal component
            frame.setModal(paneWinInfo);

        } else if (chance >= result.length) {
            // lose, show lose panel
            gameState = 3;
//            playSound("lose.wav");

            paneLoseInfo.setLocation((getWidth()/2)-120,getHeight()-290);
            paneLoseInfo.setIcon(false);
            paneLoseInfo.setVisible(true);

            // set as modal component
            frame.setModal(paneLoseInfo);

        } else {
            // wrong guess, return the button to its position
            // please try again
            for (int i=0;i < totalNumber;i++) {
                btnNumber[i].setLocation(50+(i*30),80);
            }

            for (int i=0;i < totalLogic;i++) {
                btnPos[i] = false;
            }
        }
    }


 /****************************************************************************/
 /***************************** UPDATE GAME **********************************/
 /****************************************************************************/

    public void update(long elapsedTime) {
        frame.update();

        if (keyPressed(KeyEvent.VK_ENTER)) {
            text.requestFocus();
        }

        keySpeed.update(elapsedTime);
        keyFPS.update(elapsedTime);

        // quit game when escape key pressed
        if (keyPressed(KeyEvent.VK_ESCAPE)) {
            finish();
        }
    }


 /****************************************************************************/
 /***************************** RENDER GAME **********************************/
 /****************************************************************************/

    public void render(Graphics2D g) {
        g.setColor(bgColor);
        g.fillRect(0, 0, getWidth(), getHeight());

        // draw player guessed number
        for (int i=0;i < chance;i++) {
            int x = (i/10) * ((getWidth()/2)-15),
                y = (i%10) * (f.getHeight()+2);
            f.drawString(g, result[i], 50+x, 20+y);
        }

        if (gameState == 3) {
            // lose condition, show the right number
            f2.drawString(g, logicNumberStr,
                          GameFont.CENTER,
                          0, ((getHeight()-180)>>1)-(f.getHeight()>>1),
                          getWidth());
        }

        frame.render(g);

        if (showFPS) {
            f.drawString(g, "FPS:" + getCurrentFPS(), getWidth()-120, 20);
        }
    }


 /****************************************************************************/
 /***************************** MAIN-CLASS ***********************************/
 /****************************************************************************/


    protected void notifyError(Throwable e, String environment) {
        new ErrorNotificationDialog(e, bsGraphics,
                                    "Logic Number v1.1", "pauwui@yahoo.com");
    }

}

0 comments: