Commits

Kirill Morarenko  committed bc8dc77 Draft

update() implemented

  • Participants
  • Parent commits fe29da0

Comments (0)

Files changed (3)

File fastsim/constants.h

+// blocks
 const char C_ROBOT = 'R';
 const char C_WALL = '#';
 const char C_ROCK = '*';
 const char C_OPEN_LIFT = 'O';
 const char C_EARTH = '.';
 const char C_EMPTY = ' ';
+const char C_INVALID = 0;
 
+// commands
 const char CMD_LEFT = 'a';
 const char CMD_RIGHT = 'd';
 const char CMD_UP = 'w';
 const char CMD_DOWN = 's';
+
+// points
+const int P_LAMBDA = 25;
+const int P_MOVE = -1;

File fastsim/map.cpp

     }
     stream << std::endl;
   }
+  stream << "Points so far: " << map.points() << std::endl;
 }
 
 Map readMap(std::istream& stream){
   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){
+      char in_there = get(col, row);
+      if (in_there == C_ROBOT){
 	assert(!robot_found);
-	m_robot = Point(row, col);
+	m_robot = Point(col, row);
 	robot_found = true;
+      } else if (in_there == C_LAMBDA){
+	m_lambdas.insert(Point(col, row));
       }
     }
   }
   }
   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
+      // we're withing map bounds, no check that there's not an obstacle at the target
+      // Rules: 2.2
       char inThere = map.get(p);
       // direct move
       if (inThere == C_EMPTY || inThere == C_EARTH || inThere == C_LAMBDA || inThere == C_OPEN_LIFT){
     return false;
   }
 }
+char Map::safeGet(size_t col, size_t row) const{
+  if (isValidPoint(*this, Point(col, row))){
+    return get(col, row);
+  }
+  return C_INVALID;
+}
+char Map::safeGet(const Point& p) const{
+  if (isValidPoint(*this, p)){
+    return get(p);
+  }
+  return C_INVALID;
+}
+void Map::collectLambda(const Point& p){
+  std::set<Point>::const_iterator the_lambda = m_lambdas.find(p);
+  assert(the_lambda != m_lambdas.end());
+  m_lambdas.erase(the_lambda);
+  m_points += P_LAMBDA;
+}
 bool Map::go(const Point& p){
   bool validMove = false;
   if (canGoTo(*this, p)){
       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
+    } else if (get(p) == C_LAMBDA){
+      collectLambda(p);
     }
     get(p) = C_ROBOT;
     get(m_robot) = C_EMPTY;
     m_robot = p;
+    m_points += P_MOVE;
   }
   update();
   return validMove;
 }
 
 void Map::update(){
+  Map newMap(*this); // TODO return a new map? we have to create a new one anyways
+  for (size_t row = 0; row < rows(); ++row){
+    for (size_t col = 0; col < cols(); ++col){
+      char in_there = get(col, row);
+      // Rules: 2.3
+      if (in_there == C_ROCK && safeGet(col, row - 1) == C_EMPTY){
+	// 2.3.1
+	newMap.get(col, row) = C_EMPTY;
+	newMap.get(col, row - 1) = C_ROCK;
+      } else if (in_there == C_ROCK && safeGet(col, row - 1) == C_ROCK && safeGet(col + 1, row) == C_EMPTY && safeGet(col + 1, row - 1) == C_EMPTY){
+	// 2.3.2
+	newMap.get(col, row) = C_EMPTY;
+	newMap.get(col + 1, row - 1) = C_ROCK;
+      } else if (in_there == C_ROCK 
+		 && safeGet(col, row - 1) == C_ROCK 
+		 && (
+		     (safeGet(col + 1, row) != C_EMPTY && safeGet(col + 1, row) != C_INVALID) ||
+		     (safeGet(col + 1, row - 1) != C_EMPTY && safeGet(col + 1, row - 1) != C_INVALID)
+		     )
+		 && safeGet(col - 1, row) == C_EMPTY
+		 && safeGet(col - 1, row - 1) == C_EMPTY){
+	// 2.3.3
+	newMap.get(col, row) = C_EMPTY;
+	newMap.get(col - 1, row - 1) = C_ROCK;
+      } else if (in_there == C_ROCK 
+		 && safeGet(col, row - 1) == C_LAMBDA 
+		 && safeGet(col + 1, row) == C_EMPTY
+		 && safeGet(col + 1, row - 1) == C_EMPTY){
+	// 2.3.4
+	newMap.get(col, row) = C_EMPTY;
+	newMap.get(col + 1, row - 1) = C_ROCK;
+      } else if (in_there == C_CLOSED_LIFT && m_lambdas.size() == 0){
+	// 2.3.5
+	newMap.get(col, row) = C_OPEN_LIFT;
+      } else{
+	// 2.3.6
+	newMap.get(col, row) = in_there;
+      }
+    }
+  }
+  *this = newMap;
 }

File fastsim/map.h

 // -*- mode:c++; tab-width: 2; indent-tabs-mode: nil -*-
 #include <vector>
 #include <iosfwd>
-#include <unordered_map>
+//#include <unordered_map>
+#include <set>
 
 #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)) {}
+  Map(size_t cols, size_t rows) : m_rows(rows), m_cols(cols), m_data(std::vector<char>(rows * cols, C_EMPTY)), m_points(0) {}
   size_t cols() const {return m_cols;}
   size_t rows() const {return m_rows;}
+  int points() const {return m_points;}
   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);}
+  char safeGet(size_t col, size_t row) const; // checks the boundaries
+  char safeGet(const Point& p) const; // checks the boundaries
 
-  const Point& getRobot() const{
-    return m_robot;
-  }
+  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;}
+
+  void collectLambda(const Point& p);
 private:
   bool go(const Point& p);
   void update();
   size_t m_cols;
   std::vector<char> m_data;
   Point m_robot;
+  int m_points;
+  std::set<Point> m_lambdas;
 };
 
 void printMap(const Map& map, std::ostream& stream);