1
1
use super :: basic_types:: SizeType ;
2
- use super :: field_type :: FieldType ;
2
+ use super :: field_info :: { FieldInfo , FieldState , FieldType } ;
3
3
use super :: results:: { FlagResult , OpenInfo , OpenResult } ;
4
4
use indexmap:: IndexSet ;
5
5
use mockall:: automock;
@@ -15,27 +15,9 @@ static TOO_FEW_MINES_ERROR: &'static str = "Too few mines!";
15
15
static MINE_DOES_NOT_HAVE_VALUE_ERROR : & ' static str = "Mine does not have value!" ;
16
16
static OPENED_FIELD_CAN_NOT_BE_UPDATED_ERROR : & ' static str = "An opened field can not be updated!" ;
17
17
18
- #[ derive( Eq , PartialEq , Display , Debug , Clone , Copy ) ]
19
- enum FieldState {
20
- Closed ,
21
- Opened ,
22
- Flagged ,
23
- }
24
-
25
- impl FieldState {
26
- fn is_opened ( & self ) -> bool {
27
- self == & FieldState :: Opened
28
- }
29
-
30
- fn is_flagged ( & self ) -> bool {
31
- self == & FieldState :: Flagged
32
- }
33
- }
34
-
35
18
trait Field {
36
19
fn get_field_state ( & self ) -> FieldState ;
37
20
fn get_field_type ( & self ) -> FieldType ;
38
- fn get_char_repr ( & self ) -> char ;
39
21
}
40
22
41
23
#[ automock]
@@ -58,8 +40,7 @@ enum FieldOpenResult {
58
40
59
41
#[ derive( Debug , Eq , PartialEq ) ]
60
42
struct FieldInner {
61
- field_type : FieldType ,
62
- state : FieldState ,
43
+ field_info : FieldInfo ,
63
44
}
64
45
65
46
impl FieldInner {
@@ -69,8 +50,10 @@ impl FieldInner {
69
50
70
51
fn new_with_field_type ( field_type : FieldType ) -> FieldInner {
71
52
FieldInner {
72
- field_type,
73
- state : FieldState :: Closed ,
53
+ field_info : FieldInfo {
54
+ state : FieldState :: Closed ,
55
+ field_type,
56
+ } ,
74
57
}
75
58
}
76
59
@@ -91,60 +74,60 @@ impl FieldInner {
91
74
}
92
75
93
76
fn update_type_to_mine ( & mut self ) -> Result < ( ) , & ' static str > {
94
- if self . state == FieldState :: Opened {
77
+ if self . field_info . state == FieldState :: Opened {
95
78
Err ( OPENED_FIELD_CAN_NOT_BE_UPDATED_ERROR )
96
79
} else {
97
- self . field_type = FieldType :: Mine ;
80
+ self . field_info . field_type = FieldType :: Mine ;
98
81
Ok ( ( ) )
99
82
}
100
83
}
101
84
102
85
fn update_type_to_empty ( & mut self ) -> Result < ( ) , & ' static str > {
103
- if self . state == FieldState :: Opened {
86
+ if self . field_info . state == FieldState :: Opened {
104
87
Err ( OPENED_FIELD_CAN_NOT_BE_UPDATED_ERROR )
105
88
} else {
106
- self . field_type = FieldType :: Empty ;
89
+ self . field_info . field_type = FieldType :: Empty ;
107
90
Ok ( ( ) )
108
91
}
109
92
}
110
93
111
94
fn update_type_with_value ( & mut self , value : u8 ) -> Result < ( ) , & ' static str > {
112
- if self . state == FieldState :: Opened {
95
+ if self . field_info . state == FieldState :: Opened {
113
96
Err ( OPENED_FIELD_CAN_NOT_BE_UPDATED_ERROR )
114
97
} else if !FieldInner :: is_valid_value ( value) {
115
98
Err ( INVALID_VALUE_ERROR )
116
99
} else {
117
- self . field_type = FieldType :: Numbered ( value) ;
100
+ self . field_info . field_type = FieldType :: Numbered ( value) ;
118
101
Ok ( ( ) )
119
102
}
120
103
}
121
104
122
105
fn get_open_result_inner ( & self ) -> FieldOpenResult {
123
- match self . field_type {
106
+ match self . field_info . field_type {
124
107
FieldType :: Empty => FieldOpenResult :: MultiOpen ,
125
108
FieldType :: Numbered ( _) => FieldOpenResult :: SimpleOpen ,
126
109
FieldType :: Mine => FieldOpenResult :: Boom ,
127
110
}
128
111
}
129
112
130
113
fn open ( & mut self ) -> FieldOpenResult {
131
- if self . get_field_state ( ) . is_flagged ( ) {
114
+ if self . field_info . state . is_flagged ( ) {
132
115
FieldOpenResult :: IsFlagged
133
- } else if self . get_field_state ( ) . is_opened ( ) {
116
+ } else if self . field_info . state . is_opened ( ) {
134
117
FieldOpenResult :: AlreadyOpened
135
118
} else {
136
- self . state = FieldState :: Opened ;
119
+ self . field_info . state = FieldState :: Opened ;
137
120
self . get_open_result_inner ( )
138
121
}
139
122
}
140
123
141
124
fn toggle_flag ( & mut self ) -> FlagResult {
142
- if self . state . is_flagged ( ) {
143
- self . state = FieldState :: Closed ;
125
+ if self . field_info . state . is_flagged ( ) {
126
+ self . field_info . state = FieldState :: Closed ;
144
127
FlagResult :: FlagRemoved
145
128
} else {
146
- if !self . get_field_state ( ) . is_opened ( ) {
147
- self . state = FieldState :: Flagged ;
129
+ if !self . field_info . state . is_opened ( ) {
130
+ self . field_info . state = FieldState :: Flagged ;
148
131
FlagResult :: Flagged
149
132
} else {
150
133
FlagResult :: AlreadyOpened
@@ -155,21 +138,11 @@ impl FieldInner {
155
138
156
139
impl Field for FieldInner {
157
140
fn get_field_state ( & self ) -> FieldState {
158
- self . state
141
+ self . field_info . state
159
142
}
160
143
161
144
fn get_field_type ( & self ) -> FieldType {
162
- self . field_type
163
- }
164
-
165
- fn get_char_repr ( & self ) -> char {
166
- if self . state . is_flagged ( ) {
167
- 'H'
168
- } else if !self . state . is_opened ( ) {
169
- 'O'
170
- } else {
171
- self . field_type . get_char_repr ( )
172
- }
145
+ self . field_info . field_type . clone ( )
173
146
}
174
147
}
175
148
@@ -407,11 +380,17 @@ impl BasicTable {
407
380
}
408
381
409
382
fn move_mine ( & mut self , row : SizeType , col : SizeType ) -> Result < ( ) , & ' static str > {
410
- if self . fields [ row as usize ] [ col as usize ] . field_type . is_mine ( ) {
383
+ if self . fields [ row as usize ] [ col as usize ]
384
+ . get_field_type ( )
385
+ . is_mine ( )
386
+ {
411
387
let mut new_place = ( 0 , 0 ) ;
412
388
let mut visiter = FieldVisiter :: new ( self . height , self . width , row, col) ?;
413
389
while let Some ( ( r, c) ) = visiter. next ( ) {
414
- if !self . fields [ r as usize ] [ c as usize ] . field_type . is_mine ( ) {
390
+ if !self . fields [ r as usize ] [ c as usize ]
391
+ . get_field_type ( )
392
+ . is_mine ( )
393
+ {
415
394
new_place = ( r, c) ;
416
395
break ;
417
396
}
@@ -434,7 +413,10 @@ impl BasicTable {
434
413
) ;
435
414
fields_to_recalculate. insert ( ( row, col) ) ;
436
415
for ( r, c) in fields_to_recalculate {
437
- if !self . fields [ r as usize ] [ c as usize ] . field_type . is_mine ( ) {
416
+ if !self . fields [ r as usize ] [ c as usize ]
417
+ . get_field_type ( )
418
+ . is_mine ( )
419
+ {
438
420
let field_value = self . get_field_value ( r, c) . unwrap ( ) ;
439
421
match field_value {
440
422
0 => self . fields [ r as usize ] [ c as usize ]
@@ -560,7 +542,9 @@ impl Table for BasicTable {
560
542
}
561
543
562
544
if self . number_of_opened_fields == 0
563
- && self . fields [ row as usize ] [ col as usize ] . field_type . is_mine ( )
545
+ && self . fields [ row as usize ] [ col as usize ]
546
+ . get_field_type ( )
547
+ . is_mine ( )
564
548
{
565
549
self . move_mine ( row, col) ?;
566
550
}
0 commit comments