Bay 12 Games Forum

Please login or register.

Login with username, password and session length
Advanced search  
Pages: 1 ... 464 465 [466] 467 468 ... 796

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

Thief^

  • Bay Watcher
  • Official crazy person
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #6975 on: February 05, 2015, 12:25:04 pm »

:D
Logged
Dwarven blood types are not A, B, AB, O but Ale, Wine, Beer, Rum, Whisky and so forth.
It's not an embark so much as seven dwarves having a simultaneous strange mood and going off to build an artifact fortress that menaces with spikes of awesome and hanging rings of death.

Reelya

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #6976 on: February 05, 2015, 12:46:11 pm »

More BYOND implementation fun:
You cannot have more functions than 65,535 (unsigned short), at that point it seems to start reading memory that it shouldn't be reading.
Apparently we've hit that limit, and now everything is exploding, especially all lists.

Make a big "command" function that takes an opcode + operands and uses a switch to carry out many different game actions. You could massively reduce the number of different functions you have that way. This is also helps lead to a less hardcoded, data-driven design, it makes it really easy to do custom key configs when all the possible actions are coded as data.

Do you actually need 60000+ separate functions? It sounds to me like you have an absolutely hideous amount of redundancy or something going on. BTW, what sort of game are you working on? I wouldn't mind seeing if I could give a hand to streamline the code a bit, though I'm more of a c++ person.
« Last Edit: February 05, 2015, 12:51:45 pm by Reelya »
Logged

miauw62

  • Bay Watcher
  • Every time you get ahead / it's just another hit
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #6977 on: February 05, 2015, 01:16:30 pm »

BYOND really just works that way, Reelya. It's a bit like a single very very very big KSP mod. If you want to have a new sort of computer, you make it a subtype of the general computer class and override some procs to add your own code because that's how it works. The ongoing remake plans to make it not be like that but that's something else entirely.
Link to the repo.

And every separate function we declare counts to that limit, AFAIK. Hell, maybe overrides even count.
So it all adds up. You add a handful of functions here for nice OOPness, some overrides there, a few helpers. This game has over 300k lines of code.
Logged

Quote from: NW_Kohaku
they wouldn't be able to tell the difference between the raving confessions of a mass murdering cannibal from a recipe to bake a pie.
Knowing Belgium, everyone will vote for themselves out of mistrust for anyone else, and some kind of weird direct democracy coalition will need to be formed from 11 million or so individuals.

Parsely

  • Bay Watcher
    • View Profile
    • My games!
Re: if self.isCoder(): post() #Programming Thread
« Reply #6978 on: February 05, 2015, 01:18:17 pm »

Spoiler: Back to Basics With VB (click to show/hide)
Logged

Reelya

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #6979 on: February 05, 2015, 01:51:47 pm »

BYOND really just works that way, Reelya. It's a bit like a single very very very big KSP mod. If you want to have a new sort of computer, you make it a subtype of the general computer class and override some procs to add your own code because that's how it works. The ongoing remake plans to make it not be like that but that's something else entirely.
Link to the repo.

And every separate function we declare counts to that limit, AFAIK. Hell, maybe overrides even count.
So it all adds up. You add a handful of functions here for nice OOPness, some overrides there, a few helpers. This game has over 300k lines of code.

Well looking at just one class/object, and for quick refactors that won't break anything. You can replace a multitude of helper functions for one class with a single action method, and pass it a set of flags, which tells it which action to take. You could even use 1 bit for each possible action, and use a single function call to execute multiple configuration options in one call, make the possible options as consts or enums or the BYOND equivalent so you can call them by name, but not need an actual function header for each one.

If you're really up against the wall with number of functions, then I'd say this sort of refactor is the only way forward. Longer term, I'd recommend trying to reduce the number of total classes needed, and have things more data-driven, I see a lot of hard-coded logic there. The trick is to make minor refactors that make two or more classes more similar in structure and data. Eventually, you hit a point where you can delete one, and remake it as a data-driven "mod" for an existing class, which reduces function overhead.

Do data polymorphism, not "hard-wired" polymorphism. The way you described it being done shouldn't really be necessary, in any language.

Quote
BYOND really just works that way, Reelya.

I'm usually skeptical of these claims. "shitty way is the only way that the language supports, and it's what we've always done" has never been accurate in my experience. Are you sure it's not your existing program structure rather than the language? Can't you e.g. modify the existing computer class to have an extra data field, and based on that it gets different behavior via "if" statements in the procs? That doesn't require you to use inheritance at all, or override procs. Technically, using data-polymorphism you can pack unlimited extra "types" into the same class with the same number of procs.

c++ also works that shitty way too, if you use it like that. But there's no good reason to do that, in byond or c++. if you remake the same data structures in c++ or any other language, it's still going to be the same pile of mud, and difficult to modify.
« Last Edit: February 05, 2015, 02:06:08 pm by Reelya »
Logged

miauw62

  • Bay Watcher
  • Every time you get ahead / it's just another hit
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #6980 on: February 05, 2015, 02:16:59 pm »

I was really complaining in general, not really asking for advice.
None of these things are practical to do. It'd be making code more complex and harder to read, and it's impossible to do if you're doing any OOP at all.

We already have a small programming language of our own (traffic control for radio messages), and literally nobody knows how it works.

I understand that these things are desirable in other games, but BYOND is such that this is the only efficient way to code a game, and it's worked for over ten years.

(also, BYOND doesn't really have a concept of classes, types are paths and you can define/override a proc or a var on a path.)

E:
Oh, apparently it's just massive fucking memory leaks on BYONDs part, not a proc limit.

E2:
Also, if you're going to rewrite SS13 to be data-driven, you may as well write it in a proper langauge.
This is exactly what this remake is attempting to do
« Last Edit: February 05, 2015, 02:39:39 pm by miauw62 »
Logged

Quote from: NW_Kohaku
they wouldn't be able to tell the difference between the raving confessions of a mass murdering cannibal from a recipe to bake a pie.
Knowing Belgium, everyone will vote for themselves out of mistrust for anyone else, and some kind of weird direct democracy coalition will need to be formed from 11 million or so individuals.

Antsan

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #6981 on: February 05, 2015, 02:22:05 pm »

It's true that no particular thing is to trying to handle (as you have pointed out) it's more the fact that the sum of the whole is rather annoying when you keep stumbling on little thing after little thing that could be done so much easier. Also Java doesn't do pass by reference; everything is pass by value (some people say weird things about objects, but really what is happening is that the pointers are being passed by value). It's just a line here, a class there, but it all adds up in the end.
I actually like the "pointers passed by value" thing. It's what I am used to from Common Lisp.
Still, Java looks awful to me.
Logged
Taste my Paci-Fist

MorleyDev

  • Bay Watcher
  • "It is not enough for it to just work."
    • View Profile
    • MorleyDev
Re: if self.isCoder(): post() #Programming Thread
« Reply #6982 on: February 05, 2015, 07:16:57 pm »

Well it's more than just a pointer (reference counting and all that).

Good ol' Martin Fowler wisdom holds that often when you find yourself writing a bunch of defaults parameters (or the Java equivalent of overloads), a parameter object can be a good way to go.

If they're being passed together, often it's because they all relate to a singular concept and it's that concept that the function is actually trying to act on. Often the overloads are just muddying the waters, so extracting the concept by introducing a parameter object simplifies things and makes everything easier to follow and understand.
« Last Edit: February 05, 2015, 07:25:21 pm by MorleyDev »
Logged

Telgin

  • Bay Watcher
  • Professional Programmer
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #6983 on: February 05, 2015, 10:20:21 pm »

Parameter objects can be pretty useful, and I've used them extensively in PHP and JavaScript.  One thing that's pretty important, to me at least, is some way to define them as literals in the code rather than have to go through some kind of hash map or custom class.  Maybe Java has some way to do that, but none that I know of.

Alternatively, I like named parameters like how Python uses them, but that is really only restating default parameters in a way.
Logged
Through pain, I find wisdom.

Reelya

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #6984 on: February 06, 2015, 01:32:26 am »

A constructor is the normal way to put an object in as literals in c++, i think Java would be the same. There's very little syntax overhead involved:

obj a(b,c,d); // to make a single literal set of parameters

or

obj data[3]=
{
    obj(a,b,c);
    obj(d,e,f);
    obj(g,h,i);
};

where you've already defined your parameter set "obj", will make a "table" with three of the custom objects, a nice way to initialize the types while you're getting everything debugged. I usually give these parameter objects very short names for convenience and readability.
« Last Edit: February 06, 2015, 01:40:10 am by Reelya »
Logged

Rose

  • Bay Watcher
  • Resident Elf
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #6985 on: February 06, 2015, 01:38:28 am »

Parameter objects are also pretty much required when you're doing threading.
Logged

miauw62

  • Bay Watcher
  • Every time you get ahead / it's just another hit
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #6986 on: February 10, 2015, 02:18:38 pm »

* miauw62 swallows pride

I'm trying to find a solution for the UVA online judge problem "Exact Sum"
The code isn't working, but it was working before (i had to change it because i got wrong answer). I have no idea why. It looks like it always continues, so that the output is always the first element in the vector, twice.
Code: [Select]
#include <iostream>
#include <vector>

using namespace std;
int totbooks;
int money;
vector<int> books;
vector<int>::iterator iter;
int book1;
int book2;
int book1b;
int book2b;
int books1a;
int findr(int value, int skip = -1);

int main()
{
while (true)
{
cin >> totbooks;
for (int i = 0; i < totbooks; i++)
{
int book = 0;
cin >> book;
books.push_back(book);
}
cin >> money;
book1 = -1;
int i = 0;
int size = books.size();
while(i < size) //note to self: program is not finding books properly??? (so output is books[0] and books[0])
{
book1 = findr(i);
if (book1 == -1)
{
continue;
}
book2 = findr(money - books[book1], book1);
if (book2 == -1)
{
continue;
}
else if ((book1b == 0 && book2b == 0) || abs(books[book1] - books[book2]) < abs(books[book1b] - books[book2b]))
{
book1b = book1;
book2b = book2;
}
i++;
}
int abc = books[book2b];
int books1a = books[book1b];
if (abc > books1a)
{
int temp = abc;
abc = books1a;
books1a = temp;
}
cout << "Peter should buy books whose prices are ";
cout << abc;
cout << " and ";
cout << books1a;

totbooks = 0;
money = 0;
books.clear();
iter = books.begin();
book1 = 0;
book2 = 0;
books1a = 0;

if (feof(stdin))
{
return 0;
}
cout << ".\n\n";
}
}

int findr(int value, int skip)
{
for (int i = 0; i < books.size(); i++)
{
if (i == skip)
{
continue;
}
if (books[i] == value)
{
return i;
}
}
return -1;
}

I can't give a link to the issue since chrome doesnt like the website? (it works on chrome on school)
anyway, the input is first the amount of books, then the prices for said books, and then how much money can be spent. I must find the two books with the least price difference that add up to the amount of money available.

E:
Oh, ffs.
I just realized two things:
1) that while loop is awful (its only that way because it didnt work with a for loop and i like having control :V)
2) im using books.size() as the limiting condition, which is really dumb. I should be using money. WELP.
« Last Edit: February 10, 2015, 02:49:27 pm by miauw62 »
Logged

Quote from: NW_Kohaku
they wouldn't be able to tell the difference between the raving confessions of a mass murdering cannibal from a recipe to bake a pie.
Knowing Belgium, everyone will vote for themselves out of mistrust for anyone else, and some kind of weird direct democracy coalition will need to be formed from 11 million or so individuals.

MagmaMcFry

  • Bay Watcher
  • [EXISTS]
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #6987 on: February 10, 2015, 03:01:23 pm »

This should be the problem.
Code: [Select]
book1 = findr(i);should probably be
Code: [Select]
book1 = i;Because if that doesn't happen, you'll hit continue a lot and probably not even find a match. In that case, book1b and book2b won't be set at all and stay at 0, in which case you'll get exactly what you're describing.

Other suggestions:
  • Instead of resetting your variables at the end of the infinite loop, you could just declare them inside the loop instead of globally. Much better style and readability.
  • Your algorithm runs in quadratic time, which is not very optimal. I can think of a worst-case linearithmic-time algorithm and an average-case linear-time algorithm off the top of my head.

Logged

da_nang

  • Bay Watcher
  • Argonian Overlord
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #6988 on: February 10, 2015, 03:03:24 pm »

Yeah, my mind was flashing red when I saw those continue statements in a while loop without the iteration variable incrementing.

EDIT: On reflection, it seems a bit like the knapsack problem.
« Last Edit: February 10, 2015, 03:13:42 pm by da_nang »
Logged
"Deliver yesterday, code today, think tomorrow."
Ceterum censeo Unionem Europaeam esse delendam.
Future supplanter of humanity.

MagmaMcFry

  • Bay Watcher
  • [EXISTS]
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #6989 on: February 10, 2015, 03:21:11 pm »

Actually it's 2SUM.
Logged
Pages: 1 ... 464 465 [466] 467 468 ... 796