After some internet research, it appeared that we need to figured how the server will execute threads for each client. The picture is as the following.
Client 1 --> q1 <-- Server thread for client 1 [q2,q3,q4,q5,q6,q7,q8,q9,q10] Question one sent, waiting for answer --> answer received --> execute thread (will sent next question and pause further execution)
Client 2 --> q2 <-- Server thread for client 2 [q3,q4,q5,q6,q7,q8,q9,q10]
Client 3 --> q5 <-- Server thread for client 3 [q6,q7,q8,q9,q10]
Each server thread should have a listener, which will trigger the execution of the next peace of code (assign next question for a client)
Since the way we do it now, seems like each client will receive the same question, and it assumes that all of the clients will answer questions simultaneously, which is not really happens.If we want the server to interact only with one client, then we can try to have a single user game. Otherwise, we have to come up with something that can manage multiple users independently.
walid: I believe the model we are using does use multithreading. A new thread is started and the handleClient function is called for each client that connects. After updating the code and getting the questions to display properly, I tested this theory by running the server the connecting with multiple clients. Since we have now switched to just sending the client random questions instead of requesting with a number (which we were going to have to use an rng for anyway..), I was able to see different questions on different clients. I want to explore danny's idea to how kahoot.it does it. Perhaps we can create pseudo 'game rooms' where users will be put into as they join (a gameroom for the first 3 users, when the 4th joins, create a new game room for him and the next two, etc...) We can simply store these gameroom information into a list on the server to keep track of the current running games (not that we expect more than one concurrent running game)
I've created a branch Alexperiments, where I am gonna do some wild implementations/variations of the master branch, without touching master branch.
- Run the server.py
- Run GUI.py
We now have sort of an app architecture which is similar to MVC.Which is widely used for a mobile app development. As before we wanted to import some function from client.py to the GUI.py to use them there. It is totally wrong and not necessary. Partially importing something from module A to module B, and something else from B to A is a circular dependecy. The python interpreter will know that and won't allow the program to be running. Instead we can import anything textual from GUI.py to client.py, including global variables. The module client.py will set values from the server(scores,usernames,questions,answers) into variables imported from GUI.py. The GUI.py job is primarily showing the interface and changing frames from start game state to leaderboard, showing scores and so forth. Since this small observation is based on the current code, later on it can be adjusted.
The PhotoImage class can read GIF and PGM/PPM images from files: photo = PhotoImage(file="image.gif") photo = PhotoImage(file="lenna.pgm")
You can use a PhotoImage instance everywhere Tkinter accepts an image object. An example: label = Label(image=photo) label.image = photo # keep a reference! label.pack() or label.grid(row=0, column=0)
- import the following variables from the GUI.py: username, current_question,a1,a2,a3,a4,questions_left,score
- From client.py assign any required values to the imported variables in step 1
- GUI.py will figure it out where to insert each value into labels ! Exception, any values stored as a list/dictionary/ might not be interpreted by GUI in a correct way
This is typically a way the database schema looks like. In our case it is where the questions and answers are stored. As well as user's scores, etc. Any data that we use in the app.
This is where the user interface is designed. This part should be a slave of controller. Ideally we have all the functions which inserting values into the view, stored in the controller.
This is the part which connects Model with View. So, the controller will decide what user will see at the moment. The data from the model would be transfered to the View through the controller.
- Explore a possibility of running the testServer.py file on the cloud hosting platforms, like AWS or something similar for free.
- Basic User Interface with tkinter widgets
- Show player's score
- Start a new game
- Exit the game
- Show credits
- Game instruction
- Visual styles(Colors, images, background?)
- Transition to leaderbord
- Add option to add username
- Function returns selected choice
- Function returns the username
- Update question frame function
client functions:
- Send answer to the server?
- Get a question from the server?
- Get 4 distinct answers, one of which is correct and gives points
- function send answer to server
- function req a question from server (will be sent to GUI)
- function req choices from server (sent to GUI)
- function req a score
- function req the scoreboard
- fully integrated with GUI (client can communicate with server via GUI buttons)
- Handle multiple clients?
- Server-Client model using TCP
- Store questions?
- Store answers?
- Validate correctness of the answer provided by the clients?
- Keep track of the usernames
- Keep track of user's scores
- Sent how many questions in total
We have made significant progress this week and now have a working model to go off of. We have mostly completed all of the main functions required for the client-server communication to be successful. This week should be the testing and debugging stage. We can also begin to implement some of the additional ideas that we talked about (such as live score, replay function, gameroom, etc...)
- Store questions as JSON file
- Store questions as string variables / Dictionary
- Five categories, Twenty-Five questions