1  using System;
   2  
   3  class GridIterator {
   4      public enum Direction { East, South, SouthEast, NorthEast };
   5  
   6      public GridIterator(int wordLength, GridDimensions gridDimensions) { // Initial word placement
   7          wordLength_ = wordLength;
   8          gridDimensions_ = gridDimensions;
   9          xFirstLetter_ = 0;
  10          yFirstLetter_ = 0;
  11          direction_ = wordLength_ <= gridDimensions_.width_ ? Direction.East : Direction.South;
  12          backwards_ = false;
  13  
  14          // Invalid if word is too long for GridDimensions:
  15          isValid_ = direction_ == Direction.East || wordLength_ <= gridDimensions_.height_;  
  16      }
  17  
  18      public bool isValid() { return isValid_; }
  19  
  20      public bool canPlace(string word, Grid grid) {
  21          if (word.Length != wordLength_) throw new Exception("Error:  Require same word length.");
  22          switch (direction_) {
  23              case Direction.East: {
  24                      int xLastLetter = xFirstLetter_ + wordLength_ - 1;
  25                      for (int x = xFirstLetter_; x <= xLastLetter; ++x) {
  26                          char cell = grid.getCell(x, yFirstLetter_);
  27                          if (cell != ' ' && cell != word[backwards_ ? xLastLetter - x : x - xFirstLetter_]) return false;
  28                      }
  29                  }
  30                  break;
  31  
  32              case Direction.South:  {
  33                      int yLastLetter = yFirstLetter_ + wordLength_ - 1;
  34                      for (int y = yFirstLetter_; y <= yLastLetter; ++y) {
  35                          char cell = grid.getCell(xFirstLetter_, y);
  36                          if (cell != ' ' && cell != word[backwards_ ? yLastLetter - y : y - yFirstLetter_]) return false;
  37                      }
  38                  }
  39                  break;
  40  
  41              case Direction.SouthEast: {
  42                      int xLastLetter = xFirstLetter_ + wordLength_ - 1;
  43                      if (xLastLetter >= gridDimensions_.width_) return false;
  44                      for (int x = xFirstLetter_; x <= xLastLetter; ++x) {
  45                          char cell = grid.getCell(x, yFirstLetter_ + x - xFirstLetter_);
  46                          if (cell != ' ' && cell != word[backwards_ ? xLastLetter - x : x - xFirstLetter_]) return false;
  47                      }
  48                  }
  49                  break;
  50  
  51              case Direction.NorthEast: {
  52                      int xLastLetter = xFirstLetter_ + wordLength_ - 1;
  53                      if(xLastLetter>=gridDimensions_.width_) return false;
  54                      for (int x = xFirstLetter_; x <= xLastLetter; ++x) {
  55                          char cell = grid.getCell(x, yFirstLetter_ - x + xFirstLetter_);
  56                          if (cell != ' ' && cell != word[backwards_ ? xLastLetter - x : x - xFirstLetter_]) return false;
  57                      }
  58                  }
  59                  break;
  60  
  61          }
  62          return true;
  63      }
  64  
  65  
  66      public void place(string word, Grid grid) {
  67          switch (direction_) {
  68              case Direction.East: {
  69                      int xLastLetter = xFirstLetter_ + wordLength_ - 1;
  70                      for (int x = xFirstLetter_; x <= xLastLetter; ++x) {
  71                          grid.setCell(x, yFirstLetter_, word[backwards_ ? xLastLetter - x : x - xFirstLetter_]);
  72                      }
  73                  }
  74                  break;
  75  
  76              case Direction.South: {
  77                      int yLastLetter = yFirstLetter_ + wordLength_ - 1;
  78                      for (int y = yFirstLetter_; y <= yLastLetter; ++y) {
  79                          grid.setCell(xFirstLetter_, y, word[backwards_ ? yLastLetter - y : y - yFirstLetter_]);
  80                      }
  81                  }
  82                  break;
  83  
  84              case Direction.SouthEast: {
  85                      int xLastLetter = xFirstLetter_ + wordLength_ - 1;
  86                      for (int x = xFirstLetter_; x <= xLastLetter; ++x) {
  87                          grid.setCell(x, yFirstLetter_ + x - xFirstLetter_, word[backwards_ ? xLastLetter - x : x - xFirstLetter_]);
  88                      }
  89                  }
  90                  break;
  91  
  92              case Direction.NorthEast: {
  93                      int xLastLetter = xFirstLetter_ + wordLength_ - 1;
  94                      for (int x = xFirstLetter_; x <= xLastLetter; ++x) {
  95                          grid.setCell(x, yFirstLetter_ - x + xFirstLetter_, word[backwards_ ? xLastLetter - x : x - xFirstLetter_]);
  96                      }
  97                  }
  98                  break;
  99          }
 100      }
 101  
 102  
 103      public void increment() { 
 104          if (!isValid_) throw new Exception("Error:  Attempt to increment() invalid GridIterator.");
 105  
 106          // Always change backwards_:
 107          backwards_ = !backwards_;
 108          if(backwards_) return;
 109  
 110          switch (direction_) {
 111              case Direction.East: {
 112                  if(xFirstLetter_<gridDimensions_.width_ - wordLength_) xFirstLetter_++;
 113                  else {
 114                      xFirstLetter_ = 0;
 115                      if(yFirstLetter_<gridDimensions_.height_-1) yFirstLetter_++;                    
 116                      else {
 117                          yFirstLetter_ = 0;
 118                          direction_ = Direction.South;
 119                          if(wordLength_ > gridDimensions_.height_) isValid_ = false;
 120                          }
 121                      }                    
 122                  }
 123                  break;
 124  
 125              case Direction.South: {  
 126                  if (yFirstLetter_ < gridDimensions_.height_ - wordLength_) yFirstLetter_++;
 127                  else {
 128                      yFirstLetter_ = 0;
 129                      if (xFirstLetter_ < gridDimensions_.width_ - 1) xFirstLetter_++;
 130                      else {
 131                          xFirstLetter_ = 0;
 132                          direction_ = Direction.SouthEast;
 133                          }
 134                      }
 135                  }
 136                  break;
 137  
 138              case Direction.SouthEast:  {
 139                  if (xFirstLetter_ < gridDimensions_.width_ - wordLength_) xFirstLetter_++;
 140                  else {
 141                      xFirstLetter_ = 0;
 142                      if (yFirstLetter_ < gridDimensions_.height_ - wordLength_) yFirstLetter_++;
 143                      else {
 144                          yFirstLetter_ = wordLength_ -1;
 145                          direction_ = Direction.NorthEast;
 146                          }
 147                      } 
 148                  }
 149                  break;
 150  
 151              case Direction.NorthEast: {
 152                  if (xFirstLetter_ < gridDimensions_.width_ - wordLength_) xFirstLetter_++;
 153                  else {
 154                      xFirstLetter_ = 0;
 155                      if (yFirstLetter_ < gridDimensions_.height_ - 1) yFirstLetter_++;
 156                      else isValid_ = false;
 157                      } 
 158                  }
 159                  break;
 160          }
 161      }
 162  
 163      // ======= Data Members ========
 164      private int wordLength_;
 165      private GridDimensions gridDimensions_;
 166      private int xFirstLetter_;
 167      private int yFirstLetter_;
 168      private Direction direction_;
 169      private bool backwards_;
 170      private bool isValid_;
 171  }
 172  
 173