/
settings_decorator.go
106 lines (89 loc) · 2.29 KB
/
settings_decorator.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
package robots
import (
"github.com/golang/protobuf/proto"
proto_game "github.com/dnovikoff/mahjong-api/genproto/public/game"
)
func DefaultSettings() *proto_game.Settings {
return &proto_game.Settings{
AutoTempai: true,
AutoEndGame: true,
}
}
type SuggestFunc func(*proto_game.Suggest)
func NoChi(s *proto_game.Suggest) {
NoLeft(s)
NoRight(s)
NoCenter(s)
}
func NoLeft(s *proto_game.Suggest) {
s.ChiLeft = false
}
func NoRight(s *proto_game.Suggest) {
s.ChiRight = false
}
func NoCenter(s *proto_game.Suggest) {
s.ChiCenter = false
}
func NoPon(s *proto_game.Suggest) {
s.Pon = false
}
func NoKan(s *proto_game.Suggest) {
s.Kan = false
}
type Settings struct {
proto_game.Settings
Remove []SuggestFunc
}
// SettingsDecorator is a decorator, that could accept wins.
// Also could protect other implementations from making particular calls.
type SettingsDecorator struct {
Robot
Settings Settings
}
func NewSettingsDecorator(c Robot, f ...SuggestFunc) *SettingsDecorator {
return &SettingsDecorator{c, Settings{Remove: f}}
}
func (d *SettingsDecorator) Update(x *proto_game.Settings) {
d.Settings.Settings = *x
}
func ApplySettings(req *proto_game.Server, settings *proto_game.Settings) *proto_game.Client {
x := applySettings(req, settings)
if x != nil {
x.SuggestId = req.GetSuggest().GetSuggestId()
}
return x
}
func applySettings(req *proto_game.Server, settings *proto_game.Settings) *proto_game.Client {
if req.Suggest == nil {
return nil
}
s := req.GetSuggest()
switch {
case settings.GetAutoWin() && s.GetWin():
return &proto_game.Client{
OneofClient: &proto_game.Client_Win{true},
}
case settings.GetDropTsumo() && s.GetDropMask() != 0,
settings.GetAutoTempai() && s.GetNoten(),
settings.GetAutoEndGame() && s.GetContinueGame():
return &proto_game.Client{
OneofClient: &proto_game.Client_Cancel{true},
}
}
return nil
}
func (d *SettingsDecorator) Request(req *proto_game.Server) *proto_game.Client {
if req.Suggest == nil || req.GetSuggest().GetCanceled() {
return d.Robot.Request(req)
}
applyResult := ApplySettings(req, &d.Settings.Settings)
if applyResult != nil {
d.Robot.Request(req)
return applyResult
}
cReq := proto.Clone(req).(*proto_game.Server)
for _, v := range d.Settings.Remove {
v(cReq.Suggest)
}
return d.Robot.Request(cReq)
}