flags implementation
This commit is contained in:
parent
d246f5e270
commit
a71595596a
@ -17,6 +17,51 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func answerHandler(c *fiber.Ctx) error {
|
func answerHandler(c *fiber.Ctx) error {
|
||||||
|
|
||||||
|
gameId, err := uuid.Parse(c.Cookies("app_flags_game_session"))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
answer := c.FormValue("answer")
|
||||||
|
|
||||||
|
gameSession, err := db.Queries.GetFlagsGame(context.TODO(), gameId)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err, countries := filterCountriesByTags(gameSession.Tags)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
shuffledCountries := shuffleSlice(countries, gameSession.GameSeed.UUID.String())
|
||||||
|
|
||||||
|
correctAnswer := shuffledCountries[gameSession.QuestionCurrent-1]
|
||||||
|
|
||||||
|
if answer == correctAnswer {
|
||||||
|
db.Queries.UpdateFlagsGame(context.TODO(), queries.UpdateFlagsGameParams{
|
||||||
|
GameID: gameId,
|
||||||
|
QuestionCurrent: gameSession.QuestionCurrent + 1,
|
||||||
|
})
|
||||||
|
db.Queries.UpsertGameAnswer(context.TODO(), queries.UpsertGameAnswerParams{
|
||||||
|
GameID: gameId,
|
||||||
|
Question: gameSession.QuestionCurrent,
|
||||||
|
Errors: 0,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
db.Queries.UpsertGameAnswer(context.TODO(), queries.UpsertGameAnswerParams{
|
||||||
|
GameID: gameId,
|
||||||
|
Question: gameSession.QuestionCurrent,
|
||||||
|
Errors: 1,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
err = db.Queries.UpdateQuestionCorrect(context.TODO(), gameId)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return questionHandler(c, NewGameUUID{})
|
return questionHandler(c, NewGameUUID{})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,8 +89,7 @@ func questionHandler(c *fiber.Ctx, newGame NewGameUUID) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (gameSession.QuestionAmount != 0) && (gameSession.QuestionAmount+1 == gameSession.QuestionCurrent) {
|
if (gameSession.QuestionAmount != 0) && (gameSession.QuestionAmount+1 == gameSession.QuestionCurrent) {
|
||||||
// TODO: game is over
|
return gameEndHandler(c)
|
||||||
return c.SendString("game is over")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
err, countries := filterCountriesByTags(gameSession.Tags)
|
err, countries := filterCountriesByTags(gameSession.Tags)
|
||||||
@ -53,6 +97,10 @@ func questionHandler(c *fiber.Ctx, newGame NewGameUUID) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if int(gameSession.QuestionCurrent) == len(countries) {
|
||||||
|
return gameEndHandler(c)
|
||||||
|
}
|
||||||
|
|
||||||
shuffledCountries := shuffleSlice(countries, gameSession.GameSeed.UUID.String())
|
shuffledCountries := shuffleSlice(countries, gameSession.GameSeed.UUID.String())
|
||||||
shuffledAnswers := shuffleSlice(countries, gameSession.GameSeed.UUID.String()+string(gameSession.QuestionCurrent))
|
shuffledAnswers := shuffleSlice(countries, gameSession.GameSeed.UUID.String()+string(gameSession.QuestionCurrent))
|
||||||
shuffledAnswers = shuffledAnswers[0:4] // 4 random aswers
|
shuffledAnswers = shuffledAnswers[0:4] // 4 random aswers
|
||||||
@ -74,9 +122,13 @@ func questionHandler(c *fiber.Ctx, newGame NewGameUUID) error {
|
|||||||
data["Title"] = "tmp"
|
data["Title"] = "tmp"
|
||||||
data["Answers"] = shuffledAnswers
|
data["Answers"] = shuffledAnswers
|
||||||
data["Flag"] = flag
|
data["Flag"] = flag
|
||||||
|
data["Errors"] = gameSession.QuestionsErrors
|
||||||
return c.Render("apps/flags/question", data, "layouts/base")
|
return c.Render("apps/flags/question", data, "layouts/base")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getGameData() {
|
||||||
|
}
|
||||||
|
|
||||||
func startNewGameHandler(c *fiber.Ctx) error {
|
func startNewGameHandler(c *fiber.Ctx) error {
|
||||||
values := c.Request().PostArgs().PeekMulti("tags")
|
values := c.Request().PostArgs().PeekMulti("tags")
|
||||||
var selectedTags []string
|
var selectedTags []string
|
||||||
@ -106,15 +158,31 @@ func startNewGameHandler(c *fiber.Ctx) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
c.Cookie(&fiber.Cookie{
|
c.Cookie(&fiber.Cookie{
|
||||||
Name: "app_flags_game_session",
|
Name: "app_flags_game_session",
|
||||||
Value: row.GameID.String(),
|
Value: row.GameID.String(),
|
||||||
Secure: true,
|
//Secure: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
return questionHandler(c, NewGameUUID{used: true, UUID: row.GameID})
|
return questionHandler(c, NewGameUUID{used: true, UUID: row.GameID})
|
||||||
}
|
}
|
||||||
|
|
||||||
func stopGameHandler(c *fiber.Ctx) error {
|
func gameEndHandler(c *fiber.Ctx) error {
|
||||||
|
gameId, err := uuid.Parse(c.Cookies("app_flags_game_session"))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
gameSession, err := db.Queries.GetFlagsGame(context.TODO(), gameId)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
data := *web.Common(c)
|
||||||
|
data["Title"] = "tmp"
|
||||||
|
data["Errors"] = gameSession.QuestionsErrors
|
||||||
|
return c.Render("apps/flags/end", data, "layouts/base")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func stopGameHandler(c *fiber.Ctx) error { // exit game
|
||||||
utils.ClearCookie(c, "app_flags_game_session")
|
utils.ClearCookie(c, "app_flags_game_session")
|
||||||
return EntryPageHandler(c)
|
return EntryPageHandler(c)
|
||||||
}
|
}
|
||||||
|
@ -80,8 +80,8 @@ func Setup() {
|
|||||||
case "start":
|
case "start":
|
||||||
return startNewGameHandler(c)
|
return startNewGameHandler(c)
|
||||||
case "answer":
|
case "answer":
|
||||||
return c.SendString("wip")
|
return answerHandler(c)
|
||||||
case "cancel":
|
case "exit":
|
||||||
return stopGameHandler(c)
|
return stopGameHandler(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,9 +13,16 @@ WHERE game_id = $2;
|
|||||||
|
|
||||||
-- name: UpdateQuestionCorrect :exec
|
-- name: UpdateQuestionCorrect :exec
|
||||||
UPDATE app_flags_games
|
UPDATE app_flags_games
|
||||||
SET questions_correct = (
|
SET questions_errors = (
|
||||||
SELECT COUNT(*)
|
SELECT COALESCE(SUM(errors), 0)
|
||||||
FROM app_flags_games_answers
|
FROM app_flags_games_answers
|
||||||
WHERE game_id $1 AND correct = TRUE
|
WHERE app_flags_games_answers.game_id = app_flags_games.game_id
|
||||||
)
|
)
|
||||||
WHERE game_id = $1;
|
WHERE app_flags_games.game_id = $1;
|
||||||
|
|
||||||
|
-- name: UpsertGameAnswer :exec
|
||||||
|
INSERT INTO app_flags_games_answers (game_id, question, errors)
|
||||||
|
VALUES ($1, $2, $3)
|
||||||
|
ON CONFLICT (game_id, question)
|
||||||
|
DO UPDATE SET errors = app_flags_games_answers.errors + EXCLUDED.errors;
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ func (q *Queries) CreateFlagsGame(ctx context.Context, arg CreateFlagsGameParams
|
|||||||
}
|
}
|
||||||
|
|
||||||
const getFlagsGame = `-- name: GetFlagsGame :one
|
const getFlagsGame = `-- name: GetFlagsGame :one
|
||||||
SELECT game_id, game_seed, uid, tags, question_amount, question_current, question_correct, created_at, last_activity FROM app_flags_games WHERE game_id = $1 LIMIT 1
|
SELECT game_id, game_seed, uid, tags, question_amount, question_current, questions_errors, created_at, last_activity FROM app_flags_games WHERE game_id = $1 LIMIT 1
|
||||||
`
|
`
|
||||||
|
|
||||||
func (q *Queries) GetFlagsGame(ctx context.Context, gameID uuid.UUID) (AppFlagsGame, error) {
|
func (q *Queries) GetFlagsGame(ctx context.Context, gameID uuid.UUID) (AppFlagsGame, error) {
|
||||||
@ -51,7 +51,7 @@ func (q *Queries) GetFlagsGame(ctx context.Context, gameID uuid.UUID) (AppFlagsG
|
|||||||
pq.Array(&i.Tags),
|
pq.Array(&i.Tags),
|
||||||
&i.QuestionAmount,
|
&i.QuestionAmount,
|
||||||
&i.QuestionCurrent,
|
&i.QuestionCurrent,
|
||||||
&i.QuestionCorrect,
|
&i.QuestionsErrors,
|
||||||
&i.CreatedAt,
|
&i.CreatedAt,
|
||||||
&i.LastActivity,
|
&i.LastActivity,
|
||||||
)
|
)
|
||||||
@ -76,15 +76,33 @@ func (q *Queries) UpdateFlagsGame(ctx context.Context, arg UpdateFlagsGameParams
|
|||||||
|
|
||||||
const updateQuestionCorrect = `-- name: UpdateQuestionCorrect :exec
|
const updateQuestionCorrect = `-- name: UpdateQuestionCorrect :exec
|
||||||
UPDATE app_flags_games
|
UPDATE app_flags_games
|
||||||
SET questions_correct = (
|
SET questions_errors = (
|
||||||
SELECT COUNT(*)
|
SELECT COALESCE(SUM(errors), 0)
|
||||||
FROM app_flags_games_answers
|
FROM app_flags_games_answers
|
||||||
WHERE game_id $1 AND correct = TRUE
|
WHERE app_flags_games_answers.game_id = app_flags_games.game_id
|
||||||
)
|
)
|
||||||
WHERE game_id = $1
|
WHERE app_flags_games.game_id = $1
|
||||||
`
|
`
|
||||||
|
|
||||||
func (q *Queries) UpdateQuestionCorrect(ctx context.Context, dollar_1 interface{}) error {
|
func (q *Queries) UpdateQuestionCorrect(ctx context.Context, gameID uuid.UUID) error {
|
||||||
_, err := q.db.ExecContext(ctx, updateQuestionCorrect, dollar_1)
|
_, err := q.db.ExecContext(ctx, updateQuestionCorrect, gameID)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
const upsertGameAnswer = `-- name: UpsertGameAnswer :exec
|
||||||
|
INSERT INTO app_flags_games_answers (game_id, question, errors)
|
||||||
|
VALUES ($1, $2, $3)
|
||||||
|
ON CONFLICT (game_id, question)
|
||||||
|
DO UPDATE SET errors = app_flags_games_answers.errors + EXCLUDED.errors
|
||||||
|
`
|
||||||
|
|
||||||
|
type UpsertGameAnswerParams struct {
|
||||||
|
GameID uuid.UUID
|
||||||
|
Question int32
|
||||||
|
Errors int32
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) UpsertGameAnswer(ctx context.Context, arg UpsertGameAnswerParams) error {
|
||||||
|
_, err := q.db.ExecContext(ctx, upsertGameAnswer, arg.GameID, arg.Question, arg.Errors)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ type AppFlagsGame struct {
|
|||||||
Tags []string
|
Tags []string
|
||||||
QuestionAmount int32
|
QuestionAmount int32
|
||||||
QuestionCurrent int32
|
QuestionCurrent int32
|
||||||
QuestionCorrect int32
|
QuestionsErrors int32
|
||||||
CreatedAt time.Time
|
CreatedAt time.Time
|
||||||
LastActivity time.Time
|
LastActivity time.Time
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ CREATE TABLE app_flags_games (
|
|||||||
tags VARCHAR[] NOT NULL,
|
tags VARCHAR[] NOT NULL,
|
||||||
question_amount INT NOT NULL,
|
question_amount INT NOT NULL,
|
||||||
question_current INT DEFAULT 1 NOT NULL,
|
question_current INT DEFAULT 1 NOT NULL,
|
||||||
question_correct INT DEFAULT 0 NOT NULL,
|
questions_errors INT DEFAULT 0 NOT NULL,
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||||
last_activity TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
last_activity TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||||
FOREIGN KEY (uid) REFERENCES users (uid)
|
FOREIGN KEY (uid) REFERENCES users (uid)
|
||||||
|
13
web/views/apps/flags/end.html
Normal file
13
web/views/apps/flags/end.html
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
Errors: {{.Errors}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>game is over</div>
|
||||||
|
|
||||||
|
<form method="post" hx-boost="true">
|
||||||
|
<input class="hidden" name="type" value="exit" />
|
||||||
|
<button type="submit" class="btn">exit</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
@ -2,6 +2,10 @@
|
|||||||
|
|
||||||
<div>
|
<div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
Errors: {{.Errors}}
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="flex justify-center p-4 mt-4">
|
<div class="flex justify-center p-4 mt-4">
|
||||||
<span style="font-size: 105px;">{{.Flag}}</span>
|
<span style="font-size: 105px;">{{.Flag}}</span>
|
||||||
</div>
|
</div>
|
||||||
@ -17,7 +21,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form hx-boost="true" method="post">
|
<form hx-boost="true" method="post">
|
||||||
<input class="hidden" name="type" value="cancel" />
|
<input class="hidden" name="type" value="exit" />
|
||||||
<button type="submit" class="btn hover:btn-error">Stop</button>
|
<button type="submit" class="btn hover:btn-error">Stop</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
@ -55,7 +55,6 @@
|
|||||||
<span class="text-base">{{.T.about}}</span>
|
<span class="text-base">{{.T.about}}</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<!--
|
|
||||||
<li class="flex-none">
|
<li class="flex-none">
|
||||||
<details class="dropdown">
|
<details class="dropdown">
|
||||||
<summary><a class="flex gap-4">
|
<summary><a class="flex gap-4">
|
||||||
@ -92,7 +91,6 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</details>
|
</details>
|
||||||
</li>
|
</li>
|
||||||
-->
|
|
||||||
<li>
|
<li>
|
||||||
{{if .SignedIn}}
|
{{if .SignedIn}}
|
||||||
<a class='flex gap-4 {{if eq .Path "/account"}}active{{end}}' href="/account">
|
<a class='flex gap-4 {{if eq .Path "/account"}}active{{end}}' href="/account">
|
||||||
|
Loading…
Reference in New Issue
Block a user