Bay 12 Games Forum

Please login or register.

Login with username, password and session length
Advanced search  
Pages: 1 ... 738 739 [740] 741 742 ... 795

Author Topic: if self.isCoder(): post() #Programming Thread  (Read 818355 times)

MorleyDev

  • Bay Watcher
  • "It is not enough for it to just work."
    • View Profile
    • MorleyDev
Re: if self.isCoder(): post() #Programming Thread
« Reply #11085 on: December 20, 2018, 12:02:25 pm »

Eh, some lists are infinite sequences and some algorithms are more efficient with lazy evaluation. Both of those somewhat defeat the notion of a reliable size.

It's not the responsibility of a find function to care about the length of the array it receives

I don't know how you can implement a search that can determine "not found" if it doesn't know the number of items in the collection it is searching.  Or are you suggesting some kind of abstract "get next item" interface even to arrays so the find function doesn't need to know length?  Sounds like unnecessary complexity to me.

That's actually the way the enumerable/iterator base concept is implemented in languages like C# and Java, where all lists of data are at their most abstract traversable through an iterator that can retrieve the current value and the next iterator, which does work pretty great when the standard library supports it.

C++ has it's own iterators too for use, just C++ does it with more template metaprogramming insanity (or the equivalent syntactic sugar).

But I mean that it doesn't matter to responsibilities of a find function on an array how long the array is. The implementation detail that it's using the length for it's foreach is irrelevant from the calling context, and doesn't really belong as a part of the contract of a find.
« Last Edit: December 20, 2018, 01:28:38 pm by MorleyDev »
Logged

Gentlefish

  • Bay Watcher
  • [PREFSTRING: balloon-like qualities]
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #11086 on: December 20, 2018, 01:49:34 pm »

Wouldn't
Code: [Select]
found = 0
for (i=0;i=length_of_array;i++)
     if (array[i] = thing_to_find){
          found = 1;
          do_thing;
          break;
     }
}
if(found != true)_{
     fprint("Oops! Didn't find it!");
}
else return thing;
work just as well for finding a thing in any array length and not failing quietly?

bloop_bleep

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #11087 on: December 20, 2018, 07:52:18 pm »

Wouldn't
Code: [Select]
found = 0
for (i=0;i=length_of_array;i++)
     if (array[i] = thing_to_find){
          found = 1;
          do_thing;
          break;
     }
}
if(found != true)_{
     fprint("Oops! Didn't find it!");
}
else return thing;
work just as well for finding a thing in any array length and not failing quietly?

Well, in that case, it’s essentially just printing a log message without informing the caller, which is failing quietly.

Not to fail quietly would mean to cause some sort of disturbance in the normal running of the code, like throwing an exception.
Logged
Quote from: KittyTac
The closest thing Bay12 has to a flamewar is an argument over philosophy that slowly transitioned to an argument about quantum mechanics.
Quote from: thefriendlyhacker
The trick is to only make predictions semi-seriously.  That way, I don't have a 98% failure rate. I have a 98% sarcasm rate.

Reelya

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #11088 on: December 20, 2018, 07:58:33 pm »

Wouldn't
Code: [Select]
found = 0
for (i=0;i=length_of_array;i++)
     if (array[i] = thing_to_find){
          found = 1;
          do_thing;
          break;
     }
}
if(found != true)_{
     fprint("Oops! Didn't find it!");
}
else return thing;
work just as well for finding a thing in any array length and not failing quietly?

tsk tsk, buggy.

you have assignment operator = instead of comparison operator ==, so it will over-write the first array value with the "thing_to_find" value, then return true. If the 'thing to find' happens to resolve to false however, it will over-write the entire array with zeros, then say it didn't find it. Coder tip: put a const value on the LHS of comparisons because if you accidentally have an = instead of == then the compiler will alert you instead of blindly over-writing variables.

however, "for (i=0;i=length_of_array;i++)" has assignment instead of the comparison operator <, which will cause infinite looping if it doesn't find the thing, so I'm guessing that the "didn't find it" message won't in fact ever appear :o

In addition, you didn't have a brace on the for loop but there's an unmatched one below. The compiler will pick that up however.
« Last Edit: December 20, 2018, 08:12:32 pm by Reelya »
Logged

bloop_bleep

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #11089 on: December 20, 2018, 09:36:49 pm »

...

error: ! Missing ‘/pedantic’ inserted.
Logged
Quote from: KittyTac
The closest thing Bay12 has to a flamewar is an argument over philosophy that slowly transitioned to an argument about quantum mechanics.
Quote from: thefriendlyhacker
The trick is to only make predictions semi-seriously.  That way, I don't have a 98% failure rate. I have a 98% sarcasm rate.

MorleyDev

  • Bay Watcher
  • "It is not enough for it to just work."
    • View Profile
    • MorleyDev
Re: if self.isCoder(): post() #Programming Thread
« Reply #11090 on: December 21, 2018, 07:10:48 am »

Also you don't return in the event of a not-found, which I think is undefined behaviour in C++ (as opposed to a compiler error, like in sensible languages).

To dust off my C++ experiences and throw together a stupidly-generic find example using the std::optional added in C++17,

Code: [Select]
#include <iostream>
#include <optional>
#include <vector>
#include <functional>

template<class InputIt> constexpr auto try_find_val(InputIt first, InputIt last, const typename std::iterator_traits<InputIt>::value_type & value ) -> std::optional<typename std::iterator_traits<InputIt>::value_type> {
for(auto i = first; i != last; ++i) {
if (*i == value) {
return *i;
}
}
return {};
}


void test_found()
{
std::cout << "Testing should be found" << std::endl;
std::vector<int> list = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
auto result = try_find_val(std::begin(list), std::end(list), 10);
if (result) {
std::cout << "Success: Found " << *result << std::endl;
} else {
std::cout << "Error: Not found " << std::endl;
}
}

void test_not_found()
{
std::cout << "Testing should be not found" << std::endl;
std::vector<int> list = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
auto result = try_find_val(std::begin(list), std::end(list), 12);
if (result) {
std::cout << "Error: Found " << *result << std::endl;
} else {
std::cout << "Success: Not found " << std::endl;
}
}

int main() {
test_found();
test_not_found();
return 0;
}


Naturally, if you know some or all the types you'll be working with beforehand you can simplify or remove a lot of the templated shenanigans for the extra readability.

You could also do it by ref to allow mutation, or const ref to prevent a copy:
Code: [Select]
template<class InputIt> auto try_find_ref(InputIt first, InputIt last, const typename std::iterator_traits<InputIt>::value_type& value ) -> std::optional<std::reference_wrapper<typename std::iterator_traits<InputIt>::value_type>> {
for(auto i = first; i != last; ++i) {
if (*i == value) {
return std::ref(*i);
}
}
return {};
}

template<class InputIt> auto try_find_cref(InputIt first, InputIt last, const typename std::iterator_traits<InputIt>::value_type & value ) -> std::optional<std::reference_wrapper<const typename std::iterator_traits<InputIt>::value_type>> {
for(auto i = first; i != last; ++i) {
if (*i == value) {
return std::cref(*i);
}
}
return {};
}

std::begin and std::end works for the standard collections and fixed sixed arrays.

std::begin/std::end don't work for naked dynamic arrays in the T* format (so creating using the T* arr = new T[N]).

You'd need to either pass in something like (arr, arr + N) instead of begin and end, or wrap in a class that adds the basic forward iterator-support (wrapping in a class also means not having naked pointers floating around, which I'd call a benefit in the name of developer sanity).
« Last Edit: December 21, 2018, 11:12:31 am by MorleyDev »
Logged

Telgin

  • Bay Watcher
  • Professional Programmer
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #11091 on: December 21, 2018, 11:24:29 am »

As a humorous aside, the talk of naked pointers reminds me of this: Three Star Programmer.

I wrote a C program once that I think used two levels of indirection for function pointers and three levels of indirection for some dynamically created multidimensional arrays.  Won't say I'm proud of that, but I was writing a plugin for Valgrind to simulate how Nvidia's profiling tools worked on CUDA programs, except for OpenCL on an ordinary x86 CPU so it was one of the less obnoxious parts of the program to understand.
« Last Edit: December 21, 2018, 11:26:22 am by Telgin »
Logged
Through pain, I find wisdom.

Gentlefish

  • Bay Watcher
  • [PREFSTRING: balloon-like qualities]
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #11092 on: December 21, 2018, 11:25:00 am »

My word guys, it's pseudocode :P

bloop_bleep

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #11093 on: December 21, 2018, 02:21:30 pm »

Apparently there is a quadruple pointer in the dwarf fortress map struct, which is a three-dimensional array of map block pointers.

I think I’ve officially lost my innocence.
Logged
Quote from: KittyTac
The closest thing Bay12 has to a flamewar is an argument over philosophy that slowly transitioned to an argument about quantum mechanics.
Quote from: thefriendlyhacker
The trick is to only make predictions semi-seriously.  That way, I don't have a 98% failure rate. I have a 98% sarcasm rate.

Gentlefish

  • Bay Watcher
  • [PREFSTRING: balloon-like qualities]
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #11094 on: December 21, 2018, 02:47:32 pm »

Toady's officially a four star programmer then? That's tasty.

Mephisto

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #11095 on: December 21, 2018, 03:49:25 pm »

Apparently there is a quadruple pointer in the dwarf fortress map struct, which is a three-dimensional array of map block pointers.

I think I’ve officially lost my innocence.

Do you have a source for that? I love reading about DF internals.
Logged

Telgin

  • Bay Watcher
  • Professional Programmer
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #11096 on: December 21, 2018, 07:05:07 pm »

I'm guessing it's documented in DFHack's data structures, which you can kind of get a feel for by reading this Git repo: df-structures.  Not sure where you'd start though.
Logged
Through pain, I find wisdom.

bloop_bleep

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #11097 on: December 21, 2018, 08:00:40 pm »

The source for the dwarf fortress structures is automatically generated from the xml files in df-structures. You can only see it by cloning the main DFHack repo.

I think it’s probably in library/include/df/map.h, but not 100% entirely sure.
Logged
Quote from: KittyTac
The closest thing Bay12 has to a flamewar is an argument over philosophy that slowly transitioned to an argument about quantum mechanics.
Quote from: thefriendlyhacker
The trick is to only make predictions semi-seriously.  That way, I don't have a 98% failure rate. I have a 98% sarcasm rate.

lethosor

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #11098 on: December 21, 2018, 08:03:14 pm »

From my clone of DFHack:
Code: [Select]
$ grep -r '\*\*\*' library/include/df
library/include/df/world.h:      df::map_block**** block_index;
library/include/df/world.h:      df::map_block_column*** column_index;
Generated from https://github.com/DFHack/df-structures/blob/0.44.12-r1/df.world.xml#L1054-L1067

It's worth noting that (unless we've heard from Toady), this isn't guaranteed to match the DF source code. It's just something that produces behavior that matches DF's when compiled. Toady could be using a pointer to some X*Y*Z array or something like that.

The source for the dwarf fortress structures is automatically generated from the xml files in df-structures. You can only see it by cloning the main DFHack repo.

I think it’s probably in library/include/df/map.h, but not 100% entirely sure.
(Minor clarification: you have to compile DFHack, or at least the generate_headers target, which requires Perl. Cloning would just get you what's on GitHub, not the generated stuff.)
« Last Edit: December 21, 2018, 08:05:38 pm by lethosor »
Logged
DFHack - Dwarf Manipulator (Lua) - DF Wiki talk

There was a typo in the siegers' campfire code. When the fires went out, so did the game.

bloop_bleep

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #11099 on: December 21, 2018, 08:07:01 pm »

Toady could be using a pointer to some X*Y*Z array or something like that.

Well, probably not, since the dimensions of the array are variable.
Logged
Quote from: KittyTac
The closest thing Bay12 has to a flamewar is an argument over philosophy that slowly transitioned to an argument about quantum mechanics.
Quote from: thefriendlyhacker
The trick is to only make predictions semi-seriously.  That way, I don't have a 98% failure rate. I have a 98% sarcasm rate.
Pages: 1 ... 738 739 [740] 741 742 ... 795