/
move.go
150 lines (130 loc) · 2.98 KB
/
move.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
package take6
import "fmt"
const (
// 持ち駒を打つ 100~113
// 先手飛打
DROP_R1 = iota + 100
DROP_B1
DROP_G1
DROP_S1
DROP_N1
DROP_L1
DROP_P1
DROP_R2
DROP_B2
DROP_G2
DROP_S2
DROP_N2
DROP_L2
DROP_P2
DROP_ORIGIN = DROP_R1
DROP_TYPE_SIZE = DROP_P1 - DROP_ORIGIN
)
// Move - 指し手
//
// 17bit で表せるはず(^~^)
// pddddddddssssssss
//
// 1~8bit: 移動元
// 9~16bit: 移動先
// 17bit: 成
type Move uint32
// 0 は 投了ということにするぜ(^~^)
const ResignMove = Move(0)
func NewMoveValue() Move {
return Move(0)
}
// NewMoveValue2 - 初期値として 移動元マス、移動先マスを指定してください
func NewMoveValue2(src_sq uint32, dst_sq uint32) Move {
move := Move(0)
move = move.ReplaceSource(src_sq)
return move.ReplaceDestination(dst_sq)
}
// ToCode - SFEN の moves の後に続く指し手に使える文字列を返します
func (move Move) ToCode() string {
// 投了(^~^)
if uint32(move) == 0 {
return "resign"
}
str := make([]byte, 0, 5)
count := 0
// 移動元マス(Source square)
source_sq := move.GetSource()
switch source_sq {
case DROP_R1, DROP_R2:
str = append(str, 'R')
count = 1
case DROP_B1, DROP_B2:
str = append(str, 'B')
count = 1
case DROP_G1, DROP_G2:
str = append(str, 'G')
count = 1
case DROP_S1, DROP_S2:
str = append(str, 'S')
count = 1
case DROP_N1, DROP_N2:
str = append(str, 'N')
count = 1
case DROP_L1, DROP_L2:
str = append(str, 'L')
count = 1
case DROP_P1, DROP_P2:
str = append(str, 'P')
count = 1
default:
// Ignored
}
if count == 1 {
str = append(str, '+')
}
for count < 2 {
var sq byte // マス番号
if count == 0 {
// 移動元
sq = source_sq
} else if count == 1 {
// 移動先
sq = move.GetDestination()
} else {
panic(fmt.Errorf("LogicError: count=%d", count))
}
// 正常時は必ず2桁(^~^)
file := sq / 10
rank := sq % 10
// ASCII Code
// '0'=48, '9'=57, 'a'=97, 'i'=105
str = append(str, file+48)
str = append(str, rank+96)
// fmt.Printf("Debug: move=%d sq=%d count=%d file=%d rank=%d\n", uint32(move), sq, count, file, rank)
count += 1
}
return string(str)
}
// ReplaceSource - 移動元マス
func (move Move) ReplaceSource(sq uint32) Move {
return Move(uint32(move)&0xffffff00 | sq)
}
// ReplaceDestination - 移動先マス
func (move Move) ReplaceDestination(sq uint32) Move {
return Move(uint32(move)&0xffff00ff | (sq << 8))
}
// ReplacePromotion - 成
func (move Move) ReplacePromotion(promotion bool) Move {
if promotion {
return Move(uint32(move) | 0x00010000)
}
return Move(uint32(move) & 0xfffeffff)
}
// GetSource - 移動元マス
func (move Move) GetSource() byte {
return byte(uint32(move) & 0x000000ff)
}
// GetDestination - 移動元マス
func (move Move) GetDestination() byte {
return byte((uint32(move) >> 8) & 0x000000ff)
}
// GetPromotion - 成
func (move Move) GetPromotion() byte {
return byte((uint32(move) >> 9) & 0x00000001)
}