DUB error I can't make sense of
https://github.com/nordlow/phobos-next/releases/tag/v0.6.10 fails to build as ``` ../../.dub/cache/phobos-next/0.6.10/code/phobos-next-test-library-unittest-nyN4MEoglVgAJ1A9GyL6uA/dub_test_root.d(11,15): Error: module `nxt.algorithm.comparsion` from file src/nxt/algorithm/comparison.d must be imported with 'import nxt.algorithm.comparsion;' ``` and I have no clue how to fix it. Do you?
Re: DUB error I can't make sense of
On 16/03/2024 8:23 PM, Per Nordlöw wrote: https://github.com/nordlow/phobos-next/releases/tag/v0.6.10 fails to build as ``` ../../.dub/cache/phobos-next/0.6.10/code/phobos-next-test-library-unittest-nyN4MEoglVgAJ1A9GyL6uA/dub_test_root.d(11,15): Error: module `nxt.algorithm.comparsion` from file src/nxt/algorithm/comparison.d must be imported with 'import nxt.algorithm.comparsion;' ``` and I have no clue how to fix it. Do you? ``module nxt.algorithm.comparsion;`` comparsion doesn't look much like comparison to me ;)
Re: DUB error I can't make sense of
On Saturday, 16 March 2024 at 07:23:09 UTC, Per Nordlöw wrote: Do you? Fixed it. There was some invisible character that confused the compiler.
Re: DUB error I can't make sense of
On Saturday, 16 March 2024 at 07:27:17 UTC, Richard (Rikki) Andrew Cattermole wrote: Do you? ``module nxt.algorithm.comparsion;`` comparsion doesn't look much like comparison to me ;) I know. I'm crushed. Am I getting dislyctic? ;)
Re: Deriving a struct from another one via template: Easy way to propagate UDAs?
On Thursday, 14 March 2024 at 23:19:37 UTC, Inkrementator wrote: * Is UDA propagation possible without string mixins? @(__traits(getAttributes, thingYouWantToForward)) void yourNewThing() {} * Are template mixins vulnerable to name collisions? http://dpldocs.info/this-week-in-d/Blog.Posted_2020_01_20.html#understanding-mixin-templates
Re: How to make a struct containing an associative array to deeply copy (for repeated usage in foreach) ?
On Friday, 15 March 2024 at 20:36:56 UTC, rkompass wrote: I start to see that D is heavily influenced by C++ (STL), not just C. This is not bad It is just bad; ranges are not pairs of 2 pointers, stepov was comprising with c++ or if he thinks c++ iterators are objectively good(not good for making something work with c++) he's lacks taste even simplified a "random access range" is to complex an api(close to 20 functions) when Im pretty sure you need 6 functions for a coherent array-like interface and when your talking about 100 algorthims, well 1400 functions matters
Re: Deriving a struct from another one via template: Easy way to propagate UDAs?
On Friday, 15 March 2024 at 19:13:38 UTC, cc wrote: This is trivially easy if your types are visible at module level, and mixin is a fine tool for the job. It doesn't work quite so well with [Voldemort types](https://wiki.dlang.org/Voldemort_types). I used the following lines to make it work for Unknown and I think even Voldemort types. ```d static foreach(att; allFieldTypes){ //pragma(msg, "alias %s =att;\n".format(att.stringof)); mixin("alias %s = att;\n".format(att.stringof)); } ``` But I don't know how to do this (in a general) for UDAs, since they can be values instead of types too, i.e. @UDA(Voldemort!2(3))
Re: Deriving a struct from another one via template: Easy way to propagate UDAs?
On Saturday, 16 March 2024 at 13:09:13 UTC, Adam D Ruppe wrote: On Thursday, 14 March 2024 at 23:19:37 UTC, Inkrementator wrote: @(__traits(getAttributes, thingYouWantToForward)) void yourNewThing() {} Thanks, that should solve my problem. http://dpldocs.info/this-week-in-d/Blog.Posted_2020_01_20.html#understanding-mixin-templates Nice. Btw I vaguely remember you also wrote about how and why to reduce the usage string mixins, with some real example of alternative techniques you used, but I can't find it anymore. The search query 'site:dpldocs.info string mixin "This week in D"' as well as "site:arsdnet.net mixin" don't produce it. Can you link it to me?
Re: Challenge: Make a data type for holding one of 8 directions allowing increment and overflow
On Friday, 15 March 2024 at 00:21:42 UTC, H. S. Teoh wrote: On Thu, Mar 14, 2024 at 11:39:33PM +, Liam McGillivray via Digitalmars-d-learn wrote: [...] I tried to rework the functions to use bitwise operations, but it was difficult to figure out the correct logic. I decided that it's not worth the hassle, so I just changed the value storage from `bool[3]` to `ubyte`. [...] Just wanted to note that while in theory bool[3] could be optimized by the compiler for compact storage, what you're most likely to get is 3 bytes, one for each bool, or perhaps even 3 ints (24 bytes). When dealing with units of data smaller than a byte, you generally need to do it manually, because memory is not addressable by individual bits, making it difficult to implement things like slicing an array of bool. So the compiler is most likely to simplify things by making it an array of bytes rather than emit complex bit manipulation code to make up for the lack of bit-addressability in the underlying hardware. Using bit operators like others have pointed out in this thread is probably the best way to implement what you want. T I'm curious as to what "manual implementation" would mean, since clearly making my own struct with `bool[3]` doesn't count. Does D have features for precise memory manipulation? Anyway, I'm surprised that D has a special operator `&=` for doing bit manipulation on integers, especially given that the steps to convert an int into a bool array is more complicated. I would imagine the former would be a rather niche thing.
Re: Challenge: Make a data type for holding one of 8 directions allowing increment and overflow
On Friday, 15 March 2024 at 17:25:09 UTC, Daniel N wrote: On Tuesday, 12 March 2024 at 05:38:03 UTC, Liam McGillivray wrote: I am in need of a data type for holding direction information; one of 8 directions on a single axis. They are named in terms of compass directions. If D had a 4-bit datatype, I would just use this and do `+=2` whenever I want to change the datatype, but it doesn't. Perhaps this would be a good programming challenge for someone more experienced than me. Make a data type (probably a struct) for holding one of 8 directional values using 3 bits. It should accept the use of increment operators to change the angle. Ideally (but optionally), it should work as an enum of the same name; "Direction". Here's a unittest that it should ideally pass: D actually supports both 3 and 4 bit integers. People will likely warn you of minor portability risks... but if you target a limited amount of platforms and prefer concise readable code, then it's a text book example for bitfields. The risk can easily be mitigated by having an unittest to catch the error directly(if you try to port to some exotic platform). dmd -preview=bitfields (Some lines stolen from Rikki) ```d struct Direction { private uint value : 3; alias this = value; enum Direction N = Direction(0); enum Direction NE = Direction(1); enum Direction E = Direction(2); enum Direction SE = Direction(3); enum Direction S = Direction(4); enum Direction SW = Direction(5); enum Direction W = Direction(6); enum Direction NW = Direction(7); } ``` Oh wow! That looks so clean and elegant, aside from the `: 3` part being easy to miss, and not very readable for those not aware of this feature. This would be so simple. If I used this, I wouldn't even need to make a struct and write the operator overload functions; just make an enum for a 3-bit uint. Based on the words in the command and a quick search, I'm guessing that this is an experimental feature that has not yet been accepted as part of the language. Perhaps I shouldn't use this then, just in case it gets pulled and someone who discovers my project in the future will have a build error that they don't know how to solve. This seems like a bigger problem than the extra memory the current ubyte version takes up, which is probably quite small for a computer of today anyway. I suppose this would be a nice feature for the language to have if the syntax were reworked. Perhaps something like `uint!3 value;` would be better.
Re: varargs when they're not all the same type?
On Friday, 15 March 2024 at 00:11:11 UTC, Andy Valencia wrote: (varargs & friends) Which statement leads me to section 77.2 of "Programming in D", and now I am deep into the mechanisms behind what you have very kindly shared. Thank you once more. As some fruits of my labors here, below is a link to a "fmt" module which does C-style formatting. It supports int/long signed/unsigned, right/left padding and zero padding, plus strings (w. padding). It's memory and type safe; I ended up using unions to tabulate the arguments as I need to access them as an array (rather than walking them--I'm walking the format string instead). It adds 6k to an executable, which means dlang will work out fine for all of my smaller scripting needs in the future. Calls look like: auto s = fmt("%d %u - %20s", 123, 456, "Hi, Mom"); https://sources.vsta.org:7100/dlang/file?name=fmt.d&ci=tip Comments are welcome! I'd post here, but it seems a little long for that? Andy
Reworking the control flow for my tactical role-playing game
As many of you know, I have been trying to write a tactical role-playing game (a mix of turn-based stategy & RPG) in D. This is the furthest I have ever gotten in making an interactive program from the main function up. Right now, it is not yet playable as a game, but you can interact with it and get a rough idea of what I'm going for. Feel free to download and run it to see what I have so far. https://github.com/LiamM32/Open_Emblem I'm now at a point where I have trouble figuring out the next step to making the game playable. The complexity may have just reached a point where I find it harder to keep track of everything that I have written. There is probably a fair amount of unused code that I abandoned after deciding on a different solution, but forgot to delete. There are probably also some amateur decisions I've made in structuring the program, given that I largely figured it out myself. For some time now I've thought that I may later want to overhaul how the whole rendering and UI system work. Perhaps now is a good time since my productivity under the current system is slowing down. ## The Current Structure: The code for Open Emblem (name subject to change) is split between a source library, which handles the internal game logic, and a graphical front-end program which uses that library, but makes it usable. When starting, I decided to structure it this way so that I can experiment with different graphics and UI libraries. This may have been a good move, even if it complicates some aspects, as the first library I tried wasn't the one I've stuck with. I also thought that this library may also be usable as a platform for others to make their own tactical RPG games, though that's unlikely with the current direction of the project. ### The Library: The most important modules here are `map`, `tile`, & `unit`, which contain the classes `Map`, `Tile`, & `Unit`. There is nothing here specific to any particular graphics or game library. Well, `Map` is now longer actually a class, as it's been replaced by the `Map` interface and `MapTemp` template which implements it, but for simplicity, I'll refer to `Map` as a class. This class is meant to serve as the master that controls the flow of a single game mission. Only one instance is meant to exist at a time. It holds a 2-dimensional array of `Tile` objects which represents the grid that the game is on (like a chessboard) and an array of all `Unit` objects. `Unit` represents a character in the game that can be moved on the map (like a chess piece). It has some stats stored as variables, and some functions to do various things a player (or AI) may ask the unit to do during their turn. Each unit occupies a tile object. `Tile` is a square on the map, which has it's own *x* & *y* coordinate. The `Faction` class currently only serves to store a set of units belonging to a certain player or AI, but is planned to play a bigger role later. ### The Raylib Front-end: After looking at many libraries and taking a shot at [ae](https://github.com/CyberShadow/ae) & [godot-D](https://github.com/godot-d/godot-d) but not really figuring it out, I was recommended [raylib-d](https://github.com/schveiguy/raylib-d), a binding for [raylib](https://www.raylib.com/) by @Steven Schveighoffer. Raylib is a rather simple graphical library written in C. I ended up sticking with it because the website has so many easy-to-follow examples that make it easy as my first graphical library. They're written in, but I adapted them to D rather easily. Of course, being written in C has limitations as it isn't object-oriented. This is front-end is in the [`oe-raylib/`](https://github.com/LiamM32/Open_Emblem/tree/master/oe-raylib) directory. For this front-end, I've made the classes `VisibleTile` and `VisibleUnit`, which inherit `Tile` & `Unit`, but add sprite data and other graphics-related functionality. I then have the `Mission` class which inherits the `MapTemp` class. This class dominates the program flow in it's current state. It handles loading data from JSON files, switching between different game phases and does most of the function calls related to rendering and input. The way I have it currently, there's a `startPreparation` function and `playerTurn` function, each of which run a once-per-frame loop that renders all the necessary objects and takes user input. They each have a rather messy set of if-statements for the UI system. Any UI elements that may pop-up are declared before the loop begins, with if-statements to determine whether they should be visible this frame. For UI elements, I currently have `version` flags for either `customgui` (which I started writing before discovering raygui) and `customgui`, which you can select between using `dub --config=`. Having both makes the code messier, but I haven't yet decided on which I prefer. They are both currently achieve equivalent functionality.
Re: Challenge: Make a data type for holding one of 8 directions allowing increment and overflow
On Sat, Mar 16, 2024 at 09:16:51PM +, Liam McGillivray via Digitalmars-d-learn wrote: > On Friday, 15 March 2024 at 00:21:42 UTC, H. S. Teoh wrote: [...] > > When dealing with units of data smaller than a byte, you generally > > need to do it manually, because memory is not addressable by > > individual bits, making it difficult to implement things like > > slicing an array of bool. [...] > I'm curious as to what "manual implementation" would mean, since > clearly making my own struct with `bool[3]` doesn't count. Does D have > features for precise memory manipulation? Manual implementation as in you would deal with the machine representation in terms of bytes, or more likely, uints (on modern CPUs even though bytes are individually addressible, the hardware actually works in terms of a larger unit, typically an 4-byte 32-bit unit, or an 8-byte 64-bit unit), using bitwise operators to manipulate the bits the way you want to. > Anyway, I'm surprised that D has a special operator `&=` for doing bit > manipulation on integers, especially given that the steps to convert > an int into a bool array is more complicated. I would imagine the > former would be a rather niche thing. You should understand that bitwise operators are directly implemented in hardware, and thus operators like &, |, ^, <<, >>, ~, etc., typically map directly to individual CPU instructions. As such, they are very fast, and preferred when you're doing bit-level manipulations. At this level, you typically do not work with individual bits per se, but with machine words (typically 32-bit or 64-bit units). Bitwise operators operate on all 32 or 64 bits at once, so performance-aware code typically manipulates all these bits simultaneously rather than individually. Of course, using suitable bit-masking you *can* address individual bits, but the hardware instructions themselves typically work with all 32/64 bits at once. Here's a simple example. Suppose you have 3 bits you want to store. Since the machine doesn't have a 3-bit built-in type, you typically just use the next larger available size, either a ubyte (8 bits) if you want compact storage, or if compactness isn't a big issue just a uint (32 bits, you just ignore the other 29 bits that you don't need). So you'd declare the storage something like this: uint myBits; Bits are usually indexed from 0, so bit 0 is the first position, bit 1 is the second position, and so on. So to set the first bit to 1, you'd do: myBits |= 0b001; Note that at the machine level, this operator works on all 32 bits at the same time. Most of the bits remain unchanged, though, because bitwise OR does not change the original value if the operand is 0. So the overall effect is that the first bit is set. To set the first bit to 0, there isn't a direct operator that does that, but you can take advantage of the behaviour of bitwise AND, in which any bit which is 0 in the operand will get cleared, everything else remains unchanged. So you'd do this: myBits &= 0b110; Now, since we don't really care about the other 29 bits, we could write this as follows instead, to make our intent clearer: myBits &= ~0b001; The ~ operator flips all the bits, so this is equivalent to writing: myBits &= ~0b_______1110; Writing it with ~ also has the advantage that should we later decide to add another bit to our "bit array", we don't have to update the code; whereas if we'd used `myBits &= 0b110;` then we'd need to change it to `myBits &= 0b1110;` otherwise our new 4th bit may get unexpectedly cleared when we only wanted to clear the first bit. Now, what if we wanted to set both the 1st and 3rd bits? In a hypothetical bit array implementation, we'd do the equivalent of: bool[3] myBits; myBits[0] = 1; myBits[2] = 1; However, in our uint approach, we can cut the number of operations by half, because the CPU is already operating on the entire 32 bits of the uint at once -- so there's no need to have two instructions to set two individual bits when we could just do it all in one: myBits |= 0b101; // look, ma! both bits set at once! Similarly, to clear the 1st and 3rd bits simultaneously, we simply write: myBits &= ~0b101; // clear both bits in 1 instruction! Of course, when we only have 3 bits to work with, the savings isn't that significant. However, if you have a larger bit array, say you need an array of 32 bits, this can speed your code up by 32x, because you're taking advantage of the fact that the hardware is already operating on all 32 bits at the same time. On 64-bit CPUs, you can speed it up by 64x because the CPU operates on all 64 bits simultaneously, so you can manipulate an entire array of 64 bits in a single instruction, which is 64x faster than if you looped over an array of bool with 64 iterations. T -- Without outlines, life would be pointless.
Re: Challenge: Make a data type for holding one of 8 directions allowing increment and overflow
Bit fields are currently going through the DIP process, although because of ImportC having it, its just a matter of turning them on and adding the parser stuff. However there is a major drawback to it and is why you'll still need to use a struct and that is you can't take a pointer to it.