|
|
|
@ -20,24 +20,24 @@ var LCW = Kicks{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Try all possible kicks
|
|
|
|
|
func (ks Kicks) Try(rot Rotation, reverse bool, p Placement, f Field) (np Placement) {
|
|
|
|
|
orot := (rot + 3)%4
|
|
|
|
|
if reverse { // for going backwards, you start from one more
|
|
|
|
|
rot--
|
|
|
|
|
orot = (rot + 1)%4
|
|
|
|
|
func (ks Kicks) Try(p, np Placement, f Field) Placement {
|
|
|
|
|
direction := (np.Rot - p.Rot + 4) % 4
|
|
|
|
|
rot := np.Rot
|
|
|
|
|
factor := 1
|
|
|
|
|
if direction == Spawn {
|
|
|
|
|
factor = 0
|
|
|
|
|
}
|
|
|
|
|
if direction == CounterClockwise {
|
|
|
|
|
rot = (rot + 1) % 4
|
|
|
|
|
factor = -1
|
|
|
|
|
}
|
|
|
|
|
x, y := np.X, np.Y
|
|
|
|
|
for _, k := range ks[rot] {
|
|
|
|
|
np = p
|
|
|
|
|
x, y := k.X, k.Y
|
|
|
|
|
if reverse {
|
|
|
|
|
x, y = -x, -y
|
|
|
|
|
}
|
|
|
|
|
np.X, np.Y = p.X+x, p.Y+y
|
|
|
|
|
np.X, np.Y = x + k.X * factor, y + k.Y * factor
|
|
|
|
|
if !np.Collide(f) {
|
|
|
|
|
return np
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
p.Rot = orot
|
|
|
|
|
return p
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -48,12 +48,6 @@ func (p Placement) Floor(f Field) bool {
|
|
|
|
|
return fp.Collide(f)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// CW checks if the rotation from r to nr is a Clockwise rotation
|
|
|
|
|
func (r Rotation) CW(nr Rotation) bool {
|
|
|
|
|
r += 4
|
|
|
|
|
return (r - nr)%4 == 1 // if nr is 1 modulo 4 higher than r, it is a CW rotation
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Move tries the move indicated by the parameters, applies kicks to fix when it doesn't work,
|
|
|
|
|
// and returns if the piece is on the floor or topping out
|
|
|
|
|
func (p Placement) Move(f Field, rot Rotation, x, y int) (np Placement, floor, topout bool) {
|
|
|
|
@ -67,12 +61,13 @@ func (p Placement) Move(f Field, rot Rotation, x, y int) (np Placement, floor, t
|
|
|
|
|
// start handling kicks
|
|
|
|
|
switch p.piece {
|
|
|
|
|
case IPiece:
|
|
|
|
|
np = LCW.Try(rot, np.Rot.CW(rot), np, f)
|
|
|
|
|
np = LCW.Try(p, np, f)
|
|
|
|
|
case JPiece, SPiece, ZPiece, TPiece, LPiece:
|
|
|
|
|
np = K3CW.Try(rot, np.Rot.CW(rot), np, f)
|
|
|
|
|
np = K3CW.Try(p, np, f)
|
|
|
|
|
default:
|
|
|
|
|
np = p
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
np = p // last resort reset p
|
|
|
|
|
if np.Floor(f) && np.Y < 0 {
|
|
|
|
|
return np, true, true
|
|
|
|
|
}
|
|
|
|
|