Таблица

=> CREATE TABLE animals(
    id     serial  PRIMARY KEY,
    root   boolean DEFAULT false,
    yes_id integer REFERENCES animals(id),
    no_id  integer REFERENCES animals(id),
    name   text
);
CREATE TABLE
=> INSERT INTO animals(name) VALUES ('слон'), ('черепаха');
INSERT 0 2
=> INSERT INTO animals(name,root,yes_id,no_id) VALUES ('млекопитающее',true,1,2);
INSERT 0 1
=> SELECT * FROM animals;
 id | root | yes_id | no_id |     name      
----+------+--------+-------+---------------
  1 | f    |        |       | слон
  2 | f    |        |       | черепаха
  3 | t    |      1 |     2 | млекопитающее
(3 rows)

Функции

=> CREATE FUNCTION start_game(OUT context integer, OUT question text) AS $$
BEGIN
    SELECT id, name||'?' INTO context, question FROM animals WHERE root;
END;
$$ LANGUAGE plpgsql;
CREATE FUNCTION
=> CREATE FUNCTION continue_game(INOUT context integer, answer boolean, OUT you_win boolean, OUT question text) AS $$
DECLARE
    new_context integer;
BEGIN
    SELECT CASE WHEN answer THEN yes_id ELSE no_id END INTO new_context FROM animals where id = context;
    IF new_context IS NULL THEN
        you_win := NOT answer;
        question := 'Вы ' || CASE WHEN you_win THEN 'выиграли' ELSE 'проиграли' END;
    ELSE
        SELECT id, null, name||'?' into context, you_win, question from animals where id = new_context;
    END IF;
END;
$$ LANGUAGE plpgsql;
CREATE FUNCTION
=> CREATE FUNCTION end_game(context integer, name text, question text) RETURNS void AS $$
DECLARE
    new_animal_id integer;
    new_question_id integer;
BEGIN
    INSERT INTO animals(name) VALUES (name) RETURNING id INTO new_animal_id;
    INSERT INTO animals(name) VALUES (question) RETURNING id INTO new_question_id;
    UPDATE animals SET yes_id = new_question_id WHERE yes_id = context;
    UPDATE animals SET  no_id = new_question_id WHERE  no_id = context;
    UPDATE animals SET yes_id = new_animal_id, no_id = context WHERE id = new_question_id;
END;
$$ LANGUAGE plpgsql;
CREATE FUNCTION

Пример сеанса игры (загадали "кит")

=> SELECT * FROM start_game();
 context |    question    
---------+----------------
       3 | млекопитающее?
(1 row)

=> SELECT * FROM continue_game(3,true);
 context | you_win | question 
---------+---------+----------
       1 |         | слон?
(1 row)

=> SELECT * FROM continue_game(1,false);
 context | you_win |  question   
---------+---------+-------------
       1 | t       | Вы выиграли
(1 row)

=> SELECT * FROM end_game(1,'кит','живет в воде');
 end_game 
----------
 
(1 row)

Теперь в таблице:

=> SELECT * FROM animals;
 id | root | yes_id | no_id |     name      
----+------+--------+-------+---------------
  1 | f    |        |       | слон
  2 | f    |        |       | черепаха
  4 | f    |        |       | кит
  3 | t    |      5 |     2 | млекопитающее
  5 | f    |      4 |     1 | живет в воде
(5 rows)

Еще один сеанс (снова загадали "кит")

=> SELECT * FROM start_game();
 context |    question    
---------+----------------
       3 | млекопитающее?
(1 row)

=> SELECT * FROM continue_game(3,true);
 context | you_win |   question    
---------+---------+---------------
       5 |         | живет в воде?
(1 row)

=> SELECT * FROM continue_game(5,true);
 context | you_win | question 
---------+---------+----------
       4 |         | кит?
(1 row)

=> SELECT * FROM continue_game(4,true);
 context | you_win |   question   
---------+---------+--------------
       4 | f       | Вы проиграли
(1 row)