online multiplayer chess game (note server currently down)
Diffstat (limited to 'Grid.gd')
-rw-r--r--Grid.gd258
1 files changed, 140 insertions, 118 deletions
diff --git a/Grid.gd b/Grid.gd
index b03aebb..9b6e7a8 100644
--- a/Grid.gd
+++ b/Grid.gd
@@ -1,12 +1,13 @@
extends Node2D
class_name Grid
-onready var PIECE_SET: String = Globals.piece_set
-
-export(Color) var board_color1 := Color(0.870588, 0.890196, 0.901961)
-export(Color) var board_color2 := Color(0.54902, 0.635294, 0.678431)
-export(Color) var overlay_color := Color(0.2, 0.345098, 0.188235, 0.592157)
-
+const topper_header = "┏━━━┳━━━┳━━━┳━━━┳━━━┳━━━┳━━━┳━━━┳━━━┓"
+const middle_header = "┣━━━╋━━━╋━━━╋━━━╋━━━╋━━━╋━━━╋━━━╋━━━┫"
+const middish_heads = "┗━━━╋━━━╋━━━╋━━━╋━━━╋━━━╋━━━╋━━━╋━━━┫"
+const bottom_header = "┗━━━┻━━━┻━━━┻━━━┻━━━┻━━━┻━━━┻━━━┻━━━┛"
+const smaller_heads = " ┗━━━┻━━━┻━━━┻━━━┻━━━┻━━━┻━━━┻━━━┛"
+const letter_header = " ┃ a ┃ b ┃ c ┃ d ┃ e ┃ f ┃ g ┃ h ┃"
+const ender = " ┃ " # for pretty prints
const Piece = preload("res://Piece.tscn")
const Square = preload("res://Square.tscn")
const BottomLeftLabel = preload("res://ui/BottomLeftLabel.tscn")
@@ -23,14 +24,20 @@ const default_metadata := {
"bcep": [], # black can enpassant
}
+export(Color) var board_color1 := Color(0.870588, 0.890196, 0.901961)
+export(Color) var board_color2 := Color(0.54902, 0.635294, 0.678431)
+export(Color) var overlay_color := Color(0.2, 0.345098, 0.188235, 0.592157)
+
var matrix := []
+var promoting = null
var background_matrix := []
var history_matrixes := {}
-
var last_clicked = null
+onready var PIECE_SET: String = Globals.piece_set
+
onready var background := $Background
-onready var ASSETS_PATH := "res://assets/pieces/" + PIECE_SET + "/"
+onready var ASSETS_PATH := "res://assets/pieces/%s/" % PIECE_SET
onready var foreground := $Foreground
onready var pieces := $Pieces
onready var status_label := $"../UI/Holder/Back/VBox/Status"
@@ -40,16 +47,48 @@ func _ready():
Globals.grid = self # tell the globals that this is the grid
init_board() # create the tile squares
init_matrix() # create the pieces
- init_labels()
+ init_labels() # add the labels
Events.connect("turn_over", self, "_on_turn_over") # listen for turn_over events
Events.connect("outoftime", self, "_on_outoftime") # listen for timeout events
-func _on_outoftime(who):
- if who == "white":
- win("black")
- else:
- win("white")
+func _exit_tree():
+ Globals.grid = null # reset the globals grid when leaving tree
+
+
+func _input(event): # input
+ if event.is_action_released("debug"): # if debug
+ print_matrix_pretty() # print the matrix
+ if event.is_action_released("kill"):
+ if last_clicked and OS.is_debug_build(): # last clicked isnt null and were in debug
+ last_clicked.took() # kill the piece
+ last_clicked = null
+ clear_fx() # clear the circles
+
+
+func print_matrix_pretty(mat = matrix): # print the matrix
+ for j in range(8): # for each row
+ var r: Array = mat[j] # get the row
+ if j == 0:
+ print(topper_header) # print the top border
+ else:
+ print(middle_header) # print the middle border
+ var row = "┃ %s ┃ " % str(8 - j) # init the string
+ for i in range(8): # for each column
+ var c = r[i] # get the column
+ if c: # if there is a piece
+ row += c.mininame + ender # add the shortname
+ else: # if there is no piece
+ row += " " + ender # add 00
+ print(row) # print the string
+ print("%s\n%s\n%s" % [middish_heads, letter_header, smaller_heads])
+
+
+func reload_sprites():
+ for i in range(8):
+ for j in range(8):
+ if matrix[i][j]:
+ matrix[i][j].load_texture()
func init_labels():
@@ -97,30 +136,6 @@ func mat2str(mat = matrix):
return string
-func _on_turn_over():
- var matstr: String = mat2str()
- if !history_matrixes.has(matstr):
- history_matrixes[matstr] = 1
- else:
- history_matrixes[matstr] += 1
- Globals.checking_piece = null # reset checking_piece
- Globals.in_check = false # reset in_check
- matrix[8] = default_metadata.duplicate() # add the metadata to the matrix
- matrix[8].turn = Globals.turn
- check_in_check(true) # check if in_check
- if !can_move():
- if Globals.in_check:
- var winner := "black" if Globals.turn else "white"
- status_label.text("%s won the game by checkmate" % winner)
- win(winner)
- else:
- status_label.text("stalemate")
- drawed()
- elif threefoldrepetition():
- status_label.text("draw by threefold repetition")
- drawed()
-
-
func drawed():
Events.emit_signal("game_over")
SoundFx.play("Draw")
@@ -162,10 +177,6 @@ func can_move():
return false
-func _exit_tree():
- Globals.grid = null # reset the globals grid when leaving tree
-
-
func init_matrix(): # create the matrix
for i in range(8): # for each row
matrix.append([]) # add a row
@@ -175,16 +186,14 @@ func init_matrix(): # create the matrix
add_pieces() # add the pieces
-func make_piece(position: Vector2, script: String, sprite: String, white: bool = true): # make peace
+func make_piece(position: Vector2, script: String, white: bool = true): # make peace
var piece := Piece.instance() # create a piece
piece.script = load(script) # set the script
- piece.sprite = piece.get_node("Sprite") # get the sprite
- piece.sprite.texture = load(sprite) # set the sprite
piece.real_position = position # set the real position
piece.global_position = position * piece_size # set the global position
piece.white = white # set its team
pieces.add_child(piece) # add the piece to the grid
- return piece # return the piece
+ matrix[position.y][position.x] = piece
func init_board(): # create the board
@@ -194,7 +203,6 @@ func init_board(): # create the board
var square := Square.instance() # create a square
square.rect_size = piece_size # set the size
square.rect_position = Vector2(i, j) * piece_size # set the position
- square.name = "square_" + str(i) + "_" + str(j) # set the real name
square.color = board_color1 if (i + j) % 2 == 0 else board_color2 # set the color
square.real_position = Vector2(i, j) # set the real position
background.add_child(square) # add the square to the background
@@ -204,82 +212,52 @@ func init_board(): # create the board
func add_pieces(): # add the pieces
add_pawns()
- add_rooks()
- add_knights()
- add_bishops()
+ # add_rooks()
+ # add_knights()
+ # add_bishops()
add_queens()
add_kings()
- print_matrix_pretty()
func add_pawns():
for i in range(8):
- matrix[1][i] = make_piece(Vector2(i, 1), "res://pieces/Pawn.gd", ASSETS_PATH + "bP.png", false)
- matrix[6][i] = make_piece(Vector2(i, 6), "res://pieces/Pawn.gd", ASSETS_PATH + "wP.png", true)
+ make_piece(Vector2(i, 1), "res://pieces/Pawn.gd", false)
+ make_piece(Vector2(i, 6), "res://pieces/Pawn.gd", true)
func add_rooks():
- matrix[0][0] = make_piece(Vector2(0, 0), "res://pieces/Rook.gd", ASSETS_PATH + "bR.png", false)
- matrix[0][7] = make_piece(Vector2(7, 0), "res://pieces/Rook.gd", ASSETS_PATH + "bR.png", false)
- matrix[7][0] = make_piece(Vector2(0, 7), "res://pieces/Rook.gd", ASSETS_PATH + "wR.png", true)
- matrix[7][7] = make_piece(Vector2(7, 7), "res://pieces/Rook.gd", ASSETS_PATH + "wR.png", true)
+ make_piece(Vector2(0, 0), "res://pieces/Rook.gd", false)
+ make_piece(Vector2(7, 0), "res://pieces/Rook.gd", false)
+ make_piece(Vector2(0, 7), "res://pieces/Rook.gd", true)
+ make_piece(Vector2(7, 7), "res://pieces/Rook.gd", true)
func add_knights():
- matrix[0][1] = make_piece(Vector2(1, 0), "res://pieces/Knight.gd", ASSETS_PATH + "bN.png", false)
- matrix[0][6] = make_piece(Vector2(6, 0), "res://pieces/Knight.gd", ASSETS_PATH + "bN.png", false)
- matrix[7][1] = make_piece(Vector2(1, 7), "res://pieces/Knight.gd", ASSETS_PATH + "wN.png", true)
- matrix[7][6] = make_piece(Vector2(6, 7), "res://pieces/Knight.gd", ASSETS_PATH + "wN.png", true)
+ make_piece(Vector2(1, 0), "res://pieces/Knight.gd", false)
+ make_piece(Vector2(6, 0), "res://pieces/Knight.gd", false)
+ make_piece(Vector2(1, 7), "res://pieces/Knight.gd", true)
+ make_piece(Vector2(6, 7), "res://pieces/Knight.gd", true)
func add_bishops():
- matrix[0][2] = make_piece(Vector2(2, 0), "res://pieces/Bishop.gd", ASSETS_PATH + "bB.png", false)
- matrix[0][5] = make_piece(Vector2(5, 0), "res://pieces/Bishop.gd", ASSETS_PATH + "bB.png", false)
- matrix[7][2] = make_piece(Vector2(2, 7), "res://pieces/Bishop.gd", ASSETS_PATH + "wB.png", true)
- matrix[7][5] = make_piece(Vector2(5, 7), "res://pieces/Bishop.gd", ASSETS_PATH + "wB.png", true)
+ make_piece(Vector2(2, 0), "res://pieces/Bishop.gd", false)
+ make_piece(Vector2(5, 0), "res://pieces/Bishop.gd", false)
+ make_piece(Vector2(2, 7), "res://pieces/Bishop.gd", true)
+ make_piece(Vector2(5, 7), "res://pieces/Bishop.gd", true)
func add_queens():
- matrix[0][3] = make_piece(Vector2(3, 0), "res://pieces/Queen.gd", ASSETS_PATH + "bQ.png", false)
- matrix[7][3] = make_piece(Vector2(3, 7), "res://pieces/Queen.gd", ASSETS_PATH + "wQ.png", true)
+ make_piece(Vector2(3, 0), "res://pieces/Queen.gd", false)
+ make_piece(Vector2(3, 7), "res://pieces/Queen.gd", true)
func add_kings():
- matrix[0][4] = make_piece(Vector2(4, 0), "res://pieces/King.gd", ASSETS_PATH + "bK.png", false)
- matrix[7][4] = make_piece(Vector2(4, 7), "res://pieces/King.gd", ASSETS_PATH + "wK.png", true)
+ make_piece(Vector2(4, 0), "res://pieces/King.gd", false)
+ make_piece(Vector2(4, 7), "res://pieces/King.gd", true)
Globals.white_king = matrix[7][4] # set the white king
Globals.black_king = matrix[0][4] # set the black king
-const topper_header = "┏━━━┳━━━┳━━━┳━━━┳━━━┳━━━┳━━━┳━━━┳━━━┓"
-const middle_header = "┣━━━╋━━━╋━━━╋━━━╋━━━╋━━━╋━━━╋━━━╋━━━┫"
-const middish_heads = "┗━━━╋━━━╋━━━╋━━━╋━━━╋━━━╋━━━╋━━━╋━━━┫"
-const bottom_header = "┗━━━┻━━━┻━━━┻━━━┻━━━┻━━━┻━━━┻━━━┻━━━┛"
-const smaller_heads = " ┗━━━┻━━━┻━━━┻━━━┻━━━┻━━━┻━━━┻━━━┛"
-const letter_header = " ┃ a ┃ b ┃ c ┃ d ┃ e ┃ f ┃ g ┃ h ┃"
-const ender = " ┃ "
-
-
-func print_matrix_pretty(mat = matrix): # print the matrix
- for j in range(8): # for each row
- var r = mat[j] # get the row
- if j == 0:
- print(topper_header) # print the top border
- else:
- print(middle_header) # print the middle border
- var row = "┃ " + str(8 - j) + " ┃ " # init the string
- for i in range(8): # for each column
- var c = r[i] # get the column
- if c: # if there is a piece
- row += c.mininame + ender # add the shortname
- else: # if there is no piece
- row += " " + ender # add 00
- print(row) # print the string
- print(middish_heads)
- print(letter_header)
- print(smaller_heads)
-
-
func check_for_circle(position: Vector2): # check for a circle, validating movement
return background_matrix[position.x][position.y].circle_on
@@ -291,24 +269,34 @@ func check_for_frame(position: Vector2): # check for a frame, validating taking
func square_clicked(position: Vector2): # square clicked
+ if promoting != null:
+ return
var spot = matrix[position.y][position.x] # get the spot
if !spot or spot.white != Globals.turn: # spot is not a tile or spot is not turn color
- if !last_clicked: # last clicked is null, so this is pointless
+ if !is_instance_valid(last_clicked): # last clicked is null, so this is pointless
return
if check_for_frame(position): # takeable
- last_clicked.take(matrix[position.y][position.x]) # eat
- turn_over()
+ handle_take(position)
if check_for_circle(position): # see if theres a circle at the position
handle_move(position) # move
last_clicked.clear_clicked() # remove the circles
last_clicked = null # set it to null
elif last_clicked != spot: # we got a new piece (or pawn) clicked
- if last_clicked: # remove the circles
+ if is_instance_valid(last_clicked): # remove the circles
last_clicked.clear_clicked()
last_clicked = spot # set it to the new spot
spot.clicked() # tell the piece shit happeend
+func handle_take(position):
+ if last_clicked is Pawn:
+ var pawn = last_clicked
+ if check_promote(pawn, position, "take"):
+ return
+ last_clicked.take(matrix[position.y][position.x]) # eat
+ turn_over()
+
+
func handle_move(position):
if last_clicked is King and last_clicked.can_castle:
for i in range(len(last_clicked.can_castle)):
@@ -320,19 +308,32 @@ func handle_move(position):
castle_data[1].override_moveto = false
turn_over()
return
- if last_clicked is Pawn and last_clicked.enpassant:
- for i in range(len(last_clicked.enpassant)):
- var en_passant_data = last_clicked.enpassant[i]
- if en_passant_data[0] == position:
- en_passant_data[1].took() # kill the unfortunate
- last_clicked.passant(en_passant_data[0])
- turn_over()
- return
+ if last_clicked is Pawn:
+ var pawn = last_clicked
+ if pawn.enpassant:
+ for i in range(len(pawn.enpassant)):
+ var en_passant_data = pawn.enpassant[i]
+ if en_passant_data[0] == position:
+ en_passant_data[1].took() # kill the unfortunate
+ pawn.passant(en_passant_data[0])
+ turn_over()
+ return
+ if check_promote(pawn, position):
+ return
last_clicked.moveto(position)
turn_over()
+func check_promote(pawn, position, calltype: String = "move"):
+ if pawn.can_promote(position):
+ pawn.promote(position, calltype)
+ promoting = position
+ return true
+ return false
+
+
func turn_over():
+ promoting = null
Events.emit_signal("just_before_turn_over")
Globals.add_turn()
Globals.turn = not Globals.turn
@@ -349,11 +350,32 @@ func clear_fx(): # clear the circles
piece.set_frame(false) # clear the frame
-func _input(event): # input
- if event.is_action_released("debug"): # if debug
- print_matrix_pretty() # print the matrix
- if event.is_action_released("kill"):
- if last_clicked:
- last_clicked.took() # kill the piece
- last_clicked = null
- clear_fx() # clear the circles
+func _on_outoftime(who):
+ if who == "white":
+ win("black")
+ else:
+ win("white")
+
+
+func _on_turn_over():
+ var matstr: String = mat2str()
+ if !history_matrixes.has(matstr):
+ history_matrixes[matstr] = 1
+ else:
+ history_matrixes[matstr] += 1
+ Globals.checking_piece = null # reset checking_piece
+ Globals.in_check = false # reset in_check
+ matrix[8] = default_metadata.duplicate() # add the metadata to the matrix
+ matrix[8].turn = Globals.turn
+ check_in_check(true) # check if in_check
+ if !can_move():
+ if Globals.in_check:
+ var winner := "black" if Globals.turn else "white"
+ status_label.text("%s won the game by checkmate" % winner)
+ win(winner)
+ else:
+ status_label.text("stalemate")
+ drawed()
+ elif threefoldrepetition():
+ status_label.text("draw by threefold repetition")
+ drawed()