chessgame/Main.gd
jake e31a2fd04f correctly calculate checkmate.
move check_for_promotion() at the very start of new turn.

add green color for MoveTile.gd (for showing map control)

add some functions that show board control.

modify some functions so that they will use 'text_board' rather than the player presented board.
2023-02-21 13:32:39 -05:00

792 lines
28 KiB
GDScript

extends Node
export (PackedScene) var piece_scene
export (PackedScene) var movetile_scene
var board = new_board()
var board_cell = 128
const BOARD_WIDTH = 7 # starting at 0..7
const BOARD_HEIGHT = 7
var history = []
var team1_capture = new_board()
var team2_capture = new_board()
var game_over = false
var movement_layer = false
var movement_layer_piece = null
var en_passant_pawn = null
var en_passant_wait = 0 # how many times any piece on the board must move before en_passant_pawn gets set to null
var team1_king = null
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
func _ready():
make_player1("green")
make_player2("red")
#spawn_piece('pawn', 'teal', 1, 6, team1)
#spawn_piece('pawn', 'orange', 2, 4, team2)
#checkmatet1()
#checkmatet2()
#spawn_piece('rook', 'orange', 0, 0, team2)
#spawn_piece('rook', 'orange', 7, 0, team2)
#team1_king = spawn_piece('rook', 'teal', 5, 3, team1)
#spawn_piece('pawn', 'blue', 6, 0, team1)
var captures = update_capture_tables(board_to_text_board(board))
team1_capture = captures[0]
team2_capture = captures[1]
save_turn()
OS.set_window_size(Vector2(700,700))
#OS.set_window_always_on_top(true)
func checkmatet1():
team1_king = spawn_piece('king', 'orange', 4, 7, team1)
spawn_piece('bishop', 'orange', 3, 7, team1)
spawn_piece('pawn', 'orange', 5, 6, team1)
spawn_piece('pawn', 'orange', 3, 6, team1)
spawn_piece('pawn', 'orange', 4, 6, team1)
spawn_piece('rook', 'teal', 7, 3, team2)
func checkmatet2():
team2_king = spawn_piece('king', 'teal', 4, 0, team2)
spawn_piece('bishop', 'teal', 3, 0, team2)
spawn_piece('pawn', 'teal', 5, 1, team2)
spawn_piece('pawn', 'teal', 3, 1, team2)
spawn_piece('pawn', 'teal', 4, 1, team2)
spawn_piece('rook', 'orange', 7, 2, team1)
func _process(_delta):
safely_handle_movement = false
if Input.is_action_just_pressed("mouse2"):
if click_spot() == Vector2(0,0):
print(history)
if click_spot() == Vector2(1,0):
#print(team2_every_legal_move(board_to_text_board(board)))
print("whoops")
if click_spot() == Vector2(2,0):
print(board_to_text_board(board))
if click_spot() == Vector2(4,0):
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))
if click_spot() == Vector2(5,0):
for i in 8:
for k in 8:
if team1_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 new_turn():
check_for_promotion()
var text_board = board_to_text_board(board)
var captures = update_capture_tables(text_board)
team1_capture = captures[0]
team2_capture = captures[1]
#print(captures)
is_king_team1_checked(text_board, true, team2_capture)
is_king_team2_checked(text_board, true, team1_capture)
turn += 1
print("Turn: %s" % turn)
save_turn()
print("-------------------")
func save_turn():
var text_board = board_to_text_board(board)
history.append(text_board)
enum piece_names {
pawn,
rook,
knight,
bishop,
king,
queen
}
func board_to_text_board(boarde):
var text_board = new_board()
for i in 8:
for k in 8:
if boarde[i][k] is Object:
var curr_piece = boarde[i][k]
var piece_name = curr_piece.get_piece()
var piece_enum = piece_names.get(piece_name)
var team = curr_piece.get_team()
var has_moved = curr_piece.has_moved
var in_check = curr_piece.in_check
var en_passant = null
if curr_piece == en_passant_pawn: en_passant = 1
#var color = curr_piece.get_piece_color_by_region()
text_board[i][k] = [piece_enum, team, en_passant, has_moved, in_check]
else:
text_board[i][k] = 0
return text_board
func update_capture_tables(text_board, setting=tile_setting.hide_tiles_and_cover_allies):
var t1_capture = new_board()
var t2_capture = new_board()
var pieces = get_pieces(text_board)
for e in pieces:
var coords = e[chess_enum.pos]
if e[chess_enum.team] == team1:
t1_capture[coords[0]][coords[1]] = 2
else: # team2
t2_capture[coords[0]][coords[1]] = 2
for e in pieces:
var coords = e[chess_enum.pos]
var pattern = get_move_pattern(e, coords)
var captured = can_chess_move(pattern, coords, text_board, setting)
if e[chess_enum.team] == team1:
for c in captured:
if c.size() == 3:
if c[2] == "not attacking":
continue
t1_capture[c[0]][c[1]] = 1
else: # team2
for c in captured:
if c.size() == 3:
if c[2] == "not attacking":
continue
t2_capture[c[0]][c[1]] = 1
#print(team1_capture)
#print(team2_capture)
#color_tiles(t2_capture, "red")
#color_tiles(t1_capture, "green")
return [t1_capture, t2_capture]
func color_tiles(capture, color):
for i in 8:
for k in 8:
if capture[i][k] == 1:
var move_tile = movetile_scene.instance()
add_child(move_tile)
move_tile.set_color(color)
move_tile.position = in_square(Vector2(i * board_cell, k * board_cell))
func check_for_promotion():
var pieces = get_tree().get_nodes_in_group("piece")
for e in pieces:
if e.get_piece() == "pawn":
var y = position_to_board_cell(e.position)[1]
if y == 0 or y == 7:
print("pawn is elligable for promotion")
# TODO: player option
e.set_piece("queen", e.get_piece_color_by_region())
func is_king_team2_checked(text_board, enumerate=true, capture_table=[]):
if team2_king:
for i in 8:
for k in 8:
if text_board[i][k] and text_board[i][k][chess_enum.piece_enum] == piece_names["king"] and text_board[i][k][chess_enum.team] == team2:
if capture_table[i][k] >= 1:
if enumerate:
print("Aye, team2 in check.")
team2_king.in_check = true
if enumerate_checkmate(text_board, 2):
print("Game over: Checkmate! Team 1 wins!")
game_over = true
return true
else:
team2_king.in_check = false
return false
func is_king_team1_checked(text_board, enumerate=true, capture_table=[]):
if team1_king:
for i in 8:
for k in 8:
if text_board[i][k] and text_board[i][k][chess_enum.piece_enum] == piece_names["king"] and text_board[i][k][chess_enum.team] == team1:
if capture_table[i][k] >= 1:
if enumerate:
print("Aye, team1 in check.")
team1_king.in_check = true
if enumerate_checkmate(text_board, 1):
print("Game over: Checkmate! Team 2 wins!")
game_over = true
return true
else:
team1_king.in_check = false
return false
func enumerate_checkmate(text_board, which_king=1):
var checkmate = true
var legal_every_move = team_every_legal_move(text_board, which_king)
for every_move in legal_every_move:
var piece = every_move[0]
#rint("piece at (%s,%s)" % [piece[0],piece[1]])
for move in every_move[1]:
#print("can move to: (%s,%s)" % [move[0],move[1]])
var fake_board = pretend_text_board_movement(text_board.duplicate(true), piece, move)
#print(text_board)
#print(fake_board)
var fake_captures = update_capture_tables(fake_board.duplicate(true))
var t1_captures = fake_captures[0]
var t2_captures = fake_captures[1]
if which_king == 1:
if is_king_team1_checked(fake_board, false, t2_captures):
pass
else:
checkmate = false
else: # team2
if is_king_team2_checked(fake_board, false, t1_captures):
pass
else:
checkmate = false
return checkmate
func get_pieces(text_board):
var pieces = []
var deepcopy = text_board.duplicate(true)
for i in 8:
for k in 8:
if deepcopy[i][k] is Array:
deepcopy[i][k].append([i,k])
pieces.append(deepcopy[i][k]) # 6
return pieces
func team_every_legal_move(text_board, team):
var every_legal_move = []
for i in 8:
for k in 8:
if text_board[i][k] is Array and text_board[i][k][chess_enum.team] == team:
var piece_name = text_board[i][k][chess_enum.piece_enum]
var coords = [i,k]
var move_pattern
#var name_of_this = match_piece_names_enums(piece_name)
move_pattern = get_move_pattern([piece_name, team], coords)
every_legal_move.append([[i,k], can_chess_move(move_pattern, coords, text_board, tile_setting.hide_tiles_no_cover_allies)])
#rint(every_legal_move)
return every_legal_move
func match_piece_names_enums(piece_name):
if piece_names["pawn"] == piece_name:
return "pawn"
elif piece_names["rook"] == piece_name:
return "rook"
elif piece_names["knight"] == piece_name:
return "knight"
elif piece_names["bishop"] == piece_name:
return "bishop"
elif piece_names["queen"] == piece_name:
return "queen"
elif piece_names["king"] == piece_name:
return "king"
else:
print("unknown piece: %s" % piece_name)
func pretend_text_board_movement(text_board, old_coords, new_coords):
#print("old coords: (%s , %s)" % old_coords)
#print("new coords: (%s , %s)" % [new_coords[0], new_coords[1]])
#print(text_board)
var new_text_board = text_board.duplicate(true)
new_text_board[new_coords[0]][new_coords[1]] = new_text_board[old_coords[0]][old_coords[1]]
new_text_board[old_coords[0]][old_coords[1]] = 0
#print(new_text_board)
return new_text_board
func remove_movement_layer():
movement_layer = false
movement_layer_piece = null
var movement_tiles = get_tree().get_nodes_in_group("tile")
for e in movement_tiles:
e.queue_free()
func piece_clicked(piece):
if movement_layer:
print("I was clicked on, but the movement layer is toggled")
if movement_layer_piece == click_spot():
remove_movement_layer()
else:
if ! safely_handle_movement:
#var piece_name = piece.get_piece()
#rint("You clicked on a %s, team %s" % [piece_name, piece.get_team()])
var location = click_spot()
#rint("Spot: %s " % location)
var pattern = get_move_pattern(piece, location)
if can_chess_move(pattern, location, board_to_text_board(board)):
movement_layer = true
movement_layer_piece = location
func click_spot():
var square = get_viewport().get_mouse_position()
square[0] = floor(square[0] / board_cell)
square[1] = floor(square[1] / board_cell)
return square
func make_player2(color):
spawn_piece('rook', color, 0, 0, team2)
spawn_piece('knight', color, 1, 0, team2)
spawn_piece('bishop', color, 2, 0, team2)
spawn_piece('queen', color, 3, 0, team2)
team2_king = spawn_piece('king', color, 4, 0, team2)
spawn_piece('bishop', color, 5, 0, team2)
spawn_piece('knight', color, 6, 0, team2)
spawn_piece('rook', color, 7, 0, team2)
for i in BOARD_WIDTH + 1:
spawn_piece('pawn', color, i , 1, team2)
func make_player1(color):
spawn_piece('rook', color, 0, 7, team1)
spawn_piece('knight', color, 1, 7, team1)
spawn_piece('bishop', color, 2, 7, team1)
spawn_piece('queen', color, 3, 7, team1)
team1_king = spawn_piece('king', color, 4, 7, team1)
spawn_piece('bishop', color, 5, 7, team1)
spawn_piece('knight', color, 6, 7, team1)
spawn_piece('rook', color, 7, 7, team1)
for i in BOARD_WIDTH + 1:
spawn_piece('pawn', color, i , 6, team1)
func spawn_piece(piece_name, color, x=0, y=0, team=0):
var piece = piece_scene.instance()
piece.init(piece.piece_map.get(piece_name), piece.piece_color.get(color), team)
add_child(piece)
piece.connect("clicked", self, "piece_clicked", [piece])
board_add_piece(piece, x, y)
piece.position = in_square(Vector2(x * board_cell, y * board_cell))
return piece
func rand_pos():
return Vector2(rand_range(0, get_viewport().size.x),rand_range(0, get_viewport().size.y))
# needs to be Vector2 as that is what object.position takes
func in_square(vect2):
#rint(vect2)
vect2.x = ceil(vect2.x / board_cell)
#rint(vect2.x)
vect2.x *= board_cell
vect2.x += board_cell / 2
vect2.y = ceil(vect2.y / board_cell)
#rint(vect2.y)
vect2.y *= board_cell
vect2.y += board_cell / 2
#rint(vect2)
return vect2
func new_board():
# x →
# y
# ↓
# [0][0] = top left, [0][7] = bottom left, [7][0] = top right, [7][7] = bottom right
var new_board = []
for i in BOARD_HEIGHT + 1:
new_board.append([])
new_board[i].resize(BOARD_WIDTH + 1)
for j in BOARD_WIDTH + 1:
new_board[i][j] = 0
return new_board
func board_add_piece(piece, x, y):
board[x][y] = piece
enum {
move_2_up_pawn,
move_1_up_pawn,
attack_1_nw,
attack_1_ne,
en_passant_nw,
en_passant_ne,
move_2_down_pawn,
move_1_down_pawn,
attack_1_sw,
attack_1_se,
en_passant_sw,
en_passant_se,
move_1_up,
move_1_down,
move_1_left,
move_1_right,
move_1_nw,
move_1_ne,
move_1_sw,
move_1_se,
move_up_inf,
move_down_inf,
move_left_inf,
move_right_inf,
castling,
move_nw_inf,
move_ne_inf,
move_sw_inf,
move_se_inf,
knight,
}
func get_move_pattern(piece, coords):
var piece_name
var team
if piece is Object:
piece_name = piece.get_piece()
team = piece.get_team()
else:
piece_name = match_piece_names_enums(piece[chess_enum.piece_enum])
#print(piece_name)
team = piece[1]
#rint("Array: %s, %s" % [piece_name, team])
match (piece_name):
"pawn":
if team == team1:
if coords[1] == 6:
return [attack_1_nw, move_2_up_pawn, attack_1_ne, en_passant_ne, en_passant_nw]
else:
return [attack_1_nw, move_1_up_pawn, attack_1_ne, en_passant_ne, en_passant_nw]
else:
if coords[1] == 1:
return [attack_1_sw, move_2_down_pawn, attack_1_se, en_passant_se, en_passant_sw]
else:
return [attack_1_sw, move_1_down_pawn, attack_1_se, en_passant_se, en_passant_sw]
"rook":
return [move_up_inf, move_left_inf, move_right_inf, move_down_inf]
"knight":
return [knight]
"bishop":
return [move_ne_inf, move_nw_inf, move_sw_inf, move_se_inf]
"queen":
return [move_up_inf, move_down_inf, move_left_inf, move_right_inf, move_ne_inf, move_nw_inf, move_sw_inf, move_se_inf]
"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]
_:
return []
enum chess_enum {
piece_enum = 0,
team = 1,
en_passant = 2,
has_moved = 3,
in_check = 4,
pos = 5
}
enum tile_setting {
hide_tiles_and_cover_allies = 0
show_tiles = 1
hide_tiles_no_cover_allies = 2
}
func can_chess_move(pattern, coords, text_board, create_tiles=tile_setting.show_tiles):
var can_move = []
#rint(text_board[coords[0]][coords[1]])
var curr_piece = text_board[coords[0]][coords[1]]
var curr_team = curr_piece[chess_enum.team]
for e in pattern:
match (e):
move_1_down_pawn:
var test = make_tiles(coords, [0,1], 1, true, curr_team, {}, create_tiles, text_board)
if test:
test[0].push_back("not attacking")
can_move.append_array(test)
move_2_down_pawn:
var test = make_tiles(coords, [0,1], 1, true, curr_team, {}, create_tiles, text_board)
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, text_board)
if test2:
test2[0].push_back("not attacking")
can_move.append_array(test2)
attack_1_sw:
var test = make_tiles(coords, [-1,1], 1, false, curr_team, {"must_attack": true}, create_tiles, text_board)
if test:
test[0].push_back("must attack")
can_move.append_array(test)
attack_1_se:
var test = make_tiles(coords, [1,1], 1, false, curr_team, {"must_attack": true}, create_tiles, text_board)
if test:
test[0].push_back("must attack")
can_move.append_array(test)
en_passant_sw:
var pawn_maybe = text_board[coords[0]-1][coords[1]]
if pawn_maybe and pawn_maybe[chess_enum.piece_enum] == piece_names["pawn"] and pawn_maybe[chess_enum.en_passant] == 1 and pawn_maybe[chess_enum.team] != curr_team:
can_move.append_array(make_tiles(coords, [-1,1], 1, true, curr_team, {"en_passant_pawn": pawn_maybe}, create_tiles, text_board))
en_passant_se:
if ! coords[0] + 1 > BOARD_WIDTH:
var pawn_maybe = text_board[coords[0]+1][coords[1]]
if pawn_maybe and pawn_maybe[chess_enum.piece_enum] == piece_names["pawn"] and pawn_maybe[chess_enum.en_passant] == 1 and pawn_maybe[chess_enum.team] != curr_team:
can_move.append_array(make_tiles(coords, [1,1], 1, true, curr_team, {"en_passant_pawn": pawn_maybe}, create_tiles, text_board))
move_1_up_pawn:
var test = make_tiles(coords, [0,-1], 1, true, curr_team, {}, create_tiles, text_board)
if test:
test[0].push_back("not attacking")
can_move.append_array(test)
move_2_up_pawn:
var test = make_tiles(coords, [0,-1], 1, true, curr_team, {}, create_tiles, text_board)
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, text_board)
if test2:
test2[0].push_back("not attacking")
can_move.append_array(test2)
attack_1_nw:
var test = make_tiles(coords, [-1,-1], 1, false, curr_team, {"must_attack": true}, create_tiles, text_board)
if test:
test[0].push_back("must attack")
can_move.append_array(test)
attack_1_ne:
var test = make_tiles(coords, [1,-1], 1, false, curr_team, {"must_attack": true}, create_tiles, text_board)
if test:
test[0].push_back("must attack")
can_move.append_array(test)
en_passant_nw:
var pawn_maybe = text_board[coords[0]-1][coords[1]]
if pawn_maybe and pawn_maybe[chess_enum.piece_enum] == piece_names["pawn"] and pawn_maybe[chess_enum.en_passant] == 1 and pawn_maybe[chess_enum.team] != curr_team:
can_move.append_array(make_tiles(coords, [-1,-1], 1, true, curr_team, {"en_passant_pawn": pawn_maybe}, create_tiles, text_board))
en_passant_ne:
if ! coords[0] + 1 > BOARD_WIDTH:
var pawn_maybe = text_board[coords[0]+1][coords[1]]
if pawn_maybe and pawn_maybe[chess_enum.piece_enum] == piece_names["pawn"] and pawn_maybe[chess_enum.en_passant] == 1 and pawn_maybe[chess_enum.team] != curr_team:
can_move.append_array(make_tiles(coords, [1,-1], 1, true, curr_team, {"en_passant_pawn": pawn_maybe}, create_tiles, text_board))
move_up_inf:
can_move.append_array(make_tiles(coords, [0,-1], BOARD_HEIGHT, false, curr_team, {}, create_tiles, text_board))
move_down_inf:
can_move.append_array(make_tiles(coords, [0,1], BOARD_HEIGHT, false, curr_team, {}, create_tiles, text_board))
move_left_inf:
can_move.append_array(make_tiles(coords, [-1,0], BOARD_WIDTH, false, curr_team, {}, create_tiles, text_board))
move_right_inf:
can_move.append_array(make_tiles(coords, [1,0], BOARD_WIDTH, false, curr_team, {}, create_tiles, text_board))
castling:
if ! curr_piece[chess_enum.has_moved] and ! curr_piece[chess_enum.in_check]:
var y = coords[1]
var king_x = coords[0]
#var pieces = get_tree().get_nodes_in_group("piece")
var pieces = get_pieces(text_board)
for ele in pieces:
if ele[chess_enum.team] == curr_team and ele[chess_enum.piece_enum] == piece_names["rook"] and ! ele[chess_enum.has_moved] and ele[chess_enum.pos][1] == y:
#rint(ele)
var rook_x = ele[chess_enum.pos][0]
# king side
if rook_x > king_x:
var blocked = false
var diff = rook_x - king_x
for i in range(1, diff):
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:
can_move.append_array(make_tiles(coords, [2,0], 1, false, curr_team, {"castling_rook": ele}, create_tiles, text_board))
else:
var blocked = false
var diff = king_x - rook_x
for i in range(1, diff):
#rint(board[rook_x + i][y])
if board[rook_x + i][y]:
blocked = true
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:
can_move.append_array(make_tiles(coords, [-2,0], 1, false, curr_team, {"castling_rook": ele}, create_tiles, text_board))
move_ne_inf:
can_move.append_array(make_tiles(coords, [1,-1], 8, false, curr_team, {}, create_tiles, text_board))
move_nw_inf:
can_move.append_array(make_tiles(coords, [-1,-1], 8, false, curr_team, {}, create_tiles, text_board))
move_sw_inf:
can_move.append_array(make_tiles(coords, [-1,1], 8, false, curr_team, {}, create_tiles, text_board))
move_se_inf:
can_move.append_array(make_tiles(coords, [1,1], 8, false, curr_team, {}, create_tiles, text_board))
knight:
can_move.append_array(make_tiles(coords, [1,2], 1, false, curr_team, {}, create_tiles, text_board))
can_move.append_array(make_tiles(coords, [1,-2], 1, false, curr_team, {}, create_tiles, text_board))
can_move.append_array(make_tiles(coords, [-1,-2], 1, false, curr_team, {}, create_tiles, text_board))
can_move.append_array(make_tiles(coords, [-1,2], 1, false, curr_team, {}, create_tiles, text_board))
can_move.append_array(make_tiles(coords, [2,1], 1, false, curr_team, {}, create_tiles, text_board))
can_move.append_array(make_tiles(coords, [2,-1], 1, false, curr_team, {}, create_tiles, text_board))
can_move.append_array(make_tiles(coords, [-2,-1], 1, false, curr_team, {}, create_tiles, text_board))
can_move.append_array(make_tiles(coords, [-2,1], 1, false, curr_team, {}, create_tiles, text_board))
move_1_down:
can_move.append_array(make_tiles(coords, [0,1], 1, false, curr_team, {}, create_tiles, text_board))
move_1_up:
can_move.append_array(make_tiles(coords, [0,-1], 1, false, curr_team, {}, create_tiles, text_board))
move_1_right:
can_move.append_array(make_tiles(coords, [1,0], 1, false, curr_team, {}, create_tiles, text_board))
move_1_left:
can_move.append_array(make_tiles(coords, [-1,0], 1, false, curr_team, {}, create_tiles, text_board))
move_1_ne:
can_move.append_array(make_tiles(coords, [1,-1], 1, false, curr_team, {}, create_tiles, text_board))
move_1_nw:
can_move.append_array(make_tiles(coords, [-1,-1], 1, false, curr_team, {}, create_tiles, text_board))
move_1_se:
can_move.append_array(make_tiles(coords, [1,1], 1, false, curr_team, {}, create_tiles, text_board))
move_1_sw:
can_move.append_array(make_tiles(coords, [-1,1], 1, false, curr_team, {}, create_tiles, text_board))
return can_move
func position_to_board_cell(vect2):
var x = floor(vect2.x / board_cell)
var y = floor(vect2.y / board_cell)
return [x,y]
func movetile_clicked(move_tile):
#rint("Yep, I was clicked")
var location = click_spot()
var check = board[location[0]][location[1]]
var curr_piece = board[movement_layer_piece[0]][movement_layer_piece[1]]
if ! check:
pass
else:
check.kill()
board[location[0]][location[1]] = curr_piece
if move_tile.en_passant_tile:
#rint("toggling en passant able...")
en_passant_pawn = curr_piece
en_passant_wait = 2 # gets -1 in this script later
if move_tile.castling_rook:
# move_tile.castling_rook actually an array (created by get_pieces() rather than an object)
var rook_location = move_tile.castling_rook[chess_enum["pos"]]
# need to take that pos and figure out which rook object refers to
var pos = position_to_board_cell(Vector2(rook_location[0] * board_cell, rook_location[1] * board_cell))
var rook = board[pos[0]][pos[1]]
# king side
if 7 == rook_location[0]:
rook.position = in_square(Vector2(5 * board_cell, rook_location[1] * board_cell))
board[5][rook_location[1]] = board[7][rook_location[1]]
board[7][rook_location[1]] = 0
# queen side
else:
rook.position = in_square(Vector2(3 * board_cell, rook_location[1] * board_cell))
board[3][rook_location[1]] = board[0][rook_location[1]]
board[0][rook_location[1]] = 0
curr_piece.position = in_square(Vector2(location[0] * board_cell, location[1] * board_cell))
board[movement_layer_piece[0]][movement_layer_piece[1]] = 0
remove_movement_layer()
safely_handle_movement = true
curr_piece.has_moved = true
if move_tile.en_passant_kill_tile:
kill_en_passant_pawn(location)
if en_passant_wait >= 1:
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:
board[location[0]+1][location[1]] = 0
if board[location[0]-1][location[1]] is Object and board[location[0]-1][location[1]] == en_passant_pawn:
board[location[0]-1][location[1]] = 0
if board[location[0]][location[1]+1] is Object and board[location[0]][location[1]+1] == en_passant_pawn:
board[location[0]][location[1]+1] = 0
if board[location[0]][location[1]-1] is Object and board[location[0]][location[1]-1] == en_passant_pawn:
board[location[0]][location[1]-1] = 0
en_passant_pawn.kill()
func spawn_move_tile(coords, en_passant_tile=false, en_passant_kill_tile=null, castling_rook=null):
var move_tile = movetile_scene.instance()
add_child(move_tile)
move_tile.connect("move_clicked", self, "movetile_clicked", [move_tile])
move_tile.position = in_square(Vector2(coords[0] * board_cell, coords[1] * board_cell))
if en_passant_tile: move_tile.en_passant_tile = true
if en_passant_kill_tile: move_tile.en_passant_kill_tile = true
if castling_rook: move_tile.castling_rook = castling_rook
#rint(move_tile.position)
func make_tiles(coords, pattern, go_range, cant_attack, curr_team,
dict = {
"must_attack": false,
'tile_is_en_passant': false,
'en_passant_pawn': null,
'castling_rook': null
}, create_tiles = tile_setting.show_tiles, text_board=[]):
var x = coords[0]
var y = coords[1]
var pattern0 = pattern[0]
var pattern1 = pattern[1]
var a = 0
var b = 0
var made_tile = []
for _i in range(1,go_range+1):
a += pattern0
b += pattern1
# dont go out of bounds: not bigger than board size but not smaller than 0
if (x + a) <= BOARD_WIDTH and (y + b) <= BOARD_HEIGHT and (x + a) >= 0 and (y + b) >= 0 :
var check = text_board[x + a][y + b]
if ! check and ! dict.get("must_attack"):
if create_tiles == tile_setting.show_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"): # pawn setting
if check and check[chess_enum.team] != curr_team:
if create_tiles == tile_setting.show_tiles:
spawn_move_tile([x + a, y + b])
made_tile.push_back([x + a, y + b])
elif create_tiles == 0:
made_tile.push_back([x + a, y + b])
elif ! cant_attack and check[chess_enum.team] != curr_team:
if create_tiles == tile_setting.show_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 == tile_setting.hide_tiles_and_cover_allies and ! cant_attack and check[chess_enum.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
# option (used when we KNOW it is an array)
# "object" -> sprite object
# "tile" -> return info about the tile
func array_piece(coords, option=null):
var element = board[coords[0]][coords[1]]
#rint(element)
if element is Array:
if option == "object":
return element[0]
elif option == "tile":
return element[1]
return element