Icon representing a recipe

Recipe: intro-to-the-AlphaGoStarCraft-A.i.game5.Lua

created by zo3xiaJonWeinberg

Profile


Name
intro-to-the-AlphaGoStarCraft-A.i.game5.Lua
ID
104332
Shared with
Public
Parent
intro-to-the-AlphaStarCraft-A.i.-3wayGo4.Lua
Children
None
Created on
January 13, 2021 at 20:07 PM UTC
Updated on
January 13, 2021 at 20:07 PM UTC
Description

You must be logged into both the
Foldit game client AND the Fold.it
website (scroll far down for the login
textboxes) to download recipes.

Take off your driving glasses when
playing games.
You can increase the font.

The Game of Go minigame.
15: cmd-line attempt.
14b Haiku update: foldit info bubble width.
update 14: fixed row/col bug finally.
13: noticed bugs in flat world
when playing tengen then row2col1.

Update 12: Flat world ruleset option for traditional gameplay is now implemented.

Update 11: Round world aesthetic
and also to inform new players of
Go how this ruleset would work.

Update 10: bug fix.
Update 9: Now has 3x3 cells,
though also easier to adjust board
size in code.
Uses sliders for picking row
and column.
Is still a round-world game
modification for simplicity and fun.

Update 8: Now has capturing.
"Supply-lines" style implementation
inspired by a 2012 Youtube
Go tutorial.

Go traditionally has a 9x9 board for beginners or a 19x19 board for pros.
It originally had a 17x17 board.

This board is 2x2, even though
boards usually have an odd number
of rows and columns.

Best for


Code


--keep first line blank --Jon Weinberg --Code 871 if dialog==nil then --if running outside foldit (eg. terminal) -- https://www.codeproject.com/Articles/228212/Lua-Interpreter --by Liu Junfeng --only for Windows, uses exe sadly, so IDK if it works, I have Mac print("Plz Run as Foldit recipe") dialog = Gui.Form{} end --user="Zergling" --don't overwrite user userTeam="Zergling" farm="farmland" local opt = dialog.CreateDialog("Player "..user.GetPlayerName() .." is "..userTeam) grid = {} rows=3 cols=rows for i = 1, rows do grid[i] = {} for j = 1, cols do grid[i][j] = farm -- Fill the values here end end cell=grid debug=false opt.labelMsg=dialog.AddLabel("Zerglings play first (fastest). Terrans 2nd") roundWorld=false repeat isFed={{false,false},{false,false}} print("In a real game, Player " .. user.GetPlayerName()) print (" can forfeit Round 1 to save time.") --Jon copied from Bruno Kestomont's JET 3. slash="" backslash="" dash="" space=" " --still default to space so maintain symmetric roundWorldCode=0 if roundWorld then toggleLabel="Flat" else toggleLabel="Round" end opt.roundWorld=dialog.AddButton(toggleLabel.." world",roundWorldCode) --dialog.AddCheckbox("Round world", true) -- zergling------zergling longspace=" " if(roundWorld) then opt.l0=dialog.AddLabel(" "..longspace.."---||---"..longspace.." ") --because of sans serif opt.l1=dialog.AddLabel(" / "..longspace.." | "..longspace.."\\ ") --because of sans serif and regex --opt.l2=dialog.AddLabel(" | ".." ".." | ".." ".." | ") slash="/" backslash="\\" dash="--" space=" " else opt.l0=dialog.AddLabel("") --south pole gone opt.l1=dialog.AddLabel("") end opt.row1 = dialog.AddLabel( space..space..dash..cell[1][1].."-----"..cell[1][2].."-----"..cell[1][3]..dash) --globe opt.AddAlgorithm5 = dialog.AddLabel( slash..space..space..space.." | "..longspace.." | "..longspace.." | "..space..space..space..backslash) --because of sans serif opt.row2 = dialog.AddLabel(dash..dash..cell[2][1].."------"..cell[2][2].."------"..cell[2][3]..dash..dash) opt.AddRowLines2 = dialog.AddLabel( backslash..space..space..space.." | "..longspace.." | "..longspace.." | "..space..space..space..slash) --because of sans serif opt.AddRow3 = dialog.AddLabel( space..space..dash..cell[3][1].."-----"..cell[3][2].."-----"..cell[3][3]..dash) if(roundWorld) then --opt.l3=dialog.AddLabel(" | ".. " ".." | ".." ".." | ") --because of sans serif opt.l4=dialog.AddLabel(" \\ "..longspace.." | "..longspace.."/ ") --because of sans serif and regex opt.l5=dialog.AddLabel(" "..longspace.."---||---"..longspace.." ") --because of sans serif and regex else opt.l4=dialog.AddLabel("") --south pole gone opt.l5=dialog.AddLabel("") --south pole gone end opt.label0=dialog.AddLabel("If old unhibernated pawns do have access") opt.label1=dialog.AddLabel(" to empty farmland or supply lines, they will starve. ") --attempt at linebreak") opt.label2=dialog.AddLabel("Unburrow/place stone (soldier/pawn) at row,col.: ") --attempt at linebreak --buttons will always be at the bottom of the dialog no matter the order in code --even below sliders --jon: --table dialog.AddSlider(string label, number value, number minimum, number maximum, number precision) --0 precision: 1, 2, 3, --1 precision: 0.1,0.2,0.3 --2 prec. 0.01? tengen=math.ceil(rows/2) --Ceiling to find a center cell default=tengen opt.row= dialog.AddSlider("Row ", default, 1, 3, 0)--desctrip, default, min, max, precision opt.col= dialog.AddSlider("Column ", default, 1, 3, 0)--desctrip, default, min, max, precision opt.placeStone=dialog.AddButton("Unburrow", 6) opt.pass = dialog.AddButton("Pass", 5) opt.cancel = dialog.AddButton("Cancel", -1) res=dialog.Show(opt) cpuTurn=false msg="" function canEat(eaterColor,placementCell) --more like attack if cell[(res+1)%4]==eaterColor and cell[(res+1)%4]~=eaterColor and cell[(res+1)%4]~=farm then --cell[2]~=eaterColor and cell[2]~=farm) and cell[4]==eaterColor) then return true end return false end function checkFed() --avoid this scenario with multiple deliveries of food: --white white --white empty --starved white --white empty --This is taxicab geometry so it takes width*2 iterations to deliver food -- from one corner to the opposite. --This is why living far from farms is dangerous during pandemics. -- but traveling is dangerous too. for numDeliveries=1,#cell*#cell[1] do --multiply by width and height of matrix for safety to follow Go rules, -- but is a laggy [yet intuitive] implementation of the rules. -- Another implementation is to make an array (group) of chained pawns. --Width+length iterations may not be enough, because there can be a snake: --black black black white black --black white black white black --empty white black black black if debug then print("numDeliveries of food is "..numDeliveries) end if(roundWorld) then for row=1, #cell do for col=1,#cell do if cell[row][col]==farm then --liberty --round world, though same as normal flat world rules of Go if 2x2 isFed[(row)%#cell+1][col]=true --feed to the one below isFed[row][(col)%#cell+1]=true --feed to the right-hand isFed[(row-2)%#cell+1][col]=true --feed to the one above isFed[row][(col-2)%#cell+1]=true --feed to the left-hand --minus 2 instead of 1 because arrays in lua start with 1 instead of 0 -- +1 for same reason -- (3-2)%3+1=2 -- (2-2)%3+1=1 -- (1-2)%3+1=2+1=3 else if cell[(row)%#cell+1][col]==cell[row][col] and isFed[row][col] then --supply lines isFed[(row)%#cell+1][col]=true --round world end if cell[(row-2)%#cell+1][col]==cell[row][col] and isFed[row][col] then --supply lines isFed[(row-2)%#cell+1][col]=true --round world end if cell[row][(col)%#cell+1]==cell[row][col] and isFed[row][col] then isFed[row][(col)%#cell+1]=true end if cell[row][(col-2)%#cell+1]==cell[row][col] and isFed[row][col] then isFed[row][(col-2)%#cell+1]=true end end end end else --flat print("flat") for row=1, #cell-1 do for col=1,#cell do if cell[row][col]==farm then --liberty isFed[(row)+1][col]=true --feed to the one below else if cell[(row)+1][col]==cell[row][col] and isFed[row][col] then --supply lines isFed[(row)+1][col]=true end end end end for row=1, #cell do for col=1,#cell-1 do if cell[row][col]==farm then --liberty --taxes to both factions isFed[row][(col)+1]=true --feed to the right-hand else if cell[row][(col)+1]==cell[row][col] and isFed[row][col] then isFed[row][(col)+1]=true end end end end for row=2, #cell do for col=1,#cell do if cell[row][col]==farm then --a Go Liberty, Wings of Libery LOL isFed[(row)-1][col]=true --feed to the one above else if cell[(row)-1][col]==cell[row][col] and isFed[row][col] then --supply lines isFed[(row)-1][col]=true end end end end for row=1, #cell do for col=2,#cell do if cell[row][col]==farm then --liberty isFed[row][(col)-1]=true --feed to the one to the left else if cell[row][(col)-1]==cell[row][col] and isFed[row][col] then --supply lines isFed[row][(col)-1]=true end end end end end if debug then print("fed: ") for row=1,#cell do rowString="" for col=1,#cell do rowString=rowString..tostring(isFed[row][col]).." " end print(rowString) end end end end function starve() for row=1, #cell do for col=1,#cell do --Lua can't do ~true if cell[row][col]~=farm and isFed[row][col]~=true then --no liberty msg=msg..cell[row][col]..row..","..col.." starved. " cell[row][col]=farm --died, decomposed to fertilizer D: end end end if debug then print("after famine: ") for row=1,#cell do rowString="" for col=1,#cell do rowString=rowString..tostring(isFed[row][col]).." " end print(rowString) end end end if(res==roundWorldCode) then roundWorld= not roundWorld else if(res==5) then cpuTurn=true --userTeam passes else row=opt.row.value col=opt.col.value if cell[row][col]==farm then --print("canEat is "..tostring(canEat(userTeam,res))) --old algorithm for capturing, -- confusing with eat and starve. --If Zerglings, Terrans' Firebats, or Protoss Zealot swordsmen surround you -- on all sides, you die. --In real life and also in pro 3 way games, though, surrounding enemies on all sides -- goes against the Art of War (Bing Fa), -- because it makes you and your rival weakened and vulnerable to a 3rd faction. --In nixboard github code, it uses the can_eat algorithm to tell if a capture is available, which is called atari. -- Atari in Go is like check in Chess. --Capturing is kind of like white blood cells engulfing, -- and eating infected cells. In Go, though, one color is not more evil than the other. --In my own simple code, I rename things so that the stones eat vegetables from farmland, though there is war and seige. cell[row][col]=userTeam isFed={{false,false,false},{false,false,false},{false,false,false}} --let white starve after black seiges isFed[row][col]=true print(userTeam.." played "..row..","..col..". ") checkFed() starve() isFed={{false,false,false},{false,false,false},{false,false,false}} --after giving a chance to capture, see if it was suicide checkFed() starve() cpuTurn=true else opt.labelMsg=dialog.AddLabel("Can't place at cell "..row..", "..col) end end function ai(team) --which faction isFed={{false,false,false},{false,false,false},{false,false,false}} farms={} for row=1, #cell do for col=1,#cell do if(cell[row][col]==farm) then table.insert(farms,{cornrow=row,corncol=col}) --,row=row}) --also works end end end if #farms==0 then opt.labelMsg=dialog.AddLabel("White passes. ") return false --pass else randFarm=math.random(#farms) print("corn "..farms[randFarm].cornrow) --print("row "..farms[randFarm].row) row=farms[randFarm].cornrow col=farms[randFarm].corncol cell[row][col]=team isFed={{false,false,false},{false,false,false},{false,false,false}} --let black starve after white seiges isFed[row][col]=true msg=msg..team.." played"..row..","..col..". " --save space print(team.." played "..row..","..col..". ") checkFed() starve() isFed={{false,false,false},{false,false,false},{false,false,false}} --after giving a chance to capture, see if it was suicide checkFed() starve() opt.labelMsg=dialog.AddLabel(msg) return true --fixed indents in Sublime end end if cpuTurn then ----Minerals --width ----Farmland --checking text width ----Crystals --checking text width --ai("Zergling") --looks more compact in Sans Serif ai("Terrans") ai("Protoss") end end until res==-1

Comments