Skip to content

Trò chơi & level (Mini-game) ​

Mục Công cụ tương tác → Trò chơi là nơi tạo trò chơi lập trình kéo-thả khối và các level của nó. Ba cách người dùng chơi trên cùng dữ liệu này: chơi tự do (/g/<đường-dẫn>, kèm trang tổng kết /g/<đường-dẫn>/summary), mùa giải (marketing, có giải — quy trình trọn vẹn ở Triển khai chiến dịch mini-game) và đố hằng ngày (giữ chân học viên trong Learnspace).

Yêu cầu module: MiniGames + BlocklyGames + BlocklyRuntime bật cho tổ chức — module do quản trị hệ thống (central) bật; chưa thấy mục Trò chơi trong menu thì liên hệ nhà cung cấp. Thiếu BlocklyGames thì trò chơi loại "lưới Blockly" hiện "loại không khả dụng" và trang chơi báo không tìm thấy.

Tạo trò chơi ​

ÔGhi chú
Tên / Đường dẫnTrang chơi là /g/<đường-dẫn> (chữ thường, số, gạch ngang).
Loại trò chơiHiện có Lưới Blockly (lập trình khối). Không đổi được sau khi đã có level.
Bộ hình ảnhChọn trong danh sách: nhân vật, ô bản đồ và ảnh nền khung — xem Bộ hình ảnh. Mặc định Sóc trong vườn (emoji).
Khách chơi đượcChỉ có hiệu lực khi cài đặt chung cho phép khách chơi.
Cho phép chia sẻ kết quảBật nút chia sẻ + thẻ công khai: thẻ kết quả của từng level (/g/<đường-dẫn>/r/<mã>) và thẻ thành tích cả trò chơi từ trang tổng kết (/g/<đường-dẫn>/a/<mã> — tiến độ, điểm, sao trên các level đã đăng). Tắt thì cả hai nút ẩn; thẻ đã tạo trước đó vẫn mở được.
Đố hằng ngàyChỉ hiện ở trang sửa; bật được khi đã có ≥ 3 level pool Đố hằng ngày đã đăng và đã kiểm.
Trạng tháiNháp: chỉ người có quyền sửa trò chơi xem trước được; Đã đăng: công khai; Lưu trữ: ẩn nhưng link thẻ kết quả cũ vẫn mở.

Trò chơi mẫu (kỹ thuật chạy trên máy chủ, không có nút trong trang quản trị):

Trò chơiLevelCách chèn
Thỏ ngọc về cung trăng (bộ hình Thỏ ngọc Trung thu, /g/tho-ngoc-ve-cung-trang)20 level từ dễ tới khó: chuỗi lệnh → vòng lặp đếm → vòng lặp lồng + lặp khi còn bánh → cảm biến → mê cung. Mọi level cho kéo khối lẫn gõ mã, đã có gợi ý, số khối chuẩn và lời giải mẫu đã kiểmphp artisan tenants:run blocklygames:seed-mid-autumn --tenants=<mã tổ chức> — thêm --option=draft=1 để tạo ở trạng thái Nháp (xem trước, chạy thử rồi mới đăng)
Sóc nhặt hạt (5 level)Tuần tự, rẽ, vòng lặp, nhặt hạt, cảm biếnseeder của module — xem tài liệu kỹ thuật

Chèn lại khi tổ chức đã có trò chơi đó thì lệnh bỏ qua, không ghi đè (trò chơi có thể đã có lượt chơi). Sau khi chèn, sửa tên, mô tả, level như trò chơi tự tạo.

Bộ hình ảnh ​

Bộ hình quyết định người chơi thấy gì trên bản đồ; luật chơi, level và điểm không đổi khi đổi bộ hình. Đổi bộ hình của trò chơi đang chạy là an toàn — lượt chơi cũ vẫn giữ nguyên kết quả.

Bộ hìnhKiểuNhân vật → nhặt → tới
Sóc trong vườnemoji🐿️ nhặt 🌰, tới 🏁; tường 🌳, nguy hiểm 🔥
Ong tìm mậtemoji🐝 nhặt 🌸, tới 🍯; tường 🪨, nguy hiểm 🕸️
Thỏ ngọc Trung thuảnhthỏ lấy bánh trung thu, tới trăng rằm; tường cây đa, nguy hiểm đèn lồng; nền đêm rằm
Lân đón Tếtảnhlân nhận lì xì, tới nhà câu đối đỏ; tường cây mai, nguy hiểm pháo; nền phố Tết
Tuần lộc giao quàảnhtuần lộc nhặt quà, tới ống khói; tường thông tuyết, nguy hiểm hố băng; nền làng tuyết đêm
Bí ngô tinh nghịchảnhbí ngô xin kẹo, tới lâu đài; tường bia đá, nguy hiểm vạc thuốc; nền rừng đêm
Hè ra biểnảnhcua nhặt vỏ sò, tới lâu đài cát; tường san hô, nguy hiểm sứa; nền bãi biển
Robot thám hiểm sao Hoảảnhxe tự hành thu mẫu đá, về trạm căn cứ; tường đá đỏ, nguy hiểm bão bụi; nền sao Hoả

Năm bộ theo mùa đang dùng ảnh tạm

Lân đón Tết, Tuần lộc giao quà, Bí ngô tinh nghịch, Hè ra biển và Robot thám hiểm sao Hoả hiện là ảnh vẽ khối đơn giản để dựng thử level và xem bố cục. Gửi ảnh chính thức cho nhà cung cấp trước khi chạy chiến dịch — chỉ thay file, không phải sửa level.

  • Khung bản đồ luôn vuông với ảnh nền theo bộ hình; bản đồ nằm giữa khung dù số hàng và cột khác nhau.
  • Bộ emoji: nhân vật giống nhau ở mọi hướng nên có mũi tên nhỏ ở mép ô chỉ hướng đang nhìn.
  • Bộ ảnh: nhân vật có hình riêng cho bốn hướng (nhìn lên, xuống, trái, phải) nên không cần mũi tên; màu ô được chỉnh cho hợp ảnh nền.
  • Trình vẽ level hiện đúng bộ hình của trò chơi (cả ở bảng cọ).
  • Khối nhặt vật phẩm mang tên theo bộ hình: nhặt hạt (sóc), lấy phấn hoa (ong), lấy bánh (thỏ ngọc) — cùng tên ở bảng khối, ô tick của trình vẽ và bảng hàm dưới ô gõ mã. Xem Vật phẩm có số lượng.

Muốn bộ hình riêng theo chiến dịch

Bộ hình mới không tải lên từ trang quản trị — nhà cung cấp cài vào hệ thống rồi nó xuất hiện trong danh sách. Chuẩn bị gửi kèm:

ẢnhSố lượngYêu cầu
Nhân vật4 (nhìn lên / phải / xuống / trái)cùng cỡ, cùng tư thế, chỉ khác hướng
Tường, vật phẩm, đích, ô nguy hiểm1 mỗi loạivuông, nhận ra được ở cỡ nhỏ (~40 px)
Ảnh nền khung1vuông (ví dụ 1024×1024), phần giữa thoáng vì bản đồ đè lên

Ảnh phải qua được các kiểm tra tự động, không thì nhà cung cấp trả lại: ảnh ô và ảnh nền vuông, ảnh nhân vật có nền trong suốt, và bốn hướng khác dáng rõ ràng (không chỉ khác chi tiết nhỏ) — bộ ảnh không có mũi tên chỉ hướng nên nhìn trước và nhìn sau giống nhau là người chơi không biết nhân vật quay về đâu.

Ảnh ô và nhân vật: vuông, nền trong suốt, chủ thể chiếm khoảng 85 % khung; gửi PNG nền trong suốt (hoặc WebP) từ 256×256 — hệ thống dùng bản WebP khoảng 10–15 KB mỗi ảnh. ⚠ Đừng xuất SVG từ Canva: file đó chỉ bọc ảnh PNG cỡ lớn bên trong, 0,6–2 MB mỗi file, làm trang chơi tải chậm. Gửi kèm 3–5 mã màu cho ô đường, tường, đích nếu muốn ô hợp tông ảnh nền, và tên hành động nhặt hợp chủ đề (ví dụ "lấy bánh" — cả dạng "còn bánh ở đây", "lặp khi còn bánh"). Chỉ dùng ảnh tổ chức có quyền sử dụng.

Level ​

Tab Level trong trang sửa trò chơi. Với trò chơi lưới Blockly, nút Thêm level / Soạn mở trang trình vẽ level (xem Trình vẽ level); tab JSON trên trang đó nhận cấu hình dán tay (bảng mô tả bên dưới). Các ô chung của level:

ÔGhi chú
Thứ tựDuy nhất trong trò chơi; chơi tự do và mùa giải liệt kê theo thứ tự này.
PoolChơi tự do / mùa giải (mặc định) hoặc Đố hằng ngày. Level đố hằng ngày không bao giờ xuất hiện ở chơi tự do hay mùa giải — nếu chung pool thì đề hôm nay tra được trước. Khoá sau khi level đã có lượt chơi hoặc đã từng là đề của ngày.
Độ khó1–5, chỉ để hiển thị.
Điểm tối đaMặc định 1000.
Số khối chuẩnDùng ≤ số này được trọn 40 % thưởng; để trống thì luôn trọn (ô hiện cảnh báo khi đang trống). Nên đặt bằng số khối của lời giải mẫu — trình vẽ gợi ý sẵn sau khi Chạy thử đạt. Cũng là mốc tính sao trên trang tổng kết của người chơi (≤ số khối chuẩn 3 sao, ≤ 1,5 lần 2 sao, còn lại 1 sao).
Trạng tháiĐăng đòi lời giải mẫu đạt: mỗi lần lưu, hệ thống chạy lời giải mẫu (solution) trên chính máy chấm và đóng dấu "đã kiểm" cho đúng cấu hình đó; đổi cấu hình là dấu mất, lưu lại là kiểm lại. Level không có lời giải mẫu không đăng được — một level không giải nổi là trò chơi kẹt ở đó. Nút Kiểm tra chỉ báo kết quả mà không lưu.

Trình vẽ level ​

Trang Soạn level (/admin/games/{id}/levels/{level}) có hai tab: Thiết kế và JSON — cùng một cấu hình, hai cách sửa; đổi ở tab nào cũng thấy ở tab kia.

Tab Thiết kế gồm hàng trên hai cột và hàng dưới trải hết bề ngang:

  1. Bản đồ (hàng trên, bên trái) — chọn kích thước (3–12 hàng/cột), chọn cọ (Tường, Đường, Xuất phát, Đích, Vật phẩm, Nguy hiểm) rồi bấm hoặc kéo trên lưới để tô. Chỉ một ô xuất phát và một ô đích: đặt ô mới thì ô cũ thành đường. Chọn hướng xuất phát, điều kiện thắng (tới đích / nhặt hết vật phẩm / cả hai) và cách nhặt vật phẩm (gọi lệnh nhặt / bước vào là nhặt). Khi nhặt bằng lệnh, cọ Vật phẩm có thêm ô Số vật phẩm mỗi ô (1–9) — ô có nhiều vật phẩm hiện số ở góc. Lưới hiện đúng bộ hình người chơi sẽ thấy.
  2. Khối được dùng (hàng trên, bên phải — tick từng khối theo nhóm Hành động / Vòng lặp / Điều kiện), Tối đa số khối, Tối đa số bước, Gợi ý (tối đa 3), Cách nhập (kéo khối / gõ mã, ngôn ngữ, mặc định — xem Cho người chơi gõ mã).
  3. Lời giải mẫu (hàng dưới) — soạn bằng Kéo khối (bảng khối đúng như người chơi thấy, thu hẹp theo những khối đã tick) hoặc Gõ mã (JavaScript/Python). Hai bản độc lập; bản đang chọn là lời giải được lưu. Bấm Chạy thử: máy chấm chạy lời giải và phát lại từng bước trên lưới bản đồ, tô sáng khối/dòng đang chạy; phát lại xong mới hiện kết quả "Đạt · N bước · M khối" hoặc lý do dừng (đâm tường, rơi vào ô nguy hiểm, chưa ở đích…). Đạt mà ô Số khối chuẩn còn trống thì có nút Đặt số khối chuẩn = M để điền luôn (vẫn phải Lưu level). Lỗi cấu hình hiện ngay dưới cột liên quan; lỗi cú pháp của mã tô đúng dòng.

Lời giải mẫu là của bạn, không phải của người chơi

Level chỉ cho kéo khối vẫn soạn lời giải mẫu bằng mã được (và ngược lại) — cách nhập chỉ giới hạn người chơi. Nhưng lời giải mẫu vẫn phải dùng đúng những khối đã tick và không vượt Tối đa số khối: máy chấm áp cùng luật với bài của người chơi.

Chạy thử không lưu gì. Lưu level mới ghi cấu hình và đóng dấu đã kiểm (khi lời giải mẫu đạt). Cửa sổ soạn là một trang riêng chứ không phải hộp thoại — thoát trang mà chưa bấm Lưu là mất chỉnh sửa.

Nhờ AI vẽ level ​

Trên đầu trang soạn level có nút AI vẽ level (chỉ hiện khi tổ chức bật module AI Credits — lượt gọi được ghi vào sổ chi AI, mục AI vẽ level trò chơi lưới). Bấm, gõ yêu cầu (ví dụ "mê cung 7x7 có ô nguy hiểm, bắt buộc dùng lặp tới đích và if" — hoặc để trống), bấm Vẽ:

  • AI vẽ bản đồ, chọn khối, đặt trần, viết gợi ý, đặt tiêu đề và lời giải mẫu, dựa trên các level đứng trước trong cùng pool (để khó dần), bản bạn đang vẽ dở (nếu có — AI giữ ý tưởng và hoàn thiện) và yêu cầu của bạn.
  • Máy chấm chạy lời giải mẫu trước khi đưa vào trình vẽ; không đạt thì AI được chỉ lỗi và sửa lại một lần.
  • Việc chạy nền thường mất một–hai phút (lâu hơn khi hàng đợi AI bận); trang tự cập nhật, tải lại trang cũng không mất. Xong, level rơi vào trình vẽ — bản đồ, khối, gợi ý, lời giải mẫu — kèm thông báo xanh (lời giải chạy đạt) hoặc vàng (chưa đạt: xem lý do rồi sửa tay, hoặc vẽ lại). Tiêu đề và Số khối chuẩn chỉ được điền nếu ô còn trống.
  • Chưa có gì được lưu: bạn Chạy thử, sửa nếu cần, rồi Lưu level như level tự vẽ — cổng "đăng đòi lời giải mẫu đạt" không đổi.

Mỗi người có 10 lượt vẽ mỗi giờ. Một lượt tốn tối đa hai lần gọi AI (lượt đầu + một lượt sửa).

Vật phẩm có số lượng và lệnh nhặt ​

Một ô có thể chứa 1–9 vật phẩm (phấn hoa, quả thông, bánh trung thu…), và người chơi phải gọi lệnh nhặt đúng số lần — bằng tay (ba khối "lấy bánh") hoặc bằng vòng lặp. Đây là chỗ dạy vòng lặp đếm và vòng lặp có điều kiện rất tự nhiên: ô có 3 bánh → lặp 3 lần: lấy bánh; không biết trước số lượng → lặp khi còn bánh: lấy bánh.

Cách nhặt vật phẩm (ô chọn ở trình vẽ, khoá collect ở JSON):

Cách nhặtHành viDùng khi
Gọi lệnh nhặt ("collect": "command")Bước vào ô không nhặt gì. Mỗi lần gọi khối nhặt lấy 1 vật phẩm ở ô đang đứng. Gọi khi ô không còn vật phẩm → thua ("nhặt ở ô không còn vật phẩm"). Mỗi lần nhặt tính 1 bước.Mặc định của level mới
Bước vào là nhặt (vắng khoá, hoặc "step")Như trước đây: đi qua ô là nhặt, mỗi ô đúng 1 vật phẩm. Không có số lượng, không dùng được khối nhặt.Level đã soạn trước khi có tính năng này — không cần sửa gì, vẫn chạy như cũ

Thua khi nhặt thừa là cố ý: người chơi phải đếm đúng, chứ không gọi thêm vài lần "cho chắc". Nhặt thiếu thì Chưa xong — chưa nhặt hết vật phẩm.

Ba khối mới (tick ở Khối được dùng; tên hiển thị theo bộ hình):

KhốiNhómJavaScript / Java / C++C#Python
nhặt (lấy bánh…)Hành độngcollect();Collect();collect()
còn vật phẩm ở đâyĐiều kiệnitemHere()ItemHere()item_here()
lặp khi còn vật phẩmVòng lặpwhile (itemHere()) { … }while (ItemHere()) { … }while item_here():

Hệ thống từ chối cấu hình vô nghĩa khi Chạy thử/Lưu:

  • Ô có số lượng > 1 mà cách nhặt là bước vào là nhặt.
  • Tick khối nhặt / còn vật phẩm / lặp khi còn vật phẩm mà cách nhặt là bước vào là nhặt (ô tick bị khoá sẵn trong trình vẽ).
  • Nhặt bằng lệnh mà thiếu khối nhặt — khi điều kiện thắng cần vật phẩm, hoặc khi đã tick còn vật phẩm / lặp khi còn vật phẩm.
  • Tick khối nhặt trên bản đồ không có vật phẩm nào.

Gợi ý thiết kế

  • Level đầu tiên có số lượng: một ô 2–3 vật phẩm, cho lặp N lần — người chơi thấy ngay "ô số 3 → lặp 3 lần".
  • Level sau: nhiều ô với số lượng khác nhau và cho lặp khi còn vật phẩm — một vòng lặp dùng được cho mọi ô, không phải đếm.
  • Đặt Tối đa số khối sát lời giải để người chơi không xếp tay 9 khối nhặt.

Ví dụ sẵn dùng: 7. Lấy bánh trung thu.

JSON cấu hình (lưới Blockly) ​

Tab JSON của trang soạn level (hoặc ô cấu hình với loại trò chơi không có trình vẽ). Đây cũng là thứ trình vẽ sinh ra — dán một ví dụ bên dưới rồi quay lại tab Thiết kế để sửa bằng mắt.

json
{
  "version": 1,
  "map": [
    "#######",
    "#S..*.#",
    "#.###.#",
    "#...*G#",
    "#######"
  ],
  "start_dir": 1,
  "win": "collect_all_and_goal",
  "toolbox": {
    "blocks": ["move_forward", "turn_left", "turn_right", "controls_repeat_ext", "repeat_until_goal", "controls_if", "path_ahead"],
    "max_blocks": 8
  },
  "limits": { "max_steps": 200 },
  "hints": ["Hãy dùng vòng lặp để đi hết hành lang."],
  "solution": { "blocks": { "languageVersion": 0, "blocks": [] } }
}
TrườngÝ nghĩa
map3–12 hàng × 3–12 cột. # tường, . đường, S xuất phát (đúng một), G đích (tối đa một; bắt buộc trừ khi win = collect_all), * vật phẩm (bắt buộc ≥ 1 khi win đòi nhặt), chữ số 1–9 ô có từng ấy vật phẩm (* = 1; cần collect = command), x ô nguy hiểm (dẫm là thua). Ngoài bản đồ là tường.
start_dirHướng nhìn ban đầu: 0 Bắc, 1 Đông, 2 Nam, 3 Tây.
wingoal (về đích), collect_all (nhặt hết), collect_all_and_goal.
collectcommand — chỉ khối nhặt mới nhặt, mỗi lần 1 vật phẩm, nhặt ở ô trống là thua; vắng (hoặc step) — bước vào là nhặt như trước. Xem Vật phẩm có số lượng.
toolbox.blocksKhối cho phép: move_forward, turn_left, turn_right, controls_repeat_ext (lặp N lần), repeat_until_goal, controls_if, controls_ifelse, logic_negate (không), path_ahead, path_left, path_right, at_goal (đang ở đích); với collect = command thêm collect (nhặt), item_here (còn vật phẩm ở đây), repeat_while_item (lặp khi còn vật phẩm). Khối ngoài danh sách bị từ chối khi nộp, không bỏ qua. Bắt buộc có move_forward.
toolbox.max_blocks1–200; "không giới hạn" viết là 200. Đặt trần nhỏ để ép dùng vòng lặp.
limits.max_steps10–1000, mặc định 200.
hints≤ 3 gợi ý, xếp từ nhẹ tới gần như lời giải. Người chơi không thấy sẵn — bấm Xem gợi ý để mở từng cái (sau hai lượt chưa xong nút được làm nổi).
solutionWorkspace JSON của Blockly (xuất từ trình soạn) hoặc {"code": "…", "language": "javascript"|"python"|"java"|"cpp"|"csharp"} — viết lời giải mẫu bằng mã cho nhanh. Không bao giờ gửi xuống trình duyệt người chơi.
inputChế độ nhập cho người chơi: {"modes": ["blocks", "code"], "languages": ["javascript", "python"], "default": "blocks"}. Vắng = chỉ kéo khối (mọi level cũ giữ nguyên). modes ⊆ {blocks, code}; languages ⊆ {javascript, python} (mặc định cả hai); default ∈ modes. Xem Cho người chơi gõ mã.

Hệ thống kiểm khi lưu (và khi Chạy thử): đúng một S/G, từ S có đường tới G và tới mọi * mà win đòi (ô nguy hiểm không tính là đường), khoá lạ bị từ chối. Lỗi báo ngay ở ô cấu hình, kèm đường dẫn (map[2], toolbox.max_blocks…).

Điểm không tính thời gian

Máy chấm là hệ thống (trình duyệt chỉ phát lại), nên điểm không sửa được. Thời gian giải cố ý không vào công thức — bot thắng người ở thời gian; bỏ nó đi thì bot không còn gì để thắng. Hoà xét "ai đạt trước".

Ví dụ cấu hình sẵn dùng ​

Bảy level dưới đây đã chạy qua máy chấm (lời giải mẫu đạt). Dán nguyên JSON vào tab JSON của trang soạn level, điền Số khối chuẩn như ghi chú, Lưu rồi đăng. Sửa map/toolbox tuỳ ý (ở tab Thiết kế cho dễ) — solution có thể không còn đúng, Chạy thử sẽ cho thấy. (Trường id trong solution chỉ cần duy nhất trong một level.)

1. Đi thẳng (độ khó 1, số khối chuẩn 3) ​

Bài đầu tiên: chỉ ba khối di chuyển, hành lang thẳng. Số khối chuẩn 3.

json
{
  "version": 1,
  "map": [
    "######",
    "#S..G#",
    "######"
  ],
  "start_dir": 1,
  "win": "goal",
  "toolbox": {
    "blocks": [
      "move_forward",
      "turn_left",
      "turn_right"
    ],
    "max_blocks": 10
  },
  "limits": {
    "max_steps": 200
  },
  "hints": [
    "Sóc đang quay mặt sang phải. Cần mấy lần \"tiến lên\"?"
  ],
  "solution": {
    "blocks": {
      "languageVersion": 0,
      "blocks": [
        {
          "type": "start",
          "id": "start",
          "x": 20,
          "y": 20,
          "next": {
            "block": {
              "type": "move_forward",
              "id": "seed1",
              "next": {
                "block": {
                  "type": "move_forward",
                  "id": "seed2",
                  "next": {
                    "block": {
                      "type": "move_forward",
                      "id": "seed3"
                    }
                  }
                }
              }
            }
          }
        }
      ]
    }
  }
}

2. Rẽ góc (độ khó 1, số khối chuẩn 7) ​

Dạy rằng sau khi rẽ, "tiến lên" cũng đổi hướng. Số khối chuẩn 7.

json
{
  "version": 1,
  "map": [
    "######",
    "#S..##",
    "###.##",
    "###.G#",
    "######"
  ],
  "start_dir": 1,
  "win": "goal",
  "toolbox": {
    "blocks": [
      "move_forward",
      "turn_left",
      "turn_right"
    ],
    "max_blocks": 12
  },
  "limits": {
    "max_steps": 200
  },
  "hints": [
    "Sau khi rẽ, hướng \"tiến lên\" cũng đổi theo."
  ],
  "solution": {
    "blocks": {
      "languageVersion": 0,
      "blocks": [
        {
          "type": "start",
          "id": "start",
          "x": 20,
          "y": 20,
          "next": {
            "block": {
              "type": "move_forward",
              "id": "seed4",
              "next": {
                "block": {
                  "type": "move_forward",
                  "id": "seed5",
                  "next": {
                    "block": {
                      "type": "turn_right",
                      "id": "seed6",
                      "next": {
                        "block": {
                          "type": "move_forward",
                          "id": "seed7",
                          "next": {
                            "block": {
                              "type": "move_forward",
                              "id": "seed8",
                              "next": {
                                "block": {
                                  "type": "turn_left",
                                  "id": "seed9",
                                  "next": {
                                    "block": {
                                      "type": "move_forward",
                                      "id": "seed10"
                                    }
                                  }
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      ]
    }
  }
}

3. Vòng lặp (độ khó 2, số khối chuẩn 2) ​

Trần 3 khối ép dùng vòng lặp controls_repeat_ext thay vì 7 lần "tiến lên". Số khối chuẩn 2 (khối lặp + tiến lên).

json
{
  "version": 1,
  "map": [
    "##########",
    "#S......G#",
    "##########"
  ],
  "start_dir": 1,
  "win": "goal",
  "toolbox": {
    "blocks": [
      "move_forward",
      "turn_left",
      "turn_right",
      "controls_repeat_ext"
    ],
    "max_blocks": 3
  },
  "limits": {
    "max_steps": 200
  },
  "hints": [
    "Chỉ được dùng 3 khối — hãy để vòng lặp làm việc."
  ],
  "solution": {
    "blocks": {
      "languageVersion": 0,
      "blocks": [
        {
          "type": "start",
          "id": "start",
          "x": 20,
          "y": 20,
          "next": {
            "block": {
              "type": "controls_repeat_ext",
              "id": "seed13",
              "inputs": {
                "TIMES": {
                  "shadow": {
                    "type": "math_number",
                    "id": "seed12",
                    "fields": {
                      "NUM": 7
                    }
                  }
                },
                "DO": {
                  "block": {
                    "type": "move_forward",
                    "id": "seed11"
                  }
                }
              }
            }
          }
        }
      ]
    }
  }
}

4. Nhặt hạt (độ khó 2, số khối chuẩn 8) ​

win: collect_all_and_goal — phải nhặt hết * rồi mới về G. Số khối chuẩn 8.

json
{
  "version": 1,
  "map": [
    "########",
    "#S.*..*#",
    "######.#",
    "#G*...*#",
    "########"
  ],
  "start_dir": 1,
  "win": "collect_all_and_goal",
  "toolbox": {
    "blocks": [
      "move_forward",
      "turn_left",
      "turn_right",
      "controls_repeat_ext"
    ],
    "max_blocks": 8
  },
  "limits": {
    "max_steps": 200
  },
  "hints": [
    "Phải nhặt hết hạt rồi mới về đích. Đi qua ô có hạt là tự nhặt."
  ],
  "solution": {
    "blocks": {
      "languageVersion": 0,
      "blocks": [
        {
          "type": "start",
          "id": "start",
          "x": 20,
          "y": 20,
          "next": {
            "block": {
              "type": "controls_repeat_ext",
              "id": "seed16",
              "inputs": {
                "TIMES": {
                  "shadow": {
                    "type": "math_number",
                    "id": "seed15",
                    "fields": {
                      "NUM": 5
                    }
                  }
                },
                "DO": {
                  "block": {
                    "type": "move_forward",
                    "id": "seed14"
                  }
                }
              },
              "next": {
                "block": {
                  "type": "turn_right",
                  "id": "seed17",
                  "next": {
                    "block": {
                      "type": "controls_repeat_ext",
                      "id": "seed20",
                      "inputs": {
                        "TIMES": {
                          "shadow": {
                            "type": "math_number",
                            "id": "seed19",
                            "fields": {
                              "NUM": 2
                            }
                          }
                        },
                        "DO": {
                          "block": {
                            "type": "move_forward",
                            "id": "seed18"
                          }
                        }
                      },
                      "next": {
                        "block": {
                          "type": "turn_right",
                          "id": "seed21",
                          "next": {
                            "block": {
                              "type": "controls_repeat_ext",
                              "id": "seed24",
                              "inputs": {
                                "TIMES": {
                                  "shadow": {
                                    "type": "math_number",
                                    "id": "seed23",
                                    "fields": {
                                      "NUM": 5
                                    }
                                  }
                                },
                                "DO": {
                                  "block": {
                                    "type": "move_forward",
                                    "id": "seed22"
                                  }
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      ]
    }
  }
}

5. Cảm biến (độ khó 3, số khối chuẩn 5) ​

repeat_until_goal + controls_ifelse + path_ahead: "lặp tới khi về đích: có đường phía trước thì tiến, không thì rẽ phải". Số khối chuẩn 5.

json
{
  "version": 1,
  "map": [
    "#########",
    "#S......#",
    "#######.#",
    "#######.#",
    "#######G#",
    "#########"
  ],
  "start_dir": 1,
  "win": "goal",
  "toolbox": {
    "blocks": [
      "move_forward",
      "turn_left",
      "turn_right",
      "repeat_until_goal",
      "controls_ifelse",
      "path_ahead"
    ],
    "max_blocks": 6
  },
  "limits": {
    "max_steps": 200
  },
  "hints": [
    "Lặp cho tới khi về đích: nếu có đường phía trước thì tiến, không thì rẽ phải."
  ],
  "solution": {
    "blocks": {
      "languageVersion": 0,
      "blocks": [
        {
          "type": "start",
          "id": "start",
          "x": 20,
          "y": 20,
          "next": {
            "block": {
              "type": "repeat_until_goal",
              "id": "seed29",
              "inputs": {
                "DO": {
                  "block": {
                    "type": "controls_ifelse",
                    "id": "seed28",
                    "inputs": {
                      "IF0": {
                        "block": {
                          "type": "path_ahead",
                          "id": "seed25"
                        }
                      },
                      "DO0": {
                        "block": {
                          "type": "move_forward",
                          "id": "seed26"
                        }
                      },
                      "ELSE": {
                        "block": {
                          "type": "turn_right",
                          "id": "seed27"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      ]
    }
  }
}

6. Ô nguy hiểm (độ khó 3, số khối chuẩn 8) ​

Ô x ở hành lang trên — đi thẳng là thua. Lời giải bám tường phải: if path_right → turn_right, ifelse path_ahead → move_forward / turn_left. Khối điều kiện cũng đếm vào số khối — lời giải mẫu dùng 8. Số khối chuẩn 8.

json
{
  "version": 1,
  "map": [
    "#########",
    "#S..x...#",
    "#.#####.#",
    "#.......#",
    "#.#####.#",
    "#......G#",
    "#########"
  ],
  "start_dir": 1,
  "win": "goal",
  "toolbox": {
    "blocks": [
      "move_forward",
      "turn_left",
      "turn_right",
      "repeat_until_goal",
      "controls_if",
      "controls_ifelse",
      "path_ahead",
      "path_right"
    ],
    "max_blocks": 8
  },
  "limits": {
    "max_steps": 200
  },
  "hints": [
    "Ô x là nguy hiểm — dẫm vào là thua. Bám tường bên phải: có đường bên phải thì rẽ phải; phía trước có đường thì tiến, không thì rẽ trái."
  ],
  "solution": {
    "blocks": {
      "languageVersion": 0,
      "blocks": [
        {
          "type": "start",
          "id": "start",
          "x": 20,
          "y": 20,
          "next": {
            "block": {
              "type": "repeat_until_goal",
              "id": "seed37",
              "inputs": {
                "DO": {
                  "block": {
                    "type": "controls_if",
                    "id": "seed32",
                    "inputs": {
                      "IF0": {
                        "block": {
                          "type": "path_right",
                          "id": "seed30"
                        }
                      },
                      "DO0": {
                        "block": {
                          "type": "turn_right",
                          "id": "seed31"
                        }
                      }
                    },
                    "next": {
                      "block": {
                        "type": "controls_ifelse",
                        "id": "seed36",
                        "inputs": {
                          "IF0": {
                            "block": {
                              "type": "path_ahead",
                              "id": "seed33"
                            }
                          },
                          "DO0": {
                            "block": {
                              "type": "move_forward",
                              "id": "seed34"
                            }
                          },
                          "ELSE": {
                            "block": {
                              "type": "turn_left",
                              "id": "seed35"
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      ]
    }
  }
}

7. Lấy bánh trung thu (độ khó 3, số khối chuẩn 7) ​

Vật phẩm có số lượng (ô 2, 3, 1) và nhặt bằng lệnh. Lời giải dùng lặp khi còn vật phẩm nên không phải đếm từng ô: lặp tới đích — lấy hết bánh ở ô đang đứng, có đường thì tiến lên, không thì rẽ phải. Số khối chuẩn 7 (lặp tới đích, lặp khi còn bánh, lấy bánh, nếu/không thì, có đường phía trước, tiến lên, rẽ phải). Lời giải mẫu viết bằng Python; đã chạy đạt ở cả năm ngôn ngữ (18 bước, nhặt 6/6). Hợp với bộ hình Thỏ ngọc Trung thu.

json
{
  "version": 1,
  "map": [
    "#######",
    "#S.2.3#",
    "#####.#",
    "#G..1.#",
    "#######"
  ],
  "start_dir": 1,
  "win": "collect_all_and_goal",
  "collect": "command",
  "toolbox": {
    "blocks": [
      "move_forward",
      "turn_right",
      "collect",
      "repeat_until_goal",
      "repeat_while_item",
      "controls_ifelse",
      "path_ahead",
      "item_here"
    ],
    "max_blocks": 8
  },
  "hints": [
    "Ô có số là có bấy nhiêu cái bánh — mỗi lần \"lấy bánh\" chỉ lấy một cái.",
    "\"Lặp khi còn bánh\" lấy hết bánh ở ô đang đứng, dù ô có 1, 2 hay 3 cái.",
    "Lặp tới đích: lấy hết bánh ở ô, rồi có đường thì tiến lên, không thì rẽ phải."
  ],
  "solution": {
    "code": "while not at_goal():\n    while item_here():\n        collect()\n    if path_ahead():\n        move_forward()\n    else:\n        turn_right()\n",
    "language": "python"
  },
  "input": {
    "modes": [
      "blocks",
      "code"
    ]
  }
}

Lời giải cùng chương trình bằng JavaScript (người chơi gõ mã):

js
while (!atGoal()) {
  while (itemHere()) {
    collect();
  }
  if (pathAhead()) {
    moveForward();
  } else {
    turnRight();
  }
}

Thử sai để thấy luật: thêm một khối lấy bánh ngay sau vòng lặp khi còn bánh → ngay ở ô xuất phát (không có bánh) người chơi thua ("nhặt ở ô không còn vật phẩm"); bỏ vòng lặp khi còn bánh đi → về tới trăng nhưng Chưa xong — chưa nhặt hết vật phẩm.

Cho người chơi gõ mã ​

Từ P3, mỗi level có thể cho người chơi kéo khối, gõ mã, hoặc cả hai (người chơi tự chọn trên trang chơi, có nút chuyển qua lại). Mã là một ngôn ngữ thu nhỏ mang cú pháp của JavaScript, Python, Java, C++ hoặc C# — cùng năng lực với bộ khối của level, không hơn: không có biến, số học, hàm tự định nghĩa, else if, không class/main, không kiểu dữ liệu (trừ int trong vòng for). Máy chấm vẫn là hệ thống: mã được biên dịch về đúng chương trình khối rồi chấm y hệt — cùng số khối, cùng điểm, cùng luật hộp công cụ (gọi hàm mà level chưa cấp khối tương ứng là lỗi có số dòng).

JavaScript, Java, C++ và C# dùng chung cú pháp ngoặc nhọn; khác nhau ở tên hàm (C# viết hoa chữ đầu) và từ khoá khai báo của for (let ở JavaScript, int ở ba ngôn ngữ kia). repeat(N) nhận ở cả bốn — không phải cú pháp thật của Java/C++/C#, chỉ là bậc thang cho người mới.

KhốiJavaScript / Java / C++C#Python
Tiến lên / rẽ trái / rẽ phảimoveForward(); turnLeft(); turnRight();MoveForward(); TurnLeft(); TurnRight();move_forward() turn_left() turn_right()
Lặp N lầnrepeat(3) { … } hoặc for (let i = 0; i < 3; i++) { … } (Java/C++: for (int i = 0; …))repeat(3) { … } hoặc for (int i = 0; i < 3; i++) { … }for i in range(3):
Lặp tới khi về đíchwhile (!atGoal()) { … }while (!AtGoal()) { … }while not at_goal():
Nếu / nếu-khôngif (pathAhead()) { … } else { … }if (PathAhead()) { … } else { … }if path_ahead(): … else:
Lặp khi còn vật phẩmwhile (itemHere()) { … }while (ItemHere()) { … }while item_here():
Nhặt vật phẩmcollect();Collect();collect()
Cảm biếnpathAhead() pathLeft() pathRight() atGoal() itemHere()PathAhead() PathLeft() PathRight() AtGoal() ItemHere()path_ahead() path_left() path_right() at_goal() item_here()
Phủ định!pathAhead()!PathAhead()not path_ahead()
Thân rỗng{ }{ }pass

Mỗi dòng một lệnh; các ngôn ngữ ngoặc nhọn dấu ; tuỳ chọn, nhận xét // hoặc /* */; Python thụt lề 4 khoảng trắng (tab nhất quán cũng được), nhận xét #. Số lần lặp 1–100. Mã tối đa 16 KB / 400 dòng. Dưới ô gõ mã, trang chơi liệt kê hàm và mẫu câu lệnh của đúng ngôn ngữ đang chọn, chỉ những khối level cho dùng.

Bật cho một level: ở trang soạn level, mục Cách nhập tick Gõ mã (chọn ngôn ngữ và mặc định), hoặc thêm "input": {"modes": ["blocks", "code"]} ở tab JSON (tuỳ chọn "languages" — một tập con của javascript, python, java, cpp, csharp; bỏ trống là cả năm — và "default"); Lưu (lưu là kiểm lại) rồi đăng. Level đã soạn bằng trình vẽ trước đây có ghi sẵn "languages": ["javascript", "python"] — muốn thêm Java/C++/C# thì tick ở mục Cách nhập rồi lưu lại. Level "modes": ["code"] ẩn hẳn bảng khối — trang chơi nhẹ hơn vì không tải Blockly.

Ví dụ level 5 "Cảm biến" cho gõ mã, lời giải mẫu viết bằng Python:

json
{
  "version": 1,
  "map": ["#########", "#S......#", "#######.#", "#######.#", "#######G#", "#########"],
  "start_dir": 1,
  "win": "goal",
  "toolbox": {
    "blocks": ["move_forward", "turn_left", "turn_right", "repeat_until_goal", "controls_ifelse", "path_ahead"],
    "max_blocks": 6
  },
  "hints": ["Lặp cho tới khi về đích: nếu có đường phía trước thì tiến, không thì rẽ phải."],
  "input": { "modes": ["blocks", "code"], "languages": ["javascript", "python"], "default": "blocks" },
  "solution": {
    "language": "python",
    "code": "while not at_goal():\n    if path_ahead():\n        move_forward()\n    else:\n        turn_right()\n"
  }
}

(Lời giải mẫu dạng mã viết trong một chuỗi JSON nên xuống dòng là \n, thụt lề là bốn khoảng trắng.)

Điểm và mùa giải không đổi: người gõ for i in range(3): move_forward() và người kéo khối lặp có cùng số khối (2), cùng điểm; mùa giải và đố hằng ngày dùng level nào thì theo cấu hình level đó — thể lệ nên ghi "hai chế độ tính điểm như nhau". Báo cáo có thể xem tỉ lệ dùng từng chế độ (cột variant của lượt nộp).

Cài đặt chung ​

Cài đặt → Học tập → Mini-game (quyền configure_minigames):

Cài đặtÝ nghĩa
Cho khách chơi không cần đăng nhậpTắt thì mọi trò đòi đăng nhập, bất kể cài đặt từng trò.
Giữ phiên khách (ngày)Phiên khách không hoạt động, chưa chia sẻ và không có suất mùa giải bị dọn sau số ngày này (mặc định 30).
Hashtag khi chia sẻKhông có #, ví dụ CodeGymChallenge.
Dòng chữ dưới ảnh kết quảTên trung tâm hoặc slogan trên ảnh 1200×630 của thẻ kết quả và thẻ thành tích.

Chống lạm dụng có sẵn, không cần cấu hình: trần 120 lượt nộp/phút và 120 khách mới/giờ mỗi địa chỉ IP, 30 lượt/phút mỗi phiên trên một level, kiểm tra "không phải robot" (Turnstile) khi khách chia sẻ hay nhận kết quả — cần cấu hình Turnstile ở Cài đặt → Tích hợp → Chống spam biểu mẫu.

Đố hằng ngày ​

Vỏ giữ chân học viên: mỗi ngày một đề chung cho cả tổ chức, chuỗi ngày, bảng theo khoá học, thách đấu — không có giải thưởng.

Bật: thêm ≥ 3 level với Pool = Đố hằng ngày, đăng và kiểm chúng, rồi bật Đố hằng ngày ở trang sửa trò chơi. Đề của ngày chốt lúc 00:01 (hoặc lúc học viên đầu tiên mở) và chọn tự động trong pool, không lặp lại đề đã ra trong min(số level − 1, 14) ngày gần nhất — pool 3 level là chu kỳ 3 ngày, nên pool càng nhiều đề càng đỡ đoán được. Thêm level giữa ngày không đổi đề hôm nay. Xoá level đang là đề hôm nay → "hôm nay chưa có đề" (không quay đề khác).

Bạn cùng khoá = học viên có chung ít nhất một khoá học còn hạn ghi danh (vai trò học viên, không tính người soạn/quản lý khoá). Học viên bị ẩn khỏi bảng xếp hạng (Gamification) cũng ẩn ở đây.

Thông báo: Đố hằng ngày — bị vượt hạng (tối đa một tin/người/trò/ngày) và lời thách đấu — học viên tắt được trong tuỳ chọn thông báo. Thách đấu có trần 20 gửi và 5 nhận mỗi người mỗi ngày.

Điểm & huy hiệu (module Gamification): hai quy tắc mặc định Giải đố hôm nay (mini-game) (10 XP) và Lần đầu qua một level mini-game (5 XP, mọi chế độ chơi) — sửa ở Gamification → Quy tắc điểm (tổ chức đang chạy cần kỹ thuật chạy đồng bộ quy tắc mặc định). Bốn bước Giải một đề đố hằng ngày / Qua một level mini-game lần đầu / Chuỗi 7 ngày giải đố liên tiếp / Chuỗi 30 ngày giải đố liên tiếp có sẵn để bạn tự ghép vào huy hiệu ở Gamification → Thành tựu.

Báo cáo ​

Bảng điều hành, nhóm Mức độ sử dụng: Phiên chơi mini-game, Lượt nộp mini-game, Thẻ kết quả đã tạo (chỉ đếm thẻ của từng level, chưa đếm thẻ thành tích cả trò chơi), Lượt giải đố hôm nay, Streak đố hằng ngày trung bình (chỉ tính chuỗi còn sống). Trung tâm báo cáo: Phễu level mini-game (phiên tới từng level, tỉ lệ qua). Đều cần quyền view_any_mini_game.

Quyền ​

QuyềnAi
*_mini_game (xem/tạo/sửa/xoá trò chơi và level)Người soạn khoá học (course_manager), Marketing (marketer); Giảng viên (trainer) chỉ có quyền xem
*_mini_game_season, export_mini_game_seasonNgười soạn khoá học, Marketing; Giảng viên chỉ có quyền xem
configure_minigames (cài đặt chung)Admin, Người soạn khoá học, Marketing

Quản lý đào tạo (training_manager) không có sẵn quyền mini-game nào; cần thì tick tay ở Vai trò. Quyền xem của giảng viên chỉ dùng được khi tài khoản vào được khu quản trị /admin, tức có thêm vai trò panel_user. Giảng viên chỉ mang vai trò trainer thì không mở được trang Trò chơi dù có quyền xem.

Người có quyền sửa trò chơi xem trước được trò/level nháp ở trang chơi: trang hiện dải Bạn đang xem trước ghi rõ lý do (trò chơi đang nháp/lưu trữ, level chưa đăng, lời giải mẫu chưa kiểm) và nhãn nháp trên ô level — học viên và khách không thấy những level đó. Trang tổng kết cũng tính cả level nháp cho người xem trước.

LMS Documentation