How did you learn web development?

Thank you for your suggestions!!

@yebellz gave me some very helpful advice as to how to better structure a game tree object, but I was having trouble figuring out how to implement it. I was also racking my brain (had to google this one to remember whether it’s ‘wrack’ or ‘rack’) about how making parseTokens() recursive would be helpful… Then it clicked, and i realized both of you were suggesting different parts of the same solution, and i suddenly think i know what to do ^^

Also I didn’t realize you could add hints like that with jsdoc!!! My new favorite toy just got shinier :eyes:

I’m probably going to be setting my programming studies aside for a few days because of Ludum Dare this weekend though; some of my friends are planning to team up for the game jam and I’m gonna write the music for it!

7 Likes

LOL this thought popped into my head too (I thought it was just “wrack”)

btw, the doc comments in your code better than like 75% of production code (where it’s non-existent, incomplete or out-dated) :smiley:

4 Likes

How did you learn web development?

Unfortunately I never did so. If there is such a thing as reincarnation, I will do so in my next life. Up until then I will do without.
Of course I could make the attempt to start learning web development right ow, but no thanks. There are several other challenges in life that I still find more interesting. Such as gardening, dancing, reading books about global history, keep my thread with go puzzles going, etc, etc.

In life you unavoidably miss opportunities. So be it. Accept it and go on with your life.

2 Likes
Personal update about my weekend and Ludum Dare

Long-distance communication for this project on a tight schedule wound up being harder than we thought, so I’m not actually gonna wind up submitting anything to the competition this year :sweat_smile: I’ve still had fun writing music for the theme “tiny creatures”, it’s just not gonna be included in any game entries. Next year I’ll try and be better prepared so i can submit something awesome ^^

But since I’m not trying to meet a deadline, I was able to clean up my code this weekend!!!

I had to rewrite most of my code to figure this out, but I think it finally makes a lot more sense! It definitely feels a little spaghettified in some places still, and I think I use a couple loops more than necessary, but it seems to work and create a game object like @yebellz suggested:

Segment of game object that resulted from my code
{
 "props": {
  "FF": "4",
  "CA": "UTF-8",
  "GM": "1",
  "DT": "2024-10-06",
  "PC": "OGS: https://online-go.com/game/68424726",
  "GN": "Friendly Match",
  "PB": "Wan2024",
  "PW": "learngogogo",
  "BR": "1d",
  "WR": "3d",
  "TM": "30",
  "OT": "5x10 byo-yomi",
  "RE": "?",
  "SZ": "19",
  "KM": "6.5",
  "RU": "Japanese",
  "C": "Game chats will be available in SGF downloads once the game has finished.\n"
 },
 "children": [
  {
   "props": {
    "B": "qd"
   },
   "children": [
    {
     "props": {
      "W": "dd"
     },
     "children": [
      {
       "props": {
        "B": "pq"
       },
       "children": [
        {
         "props": {
          "W": "dq"
         },
         "children": [
          {
           "props": {
            "B": "oc"
           },
           "children": [
            {
             "props": {
              "W": "qo"
             }
            }
           ]
          }
         ]
        }
       ]
      }
     ]
    }
   ]
  }
 ]
}

To be quite honest, the way the JSDoc docs are written really goes over my head, so I’m still not sure if I’m doing it right. I had to ask my friend to explain what @private means, even after reading the page on it a few times :see_no_evil: I tried to imitate the style in the example you’ve shared here, but it reeeaaally feels like I’m guessing lol.

I am very flattered by this evaluation though, thanks :joy: although it makes me think that i will never be able to understand professionally-written code, hearing that it is not well-documented :melting_face:

I’m not exactly sure what I’d like to do next - I suppose I should write a function to do the reverse, and make an SGF from my game object, or make a Game class, or figure out error handling and write a bunch of exceptions for invalid SGF files… Buuuuut i really wanna add game logic so i can have a function that generates the board position after a given move :sweat_smile: probably getting a little ahead of myself with that one, though

4 Likes

I wrote a MakeSGF function that converts my game object into an SGF!!

So my GitHub Pages site now spits out a new SGF, which doesn’t mean anything especially meaningful right now but it does at least correct the odd nested-node style that OGS does:

I kinda wanna learn how to do the syntax highlighting that all those fancy text editors do, but for SGF :thinking: not the most practical thing, but i think it would be neat

9 Likes

Gotta follow your interests :heart:

1 Like

Please tell me “new line after each node” is enabled by default and just disabled for the screenshot. :smile:

1 Like

If you could turn AB[ef:eh] back into AB[ef][eg][eh] or whatever it’s supposed to represent I’d use it from time to time :stuck_out_tongue:

Smartgo doing that when someone sends me a puzzle or if I write down a puzzle or game from a picture etc makes it annoying to upload to OGS :slight_smile:

I should find out what it’s supposed to represent :stuck_out_tongue:

3 Likes

Well… now it is :joy:

I think your examples for compressed points are correct! [ef:eh] is a rectangle, ef being the top left and eh being the bottom-right, if I’m understanding the docs correctly. Anyways this seems like a fun challenge so i’m gonna give it a shot!!

4 Likes

If you want an example test case

and how OGS doesn’t handle it

(;GM[1]FF[4]SZ[19]CA[utf-8]AP[SmartGo One:2.1.1]
GN[2024-09-26b]
PW[White]
PB[Black]
DT[2024-09-26]
RU[Simple]
AB[ca:cc][fa][bb][db:eb][gb][ob:oc][ec:ed][fc][ic:id][lc][pc:pf][gd][md:me][de:df][he][je:le][if:ii][qf:qh][eg][sg][fh][nh:nk][rh][ci:cj][ei][gi:hi][bj][fj][hj][rj][ek][pk:qk][bl:bn][kl:ml][ol:on][cm][mm][dn:do][nn:no][co][ro][op:qp][dq:dr][fq:gq][oq][cr][er][gr:hr][pr:rr][bs][fs][hs:js]
AW[da][hb:hc][ib][lb][pb:qb][bc:bd][dc:dd][gc][jc:jd][mc:nc][qc:qe][cd][fd:fe][kd:ld][nd:ng][ee][re:rg][bf][gf][cg][fg][hg][lg][og:ok][bh:bi][gh][jh:ji][gj:gk][ij][kj][pj:qj][fk][hk][jk:jl][cl:el][dm][km:lm][nm][pm][en:eq][mn:mo][rn][bp:dp][fp:gp][ip][np:nq][cq][hq][pq:rq][br][ir:kr][mr][or][ks][ns]
)

I have no idea how OGS parses it but it goes so wrong XD I don’t even think stones and colours are in the right places most of the time.

5 Likes

Done!!
image

(;GM[1]
FF[4]
SZ[19]
CA[utf-8]
AP[SmartGo One:2.1.1]
GN[2024-09-26b]
PW[White]
PB[Black]
DT[2024-09-26]
RU[Simple]
AB[ca][cb][cc][fa][bb][db][eb][gb][ob][oc][ec][ed][fc][ic][id][lc][pc][pd][pe][pf][gd][md][me][de][df][he][je][ke][le][if][ig][ih][ii][qf][qg][qh][eg][sg][fh][nh][ni][nj][nk][rh][ci][cj][ei][gi][hi][bj][fj][hj][rj][ek][pk][qk][bl][bm][bn][kl][ll][ml][ol][om][on][cm][mm][dn][do][nn][no][co][ro][op][pp][qp][dq][dr][fq][gq][oq][cr][er][gr][hr][pr][qr][rr][bs][fs][hs][is][js]
AW[da][hb][hc][ib][lb][pb][qb][bc][bd][dc][dd][gc][jc][jd][mc][nc][qc][qd][qe][cd][fd][fe][kd][ld][nd][ne][nf][ng][ee][re][rf][rg][bf][gf][cg][fg][hg][lg][og][oh][oi][oj][ok][bh][bi][gh][jh][ji][gj][gk][ij][kj][pj][qj][fk][hk][jk][jl][cl][dl][el][dm][km][lm][nm][pm][en][eo][ep][eq][mn][mo][rn][bp][cp][dp][fp][gp][ip][np][nq][cq][hq][pq][qq][rq][br][ir][jr][kr][mr][or][ks][ns]
)

That was surprisingly not terribly difficult!! Compressing coordinates, on the other hand… I’m aiming for that next >:D

6 Likes

I wonder about the possibility of efficient algorithms to find the shortest coordinate compression. I don’t think it is so simple to solve. Some simple greedy heuristics seem to result in sub-optimal compression. I think that it may be an NP-hard tiling problem to solve exactly, although probably still solvable within a reasonable amount of time or sub-optimality on a 19x19 board.

4 Likes

I’ve heard the term “NP-complete” before, but never “NP-hard”. I looked these up and having a lot of trouble understanding them :sweat_smile: if you think there’s an ELI5 way to explain what that means, I’d love to hear it, but otherwise don’t worry about it :see_no_evil:

I guess that it doesn’t seem to me like it should be all that difficult to find an optimal compression; can’t you just break the problem up by groups of stones? In the above example, the largest group of stones is only 13 stones. I suppose it seems clear enough to me that this only requires a list of 4 values, but I’m not sure how difficult it would be to have an algorithm figure that out aside from trying every possible permutation.

3 Likes

Very cool! :smiley:

2 Likes

Some problems are relatively easy to solve, in the sense that the complexity grows at a reasonable (i.e., polynomial) rate, even as the problem instances gets larger. For example, arithmetic is manageable even with larger numbers. The complexity of long multiplication is roughly quadratic in the length of the numbers. Broadly speaking, these easy problems are known as “P”.

Some problems are relatively easy to verify that one has a correct solution, but there might not be any easy to solve. For example, if I ask you to find a set of items of an arbitrary restaurant menu that add up exactly to a certain total, it might be tricky (seeming to essentially require exhaustive search, which grows exponentially with the size of menu) to find a solution, but relatively simple to verify that a solution is correct (by checking the addition). Broadly speaking, these types of problems are known as “NP”.

The set of problems “P” is contained within “NP”, since if a problem is easy to solve, it is also easy to verify that a solution is correct. However, whether “P = NP” (all easy-to-verify problems are also easy to solve) or “P != NP” (some easy-to-verify problems are hard to solve) is the biggest, open problem in computer science, and an important unsolved question for mathematics in general. Many people believe and operate under the assumption that “P != NP”, but a proof has remained elusive.

“NP-complete” are essentially the hardest subset of NP problems, and for which people have demonstrated that an algorithm solving one of those problems could be efficiently converted into solving any other NP problem. “NP-hard” refers to a superset of NP-complete problems that are at least as hard as the NP-complete problems, but could also be even harder (i.e., even verifying the correctness of a solution cannot be done efficiently).

In practice, you might only have small connected chains to deal with in most cases, so optimization by exhaustive search is not prohibitive. However, in principle, one could have contrived positions with a large number of awkwardly clumped stones.

Exhaustive search would work to find an exact solution, but it quickly blows up with exponential complexity as the number of stones grows. My previous post is essentially wondering if there might be some other clever way to do this with much less complexity. This sort of problem seems to be a tiling optimization problem, which have been widely studied, and various related problems have been shown to be NP-complete/hard. Maybe this point compression problem could be directly cast as a previously studied tiling optimization problem. I guess it is a rectangular tiling optimization problem, where each 1x1 rectangle costs 4 (e.g., “[aa]”), while all other rectangles costs 7 (e.g., “[aa:bb]”).

4 Likes

I see! This is a very easy-to-follow explanation. Thanks!

Tiling optimization sounds like an interesting, puzzle-like category of problems. I’d be interested to learn more but I imagine it’s a very densely mathematical field.

A friend recommended some general computer science courses that aren’t language-specific, so I can learn to better understand a lot of the concepts I’ve been struggling with, and hopefully I’ll pick up some more math as I do that!

2 Likes

I think this is the main popular one:

And to answer the original question, I did a ton of random projects kind of like this.

I had an advantage, I think, in that I was getting into programming right as the web was being invented, so there wasn’t such a huge amount of stuff to learn. So I got to start with C, then learned HTML and Perl to make silly little CGI scripts. Then CSS came out, which was exciting, and Java and JavaScript and PHP, which were less so. With Java in particular I remember always being confused about what I was supposed to do with its CLASSPATH thing and why it didn’t just work right out of the box…

Then Ruby on Rails appeared and made everything so much easier while being much more relaxed and flexible than Java. A key feature was its integration with Bundler, providing precise version control for all libraries used by a project. That was such a revolutionary concept for me, particularly as someone who tended to jump around between lots of different projects that used many different libraries.

I think other language ecosystems like JavaScript/node and Python have since come up with their own imitations, since library control is really a crucial thing to master for any kind of development. I guess this kind of thing has become so much more important in the last 10 years since we draw on such a huge number of open source projects that are all evolving so quickly. (Example at the top of this post!)

And libraries aren’t the only dependencies you have for a project; there’s the language itself with its associated tools, a C toolchain for building the libraries, accessory programs like ImageMagick or curl, git, editors, etc. Maintaining all that stuff in working order quickly becomes a full-time job.

Lately I’ve been learning to tame that complexity using Nix. As far as I can tell, nothing comes anywhere close to Nix as a general system for building software and managing package dependencies. It’s got an incredible learning curve and probably isn’t for everyone, but it pays off so well once you start to get it.

6 Likes

I figured out how to get capturing to work!!


There’s now a functional minimalist “SGF viewer” (BIG emphasis on those quotation marks lol) on the page :joy: all you can do is step through the game, but it works with the SGF’s i’ve tried so far!!

This looks really cool!! What I’m visualizing is an interface with a text editor on one side and a graphic SGF editor on the other side, that both update in real time as a change is made to the one of them… This seems out of reach for me right now, but maybe not for long :fire:

8 Likes

I learned about CSS today!!


It may not look like much yet but it’s starting to at least look like it could eventually be a thing!!

edit: also please don’t look at my code right now, i started writing pure spaghetti when i decided to add capture logic and i haven’t cleaned it up yet and it’s embarrassing :see_no_evil:

9 Likes

90% of my code is. And I call myself a professional! :joy:

A core part of my role is building quick PoCs. Those can be quick and dirty, no problem with that. Only they are quickly turned into demos. Into bigger demos yet. Also used for production until real product development catches up. Which can take ages. So I sit on a heap of horrible code that is in nearly daily use, but was originally meant as a one-off.

8 Likes