On 6 September 2016 at 12:32, Alexander Farber <alexander.far...@gmail.com>
wrote:

> Good afternoon,
>
> for a 2-player game I store moves in the following 9.5.4 table:
>
> CREATE TYPE words_action AS ENUM ('play', 'skip', 'swap', 'resign');
>
> CREATE TABLE words_moves (
>         mid SERIAL PRIMARY KEY,
>         action words_action NOT NULL,
>         gid integer NOT NULL REFERENCES words_games ON DELETE CASCADE,
>         uid integer NOT NULL REFERENCES words_users ON DELETE CASCADE,
>         played timestamptz NOT NULL,
>         tiles jsonb,
>         score integer CHECK (score > 0)
> );
>
> ALTER TABLE words_games ADD CONSTRAINT words_mid_fk FOREIGN KEY (mid)
> REFERENCES words_moves;
>
> And then I have a custom function for skipping a move (and inserting a
> 'skip' into the above table):
>
> CREATE OR REPLACE FUNCTION words_skip_game(
>         IN in_uid integer,
>         IN in_gid integer,
>         OUT out_gid integer)
>         RETURNS integer AS
> $func$
> DECLARE
>         _finished timestamptz;
>         _score1   integer;
>         _score2   integer;
>         _uid2     integer;
> BEGIN
>         INSERT INTO words_moves (
>                 action,
>                 gid,
>                 uid,
>                 played
>         ) VALUES (
>                 'skip',
>                 in_gid,
>                 in_uid,
>                 CURRENT_TIMESTAMP
>         );
>
> Could you please suggest a good way to check that the last 6 moves where
> 'skip', so that I can end the game when each player skipped her move 3
> times in a row?
>
>         IF /* there are 6 'skip's - how to do it please? */ THEN
>                 _finished = CURRENT_TIMESTAMP;
>         END IF;
>
> Below is the rest of my function, thank you for any ideas -
>
> Regards
> Alex
>
>         UPDATE words_games SET
>                 finished = _finished,
>                 played1  = CURRENT_TIMESTAMP
>         WHERE
>                 gid      = in_gid AND
>                 player1  = in_uid AND
>                 finished IS NULL AND
>                 -- and it is first player's turn
>                 (played1 IS NULL OR played1 < played2)
>         RETURNING
>                 gid,
>                 score1,
>                 score2,
>                 player2
>         INTO
>                 out_gid,
>                 _score1, -- my score
>                 _score2, -- her score
>                 _uid2;
>
>         IF NOT FOUND THEN
>                 UPDATE words_games SET
>                         finished = _finished,
>                         played2  = CURRENT_TIMESTAMP
>                 WHERE
>                         gid      = in_gid AND
>                         player2  = in_uid AND
>                         finished IS NULL AND
>                         -- and it is second player's turn
>                         (played2 IS NULL OR played2 < played1);
>                 RETURNING
>                         gid,
>                         score2,  -- swapped
>                         score1,
>                         player1
>                 INTO
>                         out_gid,
>                         _score1,  -- my score
>                         _score2,  -- her score
>                         _uid2;
>         END IF;
>
>         IF NOT FOUND THEN
>                 RAISE EXCEPTION 'Game % not found for user %', in_gid,
> in_uid;
>         END IF;
>
>         -- game over, update win/loss/draw stat for both players
>         IF _finished IS NOT NULL THEN
>                 IF _score1 > _score2 THEN
>
>                         UPDATE words_users SET
>                                 win = win + 1
>                         WHERE uid = in_uid;
>
>                         UPDATE words_users SET
>                                 loss = loss + 1
>                         WHERE uid = _uid2;
>
>                 ELSIF _score1 < _score2 THEN
>
>                         UPDATE words_users SET
>                                 loss = loss + 1
>                         WHERE uid = in_uid;
>
>                         UPDATE words_users SET
>                                 win = win + 1
>                         WHERE uid = _uid2;
>                 ELSE
>                         UPDATE words_users SET
>                                 draw = draw + 1
>                         WHERE uid = in_uid OR uid = _uid2;
>                 END IF;
>         END IF;
> END
> $func$ LANGUAGE plpgsql;
>

Get the last 6 record and

1.  ... action='SKIP' as isskip ... then you can group on and count the
skip moves. If there is 6 of them the game ends.

2.  ... sum(case when action='SKIP' then 1 else 0 end) ... If the result is
6 the game ends

Regards,
Sándor

Reply via email to