Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 36 additions & 1 deletion python/socha/_socha.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -785,13 +785,48 @@ class RulesEngine:
Es wird nicht beachtet, ob die Zahl kleiner 0 oder größer 59 ist.

Args:
turn (int): Die Zugzahl
turn (int): Die Zugzahl.

Returns:
TeamEnum: Das Team, was dran ist.
"""
...

@staticmethod
def swarm_from(board: Board, position: Coordinate) -> List[Coordinate]:
"""
Berechnet auf einem Spielbrett von einer Startposition aus, welche Fische
von dort aus in einem Schwarm zusammenhängen.
Dabei werden nur Fische beachtet, die im selben Team sind, wie der auf dem Startfeld.
Gibt eine Liste an Koordinaten zurück, die leer ist, wenn die Startposition
außerhalb des Spielbrettes ist, oder kein Fisch als Start angegeben ist.

Args:
board (Board): Das Spielbrett.
position (Coordinate): Die Startkoordinate

Returns:
List[Coordinate]: Die Liste an zusammenhängenden Fischen.

"""
...

@staticmethod
def swarms_of_team(board: Board, team: TeamEnum) -> List[List[Coordinate]]:
"""
Berechnet auf einem Spielbrett alle Schwärme, die ein Team gerade gebildet hat.
Gibt eine 2-Dimensionale Liste zurück, wobei jede Sub-Liste ein einzelner Schwarm ist.

Args:
board (Board): Das Spielbrett.
team (TeamEnum): Das gewählte Team.

Returns:
List[List[Coordinate]]: Die Liste an Schwärmen.

"""
...

class PluginConstants:
"""
Hält globale Konstanten.
Expand Down
88 changes: 85 additions & 3 deletions src/plugin2026/rules_engine.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
use std::vec;

use pyo3::*;

use crate::plugin2026::{
board::Board, errors::PiranhasError, field_type::FieldType, r#move::Move, utils::{
board::Board, errors::PiranhasError, field_type::FieldType, r#move::Move,
utils::{
constants::PluginConstants,
coordinate::Coordinate, team::TeamEnum
coordinate::Coordinate,
direction::Direction,
team::TeamEnum
}
};

Expand Down Expand Up @@ -76,10 +81,87 @@ impl RulesEngine {

#[staticmethod]
pub fn get_team_on_turn(turn: usize) -> TeamEnum {
if turn % 2 == 0 {
if turn.is_multiple_of(2) {
TeamEnum::One
} else {
TeamEnum::Two
}
}

#[staticmethod]
pub fn swarm_from(board: &Board, position: &Coordinate) -> Vec<Coordinate> {

if !RulesEngine::is_in_bounds(position) {
return vec![];
}

let Some(this_team) = board.get_field(position).unwrap().get_team() else {
return vec![];
};

let mut todo: Vec<Coordinate> = vec![position.to_owned()];
let mut visited: Vec<Coordinate> = Vec::new();

while !todo.is_empty() {

let neighbors = RulesEngine::valid_neighbors(&todo[0]);
for n in neighbors {
if visited.contains(&n) || todo.contains(&n) {
continue;
}

if let Some(team) = board.get_field(&n).unwrap().get_team() {
if team == this_team {
todo.push(n)
}
}
}

visited.push(todo[0]);
todo.remove(0);
}

visited
}

#[staticmethod]
pub fn swarms_of_team(board: &Board, team: &TeamEnum) -> Vec<Vec<Coordinate>> {

let mut team_fish: Vec<Coordinate> = Vec::new();
for f in team.get_fish_types() {
team_fish.extend(board.get_fields_by_type(f));
}

let mut swarms: Vec<Vec<Coordinate>> = Vec::new();
while !team_fish.is_empty() {
let visited = RulesEngine::swarm_from(board, &team_fish[0]);

for v in &visited {
if let Some(index) = team_fish.iter().position(|x| x == v) {
team_fish.remove(index);
}
}

swarms.push(visited)
}

swarms
}
}

// rust exclusive methods
impl RulesEngine {
pub fn valid_neighbors(position: &Coordinate) -> Vec<Coordinate> {

let mut coordinates: Vec<Coordinate> = Vec::new();

for d in Direction::all_directions() {
let neighbor = position.add_vector(&d.to_vector());
if RulesEngine::is_in_bounds(&neighbor) {
coordinates.push(neighbor);
}
}

coordinates
}
}