Jump to content

Sokoban: Difference between revisions

Safer second D entry
(→‎{{header|Perl}}: Totally rewrote the perl solution.)
(Safer second D entry)
Line 923:
 
enum Cell : ubyte { space, wall, player, box }
alias CellIndex = ushort;
 
alias CellIndexThash = ushort,uint;
hash_t = uint;
 
 
Line 931 ⟶ 930:
/// indices of player and boxes.
struct State { // Variable length struct.
hash_tThash h;
State* prev, next, qNext;
CellIndex[0] c_;
 
ref CellIndex idxget(in size_t i) inout pure nothrow inout {
return (cast(CellIndex*)&c_).ptr[i];
}
 
void set(in size_t i, in CellIndex v) pure nothrow {
c_.ptr[i] = v;
}
 
CellIndex[] slice(in size_t i, in size_t j) pure nothrow {
return (cast(CellIndex*)&c_).ptr[i .. j];
}
}
Line 950 ⟶ 953:
__gshared State* blockRoot, blockHead, nextLevel, done;
__gshared State*[] buckets;
__gshared hash_tThash hashSize, fillLimit, filled;
 
 
Line 1,058 ⟶ 1,061:
i.markLive;
if (s[i] == '$' || s[i] == '*')
state.idxset(++j) =, i);
else if (s[i] == '@' || s[i] == '+')
state.idxset(0) =, i);
}
 
Line 1,070 ⟶ 1,073:
void hash(State* s, in size_t nBoxes) pure nothrow {
if (!s.h) {
hash_tThash ha = 0;
foreach (immutable i; 0 .. nBoxes + 1)
ha = s.idxget(i) + 31 * ha;
s.h = ha;
}
Line 1,097 ⟶ 1,100:
buckets[oldSize .. hashSize] = null;
 
immutable hash_tThash bits = hashSize - 1;
foreach (immutable i; 0 .. oldSize) {
auto head = buckets[i];
Line 1,133 ⟶ 1,136:
extendTable;
 
immutable hash_tThash i = s.h & (hashSize - 1);
 
s.next = buckets[i];
Line 1,143 ⟶ 1,146:
bool success(in State* s) nothrow {
foreach (immutable i; 1 .. nBoxes + 1)
if (!goals[s.idxget(i)])
return false;
return true;
Line 1,150 ⟶ 1,153:
 
State* moveMe(State* s, in int dy, in int dx) nothrow {
immutable int y = s.idxget(0) / w;
immutable int x = s.idxget(0) % w;
immutable int y1 = y + dy;
immutable int x1 = x + dx;
Line 1,161 ⟶ 1,164:
int atBox = 0;
foreach (immutable i; 1 .. nBoxes + 1)
if (s.idxget(i) == c1) {
atBox = i;
break;
Line 1,172 ⟶ 1,175:
return null;
foreach (immutable i; 1 .. nBoxes + 1)
if (s.idxget(i) == c2)
return null;
}
Line 1,179 ⟶ 1,182:
n.slice(1, nBoxes + 1)[] = s.slice(1, nBoxes + 1);
 
n.idxset(0) =, cast(CellIndex)c1);
 
if (atBox)
n.idxset(atBox) =, cast(CellIndex)c2);
 
// Bubble sort.
Line 1,188 ⟶ 1,191:
CellIndex t = 0;
foreach (immutable j; 1 .. i) {
if (n.idxget(j) > n.idxget(j + 1)) {
t = n.idxget(j);
n.idxset(j) =, n.idxget(j + 1));
n.idxset(j + 1) =, t);
}
}
Line 1,235 ⟶ 1,238:
b[] = cast(typeof(b))board[];
 
b[s.idxget(0)] = Cell.player;
foreach (immutable i; 1 .. nBoxes + 1)
b[s.idxget(i)] = Cell.box;
 
foreach (immutable i, immutable bi; b) {
Cookies help us deliver our services. By using our services, you agree to our use of cookies.