-
Notifications
You must be signed in to change notification settings - Fork 2
/
castle_status.go
151 lines (135 loc) · 3.46 KB
/
castle_status.go
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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package chess_engine
import (
"strings"
)
type CastleStatus int8
const (
Both CastleStatus = iota
None
Kingside
Queenside
)
func (cs CastleStatus) String(c Color) string {
type p struct {
CastleStatus
Color
}
switch (p{cs, c}) {
case p{Both, Black}:
return "kq"
case p{Both, White}:
return "KQ"
case p{Kingside, Black}:
return "k"
case p{Kingside, White}:
return "K"
case p{Queenside, Black}:
return "q"
case p{Queenside, White}:
return "Q"
}
if cs == None {
return "-"
}
return ""
}
func (cs CastleStatus) CanCastleQueenside() bool {
return cs == Queenside || cs == Both
}
func (cs CastleStatus) CanCastleKingside() bool {
return cs == Kingside || cs == Both
}
func (cs CastleStatus) Remove(remove CastleStatus) CastleStatus {
if remove == Kingside {
if cs == Both || cs == Queenside {
return Queenside
}
} else if remove == Queenside {
if cs == Both || cs == Kingside {
return Kingside
}
}
return None
}
func ParseCastleStatus(castleStr string) (CastleStatus, CastleStatus) {
black, white := None, None
if strings.Contains(castleStr, "k") {
black = Kingside
}
if strings.Contains(castleStr, "q") {
if black == Kingside {
black = Both
} else {
black = Queenside
}
}
if strings.Contains(castleStr, "K") {
white = Kingside
}
if strings.Contains(castleStr, "Q") {
if white == Kingside {
white = Both
} else {
white = Queenside
}
}
return white, black
}
type CastleStatuses struct {
White CastleStatus
Black CastleStatus
}
func NewCastleStatuses(white, black CastleStatus) CastleStatuses {
return CastleStatuses{white, black}
}
func NewCastleStatusesFromString(str string) CastleStatuses {
return NewCastleStatuses(None, None).Parse(str)
}
func (cs CastleStatuses) CanCastleQueenside(color Color) bool {
if color == White {
return cs.White.CanCastleQueenside()
}
return cs.Black.CanCastleQueenside()
}
func (cs CastleStatuses) CanCastleKingside(color Color) bool {
if color == White {
return cs.White.CanCastleKingside()
}
return cs.Black.CanCastleKingside()
}
func (cs CastleStatuses) Parse(castleStr string) CastleStatuses {
cs.White, cs.Black = ParseCastleStatus(castleStr)
return cs
}
func (cs CastleStatuses) ApplyMove(move *Move, movingPiece Piece) CastleStatuses {
if movingPiece == BlackRook && move.From == A8 {
return NewCastleStatuses(cs.White, cs.Black.Remove(Queenside))
} else if movingPiece == BlackRook && move.From == H8 {
return NewCastleStatuses(cs.White, cs.Black.Remove(Kingside))
} else if movingPiece == WhiteRook && move.From == A1 {
return NewCastleStatuses(cs.White.Remove(Queenside), cs.Black)
} else if movingPiece == WhiteRook && move.From == H1 {
return NewCastleStatuses(cs.White.Remove(Kingside), cs.Black)
} else if movingPiece == BlackKing {
return NewCastleStatuses(cs.White, None)
} else if movingPiece == WhiteKing {
return NewCastleStatuses(None, cs.Black)
} else if move.To == A8 {
return NewCastleStatuses(cs.White, cs.Black.Remove(Queenside))
} else if move.To == H8 {
return NewCastleStatuses(cs.White, cs.Black.Remove(Kingside))
} else if move.To == A1 {
return NewCastleStatuses(cs.White.Remove(Queenside), cs.Black)
} else if move.To == H1 {
return NewCastleStatuses(cs.White.Remove(Kingside), cs.Black)
}
return cs
}
func (cs CastleStatuses) String() string {
if cs.White == None {
return cs.Black.String(Black)
} else if cs.Black == None {
return cs.White.String(White)
}
return cs.White.String(White) + cs.Black.String(Black)
}