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
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) -> void:
	match type:
		"+":
			check_type = CHECKTYPES.CHECK
		"#":
			check_type = CHECKTYPES.CHECKMATE
		_:
			check_type = CHECKTYPES.NONE


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 += Utils.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 += "=" + Utils.to_str(promotion) if promotion != -1 else ""
			match check_type:
				CHECKTYPES.CHECK:
					res += "+"
				CHECKTYPES.CHECKMATE:
					res += "#"
	return res.strip_edges()


## 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():
	if move_kind.type == MoveKind.CASTLE:
		return
	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 vectors

	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
	newvecs.append(vectors[1])

	move_kind.data = newvecs


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"