1+ use std:: vec;
2+
13use pyo3:: * ;
24
35use crate :: plugin2026:: {
4- board:: Board , errors:: PiranhasError , field_type:: FieldType , r#move:: Move , utils:: {
6+ board:: Board , errors:: PiranhasError , field_type:: FieldType , r#move:: Move ,
7+ utils:: {
58 constants:: PluginConstants ,
6- coordinate:: Coordinate , team:: TeamEnum
9+ coordinate:: Coordinate ,
10+ direction:: Direction ,
11+ team:: TeamEnum
712 }
813} ;
914
@@ -76,10 +81,87 @@ impl RulesEngine {
7681
7782 #[ staticmethod]
7883 pub fn get_team_on_turn ( turn : usize ) -> TeamEnum {
79- if turn % 2 == 0 {
84+ if turn. is_multiple_of ( 2 ) {
8085 TeamEnum :: One
8186 } else {
8287 TeamEnum :: Two
8388 }
8489 }
90+
91+ #[ staticmethod]
92+ pub fn swarm_from ( board : & Board , position : & Coordinate ) -> Vec < Coordinate > {
93+
94+ if !RulesEngine :: is_in_bounds ( position) {
95+ return vec ! [ ] ;
96+ }
97+
98+ let Some ( this_team) = board. get_field ( position) . unwrap ( ) . get_team ( ) else {
99+ return vec ! [ ] ;
100+ } ;
101+
102+ let mut todo: Vec < Coordinate > = vec ! [ position. to_owned( ) ] ;
103+ let mut visited: Vec < Coordinate > = Vec :: new ( ) ;
104+
105+ while !todo. is_empty ( ) {
106+
107+ let neighbors = RulesEngine :: valid_neighbors ( & todo[ 0 ] ) ;
108+ for n in neighbors {
109+ if visited. contains ( & n) || todo. contains ( & n) {
110+ continue ;
111+ }
112+
113+ if let Some ( team) = board. get_field ( & n) . unwrap ( ) . get_team ( ) {
114+ if team == this_team {
115+ todo. push ( n)
116+ }
117+ }
118+ }
119+
120+ visited. push ( todo[ 0 ] ) ;
121+ todo. remove ( 0 ) ;
122+ }
123+
124+ visited
125+ }
126+
127+ #[ staticmethod]
128+ pub fn swarms_of_team ( board : & Board , team : & TeamEnum ) -> Vec < Vec < Coordinate > > {
129+
130+ let mut team_fish: Vec < Coordinate > = Vec :: new ( ) ;
131+ for f in team. get_fish_types ( ) {
132+ team_fish. extend ( board. get_fields_by_type ( f) ) ;
133+ }
134+
135+ let mut swarms: Vec < Vec < Coordinate > > = Vec :: new ( ) ;
136+ while !team_fish. is_empty ( ) {
137+ let visited = RulesEngine :: swarm_from ( board, & team_fish[ 0 ] ) ;
138+
139+ for v in & visited {
140+ if let Some ( index) = team_fish. iter ( ) . position ( |x| x == v) {
141+ team_fish. remove ( index) ;
142+ }
143+ }
144+
145+ swarms. push ( visited)
146+ }
147+
148+ swarms
149+ }
150+ }
151+
152+ // rust exclusive methods
153+ impl RulesEngine {
154+ pub fn valid_neighbors ( position : & Coordinate ) -> Vec < Coordinate > {
155+
156+ let mut coordinates: Vec < Coordinate > = Vec :: new ( ) ;
157+
158+ for d in Direction :: all_directions ( ) {
159+ let neighbor = position. add_vector ( & d. to_vector ( ) ) ;
160+ if RulesEngine :: is_in_bounds ( & neighbor) {
161+ coordinates. push ( neighbor) ;
162+ }
163+ }
164+
165+ coordinates
166+ }
85167}
0 commit comments