Online Canadian Citienship Test Practice System

After a few weeks’ hard work, I finally came up with an Online Practice for the Canadian Citizenship Test. Many of my friends are Canadians and they find my online practice system very interesting and helpful.

This online system has a database of more than 120 practice questions. What makes it different from other systems is that it contains province-specific questions. For example, for citizenship applicants in Ontario, the questions will be like “What is the Premier of Ontario?”. This system can also keep track of practicing time and give a score based on the number of correct answers. After the test taker finishes a practice test, he/she can re-do the test for more practice.

So far, more than 400 daily visitors use this online practice system. I am very happy with it and will continue to work on it for improvement. More on Canadian Citizenship Practice Exam .

Oracle buys Sun: The Future of JavaFX

Now that Oracle agrees to buy Sun for $7.4B. The acquisition of Sun has finally come to an end( or at least for a while). When we comparing the deal with IBM, it seems a better result for Sun, which is one of the most innovative companies in the Silicon Valley. Unlike IBM’s overlapping product lines, most of Sun’s software and hardware products are complement to Oracle’s. It is definitely a goodmoncler jas news for Java, because now a software company owns it and should be able to make better use of it.
300-208
CISSP
The future of JavaFX may not look so optimistic. JavaFX is only a few months old(since officially released). The APIs are not stable yet. It is not an industry standard and not many vendorsmoncler outlet are committed to it. Further, competing technology such as Flash is very popular and almostcheap windows 10 key dominates the RIA domain. The only advantage of JavaFX is the broad user base of Java language. JavaFX is indeed built on top of Java, this makes it the biggestwindowskeys reason to use JavaFX. If Sun is acquired by Oracle, the roadmap or vision of JavaFX may change, or lay some uncertainty ahead.

If the acquisition does go through, I do hope Oracle can continue to foster JavaFX, which is still in its infancy.

JavaFX Game: Frozen Bubble

Liu Xuan, a Chinese programmer, had written a Frozen Bubble game in JavaFX. He is kind to allow me to share his code here. The game was originally developed in Perl/SDL. A java port is available too. Liu’s program implemented a simplified version of the Frozen Bubble game in JavaFX.


Click on the below button to start the game, use left/right arrow key to aim and space button to fire.








The key handling code is accomplished in the class Container:

public class Container extends CustomNode{
    public var bubbles = new HashMap();
    public var fadeBubbles: Bubble[];
    public var fallBubbles: Bubble[];
    public var gun: Gun = Gun{};
    public var shootAngle: Number;
    public var group: Group = Group {
        content: [
            // backgroud
            Rectangle {
                width: 320
                height: 480
                strokeWidth: 1
                stroke: Color.BLACK
                fill: LinearGradient {
                    startX: 0.0,
                    startY: 0.0,
                    endX: 0.0,
                    endY: 1.0
                    proportional: true
                    stops: [ Stop {
                            offset: 0.0
                            color: Color.YELLOWGREEN },
                        Stop {
                            offset: 1.0
                        color: Color.LIGHTBLUE } ]
                }
                onKeyPressed: function(e: KeyEvent):Void {
                  // keyboard event handling
                      .......   
             }
            }
            gun
            //warning line
            Line {
                startX: 0,
                startY: Config.RED_LINE
                endX: 320
                endY: Config.RED_LINE
                strokeWidth: 1
                stroke: Color.RED
            }
            ImageView {
                  .......
            }
        ]
    };   

    public var inverseX = 1;   

    //semi-transparent layer for game over screen
    var layer = Rectangle {
        width: 320
        height: 480
        fill: Color.BLACK
        opacity: .4
    }
    var text = Text {
        content: "Press Enter To Start"
        font: Font {
            size: 20
        }
        x: 60
        y: 250
    }   

    // status of the game
    // 0 - game start and wait for shooting
    // 1 - bubble is moving
    // 2 - game over, the animation timeLine instanc
   // will stop at this value
    public var state = 2 on replace {
        if(state == 2) {
            timeline.stop();
            insert layer into group.content;
            insert text into group.content;
        }
    }   

    override public function create(): Node {
        group
    }   

    public function getLocation(row: Integer, col: Integer) : Point{
        var locationY = Config.ROW_SPACE * row;
        var locationX;
        if(row mod 2 == 0) {
            locationX = Config.BUBBLE_DIAMETER * col
        } else {
            locationX =
            Config.BUBBLE_DIAMETER * (col + .5) as Integer
        }
        return new Point(locationX, locationY)
    }   

    public function getAround(row: Integer, col: Integer): Bubble[] {
        var bArray: Bubble[] = [];
        var flag: Integer = 0;
        if(row mod 2 == 0) {
            flag = -1;
        }
        var bubble0 = getBubble(row, col - 1);
        var bubble1 = getBubble(row - 1, col + flag);
        var bubble2 = getBubble(row - 1, col + 1 + flag);
        var bubble3 = getBubble(row, col + 1);
        var bubble4 = getBubble(row + 1, col + flag);
        var bubble5 = getBubble(row + 1, col + 1 + flag);
        insert bubble0 into bArray;
        insert bubble1 into bArray;
        insert bubble2 into bArray;
        insert bubble3 into bArray;
        insert bubble4 into bArray;
        insert bubble5 into bArray;
        return bArray;
    }   

    public function getAround(bubble: Bubble): Bubble[] {
        var row: Integer = bubble.index.x;
        var col: Integer = bubble.index.y;
        return getAround(row, col);
    }
    public function getSameBubble(bubble: Bubble): Vector {
     var vector: Vector = new Vector();
     vector.add(bubble);
     var cursor = 0;
     while(
      cursor < vector.size()) {
        var bubbleInVector: Bubble =
        vector.get(cursor++) as Bubble;
        var aroundBubbles:Bubble[]=getAround(bubbleInVector);
        for(aroundBubble in aroundBubbles) {
          if ( aroundBubble != null
               and aroundBubble.color == bubble.color
               and vector.indexOf(aroundBubble) == - 1) {
               vector.add(aroundBubble);
                }
            }
        }
        return vector;
    }   

    public function getConnected(bubble: Bubble): Vector {
      var vector: Vector = new Vector();
      vector.add(bubble);
      var cursor = 0;
      while(cursor < vector.size()) {
        var bubbleInVector: Bubble =
        vector.get(cursor++) as Bubble;
        var aroundBubbles:Bubble[]=getAround(bubbleInVector);
        for(aroundBubble in aroundBubbles) {
            if ( aroundBubble != null
              and vector.indexOf(aroundBubble) == - 1) {
              vector.add(aroundBubble);
              }
            }
        }
        return vector;
    }   

  public function getIsolatedBubble(vector: Vector): Vector {
    var islatedBubble: Vector = new Vector();
      for(object in vector) {
        var sameBubble: Bubble = object as Bubble;
        var aroundBubbles:Bubble[] = getAround(sameBubble);
        for(aroundBubble in aroundBubbles) {
          if(aroundBubble != null) {
            var connectedBubble:Vector=getConnected(aroundBubble);
            var islate = true;
            for(col in [0..= 3) {
              for(object in vector) {
                var sameBubble: Bubble = object as Bubble;
                bubbles.remove(sameBubble.index);
                insert sameBubble into fadeBubbles;
              }
              for(object in getIsolatedBubble(vector)) {
                var islatedBubble: Bubble = object as Bubble;
                bubbles.remove(islatedBubble.index);
                insert islatedBubble into fallBubbles;
              }
            }
            state = 0;
            checkGameOver();
        }
    }   

    var timeCount = 0;   

    //moving, erasing, dropping the bubbles
    def timeline = Timeline {
        repeatCount: Timeline.INDEFINITE
        keyFrames:[
            KeyFrame {
                time: 0.005s
                action: function() {
                    ......
                    checkGameOver();
                    .......
            //reduce the transparency to erase the bubbles
            for(fadeBubble in fadeBubbles) {
                fadeBubble.opacity -= .02;
                if(fadeBubble.opacity <= 0) {
                   fadeBubble.visible = false;
                   delete fadeBubble from fadeBubbles;
                   delete fadeBubble from group.content;
                   }
              }
              //drop those isolated bubbles
              for(fallBubble in fallBubbles) {
                fallBubble.locationY += 5;
                if(fallBubble.locationY >= 428) {
                   fallBubble.visible = false;
                   delete fallBubble from fallBubbles;
                   delete fallBubble from group.content;
                   }
                 }   

                if(state == 1) {
                        ......
                //rebounce and collision handling
                checkCollision(bubble);
                }
              }
            }
        ]
    }   

    // initialization
    public function gameStart():Void {
          .....
          timeline.play();
    }
}


Source code can be downloaded here. Please note that Liu Xuan has the copyright of the code.