Morpion solitaire/Unicon: Difference between revisions

Content added Content deleted
(fix for move log offset error, update help, change a default)
(fix initial move optimization, limit typo, improve record def, help, add rseed)
Line 10: Line 10:
* Save a game
* Save a game
* Use a plugable scoring/evaluation procedure at each move (for heuristics)
* Use a plugable scoring/evaluation procedure at each move (for heuristics)
* Limit initial random moves to 1 of 3 cases (inside/outside corner, outside valley) not 1 of 28
* Limit initial random moves to 1 of 4 cases (inside corners, outside corners (2 types), outside valley) not 1 of 28


For an example of a loadable and re-playable game see [[Morpion_solitaire/Rosin177|Chris Rosin's 177 move 5T previous record holder]].
For an example of a loadable and re-playable game see [[Morpion_solitaire/Rosin177|Chris Rosin's 177 move 5T previous record holder]].
Line 24: Line 24:
<lang Unicon>link printf,strings,options
<lang Unicon>link printf,strings,options


$define MORPVER "1.7" # version
$define MORPVER "1.7b" # version


procedure main(A) # Morphion
procedure main(A) # Morphion
MorpionConf(A)
MorpionConf(A)
if \M_ReplayFile then ReplayMorpion()
if \M_ReplayFile then ReplayMorpion()
else if \M_limit === 1 then PlayMorphion5T()
else if \M_Limit === 1 then PlayMorphion5T()
else MultiSimMorphion(\M_Limit)
else MultiSimMorphion(\M_Limit)
printf("Finished.\n")
printf("Finished.\n")
Line 36: Line 36:
record morpioncell(symbol,direction,row,col) # a grid cell
record morpioncell(symbol,direction,row,col) # a grid cell
record morpionmove(direction,move,line,roff,coff) # move & line
record morpionmove(direction,move,line,roff,coff) # move & line
record morpiongame(grid,log,history,roff,coff,center,pool,move,count) # all game data
record morpiongame(grid, # the grid
log,history, # move log and replayable history log
roff,coff,center, # origin expansion offsets and center
pool, # pool of avail moves
move, # selected move
count, # game number (multi-game)
rseed) # &random at start of random play


global M_Strategy,M_Eval,M_Mvalid # Pluggable procedures
global M_Strategy,M_Eval,M_Mvalid # Pluggable procedures
Line 55: Line 61:
procedure PlayMorphion5T() #: Play a 5T game
procedure PlayMorphion5T() #: Play a 5T game
G := (MG := SetupM5Grid()).grid # start new game
G := (MG := SetupM5Grid()).grid # start new game
&random := MG.rseed := \M_Rseed # set &random
if M_PrintOpt = 1 then PrintGrid(MG)
if M_PrintOpt = 1 then PrintGrid(MG)
pg := if M_PrintOpt == 2 then PrintGrid else 1
pg := if M_PrintOpt == 2 then PrintGrid else 1
Line 97: Line 104:


if *MG.history = 0 & M_Strategy ~=== Replayer then { # move 1 special case
if *MG.history = 0 & M_Strategy ~=== Replayer then { # move 1 special case
every put(pool1 := [], MG.pool[1|16|28]) # keep i/o corner, o valley
every put(pool1 := [], MG.pool[2|19|20|26]) # cor. o(2), i(1), val o(1)
MG.pool := pool1
MG.pool := pool1
}
}
Line 141: Line 148:
G[r,c] := morpioncell(XINIT,"",r,c)
G[r,c] := morpioncell(XINIT,"",r,c)
}
}
return morpiongame(G,[],[],0,0,1 + (*G-1)/2.) # Create game
return morpiongame(G,[],[],0,0,1 + (*G-1)/2.,,,,&random) # Create game
end
end


Line 229: Line 236:
\t-RF\tfile containing game record to be replayed\n_
\t-RF\tfile containing game record to be replayed\n_
\t-RN\tnumber of moves to replay (0=all)\n_
\t-RN\tnumber of moves to replay (0=all)\n_
\t-seed\tstart the seed of the random number at this value\n_
\t-L|-limit\tgames to play (if 0 or less then play until any of 'XxQq' is pressed\n_
\t-L|-limit\tgames to play (if 0 or less then play until any of 'XxQq' is pressed\n_
\t\tnote for larger n this benefits from larger BLKSIZE, STRSIZE environment variables\n_
\t\tnote for larger n this benefits from larger BLKSIZE, STRSIZE environment variables\n_
Line 240: Line 248:
procedure MorpionConf(A) # Configure the Solver
procedure MorpionConf(A) # Configure the Solver
M_CommandLine := copy(A) # preserve
M_CommandLine := copy(A) # preserve
os := "-Q! -L+ -limit+ -P+ -print+ -R! -replay! -RF: -RN+ -save! "
os := "-Q! -L+ -limit+ -P+ -print+ -R! -replay! -RF: -RN+ -seed+ -save! "
os ||:= "-UN+ -SW+ -SD+ -A: -E+ -B+ -W+"
os ||:= "-UN+ -SW+ -SD+ -A: -E+ -B+ -W+"
opt := options(A,os,Usage) # -<anything else> gets help
opt := options(A,os,Usage) # -<anything else> gets help
M_Limit := \opt["limit"|"L"] | 1
M_Limit := ( 0 <= integer(\opt["limit"|"L"])) | 1
M_GameSave := opt["save"]
M_GameSave := opt["save"]
M_PrintOpt := (0|1|2) = \opt["P"|"print"]
M_PrintOpt := (0|1|2) = \opt["P"|"print"]
Line 251: Line 259:
M_ReplayAfter := (0 < \opt["RN"]) | &null
M_ReplayAfter := (0 < \opt["RN"]) | &null
}
}
else M_ReplayFile := &null
else M_ReplayFile := &null
M_Rseed := \opt["seed"]
M_Strategy := case opt["A"] of {
M_Strategy := case opt["A"] of {
"A1" : (def_un := 50, PlayerA1)
"A1" : (def_un := 50, PlayerA1)
Line 387: Line 396:
break
break
(SetupM5Grid := ReSetupM5Grid)(MG) # replace procedure and set grid
(SetupM5Grid := ReSetupM5Grid)(MG) # replace procedure and set grid
&random := MG.rseed := \M_Rseed # set &random per M_Seed
if M_Limit === 1 then
if M_Limit === 1 then
PlayMorphion5T() # single game
PlayMorphion5T() # single game
Line 484: Line 494:
c := sprintf( "#\n# Game Record for Morphion 5T game of %i moves\n_
c := sprintf( "#\n# Game Record for Morphion 5T game of %i moves\n_
# Reference: %s\n_
# Reference: %s\n_
# &random: %i\n_
# Syntax for recorded games:\n_
# Syntax for recorded games:\n_
# 1. whitespace and comments (everything past #) are ignored\n_
# 1. whitespace and comments (everything past #) are ignored\n_
Line 495: Line 506:
# 4. all row/col coordinates are relative to the 1,1 origin\n_
# 4. all row/col coordinates are relative to the 1,1 origin\n_
# located at the intersection of the lines containing the\n_
# located at the intersection of the lines containing the\n_
# top and left most edges of the cross.\n#\n",*MG.history,savegame)
# top and left most edges of the cross.\n#\n",
*MG.history,savegame,MG.rseed)
every m := MG.history[i := 1 to *MG.history] do {
every m := MG.history[i := 1 to *MG.history] do {
e := m.move ~= (1|5)
e := m.move ~= (1|5)