1
- import { CLUE } from '../../../constants.js' ;
2
1
import { CLUE_INTERP , LEVEL } from '../h-constants.js' ;
3
2
import { cardTouched } from '../../../variants.js' ;
4
3
import { clue_safe } from './clue-safe.js' ;
5
4
import { find_fix_clues } from './fix-clues.js' ;
6
5
import { evaluate_clue , get_result } from './determine-clue.js' ;
7
- import { determine_focus , stall_severity , valuable_tempo_clue } from '../hanabi-logic.js' ;
6
+ import { determine_focus , valuable_tempo_clue } from '../hanabi-logic.js' ;
8
7
import { cardValue , isTrash , visibleFind } from '../../../basics/hanabi-util.js' ;
9
8
import { find_clue_value } from '../action-helper.js' ;
10
9
@@ -160,9 +159,6 @@ export function find_clues(game, giver = game.state.ourPlayerIndex, early_exits
160
159
} ;
161
160
logger . info ( 'result,' , JSON . stringify ( result_log ) , find_clue_value ( Object . assign ( result , { remainder } ) ) ) ;
162
161
163
- /** @type {typeof CLUE_INTERP[keyof typeof CLUE_INTERP] } */
164
- let clue_interp ;
165
-
166
162
if ( ( /** @type {any } */ ( [ CLUE_INTERP . SAVE , CLUE_INTERP . CM_5 , CLUE_INTERP . CM_TRASH ] ) . includes ( hypo_game . moveHistory . at ( - 1 ) . move ) ) ) {
167
163
if ( chop && focused_card . rank === 2 ) {
168
164
const copies = visibleFind ( state , player , focused_card ) ;
@@ -174,72 +170,55 @@ export function find_clues(game, giver = game.state.ourPlayerIndex, early_exits
174
170
}
175
171
}
176
172
177
- if ( game . level < LEVEL . CONTEXT || clue . result . avoidable_dupe == 0 ) {
173
+ if ( game . level < LEVEL . CONTEXT || clue . result . avoidable_dupe == 0 )
178
174
saves . push ( Object . assign ( clue , { game : hypo_game , playable : playables . length > 0 , cm : chop_moved , safe } ) ) ;
179
- clue_interp = CLUE_INTERP . SAVE ;
180
- }
181
- else {
175
+ else
182
176
logger . highlight ( 'yellow' , `${ logClue ( clue ) } save results in avoidable potential duplication` ) ;
183
- }
184
177
}
185
178
186
- const focus_known_bluff = hypo_game . common . waiting_connections . some ( c => {
187
- return c . connections [ 0 ] . bluff && c . focused_card . order == focused_card . order ;
188
- } ) ;
189
- // Clues where the focus isn't playable but may be assumed playable or that cause chop moves aren't plays/stalls
190
- if ( ( playables . length > 0 && ! playables . some ( ( { card } ) => card . order === focused_card . order ) && ! focus_known_bluff ) ||
191
- ( playables . length === 0 && chop_moved . length > 0 ) ||
192
- isTrash ( state , player , focused_card , focused_card . order ) ) {
193
- logger . highlight ( 'yellow' , 'invalid play clue' ) ;
179
+ if ( ! safe )
194
180
continue ;
195
- }
196
181
197
- if ( playables . length > 0 ) {
198
- if ( safe ) {
199
- const { tempo, valuable } = valuable_tempo_clue ( game , clue , playables , focused_card ) ;
182
+ switch ( hypo_game . moveHistory . at ( - 1 ) . move ) {
183
+ case CLUE_INTERP . CM_TEMPO : {
184
+ const { tempo, valuable } = valuable_tempo_clue ( game , clue , clue . result . playables , focused_card ) ;
185
+
200
186
if ( tempo && ! valuable ) {
187
+ logger . info ( 'tempo clue chop move' , logClue ( clue ) ) ;
201
188
stall_clues [ 1 ] . push ( clue ) ;
202
- clue_interp = CLUE_INTERP . CM_TEMPO ;
203
- }
204
- else if ( game . level < LEVEL . CONTEXT || clue . result . avoidable_dupe == 0 ) {
205
- play_clues [ target ] . push ( clue ) ;
206
- clue_interp = CLUE_INTERP . PLAY ;
207
189
}
208
190
else {
209
- logger . highlight ( 'yellow ', ` ${ logClue ( clue ) } results in avoidable potential duplication` ) ;
191
+ logger . info ( 'clue ', logClue ( clue ) , tempo , valuable ) ;
210
192
}
193
+ break ;
211
194
}
212
- else {
213
- logger . highlight ( 'yellow' , `${ logClue ( clue ) } is an unsafe play clue` ) ;
214
- }
215
- }
216
- // Stall clues
217
- else if ( stall_severity ( state , common , giver ) > 0 && safe ) {
218
- if ( clue . type === CLUE . RANK && clue . value === 5 && ! focused_card . clued ) {
195
+ case CLUE_INTERP . PLAY :
196
+ if ( clue . result . playables . length === 0 )
197
+ continue ;
198
+
199
+ if ( game . level < LEVEL . CONTEXT || clue . result . avoidable_dupe == 0 )
200
+ play_clues [ target ] . push ( clue ) ;
201
+ else
202
+ logger . highlight ( 'yellow' , `${ logClue ( clue ) } results in avoidable potential duplication` ) ;
203
+ break ;
204
+
205
+ case CLUE_INTERP . STALL_5 :
219
206
logger . info ( '5 stall' , logClue ( clue ) ) ;
220
207
stall_clues [ 0 ] . push ( clue ) ;
221
- clue_interp = CLUE_INTERP . STALL_5 ;
222
- }
223
- else if ( player . thinksLocked ( state , giver ) && chop ) {
208
+ break ;
209
+
210
+ case CLUE_INTERP . STALL_LOCKED :
224
211
logger . info ( 'locked hand save' , logClue ( clue ) ) ;
225
212
stall_clues [ 3 ] . push ( clue ) ;
226
- clue_interp = CLUE_INTERP . STALL_LOCKED ;
227
- }
228
- else if ( new_touched . length === 0 ) {
229
- if ( elim > 0 ) {
230
- logger . info ( 'fill in' , logClue ( clue ) ) ;
231
- stall_clues [ 2 ] . push ( clue ) ;
232
- clue_interp = CLUE_INTERP . STALL_FILLIN ;
233
- }
234
- else {
235
- logger . info ( 'hard burn' , logClue ( clue ) ) ;
236
- stall_clues [ 5 ] . push ( clue ) ;
237
- clue_interp = CLUE_INTERP . STALL_BURN ;
238
- }
239
- }
213
+ break ;
214
+
215
+ case CLUE_INTERP . STALL_BURN :
216
+ logger . info ( 'hard burn' , logClue ( clue ) ) ;
217
+ stall_clues [ 5 ] . push ( clue ) ;
218
+ break ;
240
219
}
241
220
242
- if ( clue_interp !== undefined && early_exits ( game , clue , clue_interp ) ) {
221
+ if ( early_exits ( game , clue , /** @type { typeof CLUE_INTERP[keyof typeof CLUE_INTERP] } */ ( hypo_game . moveHistory . at ( - 1 ) . move ) ) ) {
243
222
early_exit = true ;
244
223
break ;
245
224
}
0 commit comments