Shortest Gomoku (5 in a row) implementation

2

I suspect Gomoku may be one of the simplest games to implement in code. https://en.wikipedia.org/wiki/Gomoku The game is this: players BLACK and WHITE take turns putting down black and white stones. Black traditionally goes first. If, when a player puts down their stone, they now have 5 in a row of their color, they win. That's it.

A simple way to implement this is to just keep two lists of (x, y) integer coordinates, one for black stones and one for white stones. Players simply specify an integer x,y coordinate, any x,y coordinate at all! The game checks if there is already a stone there of either color, and if not x,y is added to the list, and then the game checks if that stone made them have 5 in a row now.

Notice I have said nothing about board size, or checking if a move is on the board or not. My thought is that specifying board size and determining what to do at edges actually complicates things more! Gomoku can be played on an infinite board, and the game still works actually!

Anyway, to be clear, I believe the specifications are, implement Gomoku on a board of size between or including 15x15 and infinity x infinity (I actually suspect inifinite may be simpler.) Let the user know who's turn it is to play, by alternately printing "b>","w>". If an invalid entry is made, such as playing where there already is a stone there, just keep asking the user who played the invalid move until they play a valid move. To keep things extra short, no need to print the board state, actually! But if on a user's turn, they have completed 5 in a row orthogonaly or diagonally, print, or throw an error, that can simply say "w" or "b", to say who won. Shortest code that does the specified, wins.

If you want to print the board state or make things look nicer or make an AI or whatever, no need to do that, but you can add with or separately to your submission if you feel like it.

I wrote a non-golfed but still shortish implementation in Python, with simple board printing and stuff before. Here it is: https://github.com/jeffkaufman/game-complexity/blob/master/gomoku.py

And here's my entire attempt at a golfed version with the basic IO and move checking, but without board printing. I am quite sure this is not optimal at all, I'm not often a golfer. All I mostly did was make variables one character / remove whitespace and stuff, you guys can *easily* do better, I know.

w,b=[],[]
def o((x,y),s,(v,u)):
 if (x,y) in s:return o((x+v,y+u),s,(v,u))
 if v:return x
 return y
d=((0,1),(1,0),(1,1),(-1,1))
def W(m,s):
 for (x,y) in d:
  if o(m,s,(x,y))-o(m,s,(-x,-y))>5:return 1
 return 0
def t(c,p):
 while 1:
  C=raw_input(c+'>')
  try:
   x,y=C.split()
   m=(int(x),int(y))
  except ValueError:continue
  if m in b+w:continue
  p.append(m)
  if W(m,p):raise Exception(c)
  break
while 1:t("b",b),t("w",w)

an example run from that, which throws a Python error saying who won, at the end:

b>0 0
w>-4 5
b>0 1
w>0 1
w>7 12
b>0 2
w>7 12
w>4 5
b>0 -1
w>4 4
b>0 3

Traceback (most recent call last):
  File "C:/Users/udqbp/OneDrive/Desktop/test.py", line 22, in <module>
    while 1:t("b",b),t("w",w)
  File "C:/Users/udqbp/OneDrive/Desktop/test.py", line 20, in t
    if W(m,p):raise Exception(c)
Exception: b

Xylochoron

Posted 2019-06-08T05:17:55.030

Reputation: 29

Question was closed 2019-06-08T21:37:23.980

1

Welcome to PPCG. This is a good idea for a challenge, and you have included a winning criterion (code golf = shortest code) which is very important. But it needs to be tightened up to make it indisputable whether an answer is valid or not. For example does the board have to be 15x15, or infinite, or can we choose? Note that you can post draft challenges to our sandbox for feedback. https://codegolf.meta.stackexchange.com/questions/2140/sandbox-for-proposed-challenges?cb=1

– Level River St – 2019-06-08T05:30:20.373

i think i was trying to say it could be between between 15x15 and infinite, really either one is fine by me. i think infinite may actually be easier, but if you find 15 x 15 or some larger integer easier, that's cool by me actually. should i post in the sandbox? – Xylochoron – 2019-06-08T05:51:52.090

2>

  • Yes you did specify shortest code wins, that is good. 2. it would be clearer if you had a description of Gomoku as an introduction at the top, and specific challenge rules (such as between 15 x 15 and infinite, input/output spec etc.) in a separate, titled section near the bottom. 3. You don't need to speculate about which we might find easier to implement. It's clearer if you simply state the rules and let answer posters decide what works best. 4. you don't have to post in the sandbox, I was just making you aware of it. Many people find it useful, as writing a good challenge is hard.
  • < – Level River St – 2019-06-08T05:59:09.260

    I'll not compete, but to make it clear : no 3 and 3 rule, or overline(6 in a row), right? – LegenDUST – 2019-06-08T09:08:57.700

    2

    Suggested tag: interactive. (Although I think it would have been better to just take a list of valid moves as input and return 3 distinct values for black / white / no winner.)

    – Arnauld – 2019-06-08T09:26:34.173

    1How strict are the requirements re input/output during the game? Most code-golf questions here are flexible on details like that which aren’t critical to the main challenge. I’ve posted an answer where the player whose turn it is is indicated using 1 and -1. Is that permissible? I’ve used the same to indicate the winner. Also input validation (e.g. checking whether the coordinates are numbers and are within the board dimensions) is usually not required as part of the spec. Is that the case here? – Nick Kennedy – 2019-06-08T11:56:35.220

    Sorry, guys. I'll have to find some time to re-do this all. Asking if a list of valid moves wins or loses seems to easy actually, in that case, you just check if there's five in a row of either / both colors and you're done, so it's just a "check for five in a row" "problem." I do want to say that more than 5 in a row is still valid, because I want to make it a simple game to implement that's still a game so I'm paring down to the simplest rules. So 5 or more. continued... – Xylochoron – 2019-06-09T19:14:06.970

    ...continued also, allowing print whatever you want to say who's turn it is as long as it's differentiated so that should be fine. I do want to check for a valid move, I think, or again it's just an "is there five in a row" problem. Jelly's answers are great by the way. – Xylochoron – 2019-06-09T19:14:18.693

    Answers

    0

    Jelly, 54 bytes

    Ḋ,Z,ŒD$ŒrFs2ḢƇ<5Ȧ
    0x⁹s⁴-;N1¦Ṅ©+Ɠœị®Ḋ¤$¿ṪṬṭ0x$Ʋ¹NƭƊƊ$Ç¿
    

    Try it online!

    A full program that reads input on stdin. For each loop through it prints the current player (1 or -1) and the 16x16 grid. Moves are input on stdin as a Python array (e.g. [3,2]) with or without the surrounding square brackets. The only validation done is to make sure that the relevant cell is empty. When there are 5 (or more) in a row, the program ends and prints out the winner and final grid.

    If checking for a valid move can be omitted, 10 bytes can be saved:

    Jelly, 44 bytes

    Ḋ,Z,ŒD$ŒrFs2ḢƇ<5Ȧ
    0x⁹s⁴-;N1¦Ṅ+ƓṪṬṭ0x$¹Nƭ¤ƲÇ¿
    

    Try it online!

    Conversely, if the w/b designation in the spec is strict, that costs 15 bytes:

    Jelly, 69 bytes

    ị“wb ”Ḣ
    Ḋ,Z,ŒD$ŒrFs2ḢƇ<5Ȧ
    0x⁹s⁴-;N1¦Ñ;”>ṄṛƲ©+Ɠœị®Ḋ¤$¿ṪṬṭ0x$Ʋ¹NƭƊƊ$Ç¿Ñ
    

    Try it online!

    Nick Kennedy

    Posted 2019-06-08T05:17:55.030

    Reputation: 11 829