online multiplayer chess game (note server currently down)
Diffstat (limited to 'ui/board/Board.gd')
| -rw-r--r-- | ui/board/Board.gd | 143 |
1 files changed, 97 insertions, 46 deletions
diff --git a/ui/board/Board.gd b/ui/board/Board.gd index a060366..19a9047 100644 --- a/ui/board/Board.gd +++ b/ui/board/Board.gd @@ -13,15 +13,15 @@ signal remove_last var move_indicators: PoolIntArray = [] var rot: float = 0 - var piece_size: Vector2 -export(Color) var overlay_color := Color(0.078431, 0.333333, 0.117647, 0.498039) -export(Color) var last_move_indicator_color := Color(0.74902, 0.662745, 0.223529, 0.498039) -export(Color) var last_move_take_indicator := Color(0.74902, 0.407843, 0.223529, 0.498039) -export(Color) var clockrunning_color := Color(0.219608, 0.278431, 0.133333) -export(Color) var clockrunninglow := Color(0.47451, 0.172549, 0.164706) -export(Color) var clocklow := Color(0.313726, 0.156863, 0.14902) +export(Color) var overlay_color: Color +export(Color) var premove_color: Color +export(Color) var last_move_indicator_color: Color +export(Color) var last_move_take_indicator: Color +export(Color) var clockrunning_color: Color +export(Color) var clockrunninglow: Color +export(Color) var clocklow: Color var board = [] # has `get_piece(algebraic position)` and `set_piece(algebraic position)` for ease of use @@ -34,19 +34,22 @@ func set_piece(alg: String, p: Piece) -> void: board[Chess.SQUARE_MAP[alg]] = p -var flipped = false -var labels = {numbers = [], letters = []} -var background_array = [] -var last_clicked +var flipped := false +var labels := {numbers = [], letters = []} +var background_array := [] +var last_clicked: Piece +var premove: Dictionary = {} var check_circle: GradientTexture2D = load("res://piece/check-circle.tres") var take_circle: GradientTexture2D = load("res://piece/takeable-circle.tres") +var move_circle: GradientTexture2D = load("res://piece/move-circle.tres") -onready var sidebar := get_node_or_null("%Sidebar") onready var game: GameUI = owner if owner is GameUI else null +onready var sidebar := game.get_node_or_null("%Sidebar") if game else null onready var darken = $Darken onready var foreground := $Foreground onready var background := $Background onready var pieces := $Pieces +onready var arrows := $"%Arrows" var chess := Chess.new() @@ -62,6 +65,8 @@ func _exit_tree(): func _process(_delta): rect_rotation = rot foreground.rect_rotation = rot + if Input.is_action_just_pressed("debug"): + print(chess.ascii()) func _resized(): @@ -73,6 +78,8 @@ func _resized(): check_circle.height = piece_size.y take_circle.width = piece_size.x take_circle.height = piece_size.y + move_circle.width = piece_size.x + move_circle.height = piece_size.y if foreground: rect_pivot_offset = (piece_size * 8) / 2 foreground.rect_pivot_offset = rect_pivot_offset @@ -81,27 +88,27 @@ func _resized(): Log.debug("Resizing board") +func set_take_move_circle_color( + color: Color = Color(overlay_color.r, overlay_color.g, overlay_color.b, .65) +) -> void: + take_circle.gradient.colors[1] = color + move_circle.gradient.colors[0] = color + + func _ready(): - take_circle.gradient.colors[1] = Color(overlay_color.r, overlay_color.g, overlay_color.b, 1) + set_take_move_circle_color() _resized() Events.connect("turn_over", self, "_on_turn_over") - PacketHandler.connect("move_data", self, "move") + PacketHandler.connect("move_data", self, "move", [false, false]) create_pieces() create_squares() create_labels() func resize_board(): - resize_squares() resize_pieces() -func resize_squares() -> void: - for i in Chess.SQUARE_MAP.values(): - var square: BackgroundSquare = background_array[i] - square.size() - - func create_squares() -> void: # create the board background_array.resize(128) for i in Chess.SQUARE_MAP.values(): @@ -112,9 +119,9 @@ func create_squares() -> void: # create the board square.hint_tooltip = alg square.color = (Globals.board_color1 if Chess.square_color(alg) == "light" else Globals.board_color2) # set the color background.add_child(square) # add the square to the background - square.connect("clicked", self, "square_clicked", [alg]) # connect the clicked event + square.connect("clicked", self, "square_clicked", [square]) # connect the clicked event background_array[i] = square # add the square to the background array - find_node("Arrows")._setup(self) # initialize the arrows + arrows._setup(self) # initialize the arrows func create_labels() -> void: @@ -237,24 +244,50 @@ func flip_board() -> void: flip_labels() -func square_clicked(clicked_square: String) -> void: - if chess.turn != Globals.team or Globals.spectating: +func square_clicked(clicked_square: BackgroundSquare) -> void: + if Globals.spectating: return - var p := get_piece(clicked_square) - if !p or p.color != Globals.team: - if !is_instance_valid(last_clicked): - return + + var p := get_piece(clicked_square.square) + + if chess.turn != Globals.team and is_instance_valid(last_clicked): + # PREMOVE AREA + var p_sq: int = Chess.SQUARE_MAP[clicked_square.square] + for m in chess.piece_moves(last_clicked.position, last_clicked.type, Globals.team): + if m.to == p_sq && m.from == Chess.SQUARE_MAP[last_clicked.position]: + if "from" in premove and "to" in premove: + background_array[premove.from].premove_indicator.hide() # hide premove indicators + background_array[premove.to].premove_indicator.hide() + if premove && premove.from == m.from && premove.to == m.to: + premove = {} + Log.debug("De-selected premove") + else: + premove = m + background_array[premove.from].premove_indicator.show() + background_array[premove.to].premove_indicator.show() + if premove.flags & Chess.BITS.PROMOTION: + p.open_promotion_previews(darken) + premove.promotion = yield(p, "promotion_decided") + Log.debug("Selected premove: %s" % premove) + clear_last_clicked() + return + elif (!p or p.color != Globals.team) and is_instance_valid(last_clicked): + # Attempt to make the move (NORMAL MOVE AREA) for m in chess.moves({square = last_clicked.position, verbose = true}): - if m.to == clicked_square && m.from == last_clicked.position: - move(m.san, false) - break - clear_last_clicked() - return - last_clicked = p + if m.to == clicked_square.square && m.from == last_clicked.position: + move(m.san) + clear_last_clicked() + return + + if p and p.color == Globals.team: + if chess.turn != Globals.team: + clicked_square.show_premove_indicators() + else: + clicked_square.show_move_indicators() + last_clicked = p -func move(san: String, is_recieved_move := true) -> void: - resize_board() +func move(san: String, send := true, create_promotion_input := true) -> void: var sound_handled = false var move_0x88 = chess.__move_from_san(san, true) var valid_moves = chess.moves({square = chess.algebraic(move_0x88.from), stripped = true}) @@ -279,23 +312,19 @@ func move(san: String, is_recieved_move := true) -> void: get_piece(rook_pos).move(Chess.offset(move_0x88.to, Vector2(1, 0))) if move_0x88.flags & Chess.BITS.PROMOTION: #promotion wow var p: Piece = yield(board[move_0x88.from].move(Chess.algebraic(move_0x88.to), true), "completed") - if !is_recieved_move: # was my turn, this is my move - darken.show() - p.open_promotion_previews() - yield(p, "promotion_decided") # piece kills itself now - move_0x88["promotion"] = p.promote_to + if create_promotion_input: + p.open_promotion_previews(darken) + move_0x88.promotion = yield(p, "promotion_decided") san = chess.__move_to_san(move_0x88) # update the san with new promotion data - darken.hide() + p.queue_free() else: # was opponents turn, this is opponents move: promotion is already chosen p.queue_free() - # the move animation is useless if its not my turn - # but it changes p.position, so its usefull. make_piece(p.position, move_0x88.promotion, p.color) SoundFx.play("Move" if move_0x88.flags & Chess.BITS.NORMAL else "Capture") sound_handled = true else: # not promotion: from **always** moves to `to` var _p = board[move_0x88.from].move(Chess.algebraic(move_0x88.to)) - if !is_recieved_move: + if send: PacketHandler.send_mov(san) if !sound_handled: SoundFx.play("Move") @@ -345,6 +374,28 @@ func undo(two: bool = false) -> void: func _on_turn_over(): + if get_parent() == get_viewport(): # for testing + Globals.team = chess.turn + + if Globals.grid.chess.turn == Globals.team: + set_take_move_circle_color() + # use the premove if possible + if premove: + background_array[premove.from].premove_indicator.hide() + background_array[premove.to].premove_indicator.hide() + if board[premove.from]: # see if its valid + if premove.flags & (Chess.BITS.CAPTURE | Chess.BITS.EP_CAPTURE) && not board[premove.to]: + return + var san = chess.__move_to_san(premove,chess.__generate_moves({legal = true}),false) + if san: + var legal_moves = chess.moves({square = chess.algebraic(premove.from), stripped = true}) + var is_possible_move = legal_moves.find(chess.stripped_san(san)) != -1 + if chess.__move_from_san(san, true) and (is_possible_move): # it is valid + Log.debug(["Executing premove:", san]) + move(san, true, false) # make the move, send it to the opponent, dont prompt for premoves + premove = {} + else: + set_take_move_circle_color(premove_color) SaveLoad.save("user://game.json", {pgn = chess.pgn(), fen = chess.fen()}) clear_last_clicked() check_game_over() |