On Tuesday, 12 March 2024 at 06:38:28 UTC, Richard (Rikki) Andrew Cattermole wrote:
By taking advantage of integer wrapping and a bitwise and, its quite a simple problem to solve!

Challenge for the reader: add support for binary operations and toString support.

Last night I pushed the latest commit to the GitHub repository for my game. It contains the `Direction` struct in [`source/common.d`](https://github.com/LiamM32/Open_Emblem/blob/master/source/common.d). Here it is:

```
struct Direction //One of 8 directions stored in 3 bits
{
    import std.conv;
    import std.traits: isNumeric;

    bool[3] b;

    static Direction N = Direction(b:[false,false,false]);
    static Direction NE = Direction(b:[true,false,false]);
    static Direction E = Direction(b:[false,true,false]);
    static Direction SE = Direction(b:[true,true,false]);
    static Direction S = Direction(b:[false,false,true]);
    static Direction SW = Direction(b:[true,false,true]);
    static Direction W = Direction(b:[false,true,true]);
    static Direction NW = Direction(b:[true,true,true]);

ref Direction opUnary(string op)() if (op == "++" || op == "--") {
        static if (op == "++") const bool up = true;
        else const bool up = false;

        if (b[0]) {
            if (b[1]) b[2] = !b[2];
            b[1] = !b[1];
        }
        b[0] = !b[0];
        return this;
    }

void opOpAssign(string op)(int amount) if (op == "+" || op == "-") {
        amount = amount%8;
        if (amount > 0) for (uint i = 0; i < amount; i++) {
            static if (op=="+") this++;
            else this--;
        } else for (uint i=0; i > amount; i--) {
            static if (op=="+") this--;
            else this++;
        }
    }

    T to(T)() const if(isNumeric!T) {
        return cast(T)(b[0] + 2*b[1] + 4*b[2]);
    }

    T opCast(T)() if (isNumeric!T) {
        return cast(T)(b[0] + 2*b[1] + 4*b[2]);
    }

    T to(T)() const if(is(T==string)) {
        if (this==Direction.N) return "north";
        else if (this==Direction.NE) return "northeast";
        else if (this==Direction.E) return "east";
        else if (this==Direction.SE) return "southeast";
        else if (this==Direction.S) return "south";
        else if (this==Direction.SW) return "southwest";
        else if (this==Direction.W) return "west";
        else if (this==Direction.NW) return "northwest";
else throw new Exception("Direction.to!: direction has a value that should be impossible.");
        //else return ""; //This should never happen.
    }

    bool[3] opCast() const {
        return this.b;
    }

    Direction opposite() const {
        return Direction([b[0], b[1], !b[2]]);
    }

    bool diagonal() {
        return b[0];
    }

    int getAngle() {
        if (this==Direction.N) return 0;
        else if (this==Direction.NE) return 45;
        else if (this==Direction.E) return 90;
        else if (this==Direction.SE) return 135;
        else if (this==Direction.S) return 180;
        else if (this==Direction.SW) return 225;
        else if (this==Direction.W) return 270;
        else if (this==Direction.NW) return 315;
else throw new Exception("Direction.getAngle: direction has a value that should be impossible.");
    }
}
```

The one thing that cant be done on this is doing `direction+8`. Perhaps it would have been easier if I had chosen to store the value as a ubyte rather than an array of bools. While this is probably over-optimized given the large amount of memory in today's computers, I like it that it can never be an illegitimate value.

There's probably some trick I can use to make it easier to figure out the functions to do numerical operations on bits, but I don't know how best to cleanly represent this kind of thing in code. Maybe I need to look for examples of how it's already done.

I noticed among the options for overloading unary operations are the symbols "+" & "-". What operation is being overloaded with the function `ref Direction opUnary(string op:"+")(int amount)`?
  • Challenge: Make ... Liam McGillivray via Digitalmars-d-learn
    • Re: Challen... Richard (Rikki) Andrew Cattermole via Digitalmars-d-learn
      • Re: Cha... Liam McGillivray via Digitalmars-d-learn
        • Re:... Richard (Rikki) Andrew Cattermole via Digitalmars-d-learn
      • Re: Cha... Liam McGillivray via Digitalmars-d-learn
        • Re:... Richard (Rikki) Andrew Cattermole via Digitalmars-d-learn
          • ... Liam McGillivray via Digitalmars-d-learn
            • ... Basile B. via Digitalmars-d-learn
              • ... Richard (Rikki) Andrew Cattermole via Digitalmars-d-learn
                • ... Basile B. via Digitalmars-d-learn
            • ... H. S. Teoh via Digitalmars-d-learn
            • ... Liam McGillivray via Digitalmars-d-learn
              • ... H. S. Teoh via Digitalmars-d-learn
    • Re: Challen... Salih Dincer via Digitalmars-d-learn
    • Re: Challen... Basile B. via Digitalmars-d-learn

Reply via email to