| 250 | class KnightsReified : public Knights { |
| 251 | public: |
| 252 | KnightsReified(const SizeOptions& opt) : Knights(opt) { |
| 253 | const int nn = n*n; |
| 254 | |
| 255 | // Map knight to its predecessor of successor on board |
| 256 | IntVarArgs jump(nn); |
| 257 | IntVarArgs pred(nn); |
| 258 | |
| 259 | for (int i = nn; i--; ) { |
| 260 | IntVar p(*this,0,nn-1); pred[i]=p; |
| 261 | IntVar j(*this,0,nn-1); jump[i]=j; |
| 262 | } |
| 263 | |
| 264 | // Place the first two knights |
| 265 | rel(*this, jump[f(0,0)], IRT_EQ, 0); |
| 266 | rel(*this, jump[f(1,2)], IRT_EQ, 1); |
| 267 | |
| 268 | distinct(*this, jump, opt.ipl()); |
| 269 | channel(*this, succ, pred, opt.ipl()); |
| 270 | |
| 271 | for (int f = 0; f < nn; f++) { |
| 272 | IntSet ds = neighbors(f); |
| 273 | for (IntSetValues i(ds); i(); ++i) |
| 274 | rel(*this, |
| 275 | expr(*this, (jump[i.val()]-jump[f] == 1)), |
| 276 | BOT_XOR, |
| 277 | expr(*this, (jump[i.val()]-jump[f] == 1-nn)), |
| 278 | expr(*this, (succ[f] == i.val()))); |
| 279 | dom(*this, pred[f], ds); |
| 280 | dom(*this, succ[f], ds); |
| 281 | rel(*this, succ[f], IRT_NQ, pred[f]); |
| 282 | } |
| 283 | } |
| 284 | /// Constructor for cloning \a s |
| 285 | KnightsReified(KnightsReified& s) : Knights(s) {} |
| 286 | /// Copy during cloning |