Skip to content

Instantly share code, notes, and snippets.

@MikuroXina
Created May 21, 2023 15:43
Show Gist options
  • Select an option

  • Save MikuroXina/23705bfd67432cf42f926a30e391e853 to your computer and use it in GitHub Desktop.

Select an option

Save MikuroXina/23705bfd67432cf42f926a30e391e853 to your computer and use it in GitHub Desktop.
#pragma once
#include <algorithm>
#include <optional>
enum class Direction {
North,
West,
East,
South,
};
enum FaceIndex {
Top,
South,
East,
West,
North,
Bottom,
};
const FaceIndex all_face_indexes[6] = {
Top,
South,
East,
West,
North,
Bottom,
};
class Dice {
int faces[6];
std::optional<FaceIndex> index_of_label(int label) const {
for (auto const i : all_face_indexes) {
if (faces[i] == label) {
return {i};
}
}
return {};
}
public:
Dice() : faces{1, 2, 3, 4, 5, 6} {}
Dice(int init_faces[6]) : faces{} {
for (int i = 0; i < 6; ++i) {
faces[i] = init_faces[i];
}
}
Dice(Dice const &) = default;
Dice &operator=(Dice const &) = default;
bool operator==(Dice const &other) const {
Dice clone_me{*this};
auto const max_label = *std::max_element(faces, faces + 6);
clone_me.rotate_by_axis(max_label, 1);
Dice clone_other{other};
clone_other.rotate_by_axis(clone_me.label(Top), clone_me.label(South));
for (auto const i : all_face_indexes) {
if (clone_me.label(i) != clone_other.label(i)) {
return false;
}
}
return true;
}
int label(FaceIndex index) const {
return faces[index];
}
void rotate_to(Direction dir) {
switch (dir) {
case Direction::North: {
unsigned char temp = faces[Top];
faces[Top] = faces[South];
faces[South] = faces[Bottom];
faces[Bottom] = faces[North];
faces[North] = temp;
break;
}
case Direction::West: {
unsigned char temp = faces[Top];
faces[Top] = faces[East];
faces[East] = faces[Bottom];
faces[Bottom] = faces[West];
faces[West] = temp;
break;
}
case Direction::East: {
unsigned char temp = faces[Top];
faces[Top] = faces[West];
faces[West] = faces[Bottom];
faces[Bottom] = faces[East];
faces[East] = temp;
break;
}
case Direction::South: {
unsigned char temp = faces[Top];
faces[Top] = faces[North];
faces[North] = faces[Bottom];
faces[Bottom] = faces[South];
faces[South] = temp;
break;
}
}
}
void rotate_by_axis(int to_be_top, int to_be_south) {
auto const top_index = index_of_label(to_be_top);
if (!top_index) {
return;
}
switch (*top_index) {
case Top:
break;
case Bottom:
rotate_to(Direction::North);
rotate_to(Direction::North);
break;
case North:
rotate_to(Direction::South);
break;
case West:
rotate_to(Direction::East);
break;
case East:
rotate_to(Direction::West);
break;
case South:
rotate_to(Direction::North);
break;
}
auto const south_index = index_of_label(to_be_south);
if (!south_index || *top_index == *south_index) {
return;
}
switch (*south_index) {
case South:
return;
case East:
rotate_to(Direction::North);
rotate_to(Direction::West);
rotate_to(Direction::South);
return;
case West:
rotate_to(Direction::North);
rotate_to(Direction::East);
rotate_to(Direction::South);
return;
case North:
rotate_to(Direction::North);
rotate_to(Direction::West);
rotate_to(Direction::West);
rotate_to(Direction::South);
return;
default:
break;
}
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment