]> git.scottworley.com Git - slidingtile/blobdiff - sliding_tile_lib.cc
Mark const methods const.
[slidingtile] / sliding_tile_lib.cc
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..5b2e798472d08e4b45f547461b71ff135fe787f5 100644 (file)
@@ -0,0 +1,75 @@
+#include "sliding_tile_lib.h"
+
+#include <istream>
+#include <stdexcept>
+
+signed char adjacent[BOARD_SIZE][5] = {
+  1,   4,   -1,  -1,  -1,
+  0,   2,   5,   -1,  -1,
+  1,   3,   6,   -1,  -1,
+  2,   7,   -1,  -1,  -1,
+  0,   5,   8,   -1,  -1,
+  1,   4,   6,   9,   -1,
+  2,   5,   7,   10,  -1,
+  3,   6,   11,  -1,  -1,
+  4,   9,   12,  -1,  -1,
+  5,   8,   10,  13,  -1,
+  6,   9,   11,  14,  -1,
+  7,   10,  15,  -1,  -1,
+  8,   13,  -1,  -1,  -1,
+  9,   12,  14,  -1,  -1,
+  10,  13,  15,  -1,  -1,
+  11,  14,  -1,  -1,  -1,
+};
+
+bool Board::is_valid() const {
+  bool seen[BOARD_SIZE];
+  for (int i = 0; i < BOARD_SIZE; i++) {
+    seen[i] = false;
+  }
+
+  for (int i = 0; i < BOARD_SIZE; i++) {
+    if (board[i] < 0 || board[i] >= BOARD_SIZE || seen[board[i]]) {
+      return false;
+    }
+    seen[board[i]] = true;
+  }
+
+  // Redundant because pigeon-hole-principle, but check anyway
+  for (int i = 0; i < BOARD_SIZE; i++) {
+    if (!seen[i]) {
+      return false;
+    }
+  }
+
+  return true;
+}
+
+std::istream& operator>>(std::istream& is, Board& board) {
+  for (int i = 0; i < BOARD_SIZE; i++) {
+    if (!is.good()) {
+      is.setstate(std::istream::failbit);
+      break;
+    }
+    if (i > 0 && is.get() != ',') {
+      is.setstate(std::istream::failbit);
+      break;
+    }
+    int numeric;
+    is >> numeric;
+    board.board[i] = numeric;
+  }
+  if (!board.is_valid()) {
+    is.setstate(std::istream::failbit);
+  }
+  return is;
+}
+
+signed char Board::hole() const {
+  for (int i = 0; i < BOARD_SIZE; i++) {
+    if (board[i] == 0) {
+      return i;
+    }
+  }
+  throw std::runtime_error("Board with no hole");
+}