Đoạn mã dưới đây là phiên bản đơn giản hóa và mô phỏng dựa trên text của trò chơi Snake. Nó sử dụng các cấu trúc PL/SQL để mô phỏng chuyển động của con rắn, tạo thức ăn và kiểm tra va chạm với tường và chính nó.
CREATE OR REPLACE PROCEDURE snake_game AS
TYPE position_type IS RECORD (row NUMBER, col NUMBER);
TYPE snake_type IS TABLE OF position_type INDEX BY PLS_INTEGER;
v_grid_size CONSTANT NUMBER := 10; -- Size of the grid (10x10).
v_initial_snake_length CONSTANT NUMBER := 4; -- Initial length of the snake.
v_snake snake_type;
v_snake_length NUMBER := v_initial_snake_length;
v_food position_type;
v_game_over BOOLEAN := FALSE;
v_direction CHAR := 'R'; -- Initial direction (Right).
PROCEDURE draw_grid IS
BEGIN
FOR i IN 1..v_grid_size LOOP
FOR j IN 1..v_grid_size LOOP
IF (i = v_food.row AND j = v_food.col) THEN
DBMS_OUTPUT.PUT('|F');
ELSE
DBMS_OUTPUT.PUT('| ');
END IF;
END LOOP;
DBMS_OUTPUT.PUT_LINE('|');
END LOOP;
END draw_grid;
PROCEDURE generate_food IS
BEGIN
v_food.row := DBMS_RANDOM.VALUE(1, v_grid_size + 1);
v_food.col := DBMS_RANDOM.VALUE(1, v_grid_size + 1);
END generate_food;
PROCEDURE move_snake(p_direction IN CHAR) IS
v_head_row NUMBER := v_snake(v_snake_length).row;
v_head_col NUMBER := v_snake(v_snake_length).col;
BEGIN
CASE p_direction
WHEN 'U' THEN v_head_row := v_head_row - 1; -- Up
WHEN 'D' THEN v_head_row := v_head_row + 1; -- Down
WHEN 'L' THEN v_head_col := v_head_col - 1; -- Left
WHEN 'R' THEN v_head_col := v_head_col + 1; -- Right
END CASE;
-- Check for collision with the food
IF (v_head_row = v_food.row AND v_head_col = v_food.col) THEN
v_snake_length := v_snake_length + 1;
generate_food;
END IF;
-- Update the snake's position
FOR i IN v_snake_length DOWN TO 2 LOOP
v_snake(i) := v_snake(i - 1);
END LOOP;
v_snake(1).row := v_head_row;
v_snake(1).col := v_head_col;
END move_snake;
BEGIN
-- Initialize the snake's starting position
FOR i IN 1..v_initial_snake_length LOOP
v_snake(i).row := 1;
v_snake(i).col := i;
END LOOP;
-- Generate the initial food position
generate_food;
-- Main game loop
LOOP
-- Clear the screen
DBMS_OUTPUT.PUT_LINE(chr(27) || '[2J');
-- Draw the grid
draw_grid;
-- Move the snake
move_snake(v_direction);
-- Check for collision with the walls
IF (v_snake(1).row <= 0 OR v_snake(1).row > v_grid_size OR
v_snake(1).col <= 0 OR v_snake(1).col > v_grid_size) THEN
v_game_over := TRUE;
END IF;
-- Check for collision with itself
FOR i IN 2..v_snake_length LOOP
IF (v_snake(i).row = v_snake(1).row AND v_snake(i).col = v_snake(1).col) THEN
v_game_over := TRUE;
END IF;
END LOOP;
-- Check for game over condition
IF v_game_over THEN
DBMS_OUTPUT.PUT_LINE('Game Over!');
EXIT;
END IF;
-- Sleep for a short period to control the game speed
DBMS_LOCK.SLEEP(0.5);
END LOOP;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('An error occurred: ' || SQLERRM);
END;