Jiří Kalvoda
2 years ago
8 changed files with 191 additions and 19 deletions
@ -0,0 +1,22 @@ |
|||
#!/usr/bin/env python3 |
|||
import hra.db as db |
|||
import hra.lib as lib |
|||
from hra.util import hash_passwd |
|||
|
|||
import argparse |
|||
from sqlalchemy import exc, update |
|||
import sys |
|||
|
|||
g = db.Game(game_mode="", configuration={}, teams_count=1) |
|||
|
|||
parser = argparse.ArgumentParser() |
|||
parser.add_argument("game_id") |
|||
parser.add_argument("--step", action="store_true") |
|||
parser.add_argument("--restore", action="store_true") |
|||
|
|||
args = parser.parse_args() |
|||
|
|||
if args.restore: |
|||
lib.game_restore_broken(args.game_id) |
|||
if args.step: |
|||
lib.game_step(args.game_id) |
@ -0,0 +1,25 @@ |
|||
#!/usr/bin/env python3 |
|||
from hra.game import logic_by_mode |
|||
import hra.db as db |
|||
import hra.lib as lib |
|||
|
|||
import sys |
|||
from sqlalchemy import exc, update |
|||
|
|||
|
|||
mode = "occupy" |
|||
teams_count = 6 |
|||
configuration = {} |
|||
g = db.Game(game_mode=mode, configuration=configuration, teams_count=teams_count) |
|||
|
|||
db.get_session().add(g) |
|||
db.get_session().commit() |
|||
|
|||
s = db.State(game_id=g.game_id, round=0, state=g.get_logic().zero_state()) |
|||
|
|||
db.get_session().add(s) |
|||
g.current_round = 0 |
|||
g.working_on_next_state = False |
|||
db.get_session().commit() |
|||
|
|||
print(f"Přidána hra {g.game_id}. ") |
@ -0,0 +1,50 @@ |
|||
import json |
|||
import hra.config as config |
|||
import hra.db as db |
|||
|
|||
class DuplicitMakeStep(Exception): |
|||
pass |
|||
|
|||
def game_step(game_id: int): |
|||
ses = db.get_session() |
|||
|
|||
ses.expire_all() |
|||
game = ses.query(db.Game).filter_by(game_id=game_id).with_for_update().one_or_none() |
|||
assert game is not None |
|||
if game.working_on_next_state: |
|||
ses.commit() |
|||
raise DuplicitMakeStep() |
|||
game.working_on_next_state = True |
|||
ses.commit() |
|||
|
|||
old_round_id = game.current_round |
|||
new_round_id = old_round_id + 1 |
|||
old_state = ses.query(db.State).filter_by(game_id=game.game_id, round=old_round_id).one_or_none() |
|||
|
|||
moves = [None for _ in range(game.teams_count)] |
|||
for i in ses.query(db.Move).filter_by(game_id=game.game_id, round=old_round_id).all(): |
|||
moves[i.team_id] = i.move |
|||
|
|||
ses.commit() |
|||
|
|||
x, points = game.get_logic().step(old_state.state, moves, old_round_id) |
|||
|
|||
new_state = db.State(game_id=game.game_id, round=new_round_id, state=x) |
|||
ses.add(new_state) |
|||
|
|||
ses.expire_all() |
|||
game = ses.query(db.Game).filter_by(game_id=game_id).with_for_update().one_or_none() |
|||
assert game is not None |
|||
assert game.working_on_next_state |
|||
game.current_round = new_round_id |
|||
game.working_on_next_state = False |
|||
ses.commit() |
|||
|
|||
def game_restore_broken(game_id: int) -> None: |
|||
ses = db.get_session() |
|||
ses.expire_all() |
|||
game = ses.query(db.Game).filter_by(game_id=game_id).with_for_update().one_or_none() |
|||
game.working_on_next_state = False |
|||
ses.commit() |
|||
|
|||
|
@ -1,32 +1,94 @@ |
|||
from flask import Flask, redirect, flash, render_template, session, g, request, get_flashed_messages |
|||
import werkzeug.exceptions |
|||
import time |
|||
from datetime import datetime |
|||
import json |
|||
|
|||
import hra.config as config |
|||
import hra.web.html as html |
|||
import hra.db as db |
|||
from hra.web import app, NeedLoginError |
|||
import hra.web.jinja_mac as jinja_mac |
|||
|
|||
def args_get(name, type, optional=False, default=None): |
|||
v = request.args.get(name) |
|||
if v is None: |
|||
if optional: |
|||
return default |
|||
else: |
|||
raise werkzeug.exceptions.BadRequest(f"Missing mandatory option {name}.") |
|||
try: |
|||
return type(v) |
|||
except ValueError: |
|||
raise werkzeug.exceptions.BadRequest(f"Option {name} have wrong type.") |
|||
|
|||
|
|||
def get_context(): |
|||
if g.user is None: |
|||
raise NeedLoginError |
|||
game_id = request.args.get('game') or 1 |
|||
team_id = request.args.get('team') or 0 |
|||
game_id = args_get("game", int, True, 1) |
|||
team_id = args_get('team', int, True, 0) |
|||
game = db.get_session().query(db.Game).filter_by(game_id=game_id).first() |
|||
print(game_id, game, team_id) |
|||
if game is None: |
|||
raise werkzeug.exceptions.NotFound("No such game") |
|||
return game, team_id |
|||
|
|||
|
|||
@app.route("/api/state", methods=['GET']) |
|||
def api_state(): |
|||
game, team_id = get_context() |
|||
game, team_id = get_context() |
|||
state = game.current_state() |
|||
if state is None: |
|||
return json.dumps({ |
|||
"status": "working", |
|||
"wait": 1.0, |
|||
}) |
|||
return json.dumps({ |
|||
"status": "ok", |
|||
"round": state.round, |
|||
"state": state.state, |
|||
"team_id": team_id, |
|||
"state": game.get_logic().personalize_state(state.state, team_id, state.round), |
|||
}) |
|||
|
|||
@app.route("/api/action", methods=['POST']) |
|||
def api_action(): |
|||
def to_late(): |
|||
return json.dumps({ |
|||
"status": "too-late", |
|||
}) |
|||
|
|||
game, team_id = get_context() |
|||
j = request.get_json() |
|||
state = game.current_state() |
|||
round_id = args_get('round', int) |
|||
if round_id < 0 or round_id > game.current_round: |
|||
raise werkzeug.exceptions.BadRequest("Wrong round.") |
|||
if game.working_on_next_state or round_id < game.current_round: |
|||
return to_late() |
|||
|
|||
try: |
|||
warnings = game.get_logic().validate_move(state.state, team_id, j, round_id) |
|||
except Exception as e: |
|||
return json.dumps({ |
|||
"error": "error", |
|||
"description": str(e) |
|||
}) |
|||
|
|||
db.get_session().expire_all() |
|||
game = game.lock() |
|||
|
|||
if game.working_on_next_state or round_id < game.current_round: |
|||
db.get_session().commit() |
|||
return to_late() |
|||
|
|||
move = db.get_session().query(db.Move).filter_by(game_id=game.game_id, team_id=team_id, round=round_id).one_or_none() |
|||
if move is None: |
|||
move = db.Move(game_id=game.game_id, team_id=team_id, round=round_id) |
|||
db.get_session().add(move) |
|||
|
|||
move.move = j |
|||
|
|||
db.get_session().commit() |
|||
|
|||
if warnings is not None: |
|||
return json.dumps(warnings) |
|||
return json.dumps({ |
|||
"status": "ok", |
|||
}) |
|||
|
Loading…
Reference in new issue