From 573909c7d718ea2089bac134f5a9bc1c3aa35f53 Mon Sep 17 00:00:00 2001 From: jake Date: Sun, 19 Feb 2023 03:21:43 -0500 Subject: [PATCH] complete castling rules, note if a king is checked, added 'control' boards for each team, added turn counting (based on piece movement) --- Main.gd | 234 ++++++++++++++++++++++++++++++++++++++-------------- MoveTile.gd | 4 +- Sprite.gd | 2 + 3 files changed, 175 insertions(+), 65 deletions(-) diff --git a/Main.gd b/Main.gd index 3ee2e56..e2a0a97 100644 --- a/Main.gd +++ b/Main.gd @@ -8,6 +8,9 @@ var board_cell = 128 const BOARD_WIDTH = 7 # starting at 0..7 const BOARD_HEIGHT = 7 +var team1_capture = new_board() +var team2_capture = new_board() + var movement_layer = false var movement_layer_piece = null @@ -20,6 +23,8 @@ var team2_king = null # hack to prevent 'clicking' on a killed piece var safely_handle_movement = false +var turn = 0 + var team1 = 1 var team2 = 2 @@ -29,9 +34,13 @@ func _ready(): #spawn_piece('pawn', 'teal', 1, 6, team1) #spawn_piece('pawn', 'orange', 2, 4, team2) - #team2_king = spawn_piece('king', 'teal', 4, 0, team2) - #spawn_piece('rook', 'teal', 7, 0, team2) - #spawn_piece('rook', 'teal', 0, 0, team2) + #team2_king = spawn_piece('king', 'red', 4, 0, team2) + #spawn_piece('rook', 'teal', 5, 1, team1) + #spawn_piece('rook', 'red', 7, 0, team2) + #spawn_piece('rook', 'red', 0, 0, team2) + #team1_king = spawn_piece('rook', 'teal', 5, 3, team1) + #spawn_piece('pawn', 'blue', 6, 0, team1) + update_capture_tables() OS.set_window_size(Vector2(700,700)) OS.set_window_always_on_top(true) @@ -39,6 +48,69 @@ func _ready(): func _process(_delta): safely_handle_movement = false +func new_turn(): + update_capture_tables() + is_king_checked() + turn += 1 + print("Turn: %s" % turn) + +func update_capture_tables(): + team1_capture = new_board() + team2_capture = new_board() + var pieces = get_tree().get_nodes_in_group("piece") + for e in pieces: + if ! e.killed: + var coords = position_to_board_cell(e.position) + if e.get_team() == team1: + team1_capture[coords[0]][coords[1]] = 2 + else: # team2 + team2_capture[coords[0]][coords[1]] = 2 + for e in pieces: + if ! e.killed: + var coords = position_to_board_cell(e.position) + var pattern = get_move_pattern(e, coords) + var captured = can_chess_move(pattern, coords, false) + if e.get_team() == team1: + #rint(captured) + for c in captured: + if c.size() == 3: + if c[2] == "not attacking": + continue + team1_capture[c[0]][c[1]] = 1 + else: # team2 + for c in captured: + if c.size() == 3: + if c[2] == "not attacking": + continue + team2_capture[c[0]][c[1]] = 1 + #print(team1_capture) + #print(team2_capture) + + #for i in 8: + # for k in 8: + # if team2_capture[i][k] == 1: + # var move_tile = movetile_scene.instance() + # add_child(move_tile) + # move_tile.set_color("red") + # move_tile.position = in_square(Vector2(i * board_cell, k * board_cell)) + +func is_king_checked(): + print(team2_king) + if team2_king: + var coords_team2 = position_to_board_cell(team2_king.position) + if team1_capture[coords_team2[0]][coords_team2[1]] >= 1: + print("Aye, team2 in check.") + team2_king.in_check = true + else: + team2_king.in_check = false + if team1_king: + var coords_team1 = position_to_board_cell(team1_king.position) + if team2_capture[coords_team1[0]][coords_team1[1]] >= 1: + print("Aye, team1 in check.") + team1_king.in_check = true + else: + team1_king.in_check = false + func remove_movement_layer(): movement_layer = false movement_layer_piece = null @@ -199,63 +271,78 @@ func get_move_pattern(piece, coords): "king": return [move_1_down, move_1_left, move_1_right, move_1_up, move_1_ne, move_1_nw, move_1_se, move_1_sw, castling] _: - #rint("no pattern for this one") return [] -func can_chess_move(pattern, coords): - var can_move = false +func can_chess_move(pattern, coords, create_tiles=true): + var can_move = [] var curr_piece = board[coords[0]][coords[1]] var curr_team = curr_piece.get_team() for e in pattern: match (e): move_1_down_pawn: - if make_tiles(coords, [0,1], 1, true, curr_team): can_move = true + var test = make_tiles(coords, [0,1], 1, true, curr_team, {}, create_tiles) + if test: + test[0].push_back("not attacking") + can_move.append_array(test) move_2_down_pawn: - if make_tiles(coords, [0,1], 1, true, curr_team): - can_move = true - make_tiles(coords, [0,2], 1, true, curr_team, {'tile_is_en_passant': true}) + var test = make_tiles(coords, [0,1], 1, true, curr_team, {}, create_tiles) + if test: + test[0].push_back("not attacking") + can_move.append_array(test) + var test2 = make_tiles(coords, [0,2], 1, true, curr_team, {'tile_is_en_passant': true}, create_tiles) + if test2: + test2[0].push_back("not attacking") + can_move.append_array(test2) attack_1_sw: - if make_tiles(coords, [-1,1], 1, false, curr_team, {"must_attack": true}): can_move = true + can_move.append_array(make_tiles(coords, [-1,1], 1, false, curr_team, {"must_attack": true}, create_tiles)) attack_1_se: - if make_tiles(coords, [1,1], 1, false, curr_team, {"must_attack": true}): can_move = true + can_move.append_array(make_tiles(coords, [1,1], 1, false, curr_team, {"must_attack": true}, create_tiles)) en_passent_sw: var pawn_maybe = board[coords[0]-1][coords[1]] if pawn_maybe and pawn_maybe.get_piece() == "pawn" and pawn_maybe == en_passant_pawn and pawn_maybe.get_team() != curr_team: - if make_tiles(coords, [-1,1], 1, true, curr_team, {"en_passant_pawn": pawn_maybe}): can_move = true + can_move.append_array(make_tiles(coords, [-1,1], 1, true, curr_team, {"en_passant_pawn": pawn_maybe}, create_tiles)) en_passent_se: if ! coords[0] + 1 > BOARD_WIDTH: var pawn_maybe = board[coords[0]+1][coords[1]] if pawn_maybe and pawn_maybe.get_piece() == "pawn" and pawn_maybe == en_passant_pawn and pawn_maybe.get_team() != curr_team: - if make_tiles(coords, [1,1], 1, true, curr_team, {"en_passant_pawn": pawn_maybe}): can_move = true + can_move.append_array(make_tiles(coords, [1,1], 1, true, curr_team, {"en_passant_pawn": pawn_maybe}, create_tiles)) move_1_up_pawn: - if make_tiles(coords, [0,-1], 1, true, curr_team): can_move = true + var test = make_tiles(coords, [0,-1], 1, true, curr_team, {}, create_tiles) + if test: + test[0].push_back("not attacking") + can_move.append_array(test) move_2_up_pawn: - if make_tiles(coords, [0,-1], 1, true, curr_team): - can_move = true - make_tiles(coords, [0,-2], 1, true, curr_team, {'tile_is_en_passant': true}) + var test = make_tiles(coords, [0,-1], 1, true, curr_team, {}, create_tiles) + if test: + test[0].push_back("not attacking") + can_move.append_array(test) + var test2 = make_tiles(coords, [0,-2], 1, true, curr_team, {'tile_is_en_passant': true}, create_tiles) + if test2: + test2[0].push_back("not attacking") + can_move.append_array(test2) attack_1_nw: - if make_tiles(coords, [-1,-1], 1, false, curr_team, {"must_attack": true}): can_move = true + can_move.append_array(make_tiles(coords, [-1,-1], 1, false, curr_team, {"must_attack": true}, create_tiles)) attack_1_ne: - if make_tiles(coords, [1,-1], 1, false, curr_team, {"must_attack": true}): can_move = true + can_move.append_array(make_tiles(coords, [1,-1], 1, false, curr_team, {"must_attack": true}, create_tiles)) en_passent_nw: var pawn_maybe = board[coords[0]-1][coords[1]] if pawn_maybe and pawn_maybe.get_piece() == "pawn" and pawn_maybe == en_passant_pawn and pawn_maybe.get_team() != curr_team: - if make_tiles(coords, [-1,-1], 1, true, curr_team, {"en_passant_pawn": pawn_maybe}): can_move = true + can_move.append_array(make_tiles(coords, [-1,-1], 1, true, curr_team, {"en_passant_pawn": pawn_maybe}, create_tiles)) en_passent_ne: if ! coords[0] + 1 > BOARD_WIDTH: var pawn_maybe = board[coords[0]+1][coords[1]] if pawn_maybe and pawn_maybe.get_piece() == "pawn" and pawn_maybe == en_passant_pawn and pawn_maybe.get_team() != curr_team: - if make_tiles(coords, [1,-1], 1, true, curr_team, {"en_passant_pawn": pawn_maybe}): can_move = true + can_move.append_array(make_tiles(coords, [1,-1], 1, true, curr_team, {"en_passant_pawn": pawn_maybe}, create_tiles)) move_up_inf: - if make_tiles(coords, [0,-1], BOARD_HEIGHT, false, curr_team): can_move =true + can_move.append_array(make_tiles(coords, [0,-1], BOARD_HEIGHT, false, curr_team, {}, create_tiles)) move_down_inf: - if make_tiles(coords, [0,1], BOARD_HEIGHT, false, curr_team): can_move = true + can_move.append_array(make_tiles(coords, [0,1], BOARD_HEIGHT, false, curr_team, {}, create_tiles)) move_left_inf: - if make_tiles(coords, [-1,0], BOARD_WIDTH, false, curr_team): can_move = true + can_move.append_array(make_tiles(coords, [-1,0], BOARD_WIDTH, false, curr_team, {}, create_tiles)) move_right_inf: - if make_tiles(coords, [1,0], BOARD_WIDTH, false, curr_team): can_move = true + can_move.append_array(make_tiles(coords, [1,0], BOARD_WIDTH, false, curr_team, {}, create_tiles)) castling: if ! curr_piece.has_moved and ! curr_piece.in_check: var y = coords[1] @@ -263,67 +350,79 @@ func can_chess_move(pattern, coords): var pieces = get_tree().get_nodes_in_group("piece") for ele in pieces: if ele.get_team() == curr_team and ele.get_piece() == "rook" and ! ele.has_moved and position_to_board_cell(ele.position)[1] == y: - print(ele) + #rint(ele) var rook_x = position_to_board_cell(ele.position)[0] # king side if rook_x > king_x: var blocked = false - pass var diff = rook_x - king_x for i in range(1, diff): - #rint(board[king_x + i][y]) if board[king_x + i][y]: blocked = true + # cannot castle through or to a tile that is attacked + if curr_team == team1: + if team2_capture[king_x + i][y] == 1: + blocked = true + else: # team2 + if team1_capture[king_x + i][y] == 1: + blocked = true + #rint("There is something at (%s,%s) %s" % [king_x + i,y, board[king_x + i][y].get_piece() ]) if ! blocked: - if make_tiles(coords, [2,0], 1, false, curr_team, {"castling_rook": ele}): can_move = true + can_move.append_array(make_tiles(coords, [2,0], 1, false, curr_team, {"castling_rook": ele}, create_tiles)) else: var blocked = false - pass var diff = king_x - rook_x for i in range(1, diff): - print(board[rook_x + i][y]) + #rint(board[rook_x + i][y]) if board[rook_x + i][y]: blocked = true - #rint("There is something at (%s,%s) %s" % [rook_x + i, y, board[rook_x + i][y].get_piece()]) + if i != 1: # on queenside, that first square doesn't really matter if it is attacked + if curr_team == team1: + if team2_capture[rook_x + i][y] == 1: + blocked = true + else: # team2 + if team1_capture[rook_x + i][y] == 1: + blocked = true + #rint("There is something at (%s,%s) %s" % [rook_x + i, y, board[rook_x + i][y].get_piece()]) if ! blocked: - if make_tiles(coords, [-2,0], 1, false, curr_team, {"castling_rook": ele}): can_move = true + can_move.append_array(make_tiles(coords, [-2,0], 1, false, curr_team, {"castling_rook": ele}, create_tiles)) move_ne_inf: - if make_tiles(coords, [1,-1], 8, false, curr_team): can_move = true + can_move.append_array(make_tiles(coords, [1,-1], 8, false, curr_team, {}, create_tiles)) move_nw_inf: - if make_tiles(coords, [-1,-1], 8, false, curr_team): can_move = true + can_move.append_array(make_tiles(coords, [-1,-1], 8, false, curr_team, {}, create_tiles)) move_sw_inf: - if make_tiles(coords, [-1,1], 8, false, curr_team): can_move = true + can_move.append_array(make_tiles(coords, [-1,1], 8, false, curr_team, {}, create_tiles)) move_se_inf: - if make_tiles(coords, [1,1], 8, false, curr_team): can_move = true + can_move.append_array(make_tiles(coords, [1,1], 8, false, curr_team, {}, create_tiles)) knight: - if make_tiles(coords, [1,2], 1, false, curr_team): can_move = true - if make_tiles(coords, [1,-2], 1, false, curr_team): can_move = true - if make_tiles(coords, [-1,-2], 1, false, curr_team): can_move = true - if make_tiles(coords, [-1,2], 1, false, curr_team): can_move = true - if make_tiles(coords, [2,1], 1, false, curr_team): can_move = true - if make_tiles(coords, [2,-1], 1, false, curr_team): can_move = true - if make_tiles(coords, [-2,-1], 1, false, curr_team): can_move = true - if make_tiles(coords, [-2,1], 1, false, curr_team): can_move = true + can_move.append_array(make_tiles(coords, [1,2], 1, false, curr_team, {}, create_tiles)) + can_move.append_array(make_tiles(coords, [1,-2], 1, false, curr_team, {}, create_tiles)) + can_move.append_array(make_tiles(coords, [-1,-2], 1, false, curr_team, {}, create_tiles)) + can_move.append_array(make_tiles(coords, [-1,2], 1, false, curr_team, {}, create_tiles)) + can_move.append_array(make_tiles(coords, [2,1], 1, false, curr_team, {}, create_tiles)) + can_move.append_array(make_tiles(coords, [2,-1], 1, false, curr_team, {}, create_tiles)) + can_move.append_array(make_tiles(coords, [-2,-1], 1, false, curr_team, {}, create_tiles)) + can_move.append_array(make_tiles(coords, [-2,1], 1, false, curr_team, {}, create_tiles)) move_1_down: - if make_tiles(coords, [0,1], 1, false, curr_team): can_move = true + can_move.append_array(make_tiles(coords, [0,1], 1, false, curr_team, {}, create_tiles)) move_1_up: - if make_tiles(coords, [0,-1], 1, false, curr_team): can_move = true + can_move.append_array(make_tiles(coords, [0,-1], 1, false, curr_team, {}, create_tiles)) move_1_right: - if make_tiles(coords, [1,0], 1, false, curr_team): can_move = true + can_move.append_array(make_tiles(coords, [1,0], 1, false, curr_team, {}, create_tiles)) move_1_left: - if make_tiles(coords, [-1,0], 1, false, curr_team): can_move = true + can_move.append_array(make_tiles(coords, [-1,0], 1, false, curr_team, {}, create_tiles)) move_1_ne: - if make_tiles(coords, [1,-1], 1, false, curr_team): can_move = true + can_move.append_array(make_tiles(coords, [1,-1], 1, false, curr_team, {}, create_tiles)) move_1_nw: - if make_tiles(coords, [-1,-1], 1, false, curr_team): can_move = true + can_move.append_array(make_tiles(coords, [-1,-1], 1, false, curr_team, {}, create_tiles)) move_1_se: - if make_tiles(coords, [1,1], 1, false, curr_team): can_move = true + can_move.append_array(make_tiles(coords, [1,1], 1, false, curr_team, {}, create_tiles)) move_1_sw: - if make_tiles(coords, [-1,1], 1, false, curr_team): can_move = true + can_move.append_array(make_tiles(coords, [-1,1], 1, false, curr_team, {}, create_tiles)) return can_move func position_to_board_cell(vect2): @@ -373,6 +472,8 @@ func movetile_clicked(move_tile): en_passant_wait -= 1 if en_passant_wait == 0: en_passant_pawn = null + + new_turn() func kill_en_passant_pawn(location): if board[location[0]+1][location[1]] is Object and board[location[0]+1][location[1]] == en_passant_pawn: @@ -401,7 +502,7 @@ func make_tiles(coords, pattern, go_range, cant_attack, curr_team, 'tile_is_en_passant': false, 'en_passant_pawn': null, 'castling_rook': null - }): + }, create_tiles = true): var x = coords[0] var y = coords[1] var pattern0 = pattern[0] @@ -409,7 +510,7 @@ func make_tiles(coords, pattern, go_range, cant_attack, curr_team, var a = 0 var b = 0 - var made_tile = false + var made_tile = [] for _i in range(1,go_range+1): a += pattern0 @@ -418,18 +519,25 @@ func make_tiles(coords, pattern, go_range, cant_attack, curr_team, if (x + a) <= BOARD_WIDTH and (y + b) <= BOARD_HEIGHT and (x + a) >= 0 and (y + b) >= 0 : var check = board[x + a][y + b] if ! check and ! dict.get("must_attack"): - spawn_move_tile([x + a, y + b], dict.get("tile_is_en_passant"), dict.get("en_passant_pawn"), dict.get("castling_rook")) - made_tile = true + if create_tiles: + spawn_move_tile([x + a, y + b], dict.get("tile_is_en_passant"), dict.get("en_passant_pawn"), dict.get("castling_rook")) + made_tile.push_back([x + a, y + b]) elif dict.get("must_attack"): if ! check: pass elif check.get_team() != curr_team: - spawn_move_tile([x + a, y + b]) - made_tile = true - elif ! cant_attack and check.get_team() != curr_team: - spawn_move_tile([x + a, y + b], dict.get("tile_is_en_passant"), dict.get("en_passant_pawn")) - made_tile = true + if create_tiles: + spawn_move_tile([x + a, y + b]) + made_tile.push_back([x + a, y + b]) + elif ! cant_attack and check.get_team() != curr_team: + if create_tiles: + spawn_move_tile([x + a, y + b], dict.get("tile_is_en_passant"), dict.get("en_passant_pawn")) + made_tile.push_back([x + a, y + b]) break # rules of chess say pieces cant go past another + elif ! create_tiles and ! cant_attack and check.get_team() == curr_team : + # ^ in otherwords: we won't mark it on map but will 'mark' it for non-maps (like capture board) + made_tile.push_back([x + a, y + b]) + break # but still can't go past teammate else: break return made_tile diff --git a/MoveTile.gd b/MoveTile.gd index 6d81167..bb74eba 100644 --- a/MoveTile.gd +++ b/MoveTile.gd @@ -15,6 +15,6 @@ func _on_Area2D_input_event(_viewport, event, _shape_idx): func set_color(color): if color == "blue": - color = blue + $Rect.color = blue elif color == "red": - color = red + $Rect.color = red diff --git a/Sprite.gd b/Sprite.gd index e227c11..263addc 100644 --- a/Sprite.gd +++ b/Sprite.gd @@ -10,6 +10,7 @@ export var team = 0 export var has_moved = false export var in_check = false +export var killed = false # queue_free() isn't fast enough; get_nodes.by_group("piece") will still find this so mark explictly func get_move_pattern(): return self.move_patterns.get(piece) @@ -82,4 +83,5 @@ func get_piece_color_by_region(): return map func kill(): + killed = true queue_free()