-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathchoose_card.go
151 lines (143 loc) · 4.66 KB
/
choose_card.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 main
import (
"fmt"
"log"
"github.com/pkg/errors"
)
func ChooseCard(state *State, npc bool) *Card {
var chosen Card
tmp := FilterCards(state)
// forの間一時的にコピーしたものから取り出す。
dealed := false
for {
if len(tmp) == 0 {
if !dealed {
dealed = true
// 出せるカードがないので追加で1枚引く。
fmt.Printf("\t> %v さんは出せるカードがないので1枚引きます。\n", state.Name())
ok := DealCards(state.NowPlayerIndex, 1, state)
if !ok {
fmt.Printf("\t> 山札がないので %v さんはカードを引くことができませんでした。スキップします。\n", state.Name())
return nil
}
continue
} else {
return nil
}
}
if developing && debug {
fmt.Printf("\t> %v さんの手札で出せるもの : %v\n", state.Name(), PrintCardsDescription(tmp))
}
if selected := SelectCard(state, tmp, npc); selected == nil {
return nil
} else {
chosen = *selected
}
if CheckCard(chosen, state) {
if !npc || developing && debug {
fmt.Printf(" > OK!\n")
}
break
}
if !npc || developing && debug {
fmt.Printf(" > NG!\n")
}
}
*state.Hand() = RemoveCard(*state.Hand(), chosen)
return &chosen
}
func FilterCards(state *State) []Card {
ret := make([]Card, 0, len(*state.Hand()))
for _, c := range *state.Hand() {
if CheckCard(c, state) {
if developing && debug {
log.Printf("%v -> %#v OK", state.Print(), c.Print())
}
ret = append(ret, c)
} else {
if developing && debug {
log.Printf("%v -> %#v NG", state.Print(), c.Print())
}
}
}
if developing && debug {
log.Printf("ret: %v", PrintCards(ret))
//log.Printf("%v", ret)
}
return ret
}
func CheckCard(chosen Card, state *State) bool {
// 選んだカードのチェック
if chosen.IsNum() {
if chosen.Color() == state.Color {
if developing && debug {
log.Printf("c:%v %v, s.c:%v -> %v", chosen.Print(), chosen.Color(), state.Color, chosen.Color() == state.Color)
}
return true
}
if chosen.Num() == state.Number {
if developing && debug {
log.Printf("c:%v %v, s.c:%v -> %v", chosen.Print(), chosen.Color(), state.Color, chosen.Num() == state.Number)
}
return true
}
if developing && debug {
log.Printf("c:%v %v, s.c:%v -> false", chosen.Print(), chosen.Color(), state.Color)
}
}
if chosen.IsAction() {
action := chosen.ActionType() + 100
if developing && debug {
log.Printf("chosen.Action: %v, action: %v", chosen.ActionType(), action)
}
switch action {
case WILD___: // 場のカードがどのカードであっても出せる。
if state.LastCard == nil { // 場札 nilの時は直前の人がスキップしている。nil出ないときDiscardの末尾。
return true
}
if developing && debug {
l := peek(&state.Discard)
log.Printf("c:%v --, s:%v -> true", chosen.Print(), l.Print())
}
return true
case DRAW4__:
if state.LastCard == nil { // 場札 nilの時は直前の人がスキップしている。nil出ないときDiscardの末尾。
return true //
} else {
// スキップされていないとき。
// チャレンジルールはここではないところで判定する。
// 前の人のカードがドローカードの時、ルール毎に出せるかどうか決まる。
discard := peek(&state.Discard)
action := discard.ActionType() + 100
if action == DRAW2__ && action == DRAW2__ {
if state.Rule.RequireMatchingDrawTwoForChallenge && action == DRAW2__ { // R.jua.05 ドロー2にドロー4が重ねられたとき、チャレンジするためには手札に場の色と同じ色のドロー2を必要とする。
if developing && debug {
log.Printf("RequireMatchingDrawTwoForChallenge: %v : R.jua.05 ドロー2にドロー4が重ねられたとき、チャレンジするためには手札に場の色と同じ色のドロー2を必要とする。", state.Rule.RequireMatchingDrawTwoForChallenge)
}
return state.Color == discard.Color()
}
return state.Rule.StackDrawCards // R.official-app.07 ドロー2にドロー2やドロー4、ドロー4にドロー4を重ねることができる。
}
return true // ドローカード以外は場のカードがどのカードであっても出せる。
}
case DRAW2__:
fallthrough
case REVERSE:
fallthrough
case SKIP___:
fallthrough
case DISCARD:
if state.Color == -1 {
return true
}
return chosen.Color() == state.Color // 色が一致する必要がある。
default:
// 来ないはず。
if developing && debug {
log.Printf("chosen: %v", chosen)
}
panic(errors.Errorf("%v", "バグ"))
}
}
return false // だめ。
}