From 1c622da9284ef535af71b4f259cc7f56c6cff929 Mon Sep 17 00:00:00 2001 From: Luke Hubmayer-Werner Date: Thu, 21 May 2020 23:00:50 +0930 Subject: [PATCH] Undo state tracking (no reverse yet) --- scripts/Common.gd | 8 +++++ scripts/GameField.gd | 83 +++++++++++++++++++++++++++++++++++++++----- 2 files changed, 82 insertions(+), 9 deletions(-) diff --git a/scripts/Common.gd b/scripts/Common.gd index 884ba98..03d387e 100644 --- a/scripts/Common.gd +++ b/scripts/Common.gd @@ -1,6 +1,14 @@ extends Node +func num2alpha(num: int, uppercase:=false): + var c = ord('A' if uppercase else 'a') + if num >= 26: + return char(c+(num/26)-1) + char(c+(num%26)) + else: + return char(c+num) + + class PoolArray2D: var _array var _rows := 1 diff --git a/scripts/GameField.gd b/scripts/GameField.gd index 283d46b..430a8fc 100644 --- a/scripts/GameField.gd +++ b/scripts/GameField.gd @@ -14,6 +14,11 @@ onready var cell_numbers: ByteArray2D const NUMBER_NONE := 255 onready var cell_colors: ByteArray2D onready var corner_marks: IntArray2D +enum UndoActions { + SET_L_RIGHT, SET_L_DOWN, SET_X_RIGHT, SET_X_DOWN, + CLEAR_L_RIGHT, CLEAR_L_DOWN, CLEAR_X_RIGHT, CLEAR_X_DOWN, + SET_COLOR +} enum CornerMark { L_RIGHT=1, L_DOWN=2, X_RIGHT=4, X_DOWN=8, DARC_1=16, DARC_2=32, DARC_3=64, DARC_4=128, @@ -112,14 +117,13 @@ func _draw() -> void: for row in rows: draw_string_centered(font, Vector2(h0/2, v0+row*v_space), '%02d'%row, Color.black) for col in cols: - draw_string_centered(font, Vector2(h0+(col+0.5)*h_space, v0/4), num2alpha(col), Color.black) + draw_string_centered(font, Vector2(h0+(col+0.5)*h_space, v0/4), Common.num2alpha(col), Color.black) -func num2alpha(num: int, uppercase:=false): - var c = ord('A' if uppercase else 'a') - if num >= 26: - return char(c+(num/26)-1) + char(c+(num%26)) - else: - return char(c+num) + # Undo Stack + var u = len(undo_stack) + for i in u: + draw_string(font, grid_corner(i, cols+1), str(undo_stack[u-i-1]), Color.black) +# print(action) func _process(delta: float) -> void: update() @@ -263,39 +267,100 @@ func _input(event: InputEvent) -> void: DragAction.DRAW_COLOR: sel_row = int(gridpos.y) sel_col = int(gridpos.x) - cell_colors.set_cell(sel_row, sel_col, drag_color) + set_cell_color(sel_row, sel_col, drag_color) var undo_stack = [] +class UndoAction: + var action_type + var cell_row + var cell_col + func _init(action, row, col) -> void: + action_type = action + cell_row = row + cell_col = col + +class UndoActionCorner extends UndoAction: + func _init(action, row, col).(action, row, col) -> void: + pass + + func _to_string() -> String: + match action_type: + UndoActions.SET_L_RIGHT: + return '+L %s%d:%d'%[Common.num2alpha(cell_col), cell_row-1, cell_row] + UndoActions.CLEAR_L_RIGHT: + return '-L %s%d:%d'%[Common.num2alpha(cell_col), cell_row-1, cell_row] + UndoActions.SET_X_RIGHT: + return '+X %s%d:%d'%[Common.num2alpha(cell_col), cell_row-1, cell_row] + UndoActions.CLEAR_X_RIGHT: + return '-X %s%d:%d'%[Common.num2alpha(cell_col), cell_row-1, cell_row] + UndoActions.SET_L_DOWN: + return '+L %s%d:%s'%[Common.num2alpha(cell_col-1), cell_row, Common.num2alpha(cell_col)] + UndoActions.CLEAR_L_DOWN: + return '-L %s%d:%s'%[Common.num2alpha(cell_col-1), cell_row, Common.num2alpha(cell_col)] + UndoActions.SET_X_DOWN: + return '+X %s%d:%s'%[Common.num2alpha(cell_col-1), cell_row, Common.num2alpha(cell_col)] + UndoActions.CLEAR_X_DOWN: + return '-X %s%d:%s'%[Common.num2alpha(cell_col-1), cell_row, Common.num2alpha(cell_col)] + _: + return 'unk %d %s%d'%[action_type, Common.num2alpha(cell_col), cell_row] + +class UndoActionCell extends UndoAction: + var set_state + var prev_state + func _init(action, row, col, set_state, prev_state).(action, row, col) -> void: + self.set_state = set_state + self.prev_state = prev_state + + func _to_string() -> String: + match action_type: + UndoActions.SET_COLOR: + return 'C%d->%d %s%d'%[set_state, prev_state, Common.num2alpha(cell_col), cell_row] + _: + return 'unk %d %s%d'%[action_type, Common.num2alpha(cell_col), cell_row] + +func set_cell_color(row, col, new_color): + var old_color = cell_colors.get_cell(row, col) + if old_color != new_color: + cell_colors.set_cell(row, col, new_color) + undo_stack.append(UndoActionCell.new(UndoActions.SET_COLOR, row, col, new_color, old_color)) + func set_line_right(row, col): if !corner_marks.get_flag(row, col, CornerMark.L_RIGHT) and !corner_marks.get_flag(row, col, CornerMark.X_RIGHT): corner_marks.set_flag(row, col, CornerMark.L_RIGHT) - # TODO: Add undo stack entry + undo_stack.append(UndoActionCorner.new(UndoActions.SET_L_RIGHT, row, col)) func set_line_down(row, col): if !corner_marks.get_flag(row, col, CornerMark.L_DOWN) and !corner_marks.get_flag(row, col, CornerMark.X_DOWN): corner_marks.set_flag(row, col, CornerMark.L_DOWN) + undo_stack.append(UndoActionCorner.new(UndoActions.SET_L_DOWN, row, col)) func clear_line_right(row, col): if corner_marks.get_flag(row, col, CornerMark.L_RIGHT): corner_marks.clear_flag(row, col, CornerMark.L_RIGHT) + undo_stack.append(UndoActionCorner.new(UndoActions.CLEAR_L_RIGHT, row, col)) func clear_line_down(row, col): if corner_marks.get_flag(row, col, CornerMark.L_DOWN): corner_marks.clear_flag(row, col, CornerMark.L_DOWN) + undo_stack.append(UndoActionCorner.new(UndoActions.CLEAR_L_DOWN, row, col)) func set_x_right(row, col): if !corner_marks.get_flag(row, col, CornerMark.L_RIGHT) and !corner_marks.get_flag(row, col, CornerMark.X_RIGHT): corner_marks.set_flag(row, col, CornerMark.X_RIGHT) + undo_stack.append(UndoActionCorner.new(UndoActions.SET_X_RIGHT, row, col)) func set_x_down(row, col): if !corner_marks.get_flag(row, col, CornerMark.L_DOWN) and !corner_marks.get_flag(row, col, CornerMark.X_DOWN): corner_marks.set_flag(row, col, CornerMark.X_DOWN) + undo_stack.append(UndoActionCorner.new(UndoActions.SET_X_DOWN, row, col)) func clear_x_right(row, col): if corner_marks.get_flag(row, col, CornerMark.X_RIGHT): corner_marks.clear_flag(row, col, CornerMark.X_RIGHT) + undo_stack.append(UndoActionCorner.new(UndoActions.CLEAR_X_RIGHT, row, col)) func clear_x_down(row, col): if corner_marks.get_flag(row, col, CornerMark.X_DOWN): corner_marks.clear_flag(row, col, CornerMark.X_DOWN) + undo_stack.append(UndoActionCorner.new(UndoActions.CLEAR_X_DOWN, row, col))