My implementation

http://arsdnet.net/tictactoe.d
source: 138 lines, 2420 bytes

You can see the byte count is comparable to the python 2, but I have
more lines. This reflects my preferences of one line = one instruction.

I usually prefer "Introduction to Programming" style code than
"functional code golf" style, so you see that too.

I also put in a lot of contracts just because i can. I'm trying to
get into the habit of that.

> Input the index of where you wish to place your mark at your turn.

      writef("Input the index of your move (from %s): ",

End user instructions have no place as documentation comments. Being
able to print out documentation comments at runtime is almost useless -
doing so indicates a high probability of bad comments.

You can see that I used a simple string literal for this, declaring
it where it is used.

> I'd like the DMD compiler to be able to produce a JSON tree out of > the 
> current
module during compilation, through a library, and allow > the normal code to use
it at compile time.

dmd -X to generate it, then dmd -J to load it up for use at compile
time. Documentation comments are already included in the json output.

However, see my comment above on how I feel about the need for this...

> An alias is not as good as a typedef, to make statically sure the
> various functions do take a board and nothing else as input.

I wrote: struct Board { }

If you want a separate type, make a separate type. I'm sad to see
typedef go too, personally, but this is a very poor use case for it.
typedef is actually pretty rare. A struct or class is usually
a better choice.

> I'd like join to work with a lazy range and on chars too, allowing > code like
(untested):

I think that could be useful, though it's possible today already
for this example (see toImpl for arrays)

> There is no clean way to create a tuple on the heap, the way I have
> used is the best I have found.

The method you used looks like the right way to do it - you just
"new" it, like anything else.


> I'd like Python simple functions all() and any() in Phobos2 too.
> With it you are able to write code a bit less ugly like (untested):

I think these would be useful too.

There's already one similar thing here:

http://dpldocs.info/allSatisfy

But it doesn't work on the right types it looks like. If we made
that a little more generic I think we'd have a winner.

> My suggestion to avoid this quite bad situation is to look at
> sboard, it's a char[] and not a string. So a solution to this messy
> situation is to make string a strong typedef.

This behavior is by design.

http://digitalmars.com/d/2.0/phobos/std_array.html

ElementType!(String)[] array(String)(String str);
    Convert a narrow string to an array type that fully supports random access.
This is handled as a special case and always returns a dchar[], const(dchar)[], 
or
immutable(dchar)[] depending on the constness of the input.


The idea is if you ask for an array, it's because you want to do
O(1) random access, which, assuming you want code points, means
dchar.

You probably could have done reduce!("a ~ b")("", filter....) to
get the char[]...

Though, I'd rethink this whole design. The board isn't a string,
so you shouldn't represent it as one. I used int[9] in my code.


> There are many situations where I'd like afilter() ===
> array(filter()) and amap() == array(map()).

But, this isn't orthogonal!


> auto my_turn(char xo, TBoard sboard) {
>    auto options = space();
>    char choice = options[uniform(0, options.length)];
>    sboard[to!int(choice~"") - 1] = xo;
>    return choice;
> }

I wrote this thus:
        int suggestMove(int player)
                out(ret) {
                        assert(ret >= 0);
                        assert(ret < 9);
                        assert(isAvailable(ret));
                }
        body {
                return randomCover(openPositions(),
                        Random(unpredictableSeed)).front;
        }

You can see it is a one-liner, yet not an unreadable one. The reason
is because I picked a more correct representation of the board.

It makes no sense whatsoever to populate an array with its indexes,
then get indexes to get a value which is then converted back into an
index!

I you use an index in the first place, which makes conceptual sense,
you save piles of busy work.

> to!int(choice) doesn't do what you think it does, it converts the
> choice char to its integer representation:

That's actually exactly what I think it does, coming from C. I'd be
ok with just making cast() be the thing to do though. I usually
cast for this use case anyway (again coming from C, that's just the
natural way that comes to mind).

> I'd like a _very_ handy std.random.choice(), that allows to write
> code like (untested):

I don't see the big benefit over randomCover here, but I wouldn't
veto it's inclusion (if I had such power). It's a trivial function
though.


> In Python both for and while loops have an optional "else" clause,
> that runs if the loop is not exited by a break. It is a handy
> thing, that allows to avoid the "unbroken" boolean I have used in D.

Yes, that's somewhat useful, but not enough to warrant a new language
feature. I find it is usually better to make the condition explicit,
or avoid it altogether with a better design.

> Because D2 refused to use a handy "in" for strings, this is awful.

Isn't canFind() <http://dpldocs.info/std.algorithm.canFind> that
same thing?

if(str.canFind('c'))


> Regarding raw_input() see:
> http://d.puremagic.com/issues/show_bug.cgi?id=4716

That might be useful. I even put something like it in my GUI code.

I'd say make it do a combination of writef though, so you can do more
complex prompts.

auto number = ask!int("Enter a number, %s", name);

I think I found a bug in readf() in my implementation too! It doesn't
seem to handle unexpected data very well (not even offering an error
code like C and C++ do...).


> There is another usage of unbroken.

That's only because of the code's very, very bizarre design. There's
a lot of code duplication and a really strange control flow. I don't
think it helps your case at all to use such horribly awful code to
make points. Half of your statements are the direct result of
the source code being garbage.

Reply via email to