quizup-trivia-game

Quizup is a sample online quiz game, developed for Windows Phone with backend built over AppWarp S2. The complete source code for the game is available in the downloads section. It illustrates how you can build a game such as the extremely popular QuizUp from using AppWarp S2. Users are presented trivia questions on their selected topic and are given 4 choices. They need to select the right option within the given amount of time. The thing that makes QuizUp interesting though is that users can play in realtime against other players or their friends who are online at the moment.

Quizup has a three modes

1.Single Player:In this mode the user selects a topic and plays alone.

2.With Random Player:In this mode the user plays with a random opponent on the same topic simultaneously, the one who gets more points is the winner.

3.With Facebook Friend:In this mode user first needs to login with facebook and then can invite one of its online friends to a game. If the friend accepts the invitation, the game will start.

Quizup has a following rules

1.User gets 30 points if he submits the correct answer

2.On submitting a wrong Answer 10 points will be deducted

3.If user does not submit an answer in the given time, there is no change in its points

Server Logic

Following are the operations specific to this sample. Note that you will first need to run the server application and create zones similar to how it is explained in the getting started page.

  1. The game is started when the number of joined users is equal to the desired number (1 or 2).
  2. Server broadcasts the questions to the users with the options every 10 seconds.
  3. Server gets receives user answer, checks it against with correct answer list.
  4. Server updated the user score (based on received answer) and broadcasts it to all users in room
  5. At the end of each level server broadcasts the scores of all users.
  6. When a user logs in with facebook, it sends the auth token to the server. The server fetches its friend list and returns a list of friends who are also currently online in the game.

Implementation

On server side we have defined extensions to override default server side functionality. All data for the questions and answers, is read from the resource files provided with the sample.

BaseServerAdapter: QuizServerAdaptor.java

BaseZoneAdapter: QuizZoneAdaptor.java

BaseTurnRoomAdaptor: QuizRoomAdaptor.java

Setting Adapter

Setting adapter is necessary task to override default server side functionality. First we set BaseServerAdapter at the time of starting AppWarp S2.On starting of server it also reads the json files(Level,Question) and save them in global lists.

         String appconfigPath = System.getProperty("user.dir") + System.getProperty("file.separator") + "AppConfig.json";
        boolean started = AppWarpServer.start(new QuizServerAdaptor(), appconfigPath);
        try {
            Utils.LevelJson = (Utils.ReadJsonFile("Levels.txt")).getJSONArray("Levels");
            for (Integer quiztype = 0; quiztype < Utils.TotalQuizTypes; quiztype++) {
                Utils.QuestionArrayPerLevel.add(new ArrayList<JSONArray>());
                Utils.AnswerArrayPerLevel.add(new ArrayList<JSONArray>());
                for (Integer i = 0; i < Utils.LevelJson.length(); i++) {
                    JSONObject json = Utils.ReadJsonFile("Questions_" +quiztype.toString()+ i.toString() + ".txt");
                    Utils.QuestionArrayPerLevel.get(quiztype).add(json.getJSONArray("Questions"));
                    Utils.AnswerArrayPerLevel.get(quiztype).add(json.getJSONArray("Answers"));
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        

we set zone adapter in QuizServerAdaptor.java as we receive notification onZoneCreated.

        @Override
    public void onZoneCreated(IZone zone)
    {   
        zone.setAdaptor(new QuizZoneAdaptor(zone));
    }
    

and we set BaseRoomAdaptor as we receive notification of creating room in QuizZoneAdaptor.

        @Override
    public void handleCreateRoomRequest(IUser user, IRoom room, HandlingResult result) {
           room.setAdaptor(new QuizRoomAdaptor(this.zone, room));
    }
    

Find Facebook Friends in Zone

To implements this we have logic in BaseZoneAdapter handleAddUserRequest if user selects login with facebook client sends Access_Token and Id as a authdata to server.We fetch the user friend list using AccessToken by facebook graph api and list out the friends those are playing in current zone

        @Override
    public void handleAddUserRequest(IUser user, String authData, HandlingResult result) {
            if (!authData.equals("")) {
                user.setCustomData(authData);
                    JSONObject statObj = new JSONObject(user.getCustomData());
                    List fbFriends = FacebookHandler.getFacebookFriends(statObj.getString("AccessToken"));
                    ArrayList<IUser> FBFriendsInMyZone = new ArrayList<IUser>();
                    Iterator zoneLstIterator = this.zone.getUsers().iterator();
                    while (zoneLstIterator.hasNext()) {
                        IUser zoneUser = (IUser) zoneLstIterator.next();
                        String fbId = new JSONObject(zoneUser.getCustomData()).getString("FacebookId");
                        Iterator lstIterator = fbFriends.listIterator();
                        while (lstIterator.hasNext()) {
                            User fbuser = (User) lstIterator.next();
                            if (fbId.equals(fbuser.getId())) {
                                FBFriendsInMyZone.add(zoneUser);
                            }  
                        }
                    }
           }
  }
        

Starting the game

Game is started by server if joined user in room and max users in room are same.Server starts sending questions immediately

        @Override
    public void handleTimerTick(long time){
           if (GAME_STATUS == QuizConstants.STOPPED && gameRoom.getJoinedUsers().size() == gameRoom.getMaxUsers()) {
            GAME_STATUS = QuizConstants.RUNNING;
            SendQuestion();
        }
    }
   

Handling Update Peers

Clients send answers using the SendUpdatePeers Api.In handleUpdatePeersRequest Server checks the answer, updates the score and broadcasts it to all users. We don’t want the Answer-Packet sent from the client to be broadcast to other users, so we set HandlingResult flag result.sendNotification to false;

        @Override
    public void handleUpdatePeersRequest(IUser sender, byte[] update, HandlingResult result) {
            result.sendNotification = false;
           switch (bt) {
                case QuizRequestCode.ANSWERPACKET:
                     ....
                     updateAndBroadCastScore(i, queID, ans);
                     ....
                     break
                  }
    }
    

Client Side Logic

login

facebookfriends

Windows Phone client has two screens.

  1. MainPage: User selects the topic, quiz mode and enters its name to connect to AppWarp S2 (or can also login with facebook).
  2. QuizPage: This page contains the complete game play logic.

Rooms are created with two properties “IsPrivateRoom” and “QuizTopic”. “IsPrivateRoom” value is set to true when users wants to play with their facebook friends

How to play:

play

gameover

Miscellaneous

Private chat

Quizup uses sendPrivateChat API to send the invitation to their friend.

         public static void SendInvitation()
        {
            FBInvitation FBInvitation = new FBInvitation();
            FBInvitation.MessageCode = MessageCode.INVITEDBYFRIEND;
            FBInvitation.RoomId = GlobalContext.GameRoomId;
            FBInvitation.HostFBName = GlobalContext.localUsername;
            FBInvitation.HostFBId = GlobalContext.UserFacebookId;
            FBInvitation.RemoteFBId = GlobalContext.RemoteFacebookId;
            String jsonstring = JsonConvert.SerializeObject(FBInvitation, Formatting.None);
            WarpClient.GetInstance().sendPrivateChat(GlobalContext.RemoteFacebookName, jsonstring);
        }
        

Handling leaving user

If a 2 player game room is active and any of the users leave the game, the other user is the winner. On the server side we remove this player from the UserStatusList.

    @Override
    public void onUserLeaveRequest(IUser user) {
        System.out.println(user.getName() + " left room " + user.getLocation().getId());
        for (int i = 0; i < UserStatusList.size(); i++) {
            if (UserStatusList.get(i).getUser().getName().equals(user.getName())) {
                UserStatusList.remove(i);
            }
        }
    }