Commit 709f270a authored by Ari Trachtenberg's avatar Ari Trachtenberg
Browse files

Initial commit

parent 3f7c5954
Loading
Loading
Loading
Loading

include/Enums.h

0 → 100644
+75 −0
Original line number Diff line number Diff line
//
// Created by Ari Trachtenberg on 2/6/26.
//
#ifndef ENUM_H
#define ENUM_H
#include <ostream>

/**
 * The available colors of a cell.
 * {@code __BLANK__} indicates no color.
 */
enum class Color { GREEN, ORANGE, RED, WHITE, YELLOW, BLUE, BLANK_ };

/**
 * Letters corresponding to the colors
 */
constexpr std::array<char, static_cast<size_t>(Color::BLANK_) + 1>
    ColorToCharArray = {'G', 'O', 'R', 'W', 'Y', 'B', ' '};

/**
 * @param clr The color to convert.
 * @return The character corresponding to a {@link Color}.
 */
char ColorToChar(Color clr);

/**
 * @param ch The letter representing a {@link Color}.
 * @return The {@link Color} corresponding to a given letter
 */
Color CharToColor(char ch);

/**
 * External method for displaying a color on the output
 * stream {@code os}.
 * @param os The output stream to which to produce a human-readable
 *           version of this cell.
 * @param clr The color to display.
 */
std::ostream& operator<<(std::ostream& os, Color clr);

/**
 * The six faces of the cube.
 */
enum class FaceName {
  FRONT,
  LEFT,
  RIGHT,
  TOP,
  BOTTOM,
  AFT,
  FACENAME_LAST  // a sentinel for determining the number of faces
};
constexpr size_t FACENAME_COUNT = static_cast<size_t>(FaceName::FACENAME_LAST);

/**
 * The types of moves that can be made on the cube.
 */
enum CubeMoves {
  LeftDown,
  LeftUp,
  RightDown,
  RightUp,
  TopLeft,
  TopRight,
  BottomLeft,
  BottomRight,
  OverLeft,
  OverRight,
  OverFarLeft,
  OverFarRight,
  MOVE_LAST  //  a sentinel for determining the number of moves
};
constexpr size_t CUBEMOVES_COUNT = MOVE_LAST;

#endif  // ENUM_H
 No newline at end of file

include/Face.h

0 → 100644
+103 −0
Original line number Diff line number Diff line
//
// Created by Ari on 2/5/17.
//

#ifndef RUBIKS_FACE_H
#define RUBIKS_FACE_H

#include <sstream>
#include <vector>

#include "Enums.h"

using namespace std;

/**
 * Represents one face of the {@link Rubk} cube, which is a
 * square matrix of {@link Color}ed cells.
 */
class Face {
  public:
    // NESTED CLASSES

    /**
     * Represents a row; no bounds checking.
     */
    class Row {
      public:
        explicit constexpr Row(const int theRow) : value(theRow) {}
        const int value;
    };

    /**
     * Represents a column; no bounds checking.
     */
    class Column {
      public:
        explicit constexpr Column(const int theCol) : value(theCol) {}
        const int value;
    };

    // CONSTRUCTORS
    /**
     * Constructs one [len] x [len] face of a {@link Rubk} cube,
     * all of whose cells have color {@code theColor}.
     * @param len The linear dimension of the face.
     * @requires len >= 3.
     */
    Face(const Color theColor, const int len = 3) {
      cells = std::vector(len, std::vector(len, theColor));
    }

    // GETTERS / SETTERS
    /**
     * @param row  the row in which the cell can be found
     * @param col the column in which the cell can be found
     * @return The color of the cell at column {@code col} and
     *         row {@code row} of the face.
     * @requires 0 <= row,col <= {@link faceLen()} - 1
     */
    [[nodiscard]] Color get(const Row row, const Column col) const {
      return cells[col.value][row.value];
    }

    /**
     * Change the color of a cell at the given row and column on the face.
     *
     * @param row  the row in which the cell can be found
     * @param col  the column in which the cell can be found
     * @param newColor The new color of the cell.
     * @requires 0 <= row,col <= {@link faceLen()} - 1
     */
    void set(const Row row, const Column col, const Color newColor) {
      cells[col.value][row.value] = newColor;
    }

    // INFORMATIONAL
    /**
     * @param theRow the row of the face to return
     * @return a human-readable string representing row {@code theRow} of the face
     * @requires 0 <= row,col <= {@link faceLen()} - 1
     */
    [[nodiscard]] string printRow(const Row theRow) const {
      stringstream result;
      for (int theCol = 0; theCol < faceLen(); theCol++)
        result << get(theRow, Column(theCol)) << " ";
      return result.str();
    }

    /**
     * @return The linear length of a side of the face.
     */
    [[nodiscard]] int faceLen() const { return static_cast<int>(cells.size()); }

  private:
    /**
     * Colored cells that constitute this face.
     * This is represented as a vector of rows of the face.
     * Each row, in turn, is a vector of {@link Color}s.
     */
    vector<vector<Color> > cells;
};

#endif  // RUBIKS_FACE_H

include/Rubk.h

0 → 100644
+126 −0
Original line number Diff line number Diff line
//
// Created by Ari on 2/4/17.
//

#ifndef RUBIKS_CUBE_H
#define RUBIKS_CUBE_H

#include <map>
#include <sstream>

#include "Enums.h"
#include "Face.h"

using namespace std;

/**
 * Represents a configuration of a Rubk's cube.  The cube represents an
 * immutable three-dimensional {@code len x len x len} structure, where
 * {@code len} is specified in the constructor.
 */
class Rubk {
  public:
    // CONSTRUCTORS

    /**
     * Constructs a [len] x [len] x [len] cube in standard coloring order.
     * @param len The linear length of any cube size.
     */
    Rubk(int len);

    /**
     * Copy constructor from an existing Rubk.
     * @param other The Rubk to copy.
     */
    Rubk(Rubk const &other);

    /**
     * Constructs a Rubk from its flat profile.
     * @throws invalid_argument if the profile string is in the wrong format.
     * @param flatProfile a string of the following form:
     *        B R R
     *        B R R
     *        B R R
     *
     * B B B  R W W  R R R  B B W
     * B B B  R W W  R R R  B B W
     * B B B  R W W  R R R  B B W
     *
     *        W W W
     *        W W W
     *        W W W
     */
    Rubk(const string &flatProfile);

    // MANIPULATORS

    /**
     * Makes a move and returns the resulting cube
     * @param theMove the move to make
     * @return a new cube representing the given move from the current cube.
     */
    [[nodiscard]] Rubk makeMove(CubeMoves theMove) const;

    /**
     * @param direction if true, rotates clockwise; else rotates counter-clockwise
     * @param theFaceName The face to rotate.
     * @return Rotates Face {@code theFaceName} 90 degrees and returns the resulting cube.
     */
    [[nodiscard]] Rubk rotate(bool direction, FaceName theFaceName) const;

    // INFORMATION

    /**
     *
     * @return true iff each face is monochromal
     *     (i.e., all cells on that face are the same color)
     */
    [[nodiscard]] bool isUnscrambled() const;

    /**
     * @return The linear length of the cube.
     */
    [[nodiscard]] int getLen() const { return cubeLen; }

    Face &getFace(const FaceName theFace) { return _faces.at(theFace); }
    [[nodiscard]] const Face &getFace(const FaceName theFace) const {
      return _faces.at(theFace);
    }

    /**
     * @param theFaceName The cube face where the cell resides.
     * @param theRow The row of the cell on the given face.
     * @param theColumn The column of the cell on the given face.
     * @return The color of the specified cell of the cube.
     */
    [[nodiscard]] Color getCellColor(FaceName theFaceName, Face::Row theRow,
                                     Face::Column theColumn) const;

    /**
     * @param theFaceName The cube face where the cell resides.
     * @param theRow The row of the cell on the given face.
     * @param theColumn The column of the cell on the given face.
     * @param newColor The new color of the cell.
     * @return Sets color of the specified cell of the cube to {@code newColor}.
     */
    void setCellColor(FaceName theFaceName, Face::Row theRow,
                      Face::Column theColumn, Color newColor);

    /**
     * @return A flattened representation of this cube.
     */
    [[nodiscard]] string printFlattened() const;

  private:
    // FIELDS
    int cubeLen;  // linear dimension of one side

    /** the faces of the cube */
    map<FaceName, Face> _faces;
};

// public methods
// ... stream output
std::ostream &operator<<(std::ostream &os, const Rubk &cube);

#endif  // RUBIKS_CUBE_H