e31a2fd04f
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.
792 lines
28 KiB
GDScript
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
|