Re: DUB error I can't make sense of

2024-03-16 Thread Richard (Rikki) Andrew Cattermole via Digitalmars-d-learn

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

2024-03-16 Thread Per Nordlöw via Digitalmars-d-learn

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

2024-03-16 Thread Per Nordlöw via Digitalmars-d-learn
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? ;)


DUB error I can't make sense of

2024-03-16 Thread Per Nordlöw via Digitalmars-d-learn

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: How to make a struct containing an associative array to deeply copy (for repeated usage in foreach) ?

2024-03-16 Thread monkyyy via Digitalmars-d-learn

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?

2024-03-16 Thread Adam D Ruppe via Digitalmars-d-learn

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: Challenge: Make a data type for holding one of 8 directions allowing increment and overflow

2024-03-16 Thread Liam McGillivray via Digitalmars-d-learn

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?

2024-03-16 Thread Andy Valencia via Digitalmars-d-learn

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=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

2024-03-16 Thread Liam McGillivray via Digitalmars-d-learn
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: Deriving a struct from another one via template: Easy way to propagate UDAs?

2024-03-16 Thread Inkrementator via Digitalmars-d-learn

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

2024-03-16 Thread Liam McGillivray via Digitalmars-d-learn

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: Deriving a struct from another one via template: Easy way to propagate UDAs?

2024-03-16 Thread Inkrementator via Digitalmars-d-learn

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: Challenge: Make a data type for holding one of 8 directions allowing increment and overflow

2024-03-16 Thread H. S. Teoh via Digitalmars-d-learn
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

2024-03-16 Thread Richard (Rikki) Andrew Cattermole via Digitalmars-d-learn
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.