@@ -6,7 +6,11 @@ use crate::plugin::errors::{
6
6
} ;
7
7
8
8
use super :: {
9
- action:: Action , board:: Board , errors:: CannotEnterFieldError , field:: Field , hare:: Hare ,
9
+ action:: { eat_salad:: EatSalad , Action } ,
10
+ board:: Board ,
11
+ errors:: { CannotEnterFieldError , NoSaladError } ,
12
+ field:: Field ,
13
+ hare:: Hare ,
10
14
r#move:: Move ,
11
15
} ;
12
16
@@ -17,34 +21,77 @@ pub struct RulesEngine;
17
21
impl RulesEngine {
18
22
#[ staticmethod]
19
23
pub fn calculates_carrots ( distance : usize ) -> i32 {
20
- let distancce_i32 : i32 = distance. try_into ( ) . unwrap ( ) ;
21
- ( distancce_i32 * ( distancce_i32 + 1 ) ) / 2
24
+ let distance_i32 : i32 = distance. try_into ( ) . unwrap ( ) ;
25
+ ( distance_i32 * ( distance_i32 + 1 ) ) / 2
22
26
}
23
27
24
28
#[ staticmethod]
25
- pub fn can_exchange_carrots ( board : & Board , player : & Hare , count : i32 ) -> Result < bool , PyErr > {
29
+ pub fn can_exchange_carrots ( board : & Board , player : & Hare , count : i32 ) -> Result < ( ) , PyErr > {
26
30
match board. get_field ( player. position ) {
27
- Some ( f) => {
28
- Ok ( f == Field :: Carrots && ( count == 10 || ( count == -10 && player. carrots >= 10 ) ) )
31
+ Some ( Field :: Carrots ) => {
32
+ if count != 10 && count != -10 {
33
+ return Err ( MissingCarrotsError :: new_err (
34
+ "You can only exchange 10 carrots" ,
35
+ ) ) ;
36
+ }
37
+ if count == -10 && player. carrots < 10 {
38
+ return Err ( MissingCarrotsError :: new_err ( "Not enough carrots" ) ) ;
39
+ }
40
+ Ok ( ( ) )
29
41
}
42
+ Some ( _) => Err ( CannotEnterFieldError :: new_err (
43
+ "Field is not a carrot field" ,
44
+ ) ) ,
30
45
None => Err ( CannotEnterFieldError :: new_err ( "Field not found" ) ) ,
31
46
}
32
47
}
33
48
34
49
#[ staticmethod]
35
- pub fn can_eat_salad ( board : & Board , player : & Hare ) -> Result < bool , PyErr > {
50
+ pub fn can_eat_salad ( board : & Board , player : & Hare ) -> Result < ( ) , PyErr > {
51
+ if player. salads < 1 {
52
+ return Err ( NoSaladError :: new_err ( "No salad to eat" ) ) ;
53
+ }
54
+
36
55
match board. get_field ( player. position ) {
37
- Some ( Field :: Salad ) => Ok ( !matches ! (
38
- player. last_move,
39
- Some ( Move {
40
- action: Action :: EatSalad ( _)
41
- } )
56
+ Some ( Field :: Salad )
57
+ if !matches ! (
58
+ player. last_move,
59
+ Some ( Move {
60
+ action: Action :: EatSalad ( _)
61
+ } )
62
+ ) =>
63
+ {
64
+ Ok ( ( ) )
65
+ }
66
+ Some ( Field :: Salad ) => Err ( CannotEnterFieldError :: new_err (
67
+ "Cannot eat salad twice in a row" ,
42
68
) ) ,
43
- Some ( _) => Ok ( false ) ,
69
+ Some ( _) => Err ( CannotEnterFieldError :: new_err ( "Field is not a salad" ) ) ,
44
70
None => Err ( CannotEnterFieldError :: new_err ( "Field not found" ) ) ,
45
71
}
46
72
}
47
73
74
+ #[ staticmethod]
75
+ pub fn has_to_eat_salad ( board : & Board , player : & Hare ) -> Result < ( ) , PyErr > {
76
+ match board. get_field ( player. position ) {
77
+ Some ( Field :: Salad ) => {
78
+ if player. last_move
79
+ != Some ( Move {
80
+ action : Action :: EatSalad ( EatSalad :: new ( ) ) ,
81
+ } )
82
+ {
83
+ Err ( CannotEnterFieldError :: new_err (
84
+ "Cannot advance without eating salad" ,
85
+ ) )
86
+ } else {
87
+ Ok ( ( ) )
88
+ }
89
+ }
90
+ Some ( _) => Ok ( ( ) ) ,
91
+ None => Ok ( ( ) ) ,
92
+ }
93
+ }
94
+
48
95
#[ staticmethod]
49
96
pub fn can_advance_to (
50
97
board : & Board ,
@@ -56,6 +103,8 @@ impl RulesEngine {
56
103
return Err ( CannotEnterFieldError :: new_err ( "Cannot jump to position 0" ) ) ;
57
104
}
58
105
106
+ Self :: has_to_eat_salad ( board, player) ?;
107
+
59
108
let field = match board. get_field ( new_position) {
60
109
Some ( f) => f,
61
110
None => {
0 commit comments