Commits

Kirill Morarenko  committed fe29da0 Draft

manual operations

  • Participants
  • Parent commits 24ff86e

Comments (0)

Files changed (6)

+~$
+a.out$

File fastsim/constants.h

 const char C_OPEN_LIFT = 'O';
 const char C_EARTH = '.';
 const char C_EMPTY = ' ';
+
+const char CMD_LEFT = 'a';
+const char CMD_RIGHT = 'd';
+const char CMD_UP = 'w';
+const char CMD_DOWN = 's';

File fastsim/main.cpp

+// -*- mode:c++; tab-width: 2; indent-tabs-mode: nil -*-
+#include "map.h"
+
 #include <iostream>
-#include <vector>
+#include <fstream>
 
-#include "constants.h"
-
-class Map{
-public:
-  Map(size_t rows, size_t cols) : m_rows(rows), m_cols(cols), m_data(std::vector<char>(rows * cols, C_EMPTY)) {}
-  size_t cols() const {return m_cols;}
-  size_t rows() const {return m_rows;}
-
-  char& get(size_t row, size_t col){
-    return m_data.at(row * m_cols + col); // replace with []
+int main(int argc, char** argv){
+  bool fromFile = (argc == 2 && std::string(argv[1]) != "-");
+  if (!fromFile){
+    Map map = readMap(std::cin);
+    printMap(map, std::cout);
+    return 0;
   }
-  char get(size_t row, size_t col) const{
-    return m_data.at(row * m_cols + col); // replace with []
-  }
-private:
-  size_t m_rows;
-  size_t m_cols;
-  std::vector<char> m_data;
-};
-
-void printMap(const Map& map, std::ostream& stream){
-  for (size_t row = 0; row < map.rows(); ++row){
-    for (size_t col = 0; col < map.cols(); ++col){
-      stream << map.get(row, col);
+  std::ifstream stream(argv[1]);
+  Map map = readMap(stream);
+  while (true){
+    printMap(map, std::cout);
+    char c;
+    std::cin >> c;
+    switch (c){
+    case CMD_LEFT: map.goLeft(); break;
+    case CMD_RIGHT: map.goRight(); break;
+    case CMD_UP: map.goUp(); break;
+    case CMD_DOWN: map.goDown(); break;
+    default: map.wait();
     }
-    stream << std::endl;
   }
 }
-
-Map readMap(const std::istream& stream){
-  std::vector<std::string> lines;
-  std::string line;
-  size_t cols = 0;
-  while (std::getline(std::cin, line).good()){
-    lines.push_back(line);
-    cols = std::max(cols, line.length());
-  }
-  Map map(lines.size(), cols);
-  for (size_t row = 0; row < lines.size(); ++row){
-    for (size_t col = 0; col < std::min(map.cols(), lines[row].size()); ++col){
-      map.get(row, col) = lines[row][col];
-    }
-  }
-  return map;
-}
-
-int main(){
-  Map map = readMap(std::cin);
-  printMap(map, std::cout);
-}

File fastsim/map.cpp

+// -*- mode:c++; tab-width: 2; indent-tabs-mode: nil -*-
+#include "map.h"
+#include <iostream>
+#include <cassert>
+
+void printMap(const Map& map, std::ostream& stream){
+  for (size_t row = map.rows(); row > 0; --row){
+    for (size_t col = 0; col < map.cols(); ++col){
+      stream << map.get(col, row - 1)/* << "[" << col << "," << row - 1 << "] "*/;
+    }
+    stream << std::endl;
+  }
+}
+
+Map readMap(std::istream& stream){
+  std::vector<std::string> lines;
+  std::string line;
+  size_t cols = 0;
+  while (std::getline(stream, line).good()){
+    lines.push_back(line);
+    cols = std::max(cols, line.length());
+  }
+  Map map(cols, lines.size());
+  for (size_t row = 0; row < lines.size(); ++row){
+    for (size_t col = 0; col < std::min(map.cols(), lines[row].size()); ++col){
+      map.get(col, lines.size() - row - 1) = lines[row][col];
+    }
+  }
+  map.prepare();
+  return map;
+}
+
+
+void Map::prepare(){
+  bool robot_found = false;
+  for (size_t row = 0; row < rows(); ++row){
+    for (size_t col = 0; col < cols(); ++col){
+      if (get(row, col) == C_ROBOT){
+	assert(!robot_found);
+	m_robot = Point(row, col);
+	robot_found = true;
+      }
+    }
+  }
+  assert(robot_found);
+}
+
+namespace{
+  bool isValidPoint(const Map& map, const Point& p){
+    return (p.first >= 0 /*unsigned, but in case we move to signed*/ && p.first < map.cols()
+	    && p.second >= 0 && p.second < map.rows());
+  }
+  bool canGoTo(const Map& map, const Point& p){
+    if (isValidPoint(map, p)){
+      // we're withing map, no check that there's not an obstacle at the target
+      // SEE 2.2 from rules
+      char inThere = map.get(p);
+      // direct move
+      if (inThere == C_EMPTY || inThere == C_EARTH || inThere == C_LAMBDA || inThere == C_OPEN_LIFT){
+	return true;
+      }
+      // move the rock! do this ONLY if going left/right
+      if (inThere == C_ROCK && p.second == map.getRobot().second){
+	bool goingLeft = (map.getRobot().first > p.first);
+	Point newRockPosition(goingLeft ? p.first - 1 : p.first + 1, p.second);
+	if (isValidPoint(map, newRockPosition) && map.get(newRockPosition) == C_EMPTY){
+	  return true;
+	}
+      }
+    }
+    return false;
+  }
+}
+bool Map::go(const Point& p){
+  bool validMove = false;
+  if (canGoTo(*this, p)){
+    validMove = true;
+    if (get(p) == C_ROCK){
+      // move the rock first
+      bool goingLeft = (getRobot().first > p.first);
+      Point newRockPosition(goingLeft ? p.first - 1 : p.first + 1, p.second);
+      get(newRockPosition) = C_ROCK;
+      // don't remove the original rock - it's overwritten two lines below
+    }
+    get(p) = C_ROBOT;
+    get(m_robot) = C_EMPTY;
+    m_robot = p;
+  }
+  update();
+  return validMove;
+}
+
+void Map::update(){
+}

File fastsim/map.h

+// -*- mode:c++; tab-width: 2; indent-tabs-mode: nil -*-
+#include <vector>
+#include <iosfwd>
+#include <unordered_map>
+
+#include "constants.h"
+
+typedef std::pair<size_t, size_t> Point;
+class Map{
+public:
+  Map(size_t cols, size_t rows) : m_rows(rows), m_cols(cols), m_data(std::vector<char>(rows * cols, C_EMPTY)) {}
+  size_t cols() const {return m_cols;}
+  size_t rows() const {return m_rows;}
+  void prepare(); // must be called after the map was filled in
+
+  char& get(size_t col, size_t row){return m_data.at(row * m_cols + col);}
+  char get(size_t col, size_t row) const{return m_data.at(row * m_cols + col);}
+  char& get(const Point& p){return get(p.first, p.second);}
+  char get(const Point& p) const{return get(p.first, p.second);}
+
+  const Point& getRobot() const{
+    return m_robot;
+  }
+  // returns if the move was valid
+  bool goLeft() {return go(Point(getRobot().first - 1, getRobot().second));}
+  bool goRight() {return go(Point(getRobot().first + 1, getRobot().second));}
+  bool goUp() {return go(Point(getRobot().first, getRobot().second + 1));}
+  bool goDown() {return go(Point(getRobot().first, getRobot().second - 1));}
+  bool wait() {update(); return true;}
+private:
+  bool go(const Point& p);
+  void update();
+  size_t m_rows;
+  size_t m_cols;
+  std::vector<char> m_data;
+  Point m_robot;
+};
+
+void printMap(const Map& map, std::ostream& stream);
+Map readMap(std::istream& stream);

File fastsim/run.sh

-g++ -Wall -Werror main.cpp && cat ../maps/contest1.map | ./a.out
+g++ -std=c++0x -Wall -Werror main.cpp map.cpp && ./a.out ../maps/contest1.map