Skip to content

Commit

Permalink
Added 4 more symmetries for a total of 24 * 4
Browse files Browse the repository at this point in the history
michael-wsp committed Apr 20, 2024
1 parent 754f6e1 commit d320b48
Showing 2 changed files with 122 additions and 30 deletions.
125 changes: 103 additions & 22 deletions src/game/crossteaser/mod.rs
Original file line number Diff line number Diff line change
@@ -305,7 +305,9 @@ impl Session {
if s.free / self.width != self.length - 1 {
let to_move: usize = (s.free + self.width) as usize;
let dest: usize = s.free as usize;
let piece: Orientation = new_state.pieces.remove(to_move);
let piece: Orientation = new_state
.pieces
.remove(to_move - 1);
new_state
.pieces
.insert(dest, mov::up(&piece));
@@ -331,17 +333,67 @@ impl Session {
return new_state;
}

fn board_cw(&self, s: &UnhashedState) -> UnhashedState {
if self.width != self.length {
panic!("Cannot rotate board with unequal dimensions 90 degrees");
}
let mut rep: Vec<Orientation> = Vec::new();
for col in 0..self.width {
for row in (0..self.length).rev() {
let mut pos: u64 = row * self.width + col;
if pos != s.free {
if pos > s.free {
pos -= 1;
}
rep.push(mov::cw_front(&s.pieces[pos as usize]));
}
}
}
let row: u64 = s.free / self.width;
let col: u64 = s.free % self.width;
return UnhashedState {
pieces: rep,
free: col * self.width + self.width - row - 1,
};
}

/// Not in use
fn _r180(&self, s: &UnhashedState) -> UnhashedState {
let mut new_s: UnhashedState = s.deep_copy();
new_s.pieces.reverse();
new_s.free = self.get_pieces() - new_s.free - 1;
return new_s;
fn board_180(&self, s: &UnhashedState) -> UnhashedState {
let mut rep: Vec<Orientation> = Vec::new();
for i in (0..s.pieces.len()).rev() {
rep.push(mov::front_180(&s.pieces[i]));
}
let f: u64 = self.get_pieces() - s.free;
return UnhashedState {
pieces: rep,
free: f,
};
}

/// Not in use
fn _mirror(&self, s: &UnhashedState) -> UnhashedState {
todo!()
fn flip_board(&self, s: &UnhashedState) -> UnhashedState {
let mut rep: Vec<Orientation> = Vec::new();
for row in 0..self.length {
for col in (0..self.width).rev() {
let mut pos: u64 = row * self.width + col;
if pos != s.free {
if pos > s.free {
pos -= 1;
}
rep.push(mov::top_180(&s.pieces[pos as usize]));
}
}
}
let new_free: u64 = self.width - (s.free % self.width) - 1
+ (s.free / self.width) * self.width;
return UnhashedState {
pieces: rep,
free: new_free,
};
}

fn flip_90(&self, s: &UnhashedState) -> UnhashedState {
return self.board_cw(&self.flip_board(s));
}

/// Applies a sequence of transformations on an orientation
@@ -386,6 +438,16 @@ impl Session {
free: s.free,
};
}

fn canonical_sym(&self, s: &UnhashedState) -> State {
let mut sym_list: Vec<State> = Vec::new();
sym_list.push(self.hash(s));
let flipped: UnhashedState = self.flip_90(s);
sym_list.push(self.hash(&flipped));
sym_list.push(self.hash(&self.canonical(&self.board_180(s))));
sym_list.push(self.hash(&self.canonical(&self.board_180(&flipped))));
return *sym_list.iter().min().unwrap();
}
}

/// Module which contains all transition helper functions
@@ -491,6 +553,22 @@ mod mov {
};
}

pub fn front_180(o: &Orientation) -> Orientation {
return Orientation {
front: o.front,
top: 5 - o.top,
right: 5 - o.right,
};
}

pub fn top_180(o: &Orientation) -> Orientation {
return Orientation {
front: 5 - o.front,
top: o.top,
right: 5 - o.right,
};
}

/// Performs a clowckwise orientation on an orientation
/// along the specified axis.
/// I am trying to figure out a way to make this faster.
@@ -542,13 +620,12 @@ impl Game for Session {
}

fn info(&self) -> GameData {
let var: String;
match &self.variant {
None => var = VARIANT_DEFAULT.to_string(),
Some(v) => var = v.clone(),
}
let var = match &self.variant {
None => VARIANT_DEFAULT,
Some(v) => v,
};
GameData {
variant: var,
variant: var.to_owned(),

name: NAME,
authors: AUTHORS,
@@ -577,16 +654,16 @@ impl DTransition for Session {
let s: UnhashedState = self.unhash(state);
let mut states: Vec<State> = Vec::new();
if s.free / self.width != self.length - 1 {
states.push(self.hash(&self.canonical(&self.board_up(&s))));
states.push(self.canonical_sym(&self.board_up(&s)));
}
if s.free / self.width != 0 {
states.push(self.hash(&self.canonical(&self.board_down(&s))));
states.push(self.canonical_sym(&self.board_down(&s)));
}
if s.free % self.width != 0 {
states.push(self.hash(&self.canonical(&self.board_right(&s))));
states.push(self.canonical_sym(&self.board_right(&s)));
}
if s.free % self.width != self.width - 1 {
states.push(self.hash(&self.canonical(&self.board_left(&s))));
states.push(self.canonical_sym(&self.board_left(&s)));
}
return states;
}
@@ -619,17 +696,21 @@ impl Codec for Session {
for _i in 0..self.length {
v.push(Vec::new());
}
let board_size: usize = (self.width * self.length) as usize;
let mut out: String = String::new();
let mut row: usize;
let mut i: usize = 0;
for o in &s.pieces {
let mut found_empty: usize = 0;
while i < board_size {
row = i / self.width as usize;
if i as u64 == s.free {
v[row].push("X".to_string());
i += 1;
row = i / self.width as usize;
found_empty = 1;
} else {
v[row].push(
hash_orientation(&s.pieces[i - found_empty]).to_string(),
);
}
v[row].push(hash_orientation(o).to_string());
i += 1;
}
for i in 0..self.length {
27 changes: 19 additions & 8 deletions src/game/crossteaser/states.rs
Original file line number Diff line number Diff line change
@@ -40,14 +40,25 @@ mod test {
s.pieces
.push(unhash_orientation(0));
}
let mut state_set: HashSet<State> = HashSet::new();
println!("{}", session.encode(session.hash(&s)));
let mut t: UnhashedState = session.board_right(&s);
let f: Vec<State> = session.prograde(session.hash(&s));
println!("{}", session.encode(session.hash(&t)));
println!("{}", f.len());
for p in f {
println!("{}", session.encode(p));

let mut solved: HashSet<State> = HashSet::new();
let mut unsolved: Vec<State> = Vec::new();
unsolved.push(session.hash(&s));
let mut count: u64 = 0;
while !unsolved.is_empty() {
let s: State = unsolved.pop().unwrap();
solved.insert(s);
let f: Vec<State> = session.prograde(s);
for state in f {
if !solved.contains(&state) {
unsolved.push(state);
}
}
count += 1;
if count % 100000 == 0 {
println!("discovered {}", count);
}
}
println!("{}", solved.len());
}
}

0 comments on commit d320b48

Please sign in to comment.