online multiplayer chess game (note server currently down)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
class_name Move
extends Resource

enum CHECKTYPES { NONE, CHECK, CHECKMATE }
var generated_from := ""
var piece := -1
var move_kind: MoveKind
var promotion := -1
# var annotation := "" # later
var check_type := 0
var is_capture := false


func _init(newpiece: int, newmove, capture := false) -> void:
	piece = newpiece
	is_capture = capture
	move_kind = MoveKind.new(newmove)


static func castle_type(type: String) -> int:
	return MoveKind.CASTLETYPES.QUEEN_SIDE if type == "O-O-O" else MoveKind.CASTLETYPES.KING_SIDE


func set_check_type(type: String) -> Move:
	match type:
		"+":
			check_type = CHECKTYPES.CHECK
		"#":
			check_type = CHECKTYPES.CHECKMATE
		_:
			check_type = CHECKTYPES.NONE
	return self


func compile() -> String:  # compiles the structure to a san
	var res := ""
	match move_kind.type:
		MoveKind.CASTLE:
			res += move_kind.to_str()
		MoveKind.NORMAL:
			res += to_str(piece)
			res += Utils.to_algebraic(move_kind.data[0])
			res += "x" if is_capture else ""
			res += Utils.to_algebraic(move_kind.data[1])
			res += "=" + to_str(promotion) if promotion != -1 else ""
			match check_type:
				CHECKTYPES.CHECK:
					res += "+"
				CHECKTYPES.CHECKMATE:
					res += "#"
	return res.strip_edges()


static func to_str(type: int) -> String:
	return " NBRQK"[type].strip_edges()  # if its a pawn, return nothing


## tests
#	print(Utils.to_algebraic(make_long(SanParse.parse("e4").move_kind.data, false, SanParser.PAWN)[0]) == "e2")
# 	print(Utils.to_algebraic(make_long(SanParse.parse("Nbc3").move_kind.data, false, SanParser.KNIGHT)[0]) == "b1")
# 	print(Utils.to_algebraic(make_long(SanParse.parse("N1c3").move_kind.data, false, SanParser.KNIGHT)[0]) == "b1")


# 	print(Utils.to_algebraic(make_long(SanParse.parse("exe4").move_kind.data, false, SanParser.PAWN)[0]) == "e2")
# 	print(Utils.to_algebraic(make_long(SanParse.parse("Nbxc3").move_kind.data, false, SanParser.KNIGHT)[0]) == "b1")
# 	print(Utils.to_algebraic(make_long(SanParse.parse("N1xc3").move_kind.data, false, SanParser.KNIGHT)[0]) == "b1")
### fix short san
func make_long() -> Move:
	if move_kind.type == MoveKind.CASTLE:
		return self
	var newvecs: PoolVector2Array = []

	var vectors = move_kind.data

	if Piece.is_on_board(vectors[0]):  # [0] is the only one with -1(s) possible
		return self

	if is_capture:
		newvecs.append(long_helper(vectors[0], true, false, vectors[1]))
	else:
		newvecs.append(long_helper(vectors[0], false, true, vectors[1]))

	if newvecs.empty():
		Log.error("cruddlesticks")
		return self
	newvecs.append(vectors[1])

	move_kind.data = newvecs
	return self


func long_helper(vec: Vector2, attack: bool, move: bool, touch: Vector2):
	if vec.y == -1 and vec.x != -1:
		for y in range(8):
			var spot = Piece.at_pos(Vector2(vec.x, y))
			if long_helper_helper(spot, touch, attack, move):
				return Vector2(vec.x, y)
	elif vec.x == -1 and vec.y != -1:
		for x in range(8):
			var spot = Piece.at_pos(Vector2(x, vec.y))
			if long_helper_helper(spot, touch, attack, move):
				return Vector2(x, vec.y)
	elif vec == Vector2(-1, -1):
		for x in range(8):
			for y in range(8):
				var spot = Piece.at_pos(Vector2(x, y))
				if long_helper_helper(spot, touch, attack, move):
					return Vector2(x, y)


func long_helper_helper(spot, touch, attack, move):
	return (
		Utils.spotispiece(piece, spot)
		and spot.white == Globals.turn
		and spot.can_touch(touch, attack, move)
	)


class MoveKind:
	extends Resource
	enum CASTLETYPES { NONE, QUEEN_SIDE, KING_SIDE }
	enum { NONE, NORMAL, CASTLE }
	var type := 0
	var data  # string OR array

	func _init(something):
		if typeof(something) == TYPE_ARRAY and len(something) == 2:
			type = NORMAL
			data = PoolVector2Array(something)
		elif typeof(something) == TYPE_INT:
			type = CASTLE
			data = something
		else:
			assert(false)

	func to_str() -> String:
		return "O-O-O" if data == CASTLETYPES.QUEEN_SIDE else "O-O"