155 lines
4.1 KiB
Lua
155 lines
4.1 KiB
Lua
local state = runtime.import("state")
|
||
local rules = runtime.import("rules")
|
||
local ui = runtime.import("ui")
|
||
local animation = runtime.import("animation")
|
||
---@type RuntimeWidgets
|
||
local widgets = runtime.import("runtime_widgets")
|
||
local theme = runtime.import("theme")
|
||
|
||
widgets.configure({
|
||
primary = theme.colors.dice_button,
|
||
secondary = theme.colors.board_inner,
|
||
success = theme.colors.green,
|
||
overlay = "#99000000",
|
||
surface = theme.colors.top_bar,
|
||
surfaceAlt = theme.colors.board_inner,
|
||
card = theme.colors.top_bar,
|
||
text = theme.colors.text,
|
||
muted = theme.colors.muted_text,
|
||
progress = theme.colors.green,
|
||
transparent = "#00000000"
|
||
})
|
||
|
||
function smoke_test(ctx)
|
||
return ctx ~= nil
|
||
and ctx.runtimeApiVersion ~= nil
|
||
and state.current_player ~= nil
|
||
and rules.plan_move ~= nil
|
||
and ui.create_board_nodes ~= nil
|
||
and animation.move_piece ~= nil
|
||
and widgets.dialog ~= nil
|
||
end
|
||
|
||
function init(ctx)
|
||
return {
|
||
render = { creates = ui.create_board_nodes() },
|
||
ui = { creates = ui.create_ui_nodes() },
|
||
commands = {}
|
||
}
|
||
end
|
||
|
||
local function handle_roll_dice()
|
||
if state.phase == "game_over" then
|
||
return { commands = { animation.toast("游戏已结束") } }
|
||
end
|
||
|
||
if state.phase ~= "waiting_roll" then
|
||
return { commands = { animation.toast("请先完成当前移动") } }
|
||
end
|
||
|
||
state.dice = rules.next_dice()
|
||
local movable = rules.movable_pieces()
|
||
|
||
if #movable == 0 then
|
||
local message = state.current_player .. " 无可移动飞机"
|
||
if state.dice ~= 6 then
|
||
state.current_player = rules.next_player()
|
||
end
|
||
state.phase = "waiting_roll"
|
||
return {
|
||
ui = { updates = ui.dice_and_status_updates() },
|
||
render = { updates = ui.highlight_updates(rules.all_piece_ids(), false) },
|
||
commands = { animation.toast(message) }
|
||
}
|
||
end
|
||
|
||
state.phase = "waiting_piece"
|
||
return {
|
||
ui = { updates = ui.dice_and_status_updates() },
|
||
render = { updates = ui.highlight_updates(movable, true) }
|
||
}
|
||
end
|
||
|
||
local function handle_piece_tap(piece_id)
|
||
if state.phase ~= "waiting_piece" then
|
||
return {}
|
||
end
|
||
|
||
local piece = state.pieces[piece_id]
|
||
if piece == nil or piece.owner ~= state.current_player or not rules.can_move(piece, state.dice) then
|
||
return { commands = { animation.toast("该飞机不能移动") } }
|
||
end
|
||
|
||
local plan = rules.plan_move(piece, state.dice)
|
||
state.phase = "animating"
|
||
state.selected_piece = piece_id
|
||
state.pending_move = plan
|
||
|
||
return {
|
||
ui = { updates = ui.dice_and_status_updates() },
|
||
render = { updates = ui.highlight_updates(rules.all_piece_ids(), false) },
|
||
commands = { animation.move_piece(piece_id, plan.path) }
|
||
}
|
||
end
|
||
|
||
local function handle_move_done()
|
||
local plan = state.pending_move
|
||
if plan == nil then
|
||
state.phase = "waiting_roll"
|
||
return { ui = { updates = ui.dice_and_status_updates() } }
|
||
end
|
||
|
||
rules.commit_move(plan)
|
||
local moved_piece = state.pieces[plan.piece_id]
|
||
local updates = ui.piece_position_updates(plan.captures)
|
||
table.insert(updates, ui.piece_position_update(plan.piece_id))
|
||
|
||
local messages = {}
|
||
if #plan.captures > 0 then
|
||
table.insert(messages, "撞回 " .. tostring(#plan.captures) .. " 架飞机")
|
||
end
|
||
|
||
if rules.player_finished(moved_piece.owner) then
|
||
state.winner = moved_piece.owner
|
||
state.phase = "game_over"
|
||
table.insert(messages, moved_piece.owner .. " 获胜")
|
||
else
|
||
if state.dice ~= 6 then
|
||
state.current_player = rules.next_player()
|
||
else
|
||
table.insert(messages, "掷出 6,额外回合")
|
||
end
|
||
state.phase = "waiting_roll"
|
||
end
|
||
|
||
state.selected_piece = nil
|
||
state.pending_move = nil
|
||
|
||
local commands = {}
|
||
if #messages > 0 then
|
||
commands = { animation.toast(table.concat(messages, ";")) }
|
||
end
|
||
|
||
return {
|
||
ui = { updates = ui.dice_and_status_updates() },
|
||
render = { updates = updates },
|
||
commands = commands
|
||
}
|
||
end
|
||
|
||
function on_event(event)
|
||
if event.handler == "roll_dice" then
|
||
return handle_roll_dice()
|
||
end
|
||
|
||
if event.handler == "piece_tap" then
|
||
return handle_piece_tap(event.target)
|
||
end
|
||
|
||
if event.handler == "piece_move_done" then
|
||
return handle_move_done()
|
||
end
|
||
|
||
return {}
|
||
end
|