@@ -3,7 +3,7 @@ use std::marker::ConstParamTy;
3
3
use std:: ops:: Index ;
4
4
use std:: sync:: Arc ;
5
5
use std:: { fmt:: Display , fs:: read_to_string} ;
6
- use std:: { matches, mem} ;
6
+ use std:: { matches, mem, println } ;
7
7
8
8
use async_trait:: async_trait;
9
9
use discord:: escape_string;
@@ -32,12 +32,18 @@ pub enum CardData {
32
32
}
33
33
34
34
impl CardData {
35
- fn blanks ( & self ) -> usize {
35
+ fn blanks_black ( & self ) -> usize {
36
36
match * self {
37
37
CardData :: Raw ( ref s) => s. chars ( ) . filter ( |& c| c == '_' ) . count ( ) . max ( 1 ) ,
38
38
CardData :: Full { pick, .. } => pick,
39
39
}
40
40
}
41
+ fn blanks_white ( & self ) -> usize {
42
+ match * self {
43
+ CardData :: Raw ( ref s) => s. chars ( ) . filter ( |& c| c == '_' ) . count ( ) ,
44
+ CardData :: Full { pick, .. } => pick,
45
+ }
46
+ }
41
47
fn extra_blanks ( & self ) -> usize {
42
48
match * self {
43
49
CardData :: Raw ( ref s) => {
@@ -79,82 +85,107 @@ pub struct Card<const TYPE: CardType> {
79
85
card : u32 ,
80
86
}
81
87
82
- impl Card < { CardType :: Black } > {
88
+ impl < const C : CardType > Card < C > {
89
+ pub fn is_filled (
90
+ self ,
91
+ packs : & Packs ,
92
+ white : impl Iterator < Item = Option < Card < { CardType :: White } > > > ,
93
+ ) -> bool {
94
+ let mut blanks = match C {
95
+ CardType :: White => packs[ self ] . blanks_white ( ) ,
96
+ CardType :: Black => packs[ self ] . blanks_black ( ) ,
97
+ } ;
98
+ let mut cards = 0 ;
99
+
100
+ for card in white {
101
+ match card {
102
+ Some ( card) => {
103
+ // NOTE: this already accounts for recursiveness
104
+ blanks += packs[ card] . blanks_white ( ) ;
105
+ cards += 1 ;
106
+ }
107
+ None => return false ,
108
+ }
109
+ }
110
+
111
+ cards == blanks
112
+ }
83
113
pub fn fill (
84
114
self ,
85
115
packs : & Packs ,
86
- mut white : impl Iterator < Item = Option < Card < { CardType :: White } > > > ,
116
+ white : & mut impl Iterator < Item = Option < Card < { CardType :: White } > > > ,
87
117
) -> String {
88
- let prompt = escape_string ( & packs[ self ] . to_string ( ) . replace ( "\\ n" , "\n " ) ) ;
118
+ let prompt: String = packs[ self ] . to_string ( ) . into ( ) ;
119
+ let prompt = match C {
120
+ CardType :: White => prompt. trim_end_matches ( '.' ) . into ( ) ,
121
+ CardType :: Black => escape_string ( & prompt. replace ( "\\ n" , "\n " ) ) ,
122
+ } ;
89
123
90
124
let mut prompt_slice = prompt. as_str ( ) ;
91
125
let mut filled = String :: with_capacity ( prompt. len ( ) ) ;
92
126
93
127
while let Some ( pos) = prompt_slice. find ( '_' ) {
94
128
match white. next ( ) {
95
129
Some ( Some ( c) ) => {
96
- filled. push_str ( & prompt_slice[ ..pos - 1 ] ) ;
97
-
98
- // TODO: recursive
99
- filled. push_str ( format ! ( "``{}``" , packs[ c] ) . as_str ( ) ) ;
130
+ match C {
131
+ CardType :: White => {
132
+ // trim spaces around blank
133
+ filled. push_str ( prompt_slice[ ..pos] . trim_end ( ) ) ;
134
+ prompt_slice = prompt_slice[ pos + 1 ..] . trim_start ( ) ;
135
+
136
+ filled. push_str ( format ! ( "`` ``{}`` ``" , c. fill( packs, white) ) . as_str ( ) ) ;
137
+ }
138
+ CardType :: Black => {
139
+ // also remove backslash
140
+ filled. push_str ( & prompt_slice[ ..pos - 1 ] ) ;
141
+ prompt_slice = & prompt_slice[ pos + 1 ..] ;
142
+
143
+ filled. push_str ( format ! ( "``{}``" , c. fill( packs, white) ) . as_str ( ) ) ;
144
+ }
145
+ }
100
146
}
101
147
_ => {
102
148
filled. push_str ( & prompt_slice[ ..pos + 1 ] ) ;
149
+ prompt_slice = & prompt_slice[ pos + 1 ..] ;
103
150
}
104
151
}
105
- prompt_slice = & prompt_slice[ pos + 1 ..] ;
106
152
}
107
153
filled. push_str ( prompt_slice) ;
108
154
109
- let extra_cards = packs[ self ] . extra_blanks ( ) ;
110
- for _ in 0 ..extra_cards {
111
- if let Some ( Some ( c) ) = white. next ( ) {
112
- // TODO: recursive
113
- filled. push_str ( format ! ( " ``{}``" , packs[ c] ) . as_str ( ) ) ;
155
+ match C {
156
+ CardType :: White => {
157
+ // remove empty quotes
158
+ filled = filled
159
+ . trim_start_matches ( & [ ' ' , '`' ] )
160
+ . trim_end_matches ( & [ ' ' , '`' ] )
161
+ . into ( ) ;
114
162
}
115
- }
116
-
117
- filled
118
- }
119
- pub fn is_filled (
120
- self ,
121
- packs : & Packs ,
122
- white : impl Iterator < Item = Option < Card < { CardType :: White } > > > ,
123
- ) -> bool {
124
- let mut blanks = packs[ self ] . blanks ( ) ;
125
- let mut cards = 0 ;
126
-
127
- for card in white {
128
- match card {
129
- Some ( card) => {
130
- // NOTE: this already accounts for recursiveness
131
- blanks += packs[ card] . blanks ( ) ;
132
- cards += 1 ;
163
+ CardType :: Black => {
164
+ let extra_cards = packs[ self ] . extra_blanks ( ) ;
165
+ for _ in 0 ..extra_cards {
166
+ if let Some ( Some ( c) ) = white. next ( ) {
167
+ filled. push_str ( format ! ( " ``{}``" , c. fill( packs, white) ) . as_str ( ) ) ;
168
+ }
133
169
}
134
- None => return false ,
135
170
}
136
171
}
137
172
138
- cards == blanks
173
+ println ! ( "{}" , filled) ;
174
+ filled
139
175
}
140
176
}
141
177
142
178
pub type Pack = Arc < ( String , PackData ) > ;
143
179
pub struct Packs ( Vec < Pack > ) ;
144
180
145
- impl Index < Card < { CardType :: Black } > > for Packs {
181
+ impl < const C : CardType > Index < Card < C > > for Packs {
146
182
type Output = CardData ;
147
183
148
- fn index ( & self , index : Card < { CardType :: Black } > ) -> & Self :: Output {
149
- & self . 0 [ index. pack as usize ] . 1 . black [ index. card as usize ]
150
- }
151
- }
152
-
153
- impl Index < Card < { CardType :: White } > > for Packs {
154
- type Output = CardData ;
155
-
156
- fn index ( & self , index : Card < { CardType :: White } > ) -> & Self :: Output {
157
- & self . 0 [ index. pack as usize ] . 1 . white [ index. card as usize ]
184
+ fn index ( & self , index : Card < C > ) -> & Self :: Output {
185
+ match C {
186
+ CardType :: White => & self . 0 [ index. pack as usize ] . 1 . white [ index. card as usize ] ,
187
+ CardType :: Black => & self . 0 [ index. pack as usize ] . 1 . black [ index. card as usize ] ,
188
+ }
158
189
}
159
190
}
160
191
@@ -355,7 +386,7 @@ impl Game for CAH {
355
386
}
356
387
357
388
let players: Vec < _ > = s. players ( ) . collect ( ) ;
358
- let packs = Packs (
389
+ let mut packs = Packs (
359
390
s. packs
360
391
. 0
361
392
. iter ( )
@@ -388,7 +419,7 @@ impl Game for CAH {
388
419
389
420
let mut players = players. into_iter ( ) . map ( Player :: new) . collect :: < Vec < _ > > ( ) ;
390
421
391
- let prompt = match s . packs . draw_black ( ) {
422
+ let prompt = match packs. draw_black ( ) {
392
423
Some ( c) => c,
393
424
None => {
394
425
return ActionResponse :: Error ( GameMessage :: new (
@@ -402,7 +433,7 @@ impl Game for CAH {
402
433
} ;
403
434
404
435
for player in players. iter_mut ( ) {
405
- if !player. draw ( & mut s . packs , s. cards as usize , prompt) {
436
+ if !player. draw ( & mut packs, s. cards as usize , prompt) {
406
437
return ActionResponse :: Error ( GameMessage :: new (
407
438
vec ! [ Field :: new(
408
439
"Error" ,
@@ -535,6 +566,26 @@ impl Game for CAH {
535
566
serde_json:: from_str( read_to_string( "cards/eppgroep.json" ) . unwrap( ) . as_str( ) )
536
567
. unwrap( ) ,
537
568
) ) ,
569
+ Arc :: new( (
570
+ "Modifiers" . into( ) ,
571
+ serde_json:: from_str( read_to_string( "cards/modifiers.json" ) . unwrap( ) . as_str( ) )
572
+ . unwrap( ) ,
573
+ ) ) ,
574
+ Arc :: new( (
575
+ "Modifiers" . into( ) ,
576
+ serde_json:: from_str( read_to_string( "cards/modifiers.json" ) . unwrap( ) . as_str( ) )
577
+ . unwrap( ) ,
578
+ ) ) ,
579
+ Arc :: new( (
580
+ "Modifiers" . into( ) ,
581
+ serde_json:: from_str( read_to_string( "cards/modifiers.json" ) . unwrap( ) . as_str( ) )
582
+ . unwrap( ) ,
583
+ ) ) ,
584
+ Arc :: new( (
585
+ "Modifiers" . into( ) ,
586
+ serde_json:: from_str( read_to_string( "cards/modifiers.json" ) . unwrap( ) . as_str( ) )
587
+ . unwrap( ) ,
588
+ ) ) ,
538
589
] ) ,
539
590
selected_packs : vec ! [ 0 ] ,
540
591
bots : 0 ,
0 commit comments