Commit 767d2e6b by interrogator

add info to readme, make validate.py

parent 69384f72
FROM python:3
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code
ADD requirements.txt /code/
RUN pip install -r requirements.txt
ADD . /code/
......@@ -13,21 +13,23 @@ Key specs:
## Backend
The backend receives a request for a game from a given user. It then extracts data from a language database, and generates the data needed for a game. There are a number of types of games, but most centre on linking words and concepts. Game data is transformed into JSON and sent to the frontend. When a game is finished, the frontend returns the results, which the backend then adds to a database.
The backend receives a request for a game from a given user. It then extracts data from a language database, and generates the data needed for a game. There are a number of types of games, but most centre on linking words and concepts. Game data is transformed into JSON and sent to the frontend. When a game is finished, the frontend returns the results, which the backend then adds to a database. This process can repeat for a number of games in a row.
## The JSON
To make collaboration easier, we use JSON to exchange data between frontend and backend. Information about these schemata can be found in `./schemata/schemata.md`.
To make collaboration easier, we use JSON to exchange data between frontend and backend. To aid this process, we have some schemata that describe how the JSON should be structured. Information about these schemata can be found in `schemata/schemata.md`.
The backend -> frontend format, which gives the frontend everything needed to set the look and behaviour of the game board, is provided in `schemata/new-game.json`.
The frontend -> backend format, used to communicate game results, is provided in `schemata/end-game.json`.
Python code for validating JSON is in `src/wugsy/validate.py`.
> JSON for user profiles will be done later.
## Rules
For each game type, there will be an associated rule list described in `./rules/`. For the game above, for example, in `./rules/game00.md` we may find:
For each game type, there will be an associated rule list described in `rules/`. For `game00`, for example, in `rules/game00.md` we may find:
```text
* TITLE: "Describe the concept to your opponent without using any of the displayed words"
......@@ -53,6 +55,18 @@ The frontend receives JSON that can be used to start the right game, display the
- A space that visualises an opponent when there is one (username, picture, score)
- A button that can be pushed to mark a game as bad, which may provide a request for more information
For the JSON shown above, the frontend would generate a 2x2 grid, with board functionality determined by code that implements `rules/game00.md`.
For example, for the sample data in `schemata/new-game.json`, the frontend would generate a 2x2 grid, with board functionality determined by code that implements `rules/game00.md`.
### How to add games to the frontend: one solution
For a hypothetical `game03`:
1. Open `src/static/site/js/game.js`
2. Create object representations of the various elements of the board in `BaseGame` (only needs to be done once)
3. Add a new function named `Game03` that takes one argument, the JSON from the backend.
4. Fill out this function to comply with the rules in `rules/game03.md`
5. Ensure that the game is placed in the HTML once generated (`src/templates/game.html`).
6. Ensure that on game end, JSON is POSTed via AJAX to `/game_result` that conforms to `schemata/end-game.json`
7. Add this game to the `games` map so that it will be automatically found
The game should be aesthetically pleasing, minimalistic and clean. Animations, transitions etc. are not required for the prototype, but should be included later.
......@@ -34,15 +34,15 @@
"reverse": null,
"selected": true,
"in_theme": false
}
}
],
"concept_space":
{
"ceoncept_text": "Fruits",
"concept_text": "Fruits",
"colour": "#ffffff",
"hover_text": "Done!"
},
"user_text_entry_field":
"user_text_entry_field":
{
"placeholder": "enter text here!"
},
......@@ -54,4 +54,4 @@
"picture": "path/to/photo2.jpg",
},
"extra": null
}
\ No newline at end of file
}
from django.shortcuts import render
from django.views import generic
from django.http import HttpResponse, JsonResponse
from wugsy.utils import REQUESTED, PROVIDED, _validator
from wugsy.validate import REQUESTED, PROVIDED, _validator
from wugsy.decide import DecideGame
from rest_framework.decorators import api_view
class GamePage(generic.TemplateView):
template_name = "game.html"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
print(self.request.user)
return context
@api_view(['POST'])
def generate_data(request):
"""
Frontend will request a game from here, posting session/user data.
We use this data to generate JSON suitable for a game and then return it
"""
given_data = request.data
user = request.user
decider = DecideGame(given_data, user)
out_data = decider.to_dict()
assert _validator(out_data, PROVIDED)
return JsonResponse(out_data)
def _generate_game_data(given, user):
def _add_to_database(given_data, user):
"""
From posted data, construct a new language game
Add information to the database
"""
decider = DecideGame(given, user)
return decider.to_dict()
return True
@api_view(['GET', 'POST'])
def generate_data(request):
def _is_game_over(given_data, user):
"""
Get data for a new Game
Decide if the round of games is over or not
"""
return False
@api_view(['POST'])
def game_result(request):
"""
Save game result to database, and either provide new game or redirect
"""
assert request.method == 'POST', 'Can only POST here'
given_data = request.data
user = request.user
out_data = _generate_game_data(given_data, user)
assert _validator(out_data, PROVIDED)
return JsonResponse(out_data)
assert _validator(given_data, REQUESTED)
over = _is_game_over(given_data, user)
success = _add_to_database(given_data, user)
if not success:
raise ValueError('Problem updating database!')
if over:
raise NotImplementedError('Not done yet')
else:
return generate_data(request)
......@@ -12,6 +12,7 @@ urlpatterns = [
url(r'^about/$', views.AboutPage.as_view(), name='about'),
url(r'^game/$', GamePage.as_view(), name='game'),
url(r'^generate_data$', generate_data, name='generate_data'),
url(r'^game_result$', game_result, name='game_result'),
url(r'^users/', include(profiles.urls, namespace='profiles')),
url(r'^admin/', include(admin.site.urls)),
url(r'^', include(accounts.urls, namespace='accounts')),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment