From 57e28e227eed6e2bfe393afa3219668ec2382521 Mon Sep 17 00:00:00 2001 From: TimeEntropy <3454493317@qq.com> Date: Fri, 28 Jun 2024 16:12:29 +0800 Subject: [PATCH] undo --- scene/sandbox.gd | 13 ++++++--- scene/sandbox.tscn | 6 ++--- schema/object/border.gd | 60 ++++++++++++++++++++++++++++++----------- 3 files changed, 57 insertions(+), 22 deletions(-) diff --git a/scene/sandbox.gd b/scene/sandbox.gd index 30cd2f5..6607aeb 100644 --- a/scene/sandbox.gd +++ b/scene/sandbox.gd @@ -9,9 +9,9 @@ extends Node @export var info_ME : InfoPanel @export_subgroup('buttons', 'button_') -@export var button_replay : Button -@export var button_undo : Button -@export var button_surrender : Button +@export var button_replay : Button +@export var button_undo : Button +@export var button_giveup : Button var board : BoardPanel @@ -25,6 +25,7 @@ func _ready() -> void: ) pointing.pivot_offset = Vector2(pointing.size.x / 2.0, pointing.size.y + 0.5) button_replay.pressed.connect(replay) + button_giveup.pressed.connect(giveup) replay() pass @@ -62,11 +63,17 @@ func replay() -> void: board.player_changed.connect(_on_border_player_changed) board.duel_win.connect(_on_duel_win) board.duel_draw.connect(_on_duel_draw) + button_undo.pressed.connect(board.history.undo) info_PC.nickname = board.players[0].nickname info_ME.nickname = board.players[1].nickname info_PC.image.texture = board.players[0].used_chess_image info_ME.image.texture = board.players[1].used_chess_image _on_border_player_changed(0) + # reset hostory + pass + +func giveup() -> void: + board.let_win(0) pass #endregion diff --git a/scene/sandbox.tscn b/scene/sandbox.tscn index 662a6a4..064a269 100644 --- a/scene/sandbox.tscn +++ b/scene/sandbox.tscn @@ -82,7 +82,7 @@ expand_margin_top = 1.0 expand_margin_right = 1.0 expand_margin_bottom = 1.0 -[node name="sandbox" type="Node" node_paths=PackedStringArray("game_viewport", "camera", "win_prompt", "pointing", "info_PC", "info_ME", "button_replay", "button_undo", "button_surrender")] +[node name="sandbox" type="Node" node_paths=PackedStringArray("game_viewport", "camera", "win_prompt", "pointing", "info_PC", "info_ME", "button_replay", "button_undo", "button_giveup")] script = ExtResource("1_mhra8") game_viewport = NodePath("layout/margin/aspect/game/world/viewport") camera = NodePath("layout/margin/aspect/game/world/viewport/camera") @@ -92,7 +92,7 @@ info_PC = NodePath("layout/infos/margin_1/PC/info") info_ME = NodePath("layout/infos/margin_2/ME/info") button_replay = NodePath("layout/infos/margin_2/ME/buttons/replay") button_undo = NodePath("layout/infos/margin_2/ME/buttons/undo") -button_surrender = NodePath("layout/infos/margin_2/ME/buttons/giveup") +button_giveup = NodePath("layout/infos/margin_2/ME/buttons/giveup") [node name="border" type="Panel" parent="."] anchors_preset = 15 @@ -141,7 +141,7 @@ stretch_shrink = 3 [node name="viewport" type="SubViewport" parent="layout/margin/aspect/game/world"] handle_input_locally = false -size = Vector2i(78, 78) +size = Vector2i(2, 2) render_target_update_mode = 4 [node name="camera" type="Camera2D" parent="layout/margin/aspect/game/world/viewport"] diff --git a/schema/object/border.gd b/schema/object/border.gd index 805c0ef..b61da58 100644 --- a/schema/object/border.gd +++ b/schema/object/border.gd @@ -10,7 +10,10 @@ var cells := {} var score := {} var current_player := 0 : set = _set_current_player var rest_cell_count := 0 +var turn_count := 0 +var history := UndoRedo.new() +signal chess_dropped(coords:Vector2i) signal player_changed(current:int) signal duel_win(player_id:int) signal duel_draw() @@ -22,22 +25,12 @@ signal duel_draw() #region events func _on_cell_dropped_chess(cell:BoardCell) -> void: - if cell.get_child_count() < 1: - var chess := preload("res://scene/prefab/chess.tscn").instantiate() - chess.position = cell.pivot_offset - chess.texture = players[current_player].used_chess_image - cell.add_child(chess) - score[cell.coords] = current_player - rest_cell_count -= 1 - - if is_win(current_player): - duel_win.emit(current_player) - return - elif is_draw(): - disable_cell_drop() - duel_draw.emit() - - current_player = wrapi(current_player + 1, 0, players.size()) + history.create_action(String.num(turn_count)) + history.add_do_method(drop.bind(cell)) + history.add_do_property(self, 'current_player', wrapi(current_player + 1, 0, players.size())) + history.add_undo_method(pick.bind(cell)) + history.add_undo_property(self, 'current_player', current_player) + history.commit_action() pass #endregion @@ -96,6 +89,11 @@ func check_chess_inline(player_id:int, length:=3) -> Array[Vector2i]: return result return [] +func let_win(player_id:int) -> void: + disable_cell_drop() + duel_win.emit(player_id) + pass + func is_win(player_id:int) -> bool: var result := check_chess_inline(player_id, win_count) if !result.is_empty(): @@ -115,6 +113,36 @@ func disable_cell_drop() -> void: c.handle_drop = false pass +func drop(cell:BoardCell) -> void: + if cell.get_child_count() < 1: + var chess := preload("res://scene/prefab/chess.tscn").instantiate() + chess.position = cell.pivot_offset + chess.texture = players[current_player].used_chess_image + cell.add_child(chess) + score[cell.coords] = current_player + rest_cell_count -= 1 + chess_dropped.emit(cell.coords) + + if is_win(current_player): + let_win(current_player) + return + elif is_draw(): + disable_cell_drop() + duel_draw.emit() + current_player = wrapi(current_player + 1, 0, players.size()) + turn_count += 1 + pass + +func pick(cell:BoardCell) -> void: + if cell.get_child_count() > 0: + for child in cell.get_children(): + child.queue_free() + score[cell.coords] = -1 + rest_cell_count += 1 + turn_count -= 1 + pass + + #endregion #region setget