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 |
* 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. |
$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 \ |
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, |
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[ |
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.) |
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", |
# 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) |