Skip to content

Commit

Permalink
fix duplicate identifier bug and remove passenger method bug
Browse files Browse the repository at this point in the history
resolves #47 #46
  • Loading branch information
maxblan committed Feb 18, 2024
1 parent 644c142 commit 1864f4a
Show file tree
Hide file tree
Showing 11 changed files with 130 additions and 32 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "_socha"
version = "2.1.1"
version = "2.1.2"
edition = "2021"

[lib]
Expand Down
7 changes: 5 additions & 2 deletions logic.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import logging
import random
from typing import List
# not all imports are currently used, but they might be in the future and it shows all available functionalities
from socha import Accelerate, AccelerationProblem, Advance, AdvanceInfo, AdvanceProblem, Board
from socha import CartesianCoordinate, CubeCoordinates, CubeDirection, Field, FieldType, GameState
Expand All @@ -14,10 +16,11 @@ class Logic(IClientHandler):
# this method should always be implemented otherwise the client will be disqualified
def calculate_move(self) -> Move:
logging.info("Calculate move...")
return Move([Advance(1)])
possible_moves: List[Move] = self.game_state.possible_moves()
return possible_moves[random.randint(0, len(possible_moves) - 1)]

# this method is called every time the server has sent a new game state update
# this method should be implemented to keep
# this method should be implemented to keep the game state up to date
def on_update(self, state: GameState):
self.game_state = state

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "maturin"

[project]
name = "socha"
version = "2.1.1"
version = "2.1.2"
authors = [{ name = "maxblan", email = "[email protected]" }]
description = "This is the package for the Software-Challenge Germany 2023. This Season the game will be 'Hey, danke für den Fisch' a.k.a. 'Penguins' in short."
readme = "README.md"
Expand Down
15 changes: 13 additions & 2 deletions python/socha/_socha.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class PluginConstants:
MIN_ISLANDS: int


class CartesianCoordinate(object):
class CartesianCoordinate:
x: int
y: int

Expand All @@ -31,7 +31,7 @@ class CartesianCoordinate(object):
def from_index(index: int) -> CartesianCoordinate: ...


class CubeCoordinates(object):
class CubeCoordinates:
q: int
r: int
s: int
Expand Down Expand Up @@ -103,6 +103,10 @@ class Ship:
def max_acc(self) -> int: ...
def accelerate_by(self, diff: int) -> None: ...
def read_resolve(self) -> None: ...
def resolve_direction(self, reverse: bool) -> None: ...
def update_position(self, distance: int,
advance_info: AdvanceInfo) -> None: ...

def __str__(self) -> str: ...


Expand Down Expand Up @@ -212,6 +216,7 @@ class Segment:

def tip(self) -> CubeCoordinates: ...
def get(self, coordinates: CubeCoordinates) -> Optional[Field]: ...
def set(self, coordinates: CubeCoordinates, field: Field) -> None: ...

def local_to_global(
self, coordinates: CubeCoordinates) -> CubeCoordinates: ...
Expand Down Expand Up @@ -243,6 +248,9 @@ class Board:
def get_field_in_direction(
self, direction: CubeDirection, coords: CubeCoordinates) -> Optional[Field]: ...

def set_field_in_direction(
self, direction: CubeDirection, coords: CubeCoordinates, field: Field) -> None: ...

def get_coordinate_by_index(
self, segment_index: int, x_index: int, y_index: int) -> CubeCoordinates: ...

Expand Down Expand Up @@ -363,6 +371,9 @@ class GameState:
def possible_actions(self, rank: int) -> List[Accelerate |
Advance | Push | Turn]: ...

def coal_for_action(self, action: Accelerate | Advance |
Push | Turn) -> int: ...

def can_move(self) -> bool: ...
def is_over(self) -> bool: ...
def is_winner(self, ship: Ship) -> bool: ...
Expand Down
14 changes: 8 additions & 6 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,22 @@ pub mod plugin;
use pyo3::prelude::*;
use pyo3::exceptions::PyException;

use plugin::coordinate::CubeCoordinates;
use plugin::field::{ FieldType, Passenger };
use plugin::game_state::TeamPoints;
use plugin::game_state::AdvanceInfo;
use crate::plugin::coordinate::CartesianCoordinate;
use crate::plugin::coordinate::CubeCoordinates;
use crate::plugin::coordinate::CubeDirection;
use crate::plugin::game_state::TeamPoints;
use crate::plugin::game_state::AdvanceInfo;

use crate::plugin::actions::accelerate::Accelerate;
use crate::plugin::actions::advance::Advance;
use crate::plugin::actions::push::Push;
use crate::plugin::actions::turn::Turn;

use plugin::ship::TeamEnum;
use crate::plugin::ship::TeamEnum;
use crate::plugin::board::Board;
use crate::plugin::constants::PluginConstants;
use crate::plugin::coordinate::{ CartesianCoordinate, CubeDirection };
use crate::plugin::field::FieldType;
use crate::plugin::field::Passenger;
use crate::plugin::field::Field;
use crate::plugin::game_state::GameState;
use crate::plugin::r#move::Move;
Expand Down
2 changes: 1 addition & 1 deletion src/plugin/actions/advance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ impl Advance {
let valid_distance = self.validate_distance(&state, &ship)?;
let advance_info = state.calculate_advance_info(
&ship.position,
&ship.direction(!valid_distance),
&ship.resolve_direction(!valid_distance),
ship.movement
);
let advance_possible = (advance_info.distance() as i32) >= self.distance.abs();
Expand Down
14 changes: 14 additions & 0 deletions src/plugin/board.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,20 @@ impl Board {
self.get(&(coords.clone() + direction.vector()))
}

pub fn set_field_in_direction(
&mut self,
direction: &CubeDirection,
coords: &CubeCoordinates,
field: Field
) {
for segment in &mut self.segments {
if segment.contains(*coords) {
segment.set(*coords + direction.vector(), field);
break;
}
}
}

pub fn get_coordinate_by_index(
&self,
segment_index: usize,
Expand Down
15 changes: 13 additions & 2 deletions src/plugin/coordinate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,10 @@ impl CubeCoordinates {
pub fn distance_to(&self, other: &CubeCoordinates) -> i32 {
((self.q - other.q).abs() + (self.r - other.r).abs() + (self.s - other.s).abs()) / 2
}

pub fn __repr__(&self) -> String {
format!("CubeCoordinates({}, {}, {})", self.q, self.r, self.s)
}
}

impl Add for CubeCoordinates {
Expand Down Expand Up @@ -285,8 +289,15 @@ impl CubeDirection {
}
}

pub fn __hash__(&self) -> i32 {
self.ordinal()
pub fn __repr__(&self) -> String {
format!("CubeDirection::{}", match self {
CubeDirection::Right => "Right",
CubeDirection::DownRight => "DownRight",
CubeDirection::DownLeft => "DownLeft",
CubeDirection::Left => "Left",
CubeDirection::UpLeft => "UpLeft",
CubeDirection::UpRight => "UpRight",
})
}
}

Expand Down
78 changes: 62 additions & 16 deletions src/plugin/game_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use crate::plugin::r#move::Move;
use crate::plugin::ship::Ship;
use crate::plugin::errors::advance_errors::AdvanceProblem;

use super::field::Field;
use super::field::{ Field, Passenger };
use super::ship::TeamEnum;

#[pyclass]
Expand Down Expand Up @@ -349,27 +349,34 @@ impl GameState {
}

pub fn remove_passenger_at(&mut self, coord: CubeCoordinates) -> bool {
CubeDirection::VALUES.iter().any(|&d| {
self.board
.get_field_in_direction(&d, &coord)
.and_then(|mut field| {
field.passenger.as_mut().and_then(|passenger| {
if passenger.passenger > 0 && passenger.direction == d.opposite() {
passenger.passenger -= 1;
Some(())
} else {
None
}
})
})
.is_some()
})
for &d in CubeDirection::VALUES.iter() {
if let Some(field) = self.board.get_field_in_direction(&d, &coord) {
if let Some(passenger) = field.passenger {
if passenger.passenger > 0 && passenger.direction == d.opposite() {
let updated_passenger = Passenger {
passenger: passenger.passenger - 1,
direction: passenger.direction,
};
self.board.set_field_in_direction(
&d,
&coord,
Field::new(field.field_type, Some(updated_passenger))
);
return true;
}
}
}
}
false
}

pub fn pick_up_passenger_current_ship(&mut self) {
if self.effective_speed(self.current_ship) < 2 {
if self.remove_passenger_at(self.current_ship.position) {
self.current_ship.passengers += 1;
self.current_ship.points = self
.ship_points(self.current_ship)
.expect("Could not calculate ship points");
}
}
}
Expand All @@ -378,6 +385,9 @@ impl GameState {
if self.effective_speed(self.other_ship) < 2 {
if self.remove_passenger_at(self.other_ship.position) {
self.other_ship.passengers += 1;
self.other_ship.points = self
.ship_points(self.other_ship)
.expect("Could not calculate other ship's points");
}
}
}
Expand Down Expand Up @@ -630,6 +640,19 @@ impl GameState {
actions
}

pub fn coal_for_action(&self, action: Action) -> usize {
match action {
Action::Accelerate(acc) => {
(acc.acc.abs() as usize) - (self.current_ship.free_acc as usize)
}
Action::Turn(dir) => {
let turn_count: i32 = self.current_ship.direction.turn_count_to(dir.direction);
(turn_count.abs() as usize) - (self.current_ship.free_turns as usize)
}
Action::Push(_) | Action::Advance(_) => { 0 }
}
}

pub fn can_move(&self) -> bool {
let current_ship_can_advance: bool = !self.possible_advances().is_empty();

Expand Down Expand Up @@ -722,6 +745,29 @@ mod tests {
GameState::new(Board::new(segment, CubeDirection::Right), 0, team_one, team_two, None)
}

#[test]
fn test_remove_passenger_at() {
let mut segment = vec![
create_water_segment(CubeCoordinates::new(0, 0), CubeDirection::Right)
];
let team_one = create_ship(CubeCoordinates::new(0, -1), TeamEnum::One);
let team_two = create_ship(CubeCoordinates::new(-1, 1), TeamEnum::Two);
segment[0].set(
CubeCoordinates::new(0, 0),
Field::new(FieldType::Passenger, Some(Passenger::new(CubeDirection::UpLeft, 1)))
);
let mut game_state = create_game_state(segment, team_one, team_two);

assert_eq!(game_state.current_ship.passengers, 0);
assert_eq!(game_state.current_ship.points, 0);
game_state.pick_up_passenger_current_ship();
assert_eq!(game_state.current_ship.passengers, 1);
assert_eq!(game_state.current_ship.points, 6);
game_state.pick_up_passenger_current_ship();
assert_eq!(game_state.current_ship.passengers, 1);
assert_eq!(game_state.current_ship.points, 6);
}

#[test]
fn find_possible_moves_returns_correct_count() {
let segment = vec![create_water_segment(CubeCoordinates::new(0, 0), CubeDirection::Right)];
Expand Down
11 changes: 11 additions & 0 deletions src/plugin/segment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,17 @@ impl Segment {
.cloned()
}

pub fn set(&mut self, coordinates: CubeCoordinates, field: Field) {
let local: CubeCoordinates = self.global_to_local(coordinates);

let local_cart: CartesianCoordinate = self.array_coords(local);
if let Some(row) = self.fields.get_mut(local_cart.x as usize) {
if let Some(cell) = row.get_mut(local_cart.y as usize) {
*cell = field;
}
}
}

pub fn local_to_global(&self, coordinates: CubeCoordinates) -> CubeCoordinates {
coordinates.rotated_by(CubeDirection::Right.turn_count_to(self.direction)) + self.center
}
Expand Down
2 changes: 1 addition & 1 deletion src/plugin/ship.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ impl Ship {
self.movement = self.speed;
}

pub fn direction(&self, reverse: bool) -> CubeDirection {
pub fn resolve_direction(&self, reverse: bool) -> CubeDirection {
if reverse { self.direction.opposite() } else { self.direction }
}

Expand Down

0 comments on commit 1864f4a

Please sign in to comment.