Morpion solitaire/Unicon: Difference between revisions
(→Multigame: info on histogram and work of Jean-Jacques Sibil) |
(overall and code clean up) |
||
Line 24: | Line 24: | ||
<lang Unicon>link printf,strings,options |
<lang Unicon>link printf,strings,options |
||
$define MORPVER "1. |
$define MORPVER "1.7f" # 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 |
else if \M_Limit === 1 then ShowGame(SingleMorpion()) |
||
else |
else MultiMorphion(\M_Limit) |
||
printf("Finished.\n") |
|||
end |
end |
||
$define XEMPTY "." # symbols used in Grid |
|||
record morpioncell(symbol,direction,row,col) # a grid cell |
|||
$define XINIT "*" |
|||
record morpionmove(direction,move,line,roff,coff) # move & line |
|||
$define XUSED "+" |
|||
record morpiongame(grid, # the grid |
|||
$define DHOR "-" # Directions for moves |
|||
$define DVER "|" |
|||
$define DRD "\\" |
|||
$define DLD "/" |
|||
$define DALL "-|/\\" |
|||
record morpiongame(grid,score, # the grid & score |
|||
log,history, # move log and replayable history log |
log,history, # move log and replayable history log |
||
roff,coff,center, # origin expansion offsets and center |
roff,coff,center, # origin expansion offsets and center |
||
Line 43: | Line 49: | ||
count, # game number (multi-game) |
count, # game number (multi-game) |
||
rseed) # &random at start of random play |
rseed) # &random at start of random play |
||
record morpionmove(direction,move,line,roff,coff) # move & line data |
|||
record morpioncell(symbol,direction,row,col) # a grid cell |
|||
record MorpionGameRecord(ref,row,col,darow,dacol) # record of game |
|||
procedure SingleMorpion(MG,N) #: Play a game silently |
|||
global M_Strategy,M_Eval,M_Mvalid # Pluggable procedures |
|||
/MG := SetupM5Grid() # start game with new grid? |
|||
global M_CommandLine,M_Config,M_PrintOpt,M_GameSave # Misc. |
|||
while MorphionMove(M_Strategy(MG)) do # keep moving |
|||
global M_Limit,M_StatUpd,M_BestL,M_WorstL # Multi-game simulation options |
|||
if MG.score >= \N then break # unless truncated |
|||
global M_ReplayFile,M_ReplayAfter # For game replay |
|||
$define XEMPTY "." # symbols used in Grid |
|||
$define XINIT "*" |
|||
$define XUSED "+" |
|||
$define DHOR "-" # Directions for moves |
|||
$define DVER "|" |
|||
$define DRD "\\" |
|||
$define DLD "/" |
|||
procedure PlayMorphion5T() #: Play a 5T game |
|||
G := (MG := SetupM5Grid()).grid # start new game |
|||
&random := MG.rseed := \M_Rseed # set &random |
|||
if M_PrintOpt = 1 then PrintGrid(MG) |
|||
pg := if M_PrintOpt == 2 then PrintGrid else 1 |
|||
while MorphionMove(M_Strategy(pg(MG))) # keep moving |
|||
if M_PrintOpt = 1 then PrintGrid(MG) |
|||
if M_PrintOpt > 0 then { |
|||
PrintLog(MG) |
|||
WriteMoveLog(MG) |
|||
} |
|||
return MG |
return MG |
||
end |
end |
||
procedure MorphionMove(MG) #: make a move |
procedure MorphionMove(MG) #: make a move |
||
(M := MG.move).roff := MG.roff |
(M := MG.move).roff := MG.roff # copy offsets |
||
M.coff := MG.coff |
M.coff := MG.coff |
||
put(MG.history,M) |
put(MG.history,M) # save history |
||
MG.score +:= 1 # and score |
|||
M_LogDetails(MG,M) # for analysis |
|||
log ||:= sprintf(" - of %i choices.",*MG.pool) # append # choices |
|||
log ||:= sprintf(" Metric=%i",M_Eval(MG)) # append score (opt) |
|||
put(MG.log,log) # log the move |
|||
every x := !M.line do { # draw the line |
every x := !M.line do { # draw the line |
||
g := MG.grid[x[1],x[2]] |
g := MG.grid[x[1],x[2]] |
||
Line 102: | Line 87: | ||
( c := 5 to *G[r := 1] ) do # down & left |
( c := 5 to *G[r := 1] ) do # down & left |
||
ScanGridLine(G,r,c,+1,-1,DLD,MG.pool) |
ScanGridLine(G,r,c,+1,-1,DLD,MG.pool) |
||
if MG.score = 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[2|19|20|26]) # cor. o(2), i(1), val o(1) |
every put(pool1 := [], MG.pool[2|19|20|26]) # cor. o(2), i(1), val o(1) |
||
MG.pool := pool1 |
MG.pool := pool1 |
||
Line 127: | Line 111: | ||
return pool |
return pool |
||
end |
end |
||
procedure ValidMove5T(L,dir) #: Succeed if L has valid 5T move |
procedure ValidMove5T(L,dir) #: Succeed if L has valid 5T move |
||
local i,j |
local i,j |
||
Line 135: | Line 119: | ||
every (j := 0) +:= ( find(dir,(!L).direction), 1) |
every (j := 0) +:= ( find(dir,(!L).direction), 1) |
||
if j > 1 then fail # no overlap, =1 implies at an end |
if j > 1 then fail # no overlap, =1 implies at an end |
||
return # that's it! |
|||
end |
|||
procedure ValidMove5D(L,dir) #: Succeed if L has valid 5D move #@@ |
|||
local i,j |
|||
if *L ~= 5 then fail # wrong count |
|||
every (i := 0) +:= (/(!L).symbol,1) |
|||
if i ~= 1 then fail # more than 1 avail space |
|||
every (j := 0) +:= ( find(dir,(!L).direction), 1) |
|||
if j > 0 then fail # no overlap, =1 implies at an end |
|||
return # that's it! |
return # that's it! |
||
end |
end |
||
Line 148: | Line 142: | ||
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,0,1 + (*G-1)/2.) # Create game |
||
end |
end |
||
Line 155: | Line 149: | ||
rn := *(G := MG.grid) # capture ... |
rn := *(G := MG.grid) # capture ... |
||
cn := *G[1] # ... entry dimensions |
cn := *G[1] # ... entry dimensions |
||
if \(!G)[1].symbol then { # left edge |
if \(!G)[1].symbol then { # left edge |
||
MG.coff +:= 1 |
MG.coff +:= 1 |
||
Line 177: | Line 170: | ||
} |
} |
||
return MG |
return MG |
||
end |
|||
procedure ShowGame(MG) #: show games |
|||
if M_Output === &output then |
|||
every (PrintGrid|WriteMoveLog|M_PrintDetails)(MG) |
|||
else # header first to output, game saved |
|||
every (WriteMoveLog|PrintGrid|M_PrintDetails)(MG) |
|||
end |
end |
||
procedure PrintGrid(MG) #: print the current Grid |
procedure PrintGrid(MG) #: print the current Grid |
||
G := MG.grid |
G := MG.grid |
||
every (ruler := " ") ||:= (1 to *G[1]) % 10 |
|||
write("\nMorphion Solitare Grid (move=",*(L := MG.log),"):\n") |
|||
fprintf(M_Output,"\nMorphion Solitare Grid (move=%i):\n%s\n",MG.score,ruler) |
|||
write(ruler) |
|||
every r := 1 to *G do { |
every r := 1 to *G do { |
||
fprintf(M_Output,"%s ",right(r%100,2)) |
|||
every c := 1 to *(G[r]) do |
every c := 1 to *(G[r]) do |
||
fprintf(M_Output,"%s",\G[r,c].symbol | XEMPTY) |
|||
fprintf(M_Output,"\n") |
|||
} |
} |
||
fprintf(M_Output,"%s\n",ruler) |
|||
return MG |
return MG |
||
end |
end |
||
procedure |
procedure RandomPlayer(MG) #: Simulate random player |
||
if &random := \M_Rseed then M_Rseed := &null # set seed if given only once |
|||
printf("Move Log\n") |
|||
/MG.rseed := &random # seed for this game |
|||
every printf("%i : %s\n",i := 1 to *MG.log,MG.log[i]) |
|||
end |
|||
procedure FormatMoveLog(M,roff,coff) #: format a log entry |
|||
/M.roff := \roff | 0 |
|||
/M.coff := \coff | 0 |
|||
log := sprintf("\"%s\" [%i,%i] : ",M.direction, |
|||
M.line[M.move,1]-M.roff,M.line[M.move,2]-M.coff) |
|||
every x := !M.line do |
|||
log ||:= sprintf("[%i,%i] ",x[1]-M.roff,x[2]-M.coff) |
|||
return log |
|||
end |
|||
procedure RandomPlayer(MG) #: Simulate random player |
|||
if MG.move := ?ScanGrid(MG).pool then return MG |
if MG.move := ?ScanGrid(MG).pool then return MG |
||
end |
end |
||
procedure Scorefail(MG);end #: dummy always fails</lang> |
procedure Scorefail(MG);end #: dummy always fails </lang> |
||
== Interface, Parameters, Globals == |
|||
== Strategy Support == |
|||
<lang Unicon>global M_Strategy,M_Eval,M_Mvalid # Pluggable procedures |
|||
<lang Unicon># No useful examples at this time</lang> |
|||
global M_CommandLine,M_Config,M_GameType,M_GameSave |
|||
global M_LogDetails,M_PrintDetails # Misc. |
|||
== Interface & Parameters == |
|||
global M_Output # output files |
|||
<lang Unicon>procedure Usage() |
|||
global M_Limit,M_StatUpd,M_BestL,M_WorstL # Multi-game simulation options |
|||
fprintf(&errout,"_ |
|||
global M_SrchWid,M_SrchDep # For strategy modules |
|||
Morphion [options] Plays the 5T variant of Morphion Solitaire\n_ |
|||
global M_ReplayFile,M_ReplayAfter,M_Rseed # For game replay |
|||
Arguments : ") |
|||
global M_WriteGame,M_ReadGame,M_GameFmt # Game formats to use |
|||
every fprintf(&errout," %s",!M_CommandLine) |
|||
global M_ChartW,M_ChartG # histogram |
|||
Morphion [options] Plays the 5T variant of Morphion Solitaire\n_ |
|||
Where options are:\n_ |
|||
\t-P|-print\tcontrols how much is printed \n_ |
|||
\t\t\tn=2\tshows all boards and a log of all moves (every game)\n_ |
|||
\t\t\tn=1\tshows a log of the moves and final board (default single game)\n_ |
|||
\t\t\tn=0\tproduces no per game output (default for multigames)\n_ |
|||
\t-A\tchoose player strategy approach (default=random, future)\n_ |
|||
\t-E\tSpecifiy an position fitness evaluation function (default none, future)\n_ |
|||
\t-SW\tSearch width (strategy dependent, future)\n_ |
|||
\t-SD\tSearch depth (strategy dependent, future)\n_ |
|||
\t-R|-replay\treplay\n_ |
|||
\t-RF\tfile containing game record to be replayed\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\tnote for larger n this benefits from larger BLKSIZE, STRSIZE environment variables\n_ |
|||
\t-UN\tGive status update notifications every n simulations\n_ |
|||
\t-B\tKeep best n games of unique length (default 5)\n_ |
|||
\t-W\tKeep worst n games of unique length (default 3)\n_ |
|||
\t-?|-h|-help\tthis help text") |
|||
stop() |
|||
end |
|||
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+ - |
os := "-Q! -L+ -limit+ -V: -variant: -seed+ " |
||
os ||:= "-R! -replay! -RF: -RN+ -save! -RW: -RR: " |
|||
os ||:= "-histwidth+ -histgroup+ -HW+ -HG+ " |
|||
os ||:= "-UN+ -SW+ -SD+ -A: -E+ -B+ -W+" |
os ||:= "-UN+ -SW+ -SD+ -A: -E+ -B+ -W+" |
||
os ||:= "-details! " |
|||
opt := options(A,os,Usage) # -<anything else> gets help |
opt := options(A,os,Usage) # -<anything else> gets help |
||
M_Limit := ( 0 <= integer(\opt["limit"|"L"])) | 1 |
M_Limit := ( 0 <= integer(\opt["limit"|"L"])) | 1 |
||
M_Rseed := \opt["seed"] |
|||
M_Mvalid := case opt["V"|"variant"] of { |
|||
"5D" : (M_GameType := "5D", ValidMove5D) |
|||
/M_PrintOpt := \M_Limit === 1 | 0 |
|||
default : (M_GameType := "5T", ValidMove5T) # also 5T |
|||
if \opt["R"|"replay"] then { |
|||
} |
|||
M_ReadGame := case map(\opt["RR"]) | &null of { |
|||
default : (M_GameFmt := "ps", ReadMoveLogPS) |
|||
} |
|||
"0" : (M_GameFmt := "0", ReadMoveLogOrig) |
|||
else M_ReplayFile := &null |
|||
} |
|||
M_WriteGame := case map(\opt["RW"]) | &null of { |
|||
default : (M_GameFmt := "ps", WriteMoveLogPS) |
|||
"0" : (M_GameFmt := "0", WriteMoveLogOrig) |
|||
} |
|||
M_Strategy := case opt["A"] of { |
M_Strategy := case opt["A"] of { |
||
"A1" : |
"A1" : (def_un := 50, PlayerA1) |
||
default : |
default : (def_un := 500, RandomPlayer) |
||
} |
} |
||
M_Eval := case opt["E"] of { |
|||
"1" : Score1 # test |
|||
default : &null # also "0" |
|||
} |
|||
M_ChartW := (40 <= \opt["histwidth"|"HW"]) | 80 |
|||
M_ChartG := \opt["histgroup"|"HG"] | 5 |
|||
M_LogDetails := if \opt["details"] then LogDetails else 1 |
|||
M_PrintDetails := if \opt["details"] then PrintDetails else 1 |
|||
M_StatUpd := (0 < \opt["UN"]) | def_un |
M_StatUpd := (0 < \opt["UN"]) | def_un |
||
M_BestL := (0 < \opt["B"]) | 5 |
M_BestL := (0 < \opt["B"]) | 5 |
||
M_WorstL := (0 < \opt["W"]) | 0 |
M_WorstL := (0 < \opt["W"]) | 0 |
||
M_SrchWid := (0 < \opt["SW"]) | 5 |
M_SrchWid := (0 < \opt["SW"]) | 5 |
||
M_SrchDep := (0 < \opt["SD"]) | 5 |
M_SrchDep := (0 < \opt["SD"]) | 5 |
||
if \opt["R"|"replay"] then { |
|||
M_ReplayFile := \opt["RF"] | "Games/5T/177-5T-rosin.txt" |
|||
M_ReplayAfter := (0 < \opt["RN"]) | &null |
|||
} |
} |
||
else M_ReplayFile := &null |
|||
if \(M_GameSave := opt["save"]) then { |
|||
fn := sprintf("Runs/%s-L%i-",M_GameType,M_Limit) |
|||
fn ||:= sprintf("RF%s-",map(\M_ReplayFile,"/\\","__")) |
|||
fn ||:= sprintf("RN%i-",\M_ReplayAfter) |
|||
fn ||:= sprintf("%s-%s.txt",deletec(&date,'/'),deletec(&clock,':')) |
|||
M_Output := open(fn,"w") |
|||
} |
|||
/M_Output := &output |
|||
c := sprintf("# --- Morpion Solitaire 5 (v%s) ---\n#\n",MORPVER) |
c := sprintf("# --- Morpion Solitaire 5 (v%s) ---\n#\n",MORPVER) |
||
c ||:= "# Command line options :" |
c ||:= "# Command line options :" |
||
every c ||:= " " || !A |
every c ||:= " " || !A |
||
c ||:= "\n# Summary of Morpion Configuration:\n" |
c ||:= "\n# Summary of Morpion Configuration:\n" |
||
c ||:= sprintf("# Variant (5T/ |
c ||:= sprintf("# Variant (5T/D) move validation = %i\n",M_Mvalid) |
||
c ||:= sprintf("# Games to play = %s\n",( |
c ||:= sprintf("# Games to play = %s\n",( |
||
0 < M_Limit) | "* unlimited *") |
|||
c ||:= sprintf("# Print (0=none,1=minimal,2=all) = %i\n",M_PrintOpt) |
|||
c ||:= sprintf("# Games will be saved = %s\n",\M_SaveGame) |
|||
c ||:= "# Multi-game options:\n" |
c ||:= "# Multi-game options:\n" |
||
c ||:= sprintf("# - Status Updates = %i\n",M_StatUpd) |
c ||:= sprintf("# - Status Updates = %i\n",M_StatUpd) |
||
c ||:= sprintf("# - Keep best = %i\n",M_BestL) |
c ||:= sprintf("# - Keep best = %i\n",M_BestL) |
||
c ||:= sprintf("# - Keep worst = %i\n",M_WorstL) |
c ||:= sprintf("# - Keep worst = %i\n",M_WorstL) |
||
c ||:= sprintf("# - Histogram width = %i\n",M_ChartW) |
|||
c ||:= sprintf("# - Histogram grouping = %i\n",M_ChartG) |
|||
c ||:= sprintf("# Games will be saved = %s\n", |
|||
(\M_GameSave, "Yes") | "* No *") |
|||
c ||:= sprintf("# - Format for game file (write) = %i\n",\M_WriteGame) |
|||
c ||:= "# Replaying\n" |
c ||:= "# Replaying\n" |
||
c ||:= sprintf("# - |
c ||:= sprintf("# - Format for game file (read) = %i\n",\M_ReadGame) |
||
c ||:= sprintf("# - |
c ||:= sprintf("# - Game file to be replayed = %s\n", |
||
\M_ReplayFile | "* None *") |
|||
c ||:= sprintf("# - Moves to replay = %i\n", |
|||
0 ~= \M_ReplayAfter) |
|||
c ||:= sprintf("# Player Strategy = %i\n",M_Strategy) |
c ||:= sprintf("# Player Strategy = %i\n",M_Strategy) |
||
c ||:= sprintf("# - |
c ||:= sprintf("# - Seed for &random = %i\n",\M_Rseed) |
||
c ||:= sprintf("# - Position Fitness Evaluator = %s\n", |
|||
image(\M_Eval) | "* None *") |
|||
c ||:= sprintf("# - Search Width (strategy dependant) = %i\n",M_SrchWid) |
c ||:= sprintf("# - Search Width (strategy dependant) = %i\n",M_SrchWid) |
||
c ||:= sprintf("# - Search Depth (strategy dependant) = %i\n",M_SrchDep) |
c ||:= sprintf("# - Search Depth (strategy dependant) = %i\n",M_SrchDep) |
||
c ||:= |
c ||:= sprintf("# Log Details for analysis = %s\n", |
||
if M_LogDetails === 1 then "No" else "Yes") |
|||
c ||:= "#\n" |
|||
M_Config := c |
M_Config := c |
||
if \opt["Q"] then stop(M_Config,"-Q Stops run after processing options") |
if \opt["Q"] then stop(M_Config,"-Q Stops run after processing options") |
||
else |
else fprintf(M_Output,M_Config) |
||
/M_Eval := Scorefail |
/M_Eval := Scorefail |
||
end |
|||
procedure Usage() |
|||
fprintf(&errout,"_ |
|||
Morphion [options] Plays the 5T/D variant of Morphion Solitaire\n_ |
|||
Arguments : ") |
|||
every fprintf(&errout," %s",!M_CommandLine) |
|||
fprintf(&errout,"_ |
|||
Morphion [options] Plays the 5T/D variant of Morphion Solitaire\n_ |
|||
Where options are:\n_ |
|||
\t-A\tchoose player strategy approach (default=random, future)\n_ |
|||
\t-E\tSpecifiy an position fitness evaluation function (default none, future)\n_ |
|||
\t-SW\tSearch width (strategy dependent, future)\n_ |
|||
\t-SD\tSearch depth (strategy dependent, future)\n_ |
|||
\t-V|-variant\t5D or 5T (default)\n_ |
|||
\t-R|-replay\treplay\n_ |
|||
\t-RF\tfile containing game record to be replayed\n_ |
|||
\t-RN\tnumber of moves to replay (0=all)\n_ |
|||
\t-RR\tgame recording format to read (ps=pentasol(default), 0=original)\n_ |
|||
\t-RW\tgame recording format to write ps=pentasol(default), 0=original)\n_ |
|||
\t-save\tsave the best (-B) and worst (-W) games\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\tnote for larger n this benefits from larger BLKSIZE, STRSIZE environment variables\n_ |
|||
\t-HW|-histwidth\twidth (cols) of histogram of scores\n_ |
|||
\t-HG|-histgroup\tsize of groups (buckets) for histogram\n_ |
|||
\t-UN\tGive status update notifications every n simulations\n_ |
|||
\t-B\tKeep best n games of unique length (default 5)\n_ |
|||
\t-W\tKeep worst n games of unique length (default 3)\n_ |
|||
\t-details\tLog game details for analysis\n_ |
|||
\t-Q\t(debugging) terminates after options processing\n_ |
|||
\t-?|-h|-help\tthis help text") |
|||
stop() |
|||
end</lang> |
end</lang> |
||
== Multigame Simulation and Monitoring Support == |
== Multigame Simulation and Monitoring Support == |
||
<lang Unicon> |
|||
<lang Unicon>procedure MultiSimMorphion(N) #: Simulate N games |
|||
procedure MultiMorphion(N,MG) #: Simulate N games using MG |
|||
etime := -&time |
etime := -&time |
||
scores := table(n := 0) |
scores := table(n := 0) |
||
every bestL|worstL := [] |
every bestL|worstL := [] |
||
if N <= 0 then N := "unlimited" |
if N <= 0 then N := "unlimited" |
||
repeat { |
repeat { |
||
if n >= numeric(N) then break else n +:= 1 |
if n >= numeric(N) then break else n +:= 1 |
||
mg := SingleMorpion(deepcopy(\MG)|&null) # play out game |
|||
mg. |
scores[mg.score] +:= 1 # count score |
||
mg.count := n # game number |
|||
if short := ( /short | short.score >= mg.score, mg) then { |
|||
push(worstL,short) # keep worst |
|||
if *worstL > M_WorstL then pull(worstL) |
if *worstL > M_WorstL then pull(worstL) |
||
} |
} |
||
if |
if ( /long | long.score <= mg.score) then { |
||
bestcnt := if (\long).score = mg.score then bestcnt + 1 else 1 |
|||
long := mg |
|||
put(bestL,long) # keep best |
|||
if *bestL > M_BestL then get(bestL) |
if *bestL > M_BestL then get(bestL) |
||
fprintf(M_Output,"Longest game %i after %i simulations &random=%i.\n", |
|||
long.score,n,long.rseed) |
|||
fprintf(&errout,"\r%i of %s simulations, long=%i (%s)", |
|||
fprintf(&errout,"\r%i of %s simulations, long=%i(%i) (%s %s)", |
|||
n,N,long.score,bestcnt,&date,&clock) |
|||
} |
} |
||
if (n % M_StatUpd) = 0 then # |
if (n % M_StatUpd) = 0 then # say we're alive & working |
||
fprintf(&errout,"\r%i of %s simulations, long=%i (%s)", |
fprintf(&errout,"\r%i of %s simulations, long=%i(%i) (%s %s)", |
||
n,N, |
n,N,long.score,bestcnt,&date,&clock) |
||
if kbhit() & getch() == !"QqXx" then # exit if any q/x |
if kbhit() & getch() == !"QqXx" then # exit if any q/x |
||
break fprintf(&errout,"\nExiting after %i simulations.\n",n) |
break fprintf(&errout,"\nExiting after %i simulations.\n",n) |
||
} |
} |
||
Line 336: | Line 374: | ||
avg +:= i * scores[i] |
avg +:= i * scores[i] |
||
} |
} |
||
fprintf(M_Output,"\nResults from Sample of %i games of Morpion 5T/D:\n",n) |
|||
fprintf(M_Output,"Shortest game was %i moves.\n",short) |
|||
fprintf(M_Output,"Average game was %i moves.\n",avg /:= n) |
|||
fprintf(M_Output,"Longest game was %i moves.\n",long.score) |
|||
fprintf(M_Output,"Average time/game is %i ms.\n",etime/real(n)) |
|||
fprintf(M_Output,"&random is now %i.\n",&random) |
|||
GraphScores(scores) # graph results |
GraphScores(scores) # graph results |
||
fprintf(M_Output,"\nLongest (%i) Game(s):\n",M_BestL) |
|||
every |
every ShowGame(!reverse(bestL)) # show longest game(s) and log |
||
fprintf(M_Output,"\nShortest (%i) Game(s):\n",M_WorstL) |
|||
PrintGrid(x) |
|||
every ShowGame(!worstL) # show longest game(s) and log |
|||
PrintLog(x) |
|||
} |
|||
printf("\nShortest (%i) Game(s):\n",M_WorstL) |
|||
every x := !worstL do { # show longest game(s) and log |
|||
PrintGrid(x) |
|||
PrintLog(x) |
|||
WriteMoveLog(x) |
|||
} |
|||
MemUsage() # diagnostic |
MemUsage() # diagnostic |
||
end |
end |
||
$define CHARTW 80 # chart width |
|||
$define CHARTG 20 # size of chart buckets |
|||
procedure GraphScores(S) #: graph results |
procedure GraphScores(S) #: graph results |
||
chart := [] |
chart := [] |
||
every s := key(S) do { # by score |
every s := key(S) do { # by score |
||
n := s/ |
n := s/M_ChartG+1 # chunks of ... |
||
until chart[n] do put(chart,0) # grow chart to need |
until chart[n] do put(chart,0) # grow chart to need |
||
chart[n] +:= S[s] |
chart[n] +:= S[s] |
||
} |
} |
||
s := (1 < max!chart/ |
s := (1 < max!chart/M_ChartW | 1) # scale |
||
fprintf(M_Output,"\nSummary of Results every '*' = %d games\n",s) |
|||
every n := 1 to *chart do |
every n := 1 to *chart do |
||
fprintf(M_Output,"%3d | (%6d) %s\n",(n-1)*M_ChartG,chart[n],repl("*",chart[n]/s)) |
|||
end |
end |
||
procedure MemUsage() #: monitor usage |
procedure MemUsage() #: monitor usage |
||
fprintf(M_Output,"\nTotal run time = %i ms\n",&time) |
|||
fprintf(M_Output,"&allocated (Total,static,string,block) : ") |
|||
every |
every fprintf(M_Output," %i",&allocated) ; fprintf(M_Output,"\n") |
||
fprintf(M_Output,"&collections (Total,static,string,block) : ") |
|||
every |
every fprintf(M_Output," %i",&collections) ; fprintf(M_Output,"\n") |
||
fprintf(M_Output,"®ions ( - , - ,string,block) : ") |
|||
every |
every fprintf(M_Output," %s","-"|®ions) ; fprintf(M_Output,"\n") |
||
fprintf(M_Output,"&storage ( - , - ,string,block) : ") |
|||
every |
every fprintf(M_Output," %s","-"|&storage) ; fprintf(M_Output,"\n\n") |
||
end</lang> |
end </lang> |
||
== Game Reloader/Replayer == |
|||
== Game Replayer == |
|||
<lang Unicon>procedure ReplayMorpion() #: Handle recorded games |
<lang Unicon>procedure ReplayMorpion() #: Handle recorded games |
||
Replayer(M := ReadMoveLog(M_ReplayFile)) # read game and save data |
Replayer(M := ReadMoveLog(M_ReplayFile)) # read game and save data |
||
M_Strategy := Replayer |
|||
if /M_ReplayAfter | (M_ReplayAfter > *M) then { |
if /M_ReplayAfter | (M_ReplayAfter > *M) then { |
||
fprintf(M_Output,"Single game replay\n") |
|||
ShowGame(SingleMorpion()) |
|||
M_Strategy := Replayer |
|||
PlayMorphion5T() |
|||
} |
} |
||
else { # truncation replay |
else { # truncation replay |
||
MG := SingleMorpion(,M_ReplayAfter) # play shortened game |
|||
M_Strategy := RandomPlayer |
|||
while MorphionMove(Replayer(MG)) do |
|||
if *MG.history = M_ReplayAfter then # play until move |
|||
break |
|||
(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 |
||
ShowGame(SingleMorpion(MG)) # single game |
|||
else |
else |
||
MultiMorphion(M_Limit,MG) # simulate many games from here |
|||
} |
} |
||
return |
return |
||
end |
end |
||
procedure |
procedure Replayer(MG) #: feed replayed moves from list/game |
||
static MGB |
|||
if MGB := \MG then return # 'set' partial game if arg |
|||
else return deepcopy(MGB) # otherwise return a new copy |
|||
end |
|||
procedure Replayer(MG) #: feed replayed moves |
|||
static ML,radj,cadj |
static ML,radj,cadj |
||
if type(MG[1]) == "MorpionGameRecord" then return ML := MG |
if type(MG[1]) == "MorpionGameRecord" then return ML := MG # setup list |
||
if not ScanGrid(MG) then fail |
if not ScanGrid(MG) then fail # out of moves ? |
||
x := get(ML) | fail |
x := get(ML) | fail # get next move |
||
if x.ref = 0 then x := get(ML) | fail |
if x.ref = 0 then x := get(ML) | fail # skip move 0 if any |
||
xr := x.row + MG.roff # adjust for expansion |
xr := x.row + MG.roff # adjust move for grid expansion |
||
xc := x.col + MG.coff |
xc := x.col + MG.coff |
||
dr := \x.darow + MG.roff # adjust end for grid expansion |
|||
dc := \x.dacol + MG.coff |
|||
pool := [] |
pool := [] |
||
every m := !MG.pool do { |
every m := !MG.pool do { # find possible moves here |
||
mr := m.line[m.move,1] |
mr := m.line[m.move,1] |
||
mc := m.line[m.move,2] |
mc := m.line[m.move,2] |
||
if xr=mr & xc=mc then |
if xr=mr & xc=mc then |
||
if \dr & \dc then { # info to disambiguate? |
|||
put(pool,m) |
|||
every p := (m.line)[1|5] do # try endpoints |
|||
if p[1] = dr & p[2] = dc then |
|||
put(pool,m) # save matching move |
|||
return MG |
|||
} |
|||
else # no - need to disambiguate |
|||
else |
|||
put(pool,m) # save matching move(s) |
|||
} |
|||
Need unique disambiguation, syntax: n:r,c^r,c\n",*MG.log+1,*pool) |
|||
if *pool = 1 then # unique move? |
|||
every m := !pool do |
|||
return ( MG.move := pool[1], MG) # set unique move and return MG |
|||
else { # we have a problem |
|||
ShowGame(MG) |
|||
fprintf(M_Output,"Problem encountered replaying game at move #%i, %i choices.\n",MG.score,*pool) |
|||
every m := !pool do |
|||
fprintf(M_Output," %s\n",FormatMoveLogPS(MG,m)) |
|||
&dump := 0 |
|||
stop() |
|||
} |
|||
end</lang> |
|||
== Game Reader (default is Pentasol notation) == |
|||
<lang Unicon>procedure ReadMoveLog(MG) #: read move log wrapper |
|||
fprintf(M_Output,"Reading recorded game from: %s\n",M_ReplayFile) |
|||
f := open(M_ReplayFile ,"r") | |
|||
stop("Unable to open file ",M_ReplayFile ," for read.") |
|||
R := [] |
|||
while b := trim(read(f)) do { |
|||
if b ? ="$end" then break # allow pre-mature end of file |
|||
b ?:= tab(find("#")|0) # strip comments |
|||
b := deletec(b,' \t') # strip whitespace |
|||
if *b > 0 then put(R,b) # save move for reader |
|||
} |
|||
close(f) |
|||
return M_ReadGame(R) # call reader, return move list |
|||
end |
|||
procedure ReadMoveLogPS(R) #: read pentasol style move log |
|||
static off |
|||
initial { # precalc center offsets |
|||
off := table() |
|||
off[-2] := -4 |
|||
off[-1] := -3 |
|||
off[0] := 2 |
|||
off[1] := -1 |
|||
off[2] := 4 |
|||
} |
|||
M := [] |
|||
n := 0 # move number |
|||
get(R) ? ( ="(", coff := integer(tab(many(&digits))) - 4, |
|||
=",", roff := integer(tab(many(&digits))) - 4, |
|||
=")", pos(0) ) | # Reference Cell (c,r) |
|||
stop(&output,"Syntax error in reference line.") |
|||
while b := get(R) do { # Line (c,r) d o |
|||
b ? ( ="(", c := integer(tab(many(&digits))), |
|||
=",", r := integer(tab(many(&digits))), |
|||
=")", d := tab(any(DALL)), |
|||
o := integer(=("-2"|"-1"|0|"+1"|"+2")) ) | |
|||
stop(&output,"Syntax error in line above.") |
|||
x := MorpionGameRecord() # new move / line |
|||
x.ref := n +:= 1 |
|||
x.darow := x.row := r - roff |
|||
x.dacol := x.col := c - coff |
|||
case d of { # adjust based on direction |
|||
DHOR : x.dacol +:= off[o] |
|||
DVER : x.darow +:= off[o] |
|||
DRD : ( x.darow +:= off[o], x.dacol +:= off[o]) |
|||
DLD : ( x.darow -:= off[o], x.dacol +:= off[o]) |
|||
} |
|||
put(M,x) |
|||
} |
|||
return M |
|||
end</lang> |
|||
== Game Logging (default is Pentasol style notation) == |
|||
<lang Unicon>procedure WriteMoveLog(MG) #: write move log wrapper |
|||
if \M_GameSave then { |
|||
savegame := sprintf("Games/%s/%i-L%i",M_GameType,*MG.history,M_Limit) |
|||
if M_Limit ~= 1 then |
|||
savegame ||:= sprintf("(%i)",MG.count) |
|||
if \M_ReplayFile then { |
|||
fn := map(M_ReplayFile,"/\\","__") |
|||
fn ? (="Games/", savegame ||:= "-RF" || tab(find(".txt"))) |
|||
savegame ||:= "-RN" || (0 < \M_ReplayAfter) |
|||
} |
} |
||
savegame ||:= sprintf("_%s-%s-F%s.txt",deletec(&date,'/'),deletec(&clock,':'),M_GameFmt) |
|||
else { |
|||
M_GameSave := savegame |
|||
fprintf(M_Output,WriteMoveLogHeader(MG)) # write header, game is saved |
|||
dc := x.dacol + MG.coff |
|||
f := open(savegame,"w") | stop("Unable to open ",savegame," for writing") |
|||
every p := ((m := !pool).line)[1|5] do |
|||
fprintf(f,M_WriteGame(MG),M_Config) # call desired writer for output/save |
|||
if p[1] = dr & p[2] = dc then { |
|||
close(f) |
|||
} |
|||
else |
|||
} |
|||
fprintf(M_Output,M_WriteGame(MG)) |
|||
printf("No Match found to disambiguate move #%i\n",*MG.log+1) |
|||
every m := !pool do |
|||
printf(" %s\n",FormatMoveLog(m,MG.roff,MG.coff)) |
|||
} |
|||
PrintGrid(MG) |
|||
PrintLog(MG) |
|||
WriteMoveLog(MG) |
|||
stop() |
|||
end |
end |
||
procedure WriteMoveLogHeader(MG) #: write common header comments |
|||
record MorpionGameRecord(ref,row,col,darow,dacol) |
|||
return sprintf("#\n# Game Record for Morphion %s game of %i moves\n_ |
|||
# Date: %s\n# Saved: %s\n# &random: %i\n_ |
|||
# ReplayFile: %s (%s moves)\n#\n", |
|||
M_GameType,MG.score,&date,\M_GameSave|"* none *",MG.rseed, |
|||
\M_ReplayFile|"* none *",\M_ReplayAfter|"* all *") |
|||
end |
|||
procedure WriteMoveLogPS(MG) #: write pentasol style move log |
|||
l := WriteMoveLogHeader(MG) |
|||
l ||:= sprintf("# Pentasol compatible format\n#\n#\n_ |
|||
# Morpion Solitaire game\n#\n_ |
|||
# XXXX\n# X X\n# X X\n_ |
|||
# XXXR XXXX\n# X X\n# X X\n_ |
|||
# XXXX XXXX\n# X X\n# X X\n# XXXX\n#\n_ |
|||
# R = reference point\n_ |
|||
# List of moves starts with reference point (col,row)\n_ |
|||
# Lines are\n# (col,row) <direction> <+/-centerdist>\n_ |
|||
# distance to center is left side or top edge\n#\n") |
|||
l ||:= sprintf("(%i,%i)\n",4+MG.coff,4+MG.roff) |
|||
every l ||:= FormatMoveLogPS(MG,!MG.history) |
|||
return l || "#" |
|||
end |
|||
procedure FormatMoveLogPS(MG,m) #: format a PS move |
|||
d := if m.direction == "/" then m.move-3 else 3-m.move |
|||
return sprintf("(%i,%i) %s %s%d\n", |
|||
m.line[m.move,2]-m.coff+MG.coff,m.line[m.move,1]-m.roff+MG.roff, |
|||
m.direction,(d < 0,"-")|(d = 0,"")|"+",abs(d)) |
|||
end</lang> |
|||
== Game Read/Write (alternate legacy notation) == |
|||
procedure ReadMoveLog(fn) #: Read a move log |
|||
<lang Unicon>procedure ReadMoveLogOrig(R) #: Read original style move log |
|||
printf("Reading recorded game from: %s\n",fn) |
|||
f := open(fn,"r") | stop("Unable to open file ",fn," for read.") |
|||
M := [] |
M := [] |
||
while b := |
while b := get(R) do { |
||
if b ? ="$end" then break # allow pre-mature end of file |
|||
b := deletec(b,' \t') |
|||
b ?:= tab(find("#")|0) |
|||
until *b = 0 do { |
until *b = 0 do { |
||
x := MorpionGameRecord() |
x := MorpionGameRecord() # new move |
||
b ?:= ( x.ref := integer(tab(many(&digits))),=":", # base |
b ?:= ( x.ref := integer(tab(many(&digits))),=":", # base |
||
x.row := integer(=!["-","+",""]||tab(many(&digits))),=",", |
x.row := integer(=!["-","+",""]||tab(many(&digits))),=",", |
||
Line 478: | Line 590: | ||
stop(&output,"Syntax error in line above (disamiguation).") |
stop(&output,"Syntax error in line above (disamiguation).") |
||
} |
} |
||
b ?:= ( =(";"|""), tab(0) ) |
b ?:= ( =(";"|""), tab(0) ) |
||
put(M,x) |
put(M,x) |
||
} |
} |
||
Line 485: | Line 597: | ||
end |
end |
||
procedure |
procedure WriteMoveLogOrig(MG) #: write out a re-readable move log |
||
c := WriteMoveLogHeader(MG) |
|||
savegame := sprintf("Games/%i-L%i",*MG.history,M_Limit) |
|||
c ||:= sprintf("# Alternate Recorded game format:\n_ |
|||
if M_Limit ~= 1 then |
|||
savegame ||:= sprintf("(%i)",MG.count) |
|||
if \M_ReplayFile then { |
|||
M_ReplayFile ? (="Games/", savegame ||:= "-RF" || tab(find(".txt"))) |
|||
savegame ||:= "-RN" || (0 < \M_ReplayAfter) |
|||
} |
|||
savegame ||:= sprintf("_%s-%s.txt",deletec(&date,'/'),deletec(&clock,':')) |
|||
c := sprintf( "#\n# Game Record for Morphion 5T game of %i moves\n_ |
|||
# Reference: %s\n_ |
|||
# &random: %i\n_ |
|||
# Syntax for recorded games:\n_ |
|||
# 1. whitespace and comments (everything past #) are ignored\n_ |
# 1. whitespace and comments (everything past #) are ignored\n_ |
||
# 2. moves may be ; or newline separated\n_ |
# 2. moves may be ; or newline separated\n_ |
||
Line 508: | Line 610: | ||
# 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) |
||
Line 515: | Line 616: | ||
l ||:= sprintf("%i:%i,%i^%i,%i;", |
l ||:= sprintf("%i:%i,%i^%i,%i;", |
||
i,m.line[m.move,1]-m.roff,m.line[m.move,2]-m.coff, |
i,m.line[m.move,1]-m.roff,m.line[m.move,2]-m.coff, |
||
m.line[e,1]-m.roff,m.line[e,2]-m.coff) |
m.line[e,1]-m.roff,m.line[e,2]-m.coff) |
||
if *l > 70 then { |
if *l > 70 then { |
||
c ||:= l || "\n" |
c ||:= l || "\n" |
||
Line 521: | Line 622: | ||
} |
} |
||
} |
} |
||
c ||:= \l || "\n" |
|||
return c || "#" |
|||
end |
|||
if \M_GameSave then { |
|||
== Detailed Move Logging == |
|||
f := open(savegame,"w") | stop("Unable to open ",savegame," for writing") |
|||
<lang Unicon>procedure PrintDetails(MG) #: print the log |
|||
write(f,M_Config,c) |
|||
fprintf(M_Output,"Detailed Move Log\n") |
|||
close(f) |
|||
every fprintf(M_Output,"%i : %s\n",i := 1 to *MG.log,MG.log[i]) |
|||
} |
|||
end |
|||
procedure LogFormatMove(M,roff,coff) #: format a log entry |
|||
/M.roff := \roff | 0 |
|||
/M.coff := \coff | 0 |
|||
log := sprintf("\"%s\" [%i,%i] : ",M.direction, |
|||
M.line[M.move,1]-M.roff,M.line[M.move,2]-M.coff) |
|||
every x := !M.line do |
|||
log ||:= sprintf("[%i,%i] ",x[1]-M.roff,x[2]-M.coff) |
|||
return log |
|||
end |
|||
procedure LogDetails(MG,M) #: Record details |
|||
log := LogFormatMove(M) |
|||
log ||:= sprintf(" - of %i choices.",*MG.pool) # append # choices |
|||
log ||:= sprintf(" Metric=%i",M_Eval(MG)) # append score (opt) |
|||
put(MG.log,log) # log the move |
|||
end</lang> |
end</lang> |
||
== Strategy Support == |
|||
<lang Unicon># No useful examples at this time</lang> |
|||
{{libheader|Icon Programming Library}} |
{{libheader|Icon Programming Library}} |
||
Line 540: | Line 661: | ||
=== Help === |
=== Help === |
||
<pre>Morphion [options] Plays the 5T variant of Morphion Solitaire |
<pre>Morphion [options] Plays the 5T/D variant of Morphion Solitaire |
||
Arguments : - |
Arguments : -helpMorphion [options] Plays the 5T/D variant of Morphion Solitaire |
||
Where options are: |
Where options are: |
||
-P|-print controls how much is printed |
|||
n=2 shows all boards and a log of all moves (every game) |
|||
n=1 shows a log of the moves and final board (default single game) |
|||
n=0 produces no per game output (default for multigames) |
|||
-A choose player strategy approach (default=random, future) |
-A choose player strategy approach (default=random, future) |
||
-E Specifiy an position fitness evaluation function (default none, future) |
-E Specifiy an position fitness evaluation function (default none, future) |
||
-SW Search width (strategy dependent, future) |
-SW Search width (strategy dependent, future) |
||
-SD Search depth (strategy dependent, future) |
-SD Search depth (strategy dependent, future) |
||
-V|-variant 5D or 5T (default) |
|||
-R|-replay replay |
-R|-replay replay |
||
-RF file containing game record to be replayed |
-RF file containing game record to be replayed |
||
-RN number of moves to replay (0=all) |
-RN number of moves to replay (0=all) |
||
-RR game recording format to read (ps=pentasol(default), 0=original) |
|||
-RW game recording format to write ps=pentasol(default), 0=original) |
|||
-save save the best (-B) and worst (-W) games |
|||
-seed start the seed of the random number at this value |
-seed start the seed of the random number at this value |
||
-L|-limit games to play (if 0 or less then play until any of 'XxQq' is pressed |
-L|-limit games to play (if 0 or less then play until any of 'XxQq' is pressed |
||
note for larger n this benefits from larger BLKSIZE, STRSIZE environment variables |
note for larger n this benefits from larger BLKSIZE, STRSIZE environment variables |
||
-HW|-histwidth width (cols) of histogram of scores |
|||
-HG|-histgroup size of groups (buckets) for histogram |
|||
-UN Give status update notifications every n simulations |
-UN Give status update notifications every n simulations |
||
-B Keep best n games of unique length (default 5) |
-B Keep best n games of unique length (default 5) |
||
-W Keep worst n games of unique length (default 3) |
-W Keep worst n games of unique length (default 3) |
||
-details Log game details for analysis |
|||
-?|-h|-help this help text |
|||
-Q (debugging) terminates after options processing |
|||
</pre> |
|||
-?|-h|-help this help text</pre> |
|||
=== Multigame === |
=== Multigame === |
||
Line 567: | Line 691: | ||
The multigame simulation of completely random play includes a histogram showing game scores clustering in the 20's and 60's. This result is similar to results obtained by [http://www.morpionsolitaire.com/English/RecordsGrids5T.htm Jean-Jacques Sibil] (scroll down to find reference) who has run nearly a billion such simulations achieving a high score of 102 as of 2010. |
The multigame simulation of completely random play includes a histogram showing game scores clustering in the 20's and 60's. This result is similar to results obtained by [http://www.morpionsolitaire.com/English/RecordsGrids5T.htm Jean-Jacques Sibil] (scroll down to find reference) who has run nearly a billion such simulations achieving a high score of 102 as of 2010. |
||
The following is a summary file: |
|||
<pre># --- Morpion Solitaire 5 (v1.7b) --- |
|||
<pre># --- Morpion Solitaire 5 (v1.7e) --- |
|||
# |
# |
||
# Command line options : |
# Command line options : |
||
# Summary of Morpion Configuration: |
# Summary of Morpion Configuration: |
||
# Variant (5T/ |
# Variant (5T/D) move validation = procedure ValidMove5T |
||
# Games to play = * unlimited * |
# Games to play = * unlimited * |
||
# Print (0=none,1=minimal,2=all) = 0 |
|||
# Multi-game options: |
# Multi-game options: |
||
# - Status Updates = 500 |
# - Status Updates = 500 |
||
# - Keep best = 5 |
# - Keep best = 5 |
||
# - Keep worst = 0 |
# - Keep worst = 0 |
||
# - Histogram width = 80 |
|||
# - Histogram grouping = 5 |
|||
# Games will be saved = Yes |
|||
# - Format for game file (write) = procedure WriteMoveLogPS |
|||
# Replaying |
# Replaying |
||
# - |
# - Format for game file (read) = procedure ReadMoveLogPS |
||
# - Game file to be replayed = * None * |
|||
# Player Strategy = procedure RandomPlayer |
# Player Strategy = procedure RandomPlayer |
||
# - Position Fitness Evaluator = |
# - Position Fitness Evaluator = * None * |
||
# - Search Width (strategy dependant) = 5 |
# - Search Width (strategy dependant) = 5 |
||
# - Search Depth (strategy dependant) = 5 |
# - Search Depth (strategy dependant) = 5 |
||
# Log Details for analysis = No |
|||
# |
# |
||
Longest game 77 after 1 simulations &random=20122297. |
|||
# Running: |
|||
Longest game 77 after 85 simulations &random=274082001. |
|||
Longest game |
Longest game 78 after 118 simulations &random=559240181. |
||
Longest game |
Longest game 78 after 123 simulations &random=1682993637. |
||
Longest game |
Longest game 81 after 292 simulations &random=826134037. |
||
Longest game |
Longest game 84 after 1181 simulations &random=1936506737. |
||
Longest game |
Longest game 86 after 4584 simulations &random=1266457499. |
||
Longest game |
Longest game 86 after 44424 simulations &random=1725594333. |
||
Longest game |
Longest game 86 after 47918 simulations &random=1686351259. |
||
Longest game |
Longest game 86 after 50600 simulations &random=665807725. |
||
Longest game |
Longest game 87 after 60841 simulations &random=152917603. |
||
Longest game |
Longest game 87 after 74778 simulations &random=1037682795. |
||
Longest game |
Longest game 88 after 173368 simulations &random=72059739. |
||
Longest game |
Longest game 88 after 241134 simulations &random=2095899781. |
||
Longest game 86 after 3092 simulations. |
|||
Results from Sample of |
Results from Sample of 242921 games of Morpion 5T/D: |
||
Shortest game was 20 moves. |
Shortest game was 20 moves. |
||
Average game was 53. |
Average game was 53.65064774144681 moves. |
||
Longest game was |
Longest game was 88 moves. |
||
Average time/game is |
Average time/game is 133.1678282239905 ms. |
||
&random is now 452165683. |
|||
Summary of Results every '*' = |
Summary of Results every '*' = 940 games |
||
0 | ( 0) |
0 | ( 0) |
||
5 | ( 0) |
|||
20 | ( 7970) ******************************** |
|||
10 | ( 0) |
|||
15 | ( 0) |
|||
60 | ( 19737) ******************************************************************************** |
|||
20 | ( 38637) ***************************************** |
|||
80 | ( 46) |
|||
25 | ( 13790) ************** |
|||
30 | ( 6657) ******* |
|||
35 | ( 2604) ** |
|||
40 | ( 1306) * |
|||
45 | ( 1088) * |
|||
50 | ( 3448) *** |
|||
55 | ( 22481) *********************** |
|||
60 | ( 75207) ******************************************************************************** |
|||
65 | ( 61501) ***************************************************************** |
|||
70 | ( 13902) ************** |
|||
75 | ( 1922) ** |
|||
80 | ( 349) |
|||
85 | ( 29) |
|||
Longest (5) Game(s): |
Longest (5) Game(s): |
||
# |
|||
# Game Record for Morphion 5T game of 88 moves |
|||
# Date: 2012/02/18 |
|||
# Saved: Games/5T/88-L0(241134)_20120218-083009-Fps.txt |
|||
# &random: 2095899781 |
|||
# ReplayFile: * none * (* all * moves) |
|||
# |
|||
Morphion Solitare Grid (move= |
Morphion Solitare Grid (move=88): |
||
1234567890123456 |
|||
1 ................ |
|||
2 ....+.+......... |
|||
3 .....+++........ |
|||
4 ..+++++++....... |
|||
5 .+++++++++...... |
|||
6 ..++++****+..... |
|||
7 .+++++*++*+..... |
|||
8 ..++++*++*++.... |
|||
9 ...****++****+.. |
|||
10 ...*++++++++*+.. |
|||
11 .++*++++++++*++. |
|||
12 ...****++****+.. |
|||
13 ....++*++*++++.. |
|||
14 .....+*++*+++... |
|||
15 .....+****+..... |
|||
16 .......++....... |
|||
17 ........+....... |
|||
18 ................ |
|||
1234567890123456 |
|||
# |
|||
# Game Record for Morphion 5T game of 88 moves |
|||
# Date: 2012/02/18 |
|||
# Saved: Games/5T/88-L0(173368)_20120218-083009-Fps.txt |
|||
# &random: 72059739 |
|||
# ReplayFile: * none * (* all * moves) |
|||
# |
|||
Morphion Solitare Grid (move=88): |
|||
1234567890123456 |
1234567890123456 |
||
1 ................ |
1 ................ |
||
2 ..... |
2 .......+........ |
||
3 ..... |
3 ......++...+.... |
||
4 .....+****+..... |
4 .....+****+..... |
||
5 ..++++*++*+ |
5 ..++++*++*+..... |
||
6 . |
6 ..++++*++*+++... |
||
7 .. |
7 ...****++****+.. |
||
8 ...*++++++++*+.. |
8 ...*++++++++*+.. |
||
9 . |
9 .++*++++++++*+.. |
||
10 .. |
10 ...****++****+.. |
||
11 ..+ |
11 ..++++*++*+++++. |
||
12 .... |
12 .+...+*++*+++++. |
||
13 ..... |
13 .....+****++++.. |
||
14 |
14 ....+..+++++++.. |
||
15 .........++ |
15 .........+++++.. |
||
16 ......... |
16 ..........+..... |
||
17 ........... |
17 ...........+.... |
||
18 ................ |
|||
1234567890123456 |
1234567890123456 |
||
# |
# |
||
# Game Record for Morphion 5T game of |
# Game Record for Morphion 5T game of 87 moves |
||
# Date: 2012/02/18 |
|||
# Reference: Games/86-L0(3092)_20120208-090217.txt |
|||
# Saved: Games/5T/87-L0(74778)_20120218-083009-Fps.txt |
|||
# &random: 913514172 |
|||
# &random: 1037682795 |
|||
# Syntax for recorded games: |
|||
# ReplayFile: * none * (* all * moves) |
|||
# 1. whitespace and comments (everything past #) are ignored |
|||
# 2. moves may be ; or newline separated |
|||
# 3. moves are formatted (using BNF style variables like <x>): |
|||
# <movenumber>:<row>,<col>[^<drow>,<dcol>] |
|||
# The optional drow/dcol values provide an additional point |
|||
# used to disambiguate moves. The point drow/dcol must be |
|||
# chosen at one end of the line. |
|||
# Moves are applied in sorted order. |
|||
# 4. all row/col coordinates are relative to the 1,1 origin |
|||
# located at the intersection of the lines containing the |
|||
# top and left most edges of the cross. |
|||
# |
# |
||
1:5,7^1,7;2:10,8^10,4;3:3,1^7,1;4:3,3^1,5;5:3,8^1,6;6:4,6^4,10;7:4,5^4,2; |
|||
8:5,4^1,4;9:7,0^7,4;10:6,4^5,4;11:3,10^7,10;12:7,11^7,7;13:6,7^5,7;14:5,2^3,4; |
|||
15:8,8^6,10;16:5,6^3,4;17:5,5^3,7;18:1,3^1,7;19:3,5^1,3;20:2,5^1,5;21:5,9^3,7; |
|||
22:5,3^5,1;23:5,8^5,5;24:7,6^3,10;25:3,6^3,3;26:1,8^5,4;27:2,0^6,4;28:2,3^1,3; |
|||
29:6,6^3,3;30:7,5^4,8;31:6,8^3,8;32:8,3^6,1;33:2,6^1,6;34:2,8^2,4;35:0,8^4,4; |
|||
36:0,3^4,7;37:8,6^6,4;38:3,11^7,7;39:9,6^5,6;40:6,5^3,8;41:3,2^7,6;42:8,5^8,3; |
|||
43:6,2^3,2;44:9,5^6,5;45:8,0^4,4;46:11,7^7,3;47:-1,8^3,8;48:6,3^6,2;49:9,3^5,3; |
|||
50:9,2^9,6;51:6,9^10,5;52:8,11^4,7;53:3,9^3,7;54:6,11^6,7;55:0,5^4,1;56:0,6^4,10; |
|||
57:0,7^-1,8;58:2,9^6,9;59:0,4^0,3;60:4,11^0,7;61:5,11^3,11;62:-1,3^3,7; |
|||
63:11,3^7,7;64:3,0^7,4;65:3,-1^3,3;66:4,0^3,-1;67:11,8^7,4;68:2,2^0,4;69:9,8^7,8; |
|||
70:2,1^2,0;71:8,9^6,11;72:8,10^8,7;73:9,9^7,11;74:9,11^5,7;75:10,9^6,9; |
|||
76:11,10^7,6;77:9,10^9,7;78:12,7^8,11;79:10,10^7,10;80:13,7^9,7;81:11,11^7,7; |
|||
82:11,9^11,7;83:12,8^9,11;84:10,11^7,11;85:10,12^10,8;86:11,12^7,8; |
|||
Move Log |
|||
1 : "|" [5,7] : [1,7] [2,7] [3,7] [4,7] [5,7] - of 4 choices. |
|||
2 : "-" [10,8] : [10,4] [10,5] [10,6] [10,7] [10,8] - of 27 choices. |
|||
3 : "|" [3,1] : [3,1] [4,1] [5,1] [6,1] [7,1] - of 25 choices. |
|||
4 : "/" [3,3] : [1,5] [2,4] [3,3] [4,2] [5,1] - of 23 choices. |
|||
5 : "\" [3,8] : [1,6] [2,7] [3,8] [4,9] [5,10] - of 22 choices. |
|||
6 : "-" [4,6] : [4,6] [4,7] [4,8] [4,9] [4,10] - of 21 choices. |
|||
7 : "-" [4,5] : [4,2] [4,3] [4,4] [4,5] [4,6] - of 20 choices. |
|||
8 : "|" [5,4] : [1,4] [2,4] [3,4] [4,4] [5,4] - of 17 choices. |
|||
9 : "-" [7,0] : [7,0] [7,1] [7,2] [7,3] [7,4] - of 16 choices. |
|||
10 : "|" [6,4] : [5,4] [6,4] [7,4] [8,4] [9,4] - of 15 choices. |
|||
11 : "|" [3,10] : [3,10] [4,10] [5,10] [6,10] [7,10] - of 13 choices. |
|||
12 : "-" [7,11] : [7,7] [7,8] [7,9] [7,10] [7,11] - of 11 choices. |
|||
13 : "|" [6,7] : [5,7] [6,7] [7,7] [8,7] [9,7] - of 10 choices. |
|||
14 : "/" [5,2] : [3,4] [4,3] [5,2] [6,1] [7,0] - of 8 choices. |
|||
15 : "/" [8,8] : [6,10] [7,9] [8,8] [9,7] [10,6] - of 7 choices. |
|||
16 : "\" [5,6] : [3,4] [4,5] [5,6] [6,7] [7,8] - of 6 choices. |
|||
17 : "/" [5,5] : [3,7] [4,6] [5,5] [6,4] [7,3] - of 6 choices. |
|||
18 : "-" [1,3] : [1,3] [1,4] [1,5] [1,6] [1,7] - of 11 choices. |
|||
19 : "\" [3,5] : [1,3] [2,4] [3,5] [4,6] [5,7] - of 10 choices. |
|||
20 : "|" [2,5] : [1,5] [2,5] [3,5] [4,5] [5,5] - of 13 choices. |
|||
21 : "\" [5,9] : [3,7] [4,8] [5,9] [6,10] [7,11] - of 12 choices. |
|||
22 : "-" [5,3] : [5,1] [5,2] [5,3] [5,4] [5,5] - of 13 choices. |
|||
23 : "-" [5,8] : [5,5] [5,6] [5,7] [5,8] [5,9] - of 15 choices. |
|||
24 : "/" [7,6] : [3,10] [4,9] [5,8] [6,7] [7,6] - of 18 choices. |
|||
25 : "-" [3,6] : [3,3] [3,4] [3,5] [3,6] [3,7] - of 17 choices. |
|||
26 : "/" [1,8] : [1,8] [2,7] [3,6] [4,5] [5,4] - of 21 choices. |
|||
27 : "\" [2,0] : [2,0] [3,1] [4,2] [5,3] [6,4] - of 19 choices. |
|||
28 : "|" [2,3] : [1,3] [2,3] [3,3] [4,3] [5,3] - of 17 choices. |
|||
29 : "\" [6,6] : [3,3] [4,4] [5,5] [6,6] [7,7] - of 16 choices. |
|||
30 : "/" [7,5] : [4,8] [5,7] [6,6] [7,5] [8,4] - of 16 choices. |
|||
31 : "|" [6,8] : [3,8] [4,8] [5,8] [6,8] [7,8] - of 16 choices. |
|||
32 : "\" [8,3] : [6,1] [7,2] [8,3] [9,4] [10,5] - of 17 choices. |
|||
33 : "|" [2,6] : [1,6] [2,6] [3,6] [4,6] [5,6] - of 17 choices. |
|||
34 : "-" [2,8] : [2,4] [2,5] [2,6] [2,7] [2,8] - of 16 choices. |
|||
35 : "/" [0,8] : [0,8] [1,7] [2,6] [3,5] [4,4] - of 14 choices. |
|||
36 : "\" [0,3] : [0,3] [1,4] [2,5] [3,6] [4,7] - of 12 choices. |
|||
37 : "\" [8,6] : [6,4] [7,5] [8,6] [9,7] [10,8] - of 9 choices. |
|||
38 : "/" [3,11] : [3,11] [4,10] [5,9] [6,8] [7,7] - of 13 choices. |
|||
39 : "|" [9,6] : [5,6] [6,6] [7,6] [8,6] [9,6] - of 11 choices. |
|||
40 : "/" [6,5] : [3,8] [4,7] [5,6] [6,5] [7,4] - of 12 choices. |
|||
41 : "\" [3,2] : [3,2] [4,3] [5,4] [6,5] [7,6] - of 12 choices. |
|||
42 : "-" [8,5] : [8,3] [8,4] [8,5] [8,6] [8,7] - of 13 choices. |
|||
43 : "|" [6,2] : [3,2] [4,2] [5,2] [6,2] [7,2] - of 17 choices. |
|||
44 : "|" [9,5] : [6,5] [7,5] [8,5] [9,5] [10,5] - of 22 choices. |
|||
45 : "/" [8,0] : [4,4] [5,3] [6,2] [7,1] [8,0] - of 22 choices. |
|||
46 : "\" [11,7] : [7,3] [8,4] [9,5] [10,6] [11,7] - of 21 choices. |
|||
47 : "|" [-1,8] : [-1,8] [0,8] [1,8] [2,8] [3,8] - of 19 choices. |
|||
48 : "-" [6,3] : [6,2] [6,3] [6,4] [6,5] [6,6] - of 19 choices. |
|||
49 : "|" [9,3] : [5,3] [6,3] [7,3] [8,3] [9,3] - of 14 choices. |
|||
50 : "-" [9,2] : [9,2] [9,3] [9,4] [9,5] [9,6] - of 13 choices. |
|||
51 : "/" [6,9] : [6,9] [7,8] [8,7] [9,6] [10,5] - of 11 choices. |
|||
52 : "\" [8,11] : [4,7] [5,8] [6,9] [7,10] [8,11] - of 11 choices. |
|||
53 : "-" [3,9] : [3,7] [3,8] [3,9] [3,10] [3,11] - of 10 choices. |
|||
54 : "-" [6,11] : [6,7] [6,8] [6,9] [6,10] [6,11] - of 11 choices. |
|||
55 : "/" [0,5] : [0,5] [1,4] [2,3] [3,2] [4,1] - of 10 choices. |
|||
56 : "\" [0,6] : [0,6] [1,7] [2,8] [3,9] [4,10] - of 8 choices. |
|||
57 : "/" [0,7] : [-1,8] [0,7] [1,6] [2,5] [3,4] - of 6 choices. |
|||
58 : "|" [2,9] : [2,9] [3,9] [4,9] [5,9] [6,9] - of 8 choices. |
|||
59 : "-" [0,4] : [0,3] [0,4] [0,5] [0,6] [0,7] - of 8 choices. |
|||
60 : "\" [4,11] : [0,7] [1,8] [2,9] [3,10] [4,11] - of 6 choices. |
|||
61 : "|" [5,11] : [3,11] [4,11] [5,11] [6,11] [7,11] - of 6 choices. |
|||
62 : "\" [-1,3] : [-1,3] [0,4] [1,5] [2,6] [3,7] - of 4 choices. |
|||
63 : "/" [11,3] : [7,7] [8,6] [9,5] [10,4] [11,3] - of 3 choices. |
|||
64 : "\" [3,0] : [3,0] [4,1] [5,2] [6,3] [7,4] - of 2 choices. |
|||
65 : "-" [3,-1] : [3,-1] [3,0] [3,1] [3,2] [3,3] - of 2 choices. |
|||
66 : "\" [4,0] : [3,-1] [4,0] [5,1] [6,2] [7,3] - of 2 choices. |
|||
67 : "\" [11,8] : [7,4] [8,5] [9,6] [10,7] [11,8] - of 2 choices. |
|||
68 : "/" [2,2] : [0,4] [1,3] [2,2] [3,1] [4,0] - of 2 choices. |
|||
69 : "|" [9,8] : [7,8] [8,8] [9,8] [10,8] [11,8] - of 2 choices. |
|||
70 : "-" [2,1] : [2,0] [2,1] [2,2] [2,3] [2,4] - of 2 choices. |
|||
71 : "/" [8,9] : [6,11] [7,10] [8,9] [9,8] [10,7] - of 1 choices. |
|||
72 : "-" [8,10] : [8,7] [8,8] [8,9] [8,10] [8,11] - of 1 choices. |
|||
73 : "/" [9,9] : [7,11] [8,10] [9,9] [10,8] [11,7] - of 2 choices. |
|||
74 : "\" [9,11] : [5,7] [6,8] [7,9] [8,10] [9,11] - of 3 choices. |
|||
75 : "|" [10,9] : [6,9] [7,9] [8,9] [9,9] [10,9] - of 3 choices. |
|||
76 : "\" [11,10] : [7,6] [8,7] [9,8] [10,9] [11,10] - of 3 choices. |
|||
77 : "-" [9,10] : [9,7] [9,8] [9,9] [9,10] [9,11] - of 2 choices. |
|||
78 : "/" [12,7] : [8,11] [9,10] [10,9] [11,8] [12,7] - of 3 choices. |
|||
79 : "|" [10,10] : [7,10] [8,10] [9,10] [10,10] [11,10] - of 2 choices. |
|||
80 : "|" [13,7] : [9,7] [10,7] [11,7] [12,7] [13,7] - of 2 choices. |
|||
81 : "\" [11,11] : [7,7] [8,8] [9,9] [10,10] [11,11] - of 1 choices. |
|||
82 : "-" [11,9] : [11,7] [11,8] [11,9] [11,10] [11,11] - of 2 choices. |
|||
83 : "/" [12,8] : [9,11] [10,10] [11,9] [12,8] [13,7] - of 2 choices. |
|||
84 : "|" [10,11] : [7,11] [8,11] [9,11] [10,11] [11,11] - of 1 choices. |
|||
85 : "-" [10,12] : [10,8] [10,9] [10,10] [10,11] [10,12] - of 2 choices. |
|||
86 : "\" [11,12] : [7,8] [8,9] [9,10] [10,11] [11,12] - of 1 choices. |
|||
Morphion Solitare Grid (move=82): |
|||
12345678901234567 |
|||
1 ................. |
|||
2 ....+.+.......... |
|||
3 ....++++++++..... |
|||
4 ..+++++****...... |
|||
5 ..+++++*++*...... |
|||
6 ..+++++*++*+..... |
|||
7 ..++****++****... |
|||
8 .+++*++++++++*... |
|||
9 ....*++++++++*... |
|||
10 ...+****++****+.. |
|||
11 ..+++++*++*++++.. |
|||
12 ......+*++*++..+. |
|||
13 .......****+..... |
|||
14 .......++++++.... |
|||
15 .........+....... |
|||
16 ................. |
|||
12345678901234567 |
|||
Morphion Solitare Grid (move=87): |
|||
123456789012345 |
|||
1 ............... |
|||
2 ....+.+........ |
|||
3 .....+......... |
|||
4 ....+++++...... |
|||
5 ...++++++...... |
|||
6 .+++++****+.... |
|||
7 ..++++*++*+.... |
|||
8 .+++++*++*++... |
|||
9 ..+****++****.. |
|||
10 ..+*++++++++*+. |
|||
11 ...*++++++++*.. |
|||
12 ..+****++****+. |
|||
13 ...+++*++*++++. |
|||
14 ..++++*++*++... |
|||
15 .....+****+.+.. |
|||
16 ......+++++.... |
|||
17 ........+...... |
|||
18 ............... |
|||
123456789012345 |
|||
# |
# |
||
# Game Record for Morphion 5T game of |
# Game Record for Morphion 5T game of 87 moves |
||
# Date: 2012/02/18 |
|||
# Reference: Games/82-L0(2119)_20120208-090217.txt |
|||
# Saved: Games/5T/87-L0(60841)_20120218-083009-Fps.txt |
|||
# &random: 2066669156 |
|||
# &random: 152917603 |
|||
# Syntax for recorded games: |
|||
# ReplayFile: * none * (* all * moves) |
|||
# 1. whitespace and comments (everything past #) are ignored |
|||
# 2. moves may be ; or newline separated |
|||
# 3. moves are formatted (using BNF style variables like <x>): |
|||
# <movenumber>:<row>,<col>[^<drow>,<dcol>] |
|||
# The optional drow/dcol values provide an additional point |
|||
# used to disambiguate moves. The point drow/dcol must be |
|||
# chosen at one end of the line. |
|||
# Moves are applied in sorted order. |
|||
# 4. all row/col coordinates are relative to the 1,1 origin |
|||
# located at the intersection of the lines containing the |
|||
# top and left most edges of the cross. |
|||
# |
# |
||
1:0,7^4,7;2:3,8^1,6;3:8,1^4,1;4:11,7^7,7;5:9,5^7,3;6:8,8^6,10;7:7,11^7,7; |
|||
8:8,3^6,1;9:4,0^4,4;10:7,5^7,1;11:5,9^3,7;12:3,3^1,5;13:8,10^4,10;14:2,5^0,7; |
|||
15:11,4^7,4;16:10,8^10,4;17:1,3^1,7;18:9,9^7,11;19:4,6^4,10;20:9,6^7,8; |
|||
21:9,8^9,5;22:11,8^7,8;23:8,5^7,4;24:8,6^8,3;25:11,9^7,5;26:6,8^5,9;27:0,4^4,4; |
|||
28:5,8^3,8;29:3,6^1,4;30:5,7^4,6;31:5,6^5,10;32:11,5^7,5;33:2,6^1,6;34:3,5^3,4; |
|||
35:-1,3^3,7;36:2,3^2,7;37:6,5^4,7;38:11,6^11,5;39:12,6^8,6;40:0,8^4,4;41:0,3^4,3; |
|||
42:8,9^7,10;43:0,2^4,6;44:6,9^4,9;45:8,11^8,7;46:6,6^4,8;47:5,5^9,9;48:6,7^6,6; |
|||
49:6,4^3,7;50:4,5^8,9;51:0,5^4,5;52:7,6^5,8;53:5,4^9,8;54:6,3^3,6;55:9,12^5,8; |
|||
56:0,6^0,2;57:3,2^0,5;58:5,3^4,3;59:3,1^7,5;60:6,2^6,6;61:3,-1^7,3;62:3,0^3,-1; |
|||
63:5,2^5,6;64:2,2^0,4;65:1,1^5,5;66:2,-1^6,3;67:2,0^-1,3;68:1,2^0,2;69:8,2^4,2; |
|||
70:9,3^8,2;71:8,0^4,4;72:2,1^2,-1;73:0,1^4,5;74:4,-1^0,3;75:1,0^5,4;76:5,0^1,0; |
|||
77:1,-1^1,3;78:8,-1^8,3;79:5,-1^1,-1;80:-1,1^3,1;81:7,0^4,3;82:5,-2^5,2; |
|||
Move Log |
|||
1 : "|" [0,7] : [0,7] [1,7] [2,7] [3,7] [4,7] - of 4 choices. |
|||
2 : "\" [3,8] : [1,6] [2,7] [3,8] [4,9] [5,10] - of 27 choices. |
|||
3 : "|" [8,1] : [4,1] [5,1] [6,1] [7,1] [8,1] - of 26 choices. |
|||
4 : "|" [11,7] : [7,7] [8,7] [9,7] [10,7] [11,7] - of 24 choices. |
|||
5 : "\" [9,5] : [7,3] [8,4] [9,5] [10,6] [11,7] - of 23 choices. |
|||
6 : "/" [8,8] : [6,10] [7,9] [8,8] [9,7] [10,6] - of 22 choices. |
|||
7 : "-" [7,11] : [7,7] [7,8] [7,9] [7,10] [7,11] - of 21 choices. |
|||
8 : "\" [8,3] : [6,1] [7,2] [8,3] [9,4] [10,5] - of 20 choices. |
|||
9 : "-" [4,0] : [4,0] [4,1] [4,2] [4,3] [4,4] - of 19 choices. |
|||
10 : "-" [7,5] : [7,1] [7,2] [7,3] [7,4] [7,5] - of 17 choices. |
|||
11 : "\" [5,9] : [3,7] [4,8] [5,9] [6,10] [7,11] - of 15 choices. |
|||
12 : "/" [3,3] : [1,5] [2,4] [3,3] [4,2] [5,1] - of 14 choices. |
|||
13 : "|" [8,10] : [4,10] [5,10] [6,10] [7,10] [8,10] - of 13 choices. |
|||
14 : "/" [2,5] : [0,7] [1,6] [2,5] [3,4] [4,3] - of 11 choices. |
|||
15 : "|" [11,4] : [7,4] [8,4] [9,4] [10,4] [11,4] - of 10 choices. |
|||
16 : "-" [10,8] : [10,4] [10,5] [10,6] [10,7] [10,8] - of 9 choices. |
|||
17 : "-" [1,3] : [1,3] [1,4] [1,5] [1,6] [1,7] - of 8 choices. |
|||
18 : "/" [9,9] : [7,11] [8,10] [9,9] [10,8] [11,7] - of 6 choices. |
|||
19 : "-" [4,6] : [4,6] [4,7] [4,8] [4,9] [4,10] - of 5 choices. |
|||
20 : "/" [9,6] : [7,8] [8,7] [9,6] [10,5] [11,4] - of 3 choices. |
|||
21 : "-" [9,8] : [9,5] [9,6] [9,7] [9,8] [9,9] - of 5 choices. |
|||
22 : "|" [11,8] : [7,8] [8,8] [9,8] [10,8] [11,8] - of 4 choices. |
|||
23 : "\" [8,5] : [7,4] [8,5] [9,6] [10,7] [11,8] - of 3 choices. |
|||
24 : "-" [8,6] : [8,3] [8,4] [8,5] [8,6] [8,7] - of 7 choices. |
|||
25 : "\" [11,9] : [7,5] [8,6] [9,7] [10,8] [11,9] - of 10 choices. |
|||
26 : "/" [6,8] : [5,9] [6,8] [7,7] [8,6] [9,5] - of 8 choices. |
|||
27 : "|" [0,4] : [0,4] [1,4] [2,4] [3,4] [4,4] - of 6 choices. |
|||
28 : "|" [5,8] : [3,8] [4,8] [5,8] [6,8] [7,8] - of 4 choices. |
|||
29 : "\" [3,6] : [1,4] [2,5] [3,6] [4,7] [5,8] - of 4 choices. |
|||
30 : "\" [5,7] : [4,6] [5,7] [6,8] [7,9] [8,10] - of 5 choices. |
|||
31 : "-" [5,6] : [5,6] [5,7] [5,8] [5,9] [5,10] - of 7 choices. |
|||
32 : "|" [11,5] : [7,5] [8,5] [9,5] [10,5] [11,5] - of 8 choices. |
|||
33 : "|" [2,6] : [1,6] [2,6] [3,6] [4,6] [5,6] - of 8 choices. |
|||
34 : "-" [3,5] : [3,4] [3,5] [3,6] [3,7] [3,8] - of 10 choices. |
|||
35 : "\" [-1,3] : [-1,3] [0,4] [1,5] [2,6] [3,7] - of 11 choices. |
|||
36 : "-" [2,3] : [2,3] [2,4] [2,5] [2,6] [2,7] - of 10 choices. |
|||
37 : "/" [6,5] : [4,7] [5,6] [6,5] [7,4] [8,3] - of 11 choices. |
|||
38 : "-" [11,6] : [11,5] [11,6] [11,7] [11,8] [11,9] - of 9 choices. |
|||
39 : "|" [12,6] : [8,6] [9,6] [10,6] [11,6] [12,6] - of 10 choices. |
|||
40 : "/" [0,8] : [0,8] [1,7] [2,6] [3,5] [4,4] - of 8 choices. |
|||
41 : "|" [0,3] : [0,3] [1,3] [2,3] [3,3] [4,3] - of 6 choices. |
|||
42 : "/" [8,9] : [7,10] [8,9] [9,8] [10,7] [11,6] - of 3 choices. |
|||
43 : "\" [0,2] : [0,2] [1,3] [2,4] [3,5] [4,6] - of 6 choices. |
|||
44 : "|" [6,9] : [4,9] [5,9] [6,9] [7,9] [8,9] - of 5 choices. |
|||
45 : "-" [8,11] : [8,7] [8,8] [8,9] [8,10] [8,11] - of 2 choices. |
|||
46 : "/" [6,6] : [4,8] [5,7] [6,6] [7,5] [8,4] - of 2 choices. |
|||
47 : "\" [5,5] : [5,5] [6,6] [7,7] [8,8] [9,9] - of 7 choices. |
|||
48 : "-" [6,7] : [6,6] [6,7] [6,8] [6,9] [6,10] - of 7 choices. |
|||
49 : "/" [6,4] : [3,7] [4,6] [5,5] [6,4] [7,3] - of 11 choices. |
|||
50 : "\" [4,5] : [4,5] [5,6] [6,7] [7,8] [8,9] - of 10 choices. |
|||
51 : "|" [0,5] : [0,5] [1,5] [2,5] [3,5] [4,5] - of 4 choices. |
|||
52 : "/" [7,6] : [5,8] [6,7] [7,6] [8,5] [9,4] - of 8 choices. |
|||
53 : "\" [5,4] : [5,4] [6,5] [7,6] [8,7] [9,8] - of 9 choices. |
|||
54 : "/" [6,3] : [3,6] [4,5] [5,4] [6,3] [7,2] - of 10 choices. |
|||
55 : "\" [9,12] : [5,8] [6,9] [7,10] [8,11] [9,12] - of 9 choices. |
|||
56 : "-" [0,6] : [0,2] [0,3] [0,4] [0,5] [0,6] - of 8 choices. |
|||
57 : "/" [3,2] : [0,5] [1,4] [2,3] [3,2] [4,1] - of 4 choices. |
|||
58 : "|" [5,3] : [4,3] [5,3] [6,3] [7,3] [8,3] - of 3 choices. |
|||
59 : "\" [3,1] : [3,1] [4,2] [5,3] [6,4] [7,5] - of 5 choices. |
|||
60 : "-" [6,2] : [6,2] [6,3] [6,4] [6,5] [6,6] - of 6 choices. |
|||
61 : "\" [3,-1] : [3,-1] [4,0] [5,1] [6,2] [7,3] - of 7 choices. |
|||
62 : "-" [3,0] : [3,-1] [3,0] [3,1] [3,2] [3,3] - of 7 choices. |
|||
63 : "-" [5,2] : [5,2] [5,3] [5,4] [5,5] [5,6] - of 6 choices. |
|||
64 : "/" [2,2] : [0,4] [1,3] [2,2] [3,1] [4,0] - of 5 choices. |
|||
65 : "\" [1,1] : [1,1] [2,2] [3,3] [4,4] [5,5] - of 6 choices. |
|||
66 : "\" [2,-1] : [2,-1] [3,0] [4,1] [5,2] [6,3] - of 6 choices. |
|||
67 : "/" [2,0] : [-1,3] [0,2] [1,1] [2,0] [3,-1] - of 5 choices. |
|||
68 : "|" [1,2] : [0,2] [1,2] [2,2] [3,2] [4,2] - of 5 choices. |
|||
69 : "|" [8,2] : [4,2] [5,2] [6,2] [7,2] [8,2] - of 4 choices. |
|||
70 : "\" [9,3] : [8,2] [9,3] [10,4] [11,5] [12,6] - of 5 choices. |
|||
71 : "/" [8,0] : [4,4] [5,3] [6,2] [7,1] [8,0] - of 3 choices. |
|||
72 : "-" [2,1] : [2,-1] [2,0] [2,1] [2,2] [2,3] - of 3 choices. |
|||
73 : "\" [0,1] : [0,1] [1,2] [2,3] [3,4] [4,5] - of 6 choices. |
|||
74 : "/" [4,-1] : [0,3] [1,2] [2,1] [3,0] [4,-1] - of 5 choices. |
|||
75 : "\" [1,0] : [1,0] [2,1] [3,2] [4,3] [5,4] - of 3 choices. |
|||
76 : "|" [5,0] : [1,0] [2,0] [3,0] [4,0] [5,0] - of 5 choices. |
|||
77 : "-" [1,-1] : [1,-1] [1,0] [1,1] [1,2] [1,3] - of 3 choices. |
|||
78 : "-" [8,-1] : [8,-1] [8,0] [8,1] [8,2] [8,3] - of 4 choices. |
|||
79 : "|" [5,-1] : [1,-1] [2,-1] [3,-1] [4,-1] [5,-1] - of 4 choices. |
|||
80 : "|" [-1,1] : [-1,1] [0,1] [1,1] [2,1] [3,1] - of 3 choices. |
|||
81 : "/" [7,0] : [4,3] [5,2] [6,1] [7,0] [8,-1] - of 2 choices. |
|||
82 : "-" [5,-2] : [5,-2] [5,-1] [5,0] [5,1] [5,2] - of 1 choices. |
|||
Morphion Solitare Grid (move=82): |
|||
1234567890123456789 |
|||
1 ................... |
|||
2 .........+.++...... |
|||
3 ........****++..... |
|||
4 ........*++*+++.... |
|||
5 .......+*++*++++... |
|||
6 .....****++****+++. |
|||
7 ....+*++++++++*+++. |
|||
8 ...++*++++++++*+... |
|||
9 ..+.+****++****+... |
|||
10 .+++++++*++*++++... |
|||
11 ....++++*++*++..+.. |
|||
12 ....++++****+...... |
|||
13 ......++...+....... |
|||
14 ......+.+.......... |
|||
15 ................... |
|||
1234567890123456789 |
|||
Morphion Solitare Grid (move=87): |
|||
123456789012345678 |
|||
1 .................. |
|||
2 .........+.+..+... |
|||
3 .....+...++++++... |
|||
4 ......****+++++... |
|||
5 .....+*++*+++++... |
|||
6 ....++*++*+++++++. |
|||
7 ..+****++****+.+.. |
|||
8 .++*++++++++*+.... |
|||
9 .++*++++++++*+.... |
|||
10 ..+****++****+.... |
|||
11 .+++++*++*++++.... |
|||
12 ....++*++*++...... |
|||
13 ....++****........ |
|||
14 ....+++........... |
|||
15 .................. |
|||
123456789012345678 |
|||
# |
# |
||
# Game Record for Morphion 5T game of |
# Game Record for Morphion 5T game of 86 moves |
||
# Date: 2012/02/18 |
|||
# Reference: Games/82-L0(887)_20120208-090217.txt |
|||
# Saved: Games/5T/86-L0(50600)_20120218-083009-Fps.txt |
|||
# &random: 1478604792 |
|||
# &random: 665807725 |
|||
# Syntax for recorded games: |
|||
# ReplayFile: * none * (* all * moves) |
|||
# 1. whitespace and comments (everything past #) are ignored |
|||
# 2. moves may be ; or newline separated |
|||
# 3. moves are formatted (using BNF style variables like <x>): |
|||
# <movenumber>:<row>,<col>[^<drow>,<dcol>] |
|||
# The optional drow/dcol values provide an additional point |
|||
# used to disambiguate moves. The point drow/dcol must be |
|||
# chosen at one end of the line. |
|||
# Moves are applied in sorted order. |
|||
# 4. all row/col coordinates are relative to the 1,1 origin |
|||
# located at the intersection of the lines containing the |
|||
# top and left most edges of the cross. |
|||
# |
# |
||
1:0,7^4,7;2:2,5^0,7;3:4,5^4,1;4:10,8^10,4;5:4,6^4,5;6:11,7^7,7;7:3,8^1,6; |
|||
8:8,8^6,10;9:7,11^7,7;10:1,8^1,4;11:3,3^1,5;12:6,4^10,4;13:5,9^3,7;14:8,10^4,10; |
|||
15:7,0^7,4;16:5,4^2,4;17:3,6^1,8;18:5,8^1,4;19:2,8^1,8;20:8,1^4,1;21:5,5^2,8; |
|||
22:6,6^3,3;23:3,5^3,3;24:0,5^4,5;25:9,9^7,11;26:9,5^7,3;27:2,6^2,4;28:0,8^4,4; |
|||
29:5,6^1,6;30:6,7^3,4;31:8,3^6,1;32:6,5^4,7;33:5,7^5,4;34:6,3^6,7;35:5,3^3,3; |
|||
36:9,0^5,4;37:6,8^4,6;38:9,8^5,8;39:9,6^9,4;40:3,11^7,7;41:7,6^4,3;42:6,9^5,10; |
|||
43:8,6^5,6;44:3,10^7,6;45:8,9^5,9;46:7,5^5,3;47:8,5^4,5;48:8,11^8,7;49:6,11^6,7; |
|||
50:8,2^8,6;51:11,3^7,7;52:3,9^3,7;53:5,11^1,7;54:4,11^8,11;55:5,12^5,8; |
|||
56:4,13^8,9;57:5,2^4,1;58:2,9^0,7;59:2,10^6,6;60:9,12^5,8;61:4,12^4,9;62:5,0^5,4; |
|||
63:1,9^5,9;64:6,2^4,2;65:5,13^1,9;66:8,-1^4,3;67:8,0^4,4;68:6,0^5,0;69:8,-2^8,2; |
|||
70:9,3^6,0;71:10,2^6,6;72:10,3^7,3;73:6,-1^6,3;74:9,2^6,-1;75:11,2^7,6; |
|||
76:9,1^9,0;77:10,0^6,4;78:12,2^8,2;79:10,1^10,0;80:12,4^8,0;81:7,-2^11,2; |
|||
82:8,-3^4,1; |
|||
Move Log |
|||
1 : "|" [0,7] : [0,7] [1,7] [2,7] [3,7] [4,7] - of 4 choices. |
|||
2 : "/" [2,5] : [0,7] [1,6] [2,5] [3,4] [4,3] - of 27 choices. |
|||
3 : "-" [4,5] : [4,1] [4,2] [4,3] [4,4] [4,5] - of 26 choices. |
|||
4 : "-" [10,8] : [10,4] [10,5] [10,6] [10,7] [10,8] - of 25 choices. |
|||
5 : "-" [4,6] : [4,5] [4,6] [4,7] [4,8] [4,9] - of 23 choices. |
|||
6 : "|" [11,7] : [7,7] [8,7] [9,7] [10,7] [11,7] - of 20 choices. |
|||
7 : "\" [3,8] : [1,6] [2,7] [3,8] [4,9] [5,10] - of 19 choices. |
|||
8 : "/" [8,8] : [6,10] [7,9] [8,8] [9,7] [10,6] - of 18 choices. |
|||
9 : "-" [7,11] : [7,7] [7,8] [7,9] [7,10] [7,11] - of 17 choices. |
|||
10 : "-" [1,8] : [1,4] [1,5] [1,6] [1,7] [1,8] - of 16 choices. |
|||
11 : "/" [3,3] : [1,5] [2,4] [3,3] [4,2] [5,1] - of 14 choices. |
|||
12 : "|" [6,4] : [6,4] [7,4] [8,4] [9,4] [10,4] - of 13 choices. |
|||
13 : "\" [5,9] : [3,7] [4,8] [5,9] [6,10] [7,11] - of 13 choices. |
|||
14 : "|" [8,10] : [4,10] [5,10] [6,10] [7,10] [8,10] - of 12 choices. |
|||
15 : "-" [7,0] : [7,0] [7,1] [7,2] [7,3] [7,4] - of 11 choices. |
|||
16 : "|" [5,4] : [2,4] [3,4] [4,4] [5,4] [6,4] - of 9 choices. |
|||
17 : "/" [3,6] : [1,8] [2,7] [3,6] [4,5] [5,4] - of 7 choices. |
|||
18 : "\" [5,8] : [1,4] [2,5] [3,6] [4,7] [5,8] - of 10 choices. |
|||
19 : "|" [2,8] : [1,8] [2,8] [3,8] [4,8] [5,8] - of 11 choices. |
|||
20 : "|" [8,1] : [4,1] [5,1] [6,1] [7,1] [8,1] - of 10 choices. |
|||
21 : "/" [5,5] : [2,8] [3,7] [4,6] [5,5] [6,4] - of 8 choices. |
|||
22 : "\" [6,6] : [3,3] [4,4] [5,5] [6,6] [7,7] - of 9 choices. |
|||
23 : "-" [3,5] : [3,3] [3,4] [3,5] [3,6] [3,7] - of 7 choices. |
|||
24 : "|" [0,5] : [0,5] [1,5] [2,5] [3,5] [4,5] - of 6 choices. |
|||
25 : "/" [9,9] : [7,11] [8,10] [9,9] [10,8] [11,7] - of 4 choices. |
|||
26 : "\" [9,5] : [7,3] [8,4] [9,5] [10,6] [11,7] - of 3 choices. |
|||
27 : "-" [2,6] : [2,4] [2,5] [2,6] [2,7] [2,8] - of 2 choices. |
|||
28 : "/" [0,8] : [0,8] [1,7] [2,6] [3,5] [4,4] - of 6 choices. |
|||
29 : "|" [5,6] : [1,6] [2,6] [3,6] [4,6] [5,6] - of 4 choices. |
|||
30 : "\" [6,7] : [3,4] [4,5] [5,6] [6,7] [7,8] - of 6 choices. |
|||
31 : "\" [8,3] : [6,1] [7,2] [8,3] [9,4] [10,5] - of 5 choices. |
|||
32 : "/" [6,5] : [4,7] [5,6] [6,5] [7,4] [8,3] - of 5 choices. |
|||
33 : "-" [5,7] : [5,4] [5,5] [5,6] [5,7] [5,8] - of 6 choices. |
|||
34 : "-" [6,3] : [6,3] [6,4] [6,5] [6,6] [6,7] - of 8 choices. |
|||
35 : "|" [5,3] : [3,3] [4,3] [5,3] [6,3] [7,3] - of 9 choices. |
|||
36 : "/" [9,0] : [5,4] [6,3] [7,2] [8,1] [9,0] - of 7 choices. |
|||
37 : "\" [6,8] : [4,6] [5,7] [6,8] [7,9] [8,10] - of 6 choices. |
|||
38 : "|" [9,8] : [5,8] [6,8] [7,8] [8,8] [9,8] - of 8 choices. |
|||
39 : "-" [9,6] : [9,4] [9,5] [9,6] [9,7] [9,8] - of 9 choices. |
|||
40 : "/" [3,11] : [3,11] [4,10] [5,9] [6,8] [7,7] - of 11 choices. |
|||
41 : "\" [7,6] : [4,3] [5,4] [6,5] [7,6] [8,7] - of 7 choices. |
|||
42 : "/" [6,9] : [5,10] [6,9] [7,8] [8,7] [9,6] - of 10 choices. |
|||
43 : "|" [8,6] : [5,6] [6,6] [7,6] [8,6] [9,6] - of 11 choices. |
|||
44 : "/" [3,10] : [3,10] [4,9] [5,8] [6,7] [7,6] - of 16 choices. |
|||
45 : "|" [8,9] : [5,9] [6,9] [7,9] [8,9] [9,9] - of 14 choices. |
|||
46 : "\" [7,5] : [5,3] [6,4] [7,5] [8,6] [9,7] - of 14 choices. |
|||
47 : "|" [8,5] : [4,5] [5,5] [6,5] [7,5] [8,5] - of 15 choices. |
|||
48 : "-" [8,11] : [8,7] [8,8] [8,9] [8,10] [8,11] - of 13 choices. |
|||
49 : "-" [6,11] : [6,7] [6,8] [6,9] [6,10] [6,11] - of 13 choices. |
|||
50 : "-" [8,2] : [8,2] [8,3] [8,4] [8,5] [8,6] - of 12 choices. |
|||
51 : "/" [11,3] : [7,7] [8,6] [9,5] [10,4] [11,3] - of 10 choices. |
|||
52 : "-" [3,9] : [3,7] [3,8] [3,9] [3,10] [3,11] - of 9 choices. |
|||
53 : "\" [5,11] : [1,7] [2,8] [3,9] [4,10] [5,11] - of 10 choices. |
|||
54 : "|" [4,11] : [4,11] [5,11] [6,11] [7,11] [8,11] - of 12 choices. |
|||
55 : "-" [5,12] : [5,8] [5,9] [5,10] [5,11] [5,12] - of 10 choices. |
|||
56 : "/" [4,13] : [4,13] [5,12] [6,11] [7,10] [8,9] - of 10 choices. |
|||
57 : "\" [5,2] : [4,1] [5,2] [6,3] [7,4] [8,5] - of 9 choices. |
|||
58 : "\" [2,9] : [0,7] [1,8] [2,9] [3,10] [4,11] - of 9 choices. |
|||
59 : "/" [2,10] : [2,10] [3,9] [4,8] [5,7] [6,6] - of 8 choices. |
|||
60 : "\" [9,12] : [5,8] [6,9] [7,10] [8,11] [9,12] - of 6 choices. |
|||
61 : "-" [4,12] : [4,9] [4,10] [4,11] [4,12] [4,13] - of 5 choices. |
|||
62 : "-" [5,0] : [5,0] [5,1] [5,2] [5,3] [5,4] - of 5 choices. |
|||
63 : "|" [1,9] : [1,9] [2,9] [3,9] [4,9] [5,9] - of 4 choices. |
|||
64 : "|" [6,2] : [4,2] [5,2] [6,2] [7,2] [8,2] - of 4 choices. |
|||
65 : "\" [5,13] : [1,9] [2,10] [3,11] [4,12] [5,13] - of 4 choices. |
|||
66 : "/" [8,-1] : [4,3] [5,2] [6,1] [7,0] [8,-1] - of 2 choices. |
|||
67 : "/" [8,0] : [4,4] [5,3] [6,2] [7,1] [8,0] - of 1 choices. |
|||
68 : "|" [6,0] : [5,0] [6,0] [7,0] [8,0] [9,0] - of 2 choices. |
|||
69 : "-" [8,-2] : [8,-2] [8,-1] [8,0] [8,1] [8,2] - of 3 choices. |
|||
70 : "\" [9,3] : [6,0] [7,1] [8,2] [9,3] [10,4] - of 2 choices. |
|||
71 : "/" [10,2] : [6,6] [7,5] [8,4] [9,3] [10,2] - of 3 choices. |
|||
72 : "|" [10,3] : [7,3] [8,3] [9,3] [10,3] [11,3] - of 2 choices. |
|||
73 : "-" [6,-1] : [6,-1] [6,0] [6,1] [6,2] [6,3] - of 2 choices. |
|||
74 : "\" [9,2] : [6,-1] [7,0] [8,1] [9,2] [10,3] - of 2 choices. |
|||
75 : "/" [11,2] : [7,6] [8,5] [9,4] [10,3] [11,2] - of 2 choices. |
|||
76 : "-" [9,1] : [9,0] [9,1] [9,2] [9,3] [9,4] - of 2 choices. |
|||
77 : "/" [10,0] : [6,4] [7,3] [8,2] [9,1] [10,0] - of 4 choices. |
|||
78 : "|" [12,2] : [8,2] [9,2] [10,2] [11,2] [12,2] - of 4 choices. |
|||
79 : "-" [10,1] : [10,0] [10,1] [10,2] [10,3] [10,4] - of 3 choices. |
|||
80 : "\" [12,4] : [8,0] [9,1] [10,2] [11,3] [12,4] - of 4 choices. |
|||
81 : "\" [7,-2] : [7,-2] [8,-1] [9,0] [10,1] [11,2] - of 2 choices. |
|||
82 : "/" [8,-3] : [4,1] [5,0] [6,-1] [7,-2] [8,-3] - of 2 choices. |
|||
Morphion Solitare Grid (move=81): |
|||
12345678901234567 |
|||
1 ................. |
|||
2 ...........+..... |
|||
3 ..........+...... |
|||
4 .........+++++... |
|||
5 .....+..++++++... |
|||
6 .....+****++++... |
|||
7 .....+*++*+++++.. |
|||
8 .....+*++*+++++.. |
|||
9 ...****++****+.+. |
|||
10 ...*++++++++*+... |
|||
11 ...*++++++++*.... |
|||
12 ..+****++****.... |
|||
13 .+.+++*++*++.+... |
|||
14 ....++*++*+...... |
|||
15 ...+.+****+...... |
|||
16 .....+++++....... |
|||
17 ................. |
|||
12345678901234567 |
|||
# |
|||
# Game Record for Morphion 5T game of 81 moves |
|||
# Reference: Games/81-L0(555)_20120208-090217.txt |
|||
# &random: 1350476946 |
|||
# Syntax for recorded games: |
|||
# 1. whitespace and comments (everything past #) are ignored |
|||
# 2. moves may be ; or newline separated |
|||
# 3. moves are formatted (using BNF style variables like <x>): |
|||
# <movenumber>:<row>,<col>[^<drow>,<dcol>] |
|||
# The optional drow/dcol values provide an additional point |
|||
# used to disambiguate moves. The point drow/dcol must be |
|||
# chosen at one end of the line. |
|||
# Moves are applied in sorted order. |
|||
# 4. all row/col coordinates are relative to the 1,1 origin |
|||
# located at the intersection of the lines containing the |
|||
# top and left most edges of the cross. |
|||
# |
|||
1:5,7^1,7;2:10,3^10,7;3:8,3^6,1;4:1,3^1,7;5:4,5^4,1;6:5,4^1,4;7:7,6^7,10; |
|||
8:8,1^4,1;9:11,7^7,7;10:11,4^7,4;11:6,3^4,5;12:7,5^7,2;13:6,5^4,3;14:3,10^7,10; |
|||
15:9,3^6,3;16:9,6^7,8;17:4,11^4,7;18:9,5^7,3;19:9,2^9,6;20:8,5^6,5;21:8,8^6,10; |
|||
22:7,0^11,4;23:5,2^9,6;24:8,2^8,1;25:6,7^10,3;26:8,-1^4,3;27:10,1^6,5;28:3,3^1,5; |
|||
29:11,5^7,1;30:6,6^5,7;31:5,5^4,4;32:5,3^5,1;33:6,2^4,2;34:3,5^7,1;35:8,6^6,6; |
|||
36:6,4^6,2;37:5,6^3,4;38:11,3^7,7;39:3,6^3,3;40:2,3^6,3;41:4,6^8,2;42:6,8^3,5; |
|||
43:2,5^6,5;44:0,7^4,3;45:6,9^6,6;46:2,6^1,6;47:10,8^6,4;48:3,8^1,6;49:5,9^2,6; |
|||
50:3,9^7,9;51:2,8^2,4;52:5,8^4,8;53:8,9^8,5;54:0,6^4,10;55:2,9^6,5;56:0,3^4,7; |
|||
57:11,6^11,3;58:9,8^7,10;59:3,11^3,7;60:8,11^4,7;61:2,12^6,8;62:2,11^6,7; |
|||
63:2,10^2,8;64:5,11^5,7;65:1,11^5,7;66:1,8^0,7;67:0,9^4,5;68:3,12^7,8;69:0,11^4,11; |
|||
70:0,8^4,8;71:-1,9^3,5;72:1,9^-1,9;73:0,10^0,6;74:-1,11^3,7;75:-1,7^3,11; |
|||
76:-2,8^2,12;77:1,10^1,7;78:4,13^0,9;79:-3,9^1,5;80:-1,10^3,10;81:-1,8^-1,7; |
|||
Move Log |
|||
1 : "|" [5,7] : [1,7] [2,7] [3,7] [4,7] [5,7] - of 4 choices. |
|||
2 : "-" [10,3] : [10,3] [10,4] [10,5] [10,6] [10,7] - of 27 choices. |
|||
3 : "\" [8,3] : [6,1] [7,2] [8,3] [9,4] [10,5] - of 25 choices. |
|||
4 : "-" [1,3] : [1,3] [1,4] [1,5] [1,6] [1,7] - of 24 choices. |
|||
5 : "-" [4,5] : [4,1] [4,2] [4,3] [4,4] [4,5] - of 22 choices. |
|||
6 : "|" [5,4] : [1,4] [2,4] [3,4] [4,4] [5,4] - of 21 choices. |
|||
7 : "-" [7,6] : [7,6] [7,7] [7,8] [7,9] [7,10] - of 20 choices. |
|||
8 : "|" [8,1] : [4,1] [5,1] [6,1] [7,1] [8,1] - of 20 choices. |
|||
9 : "|" [11,7] : [7,7] [8,7] [9,7] [10,7] [11,7] - of 19 choices. |
|||
10 : "|" [11,4] : [7,4] [8,4] [9,4] [10,4] [11,4] - of 17 choices. |
|||
11 : "/" [6,3] : [4,5] [5,4] [6,3] [7,2] [8,1] - of 15 choices. |
|||
12 : "-" [7,5] : [7,2] [7,3] [7,4] [7,5] [7,6] - of 16 choices. |
|||
13 : "\" [6,5] : [4,3] [5,4] [6,5] [7,6] [8,7] - of 14 choices. |
|||
14 : "|" [3,10] : [3,10] [4,10] [5,10] [6,10] [7,10] - of 14 choices. |
|||
15 : "|" [9,3] : [6,3] [7,3] [8,3] [9,3] [10,3] - of 12 choices. |
|||
16 : "/" [9,6] : [7,8] [8,7] [9,6] [10,5] [11,4] - of 11 choices. |
|||
17 : "-" [4,11] : [4,7] [4,8] [4,9] [4,10] [4,11] - of 12 choices. |
|||
18 : "\" [9,5] : [7,3] [8,4] [9,5] [10,6] [11,7] - of 9 choices. |
|||
19 : "-" [9,2] : [9,2] [9,3] [9,4] [9,5] [9,6] - of 10 choices. |
|||
20 : "|" [8,5] : [6,5] [7,5] [8,5] [9,5] [10,5] - of 12 choices. |
|||
21 : "/" [8,8] : [6,10] [7,9] [8,8] [9,7] [10,6] - of 17 choices. |
|||
22 : "\" [7,0] : [7,0] [8,1] [9,2] [10,3] [11,4] - of 17 choices. |
|||
23 : "\" [5,2] : [5,2] [6,3] [7,4] [8,5] [9,6] - of 16 choices. |
|||
24 : "-" [8,2] : [8,1] [8,2] [8,3] [8,4] [8,5] - of 15 choices. |
|||
25 : "/" [6,7] : [6,7] [7,6] [8,5] [9,4] [10,3] - of 16 choices. |
|||
26 : "/" [8,-1] : [4,3] [5,2] [6,1] [7,0] [8,-1] - of 15 choices. |
|||
27 : "/" [10,1] : [6,5] [7,4] [8,3] [9,2] [10,1] - of 12 choices. |
|||
28 : "/" [3,3] : [1,5] [2,4] [3,3] [4,2] [5,1] - of 9 choices. |
|||
29 : "\" [11,5] : [7,1] [8,2] [9,3] [10,4] [11,5] - of 8 choices. |
|||
30 : "/" [6,6] : [5,7] [6,6] [7,5] [8,4] [9,3] - of 6 choices. |
|||
31 : "\" [5,5] : [4,4] [5,5] [6,6] [7,7] [8,8] - of 8 choices. |
|||
32 : "-" [5,3] : [5,1] [5,2] [5,3] [5,4] [5,5] - of 7 choices. |
|||
33 : "|" [6,2] : [4,2] [5,2] [6,2] [7,2] [8,2] - of 8 choices. |
|||
34 : "/" [3,5] : [3,5] [4,4] [5,3] [6,2] [7,1] - of 10 choices. |
|||
35 : "|" [8,6] : [6,6] [7,6] [8,6] [9,6] [10,6] - of 12 choices. |
|||
36 : "-" [6,4] : [6,2] [6,3] [6,4] [6,5] [6,6] - of 16 choices. |
|||
37 : "\" [5,6] : [3,4] [4,5] [5,6] [6,7] [7,8] - of 16 choices. |
|||
38 : "/" [11,3] : [7,7] [8,6] [9,5] [10,4] [11,3] - of 15 choices. |
|||
39 : "-" [3,6] : [3,3] [3,4] [3,5] [3,6] [3,7] - of 14 choices. |
|||
40 : "|" [2,3] : [2,3] [3,3] [4,3] [5,3] [6,3] - of 13 choices. |
|||
41 : "/" [4,6] : [4,6] [5,5] [6,4] [7,3] [8,2] - of 11 choices. |
|||
42 : "\" [6,8] : [3,5] [4,6] [5,7] [6,8] [7,9] - of 12 choices. |
|||
43 : "|" [2,5] : [2,5] [3,5] [4,5] [5,5] [6,5] - of 11 choices. |
|||
44 : "/" [0,7] : [0,7] [1,6] [2,5] [3,4] [4,3] - of 13 choices. |
|||
45 : "-" [6,9] : [6,6] [6,7] [6,8] [6,9] [6,10] - of 12 choices. |
|||
46 : "|" [2,6] : [1,6] [2,6] [3,6] [4,6] [5,6] - of 14 choices. |
|||
47 : "\" [10,8] : [6,4] [7,5] [8,6] [9,7] [10,8] - of 16 choices. |
|||
48 : "\" [3,8] : [1,6] [2,7] [3,8] [4,9] [5,10] - of 15 choices. |
|||
49 : "\" [5,9] : [2,6] [3,7] [4,8] [5,9] [6,10] - of 16 choices. |
|||
50 : "|" [3,9] : [3,9] [4,9] [5,9] [6,9] [7,9] - of 18 choices. |
|||
51 : "-" [2,8] : [2,4] [2,5] [2,6] [2,7] [2,8] - of 17 choices. |
|||
52 : "|" [5,8] : [4,8] [5,8] [6,8] [7,8] [8,8] - of 18 choices. |
|||
53 : "-" [8,9] : [8,5] [8,6] [8,7] [8,8] [8,9] - of 12 choices. |
|||
54 : "\" [0,6] : [0,6] [1,7] [2,8] [3,9] [4,10] - of 11 choices. |
|||
55 : "/" [2,9] : [2,9] [3,8] [4,7] [5,6] [6,5] - of 9 choices. |
|||
56 : "\" [0,3] : [0,3] [1,4] [2,5] [3,6] [4,7] - of 9 choices. |
|||
57 : "-" [11,6] : [11,3] [11,4] [11,5] [11,6] [11,7] - of 8 choices. |
|||
58 : "/" [9,8] : [7,10] [8,9] [9,8] [10,7] [11,6] - of 8 choices. |
|||
59 : "-" [3,11] : [3,7] [3,8] [3,9] [3,10] [3,11] - of 7 choices. |
|||
60 : "\" [8,11] : [4,7] [5,8] [6,9] [7,10] [8,11] - of 6 choices. |
|||
61 : "/" [2,12] : [2,12] [3,11] [4,10] [5,9] [6,8] - of 5 choices. |
|||
62 : "/" [2,11] : [2,11] [3,10] [4,9] [5,8] [6,7] - of 4 choices. |
|||
63 : "-" [2,10] : [2,8] [2,9] [2,10] [2,11] [2,12] - of 4 choices. |
|||
64 : "-" [5,11] : [5,7] [5,8] [5,9] [5,10] [5,11] - of 4 choices. |
|||
65 : "/" [1,11] : [1,11] [2,10] [3,9] [4,8] [5,7] - of 5 choices. |
|||
66 : "\" [1,8] : [0,7] [1,8] [2,9] [3,10] [4,11] - of 4 choices. |
|||
67 : "/" [0,9] : [0,9] [1,8] [2,7] [3,6] [4,5] - of 5 choices. |
|||
68 : "/" [3,12] : [3,12] [4,11] [5,10] [6,9] [7,8] - of 4 choices. |
|||
69 : "|" [0,11] : [0,11] [1,11] [2,11] [3,11] [4,11] - of 3 choices. |
|||
70 : "|" [0,8] : [0,8] [1,8] [2,8] [3,8] [4,8] - of 1 choices. |
|||
71 : "/" [-1,9] : [-1,9] [0,8] [1,7] [2,6] [3,5] - of 4 choices. |
|||
72 : "|" [1,9] : [-1,9] [0,9] [1,9] [2,9] [3,9] - of 4 choices. |
|||
73 : "-" [0,10] : [0,6] [0,7] [0,8] [0,9] [0,10] - of 7 choices. |
|||
74 : "/" [-1,11] : [-1,11] [0,10] [1,9] [2,8] [3,7] - of 6 choices. |
|||
75 : "\" [-1,7] : [-1,7] [0,8] [1,9] [2,10] [3,11] - of 5 choices. |
|||
76 : "\" [-2,8] : [-2,8] [-1,9] [0,10] [1,11] [2,12] - of 3 choices. |
|||
77 : "-" [1,10] : [1,7] [1,8] [1,9] [1,10] [1,11] - of 2 choices. |
|||
78 : "\" [4,13] : [0,9] [1,10] [2,11] [3,12] [4,13] - of 4 choices. |
|||
79 : "/" [-3,9] : [-3,9] [-2,8] [-1,7] [0,6] [1,5] - of 2 choices. |
|||
80 : "|" [-1,10] : [-1,10] [0,10] [1,10] [2,10] [3,10] - of 1 choices. |
|||
81 : "-" [-1,8] : [-1,7] [-1,8] [-1,9] [-1,10] [-1,11] - of 1 choices. |
|||
Morphion Solitare Grid (move=79): |
|||
Morphion Solitare Grid (move=86): |
|||
1234567890123456 |
1234567890123456 |
||
1 ................ |
1 ................ |
||
2 .....+.. |
2 .....++..+++.... |
||
3 .....++ |
3 .....+****+..... |
||
4 .....+* |
4 ....+.*++*+..... |
||
5 .+ |
5 ...+.+*++*+..+.. |
||
6 ..+ |
6 ..+****++****... |
||
7 ..+ |
7 ..+*++++++++*... |
||
8 . |
8 ..+*++++++++*... |
||
9 ..+*++ |
9 ..+****++****++. |
||
10 . |
10 .+++++*++*+++++. |
||
11 ....++*++*++++ |
11 ....++*++*+++++. |
||
12 .... |
12 .....+****+++++. |
||
13 ....++ |
13 .....++++++++++. |
||
14 ....+++++ |
14 ..........+++++. |
||
15 ..........+..... |
15 ..........+..... |
||
16 ................ |
16 ................ |
||
1234567890123456 |
1234567890123456 |
||
# |
|||
# Game Record for Morphion 5T game of 79 moves |
|||
# Reference: Games/79-L0(357)_20120208-090217.txt |
|||
# &random: 417754092 |
|||
# Syntax for recorded games: |
|||
# 1. whitespace and comments (everything past #) are ignored |
|||
# 2. moves may be ; or newline separated |
|||
# 3. moves are formatted (using BNF style variables like <x>): |
|||
# <movenumber>:<row>,<col>[^<drow>,<dcol>] |
|||
# The optional drow/dcol values provide an additional point |
|||
# used to disambiguate moves. The point drow/dcol must be |
|||
# chosen at one end of the line. |
|||
# Moves are applied in sorted order. |
|||
# 4. all row/col coordinates are relative to the 1,1 origin |
|||
# located at the intersection of the lines containing the |
|||
# top and left most edges of the cross. |
|||
# |
|||
1:5,7^1,7;2:7,11^7,7;3:10,8^10,4;4:7,5^7,1;5:3,3^1,5;6:3,8^1,6;7:8,8^6,10; |
|||
8:11,4^7,4;9:1,3^1,7;10:5,9^3,7;11:4,6^4,10;12:4,0^4,4;13:6,2^4,0;14:3,1^7,1; |
|||
15:3,5^1,3;16:5,4^1,4;17:9,6^7,8;18:11,7^7,7;19:8,3^6,1;20:3,10^7,10;21:3,6^3,4; |
|||
22:5,3^3,5;23:6,6^4,8;24:6,3^3,3;25:4,5^2,7;26:6,4^3,1;27:6,0^6,4;28:5,5^4,4; |
|||
29:8,2^4,6;30:9,3^6,0;31:8,5^6,3;32:9,5^9,3;33:12,8^8,4;34:8,6^8,3;35:6,5^5,5; |
|||
36:2,5^1,5;37:0,3^4,7;38:5,6^5,3;39:2,6^1,6;40:11,9^7,5;41:5,2^2,5;42:9,2^5,6; |
|||
43:3,2^7,2;44:6,7^3,4;45:6,8^6,4;46:7,6^3,2;47:11,3^7,7;48:9,8^6,8;49:3,0^3,4; |
|||
50:5,8^3,10;51:10,3^7,3;52:11,6^7,6;53:3,11^7,7;54:2,8^6,8;55:2,3^2,7;56:8,9^7,10; |
|||
57:6,9^4,9;58:11,2^7,6;59:5,0^1,4;60:11,5^11,3;61:-1,3^3,3;62:5,11^5,7; |
|||
63:2,0^6,0;64:3,9^1,7;65:3,12^3,8;66:4,11^3,12;67:8,11^4,7;68:5,-1^5,3; |
|||
69:8,10^8,7;70:2,-1^6,3;71:10,2^7,2;72:9,9^7,11;73:2,2^1,3;74:2,1^2,-1; |
|||
75:9,11^5,7;76:6,11^5,11;77:9,10^9,7;78:0,4^-1,3;79:6,12^6,8; |
|||
Move Log |
|||
1 : "|" [5,7] : [1,7] [2,7] [3,7] [4,7] [5,7] - of 4 choices. |
|||
2 : "-" [7,11] : [7,7] [7,8] [7,9] [7,10] [7,11] - of 27 choices. |
|||
3 : "-" [10,8] : [10,4] [10,5] [10,6] [10,7] [10,8] - of 26 choices. |
|||
4 : "-" [7,5] : [7,1] [7,2] [7,3] [7,4] [7,5] - of 24 choices. |
|||
5 : "/" [3,3] : [1,5] [2,4] [3,3] [4,2] [5,1] - of 23 choices. |
|||
6 : "\" [3,8] : [1,6] [2,7] [3,8] [4,9] [5,10] - of 22 choices. |
|||
7 : "/" [8,8] : [6,10] [7,9] [8,8] [9,7] [10,6] - of 21 choices. |
|||
8 : "|" [11,4] : [7,4] [8,4] [9,4] [10,4] [11,4] - of 20 choices. |
|||
9 : "-" [1,3] : [1,3] [1,4] [1,5] [1,6] [1,7] - of 19 choices. |
|||
10 : "\" [5,9] : [3,7] [4,8] [5,9] [6,10] [7,11] - of 17 choices. |
|||
11 : "-" [4,6] : [4,6] [4,7] [4,8] [4,9] [4,10] - of 16 choices. |
|||
12 : "-" [4,0] : [4,0] [4,1] [4,2] [4,3] [4,4] - of 16 choices. |
|||
13 : "\" [6,2] : [4,0] [5,1] [6,2] [7,3] [8,4] - of 14 choices. |
|||
14 : "|" [3,1] : [3,1] [4,1] [5,1] [6,1] [7,1] - of 13 choices. |
|||
15 : "\" [3,5] : [1,3] [2,4] [3,5] [4,6] [5,7] - of 11 choices. |
|||
16 : "|" [5,4] : [1,4] [2,4] [3,4] [4,4] [5,4] - of 14 choices. |
|||
17 : "/" [9,6] : [7,8] [8,7] [9,6] [10,5] [11,4] - of 12 choices. |
|||
18 : "|" [11,7] : [7,7] [8,7] [9,7] [10,7] [11,7] - of 11 choices. |
|||
19 : "\" [8,3] : [6,1] [7,2] [8,3] [9,4] [10,5] - of 8 choices. |
|||
20 : "|" [3,10] : [3,10] [4,10] [5,10] [6,10] [7,10] - of 7 choices. |
|||
21 : "-" [3,6] : [3,4] [3,5] [3,6] [3,7] [3,8] - of 5 choices. |
|||
22 : "/" [5,3] : [3,5] [4,4] [5,3] [6,2] [7,1] - of 2 choices. |
|||
23 : "/" [6,6] : [4,8] [5,7] [6,6] [7,5] [8,4] - of 5 choices. |
|||
24 : "|" [6,3] : [3,3] [4,3] [5,3] [6,3] [7,3] - of 6 choices. |
|||
25 : "/" [4,5] : [2,7] [3,6] [4,5] [5,4] [6,3] - of 6 choices. |
|||
26 : "\" [6,4] : [3,1] [4,2] [5,3] [6,4] [7,5] - of 4 choices. |
|||
27 : "-" [6,0] : [6,0] [6,1] [6,2] [6,3] [6,4] - of 7 choices. |
|||
28 : "\" [5,5] : [4,4] [5,5] [6,6] [7,7] [8,8] - of 4 choices. |
|||
29 : "/" [8,2] : [4,6] [5,5] [6,4] [7,3] [8,2] - of 7 choices. |
|||
30 : "\" [9,3] : [6,0] [7,1] [8,2] [9,3] [10,4] - of 7 choices. |
|||
31 : "\" [8,5] : [6,3] [7,4] [8,5] [9,6] [10,7] - of 7 choices. |
|||
32 : "-" [9,5] : [9,3] [9,4] [9,5] [9,6] [9,7] - of 11 choices. |
|||
33 : "\" [12,8] : [8,4] [9,5] [10,6] [11,7] [12,8] - of 14 choices. |
|||
34 : "-" [8,6] : [8,3] [8,4] [8,5] [8,6] [8,7] - of 13 choices. |
|||
35 : "|" [6,5] : [5,5] [6,5] [7,5] [8,5] [9,5] - of 15 choices. |
|||
36 : "|" [2,5] : [1,5] [2,5] [3,5] [4,5] [5,5] - of 13 choices. |
|||
37 : "\" [0,3] : [0,3] [1,4] [2,5] [3,6] [4,7] - of 17 choices. |
|||
38 : "-" [5,6] : [5,3] [5,4] [5,5] [5,6] [5,7] - of 15 choices. |
|||
39 : "|" [2,6] : [1,6] [2,6] [3,6] [4,6] [5,6] - of 19 choices. |
|||
40 : "\" [11,9] : [7,5] [8,6] [9,7] [10,8] [11,9] - of 17 choices. |
|||
41 : "/" [5,2] : [2,5] [3,4] [4,3] [5,2] [6,1] - of 16 choices. |
|||
42 : "/" [9,2] : [5,6] [6,5] [7,4] [8,3] [9,2] - of 14 choices. |
|||
43 : "|" [3,2] : [3,2] [4,2] [5,2] [6,2] [7,2] - of 12 choices. |
|||
44 : "\" [6,7] : [3,4] [4,5] [5,6] [6,7] [7,8] - of 13 choices. |
|||
45 : "-" [6,8] : [6,4] [6,5] [6,6] [6,7] [6,8] - of 13 choices. |
|||
46 : "\" [7,6] : [3,2] [4,3] [5,4] [6,5] [7,6] - of 13 choices. |
|||
47 : "/" [11,3] : [7,7] [8,6] [9,5] [10,4] [11,3] - of 13 choices. |
|||
48 : "|" [9,8] : [6,8] [7,8] [8,8] [9,8] [10,8] - of 13 choices. |
|||
49 : "-" [3,0] : [3,0] [3,1] [3,2] [3,3] [3,4] - of 10 choices. |
|||
50 : "/" [5,8] : [3,10] [4,9] [5,8] [6,7] [7,6] - of 10 choices. |
|||
51 : "|" [10,3] : [7,3] [8,3] [9,3] [10,3] [11,3] - of 8 choices. |
|||
52 : "|" [11,6] : [7,6] [8,6] [9,6] [10,6] [11,6] - of 8 choices. |
|||
53 : "/" [3,11] : [3,11] [4,10] [5,9] [6,8] [7,7] - of 9 choices. |
|||
54 : "|" [2,8] : [2,8] [3,8] [4,8] [5,8] [6,8] - of 8 choices. |
|||
55 : "-" [2,3] : [2,3] [2,4] [2,5] [2,6] [2,7] - of 7 choices. |
|||
56 : "/" [8,9] : [7,10] [8,9] [9,8] [10,7] [11,6] - of 8 choices. |
|||
57 : "|" [6,9] : [4,9] [5,9] [6,9] [7,9] [8,9] - of 8 choices. |
|||
58 : "/" [11,2] : [7,6] [8,5] [9,4] [10,3] [11,2] - of 8 choices. |
|||
59 : "/" [5,0] : [1,4] [2,3] [3,2] [4,1] [5,0] - of 9 choices. |
|||
60 : "-" [11,5] : [11,3] [11,4] [11,5] [11,6] [11,7] - of 10 choices. |
|||
61 : "|" [-1,3] : [-1,3] [0,3] [1,3] [2,3] [3,3] - of 8 choices. |
|||
62 : "-" [5,11] : [5,7] [5,8] [5,9] [5,10] [5,11] - of 8 choices. |
|||
63 : "|" [2,0] : [2,0] [3,0] [4,0] [5,0] [6,0] - of 8 choices. |
|||
64 : "\" [3,9] : [1,7] [2,8] [3,9] [4,10] [5,11] - of 6 choices. |
|||
65 : "-" [3,12] : [3,8] [3,9] [3,10] [3,11] [3,12] - of 6 choices. |
|||
66 : "/" [4,11] : [3,12] [4,11] [5,10] [6,9] [7,8] - of 6 choices. |
|||
67 : "\" [8,11] : [4,7] [5,8] [6,9] [7,10] [8,11] - of 6 choices. |
|||
68 : "-" [5,-1] : [5,-1] [5,0] [5,1] [5,2] [5,3] - of 7 choices. |
|||
69 : "-" [8,10] : [8,7] [8,8] [8,9] [8,10] [8,11] - of 7 choices. |
|||
70 : "\" [2,-1] : [2,-1] [3,0] [4,1] [5,2] [6,3] - of 8 choices. |
|||
71 : "|" [10,2] : [7,2] [8,2] [9,2] [10,2] [11,2] - of 7 choices. |
|||
72 : "/" [9,9] : [7,11] [8,10] [9,9] [10,8] [11,7] - of 6 choices. |
|||
73 : "/" [2,2] : [1,3] [2,2] [3,1] [4,0] [5,-1] - of 5 choices. |
|||
74 : "-" [2,1] : [2,-1] [2,0] [2,1] [2,2] [2,3] - of 5 choices. |
|||
75 : "\" [9,11] : [5,7] [6,8] [7,9] [8,10] [9,11] - of 4 choices. |
|||
76 : "|" [6,11] : [5,11] [6,11] [7,11] [8,11] [9,11] - of 5 choices. |
|||
77 : "-" [9,10] : [9,7] [9,8] [9,9] [9,10] [9,11] - of 3 choices. |
|||
78 : "\" [0,4] : [-1,3] [0,4] [1,5] [2,6] [3,7] - of 2 choices. |
|||
79 : "-" [6,12] : [6,8] [6,9] [6,10] [6,11] [6,12] - of 1 choices. |
|||
Shortest (0) Game(s): |
Shortest (0) Game(s): |
||
Total run time = |
Total run time = 32349320 ms |
||
&allocated (Total,static,string,block) : |
&allocated (Total,static,string,block) : 1152124804 0 144396168 1007728636 |
||
&collections (Total,static,string,block) : |
&collections (Total,static,string,block) : 4623 0 0 4623 |
||
®ions ( - , - ,string,block) : - 0 41859440 41859440 |
®ions ( - , - ,string,block) : - 0 41859440 41859440 |
||
&storage ( - , - ,string,block) : - 0 |
&storage ( - , - ,string,block) : - 0 37784 13290772</pre> |
||
The following is an example of a game log that was replayed from a long run: |
|||
Finished.</pre> |
|||
<pre># |
|||
Oops, notice the memory counters overflowed here (known bug). |
|||
# Game Record for Morphion 5T game of 92 moves |
|||
# Date: 2012/02/18 |
|||
# Saved: Games/5T/92-L1_20120218-163208-Fps.txt |
|||
# &random: 1617565851 |
|||
# ReplayFile: * none * (* all * moves) |
|||
# |
|||
# Pentasol compatible format |
|||
# |
|||
# |
|||
# Morpion Solitaire game |
|||
# |
|||
# XXXX |
|||
# X X |
|||
# X X |
|||
# XXXR XXXX |
|||
# X X |
|||
# X X |
|||
# XXXX XXXX |
|||
# X X |
|||
# X X |
|||
# XXXX |
|||
# |
|||
# R = reference point |
|||
# List of moves starts with reference point (col,row) |
|||
# Lines are |
|||
# (col,row) <direction> <+/-centerdist> |
|||
# distance to center is left side or top edge |
|||
# |
|||
(9,7) |
|||
(12,8) | -2 |
|||
(16,7) - -2 |
|||
(9,8) | -2 |
|||
(13,11) / 0 |
|||
(9,9) | +2 |
|||
(15,11) | -2 |
|||
(13,13) - -2 |
|||
(6,11) | -2 |
|||
(16,10) - -2 |
|||
(12,14) | -2 |
|||
(8,4) - +2 |
|||
(5,7) - +2 |
|||
(13,6) \ 0 |
|||
(10,12) \ 0 |
|||
(14,8) \ 0 |
|||
(14,12) / 0 |
|||
(10,10) - -2 |
|||
(11,9) / 0 |
|||
(8,6) / 0 |
|||
(10,8) \ +1 |
|||
(8,11) \ 0 |
|||
(11,7) / -1 |
|||
(13,9) \ 0 |
|||
(11,11) \ 0 |
|||
(14,11) - -1 |
|||
(14,9) | +1 |
|||
(13,12) | -1 |
|||
(12,9) - +1 |
|||
(16,9) / -2 |
|||
(17,6) / -2 |
|||
(11,12) - +1 |
|||
(16,6) / -2 |
|||
(16,8) | 0 |
|||
(11,10) | +1 |
|||
(10,9) \ +1 |
|||
(11,8) / 0 |
|||
(13,8) - -2 |
|||
(15,6) / -2 |
|||
(13,5) | +2 |
|||
(10,7) \ +2 |
|||
(14,6) \ 0 |
|||
(10,6) | +2 |
|||
(16,11) \ -2 |
|||
(11,6) - +2 |
|||
(11,5) | +2 |
|||
(8,8) / +2 |
|||
(8,14) / +2 |
|||
(8,9) | -1 |
|||
(7,9) - +2 |
|||
(4,6) \ +2 |
|||
(5,12) / +2 |
|||
(13,4) / -2 |
|||
(10,5) - +1 |
|||
(10,11) \ 0 |
|||
(7,8) / +2 |
|||
(7,6) | +2 |
|||
(7,11) - +1 |
|||
(10,14) | -2 |
|||
(9,14) / +2 |
|||
(7,3) \ +2 |
|||
(17,8) - -2 |
|||
(14,5) \ +1 |
|||
(11,14) - -1 |
|||
(8,12) \ 0 |
|||
(5,8) - +2 |
|||
(8,13) | -1 |
|||
(14,4) | +2 |
|||
(8,5) / -1 |
|||
(7,14) / +2 |
|||
(8,3) \ +2 |
|||
(6,6) - +2 |
|||
(5,5) \ +2 |
|||
(8,2) | +2 |
|||
(6,4) / 0 |
|||
(9,3) \ +1 |
|||
(7,5) / 0 |
|||
(5,3) \ +2 |
|||
(6,3) - +1 |
|||
(6,5) - +1 |
|||
(6,2) | +2 |
|||
(7,4) \ +1 |
|||
(7,2) | +2 |
|||
(5,4) \ +2 |
|||
(5,6) | 0 |
|||
(9,2) / -2 |
|||
(10,2) - -2 |
|||
(4,5) \ +2 |
|||
(10,3) | +1 |
|||
(3,6) / +2 |
|||
(4,4) - +2 |
|||
(2,6) - +2 |
|||
(3,5) / +1 |
|||
#</pre> |
Revision as of 21:36, 18 February 2012
This example goes beyond the task goal of playing a random game of Morpion solitaire. The program was designed as a first cut/test bed more for understanding and exploring the problem space rather than for high efficiency. The program is structured to allow its behaviour to be configured (see options and M_ vars). Some of the features and extensions include:
- Playing single games or running multigame simulations to find and capture the best games
- Producing re-loadable game records and the ability to replay a saved game from a given position forward
- The ability to reproduce purely random games from the random number seed
- Limiting the initial random moves to 1 of 4 cases (inside corners (1 type) x 8, outside corners (2 types) x 8, outside valley (1 type x 4)) not 1 of 28. In the case of this program these are all in the North East quadrant.
- Plugable modules for functions including applying player strategy, position evaluation (fitness/heuristics)to facilitate quick experimentation
- The version of the game played is a 'touching' (5T) game, although the validation procedure is easily parametrized.
Using random play in many summary runs, the highest (5T) score achieved was 90. While it was fairly easy to push random games into the low 80's running simulations of as little as a few hundred games, going beyond the highest score without adding some smarts will require some very long runs and is unlikely to result in any significant progress. Observing multigame runs show that play advances fairly quickly before a progress grinds to a virtual halt. Many runs peak in the first few hundred or thousand games.
The ability to replay recorded games provides a way to study the behaviour of the problem. Selecting successful random games, truncating them and running multigame simulations using a successful base shows that the seeds of success are sown early. It was possible to better the results of good random game scores (mid 80s) pushing the new scores up into the mid 90s. Unfortunately this technique when applied to Chris Rosin's 177 move record game did not produce any new records :(. Surprisingly however, it was possible to produce games in the high 160's! using random play with a truncated (approx 60%) version of this game.
The observation that a game becomes bad or good fairly early suggests that finding an intelligent forward looking position fitness evaluator is going to be a challenge to say the least.
It's also possible to capture bad games. This might provide some kind of comparison against good games when considering fitness evaluators. Or not.
Internally, the grid is automatically expanded as needed whenever a cell is played on an outer edge. When this happens only the affected side is expanded. As a side effect the grid numbering will seem unusual. The game log shows all row/col coordinates relative to the 1,1 origin located at the intersection of the lines containing top and left most edges of the cross. A fixed grid might be more efficient. With the ability to detect an off page condition and save and replay the game later this could be easier to deal with. The issue of grid origin comes up all the time when working with the code and debugging output.
For an example of a loadable and re-playable game see Chris Rosin's 177 move 5T previous record holder.
For more see: Morpion -h|-help
Core Morpion Routines
<lang Unicon>link printf,strings,options
$define MORPVER "1.7f" # version
procedure main(A) # Morphion
MorpionConf(A) if \M_ReplayFile then ReplayMorpion() else if \M_Limit === 1 then ShowGame(SingleMorpion()) else MultiMorphion(\M_Limit)
end
$define XEMPTY "." # symbols used in Grid $define XINIT "*" $define XUSED "+" $define DHOR "-" # Directions for moves $define DVER "|" $define DRD "\\" $define DLD "/" $define DALL "-|/\\"
record morpiongame(grid,score, # the grid & score
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
record morpionmove(direction,move,line,roff,coff) # move & line data record morpioncell(symbol,direction,row,col) # a grid cell record MorpionGameRecord(ref,row,col,darow,dacol) # record of game
procedure SingleMorpion(MG,N) #: Play a game silently
/MG := SetupM5Grid() # start game with new grid? while MorphionMove(M_Strategy(MG)) do # keep moving if MG.score >= \N then break # unless truncated return MG
end
procedure MorphionMove(MG) #: make a move
(M := MG.move).roff := MG.roff # copy offsets M.coff := MG.coff put(MG.history,M) # save history MG.score +:= 1 # and score M_LogDetails(MG,M) # for analysis every x := !M.line do { # draw the line g := MG.grid[x[1],x[2]] g.direction ||:= M.direction /g.symbol := XUSED # remove / for all XUSED } return
end
procedure ScanGrid(MG) #: Scan all grid lines
G := ExpandGrid(MG).grid # expand the grid if needed MG.pool := [] # candidate moves every c := 1 & r := 1 to *G do # horizontal ScanGridLine(G,r,c,0,+1,DHOR,MG.pool) every r := 1 & c := 1 to *G[1] do # vertical ScanGridLine(G,r,c,+1,0,DVER,MG.pool) every ( c := 1 & r := 1 to *G-4 ) | ( c := 2 to *G[r := 1] ) do # down & right ScanGridLine(G,r,c,+1,+1,DRD,MG.pool) every ( r := 2 to *G-4 & c := *G[r] ) | ( c := 5 to *G[r := 1] ) do # down & left ScanGridLine(G,r,c,+1,-1,DLD,MG.pool) if MG.score = 0 & M_Strategy ~=== Replayer then { # move 1 special case every put(pool1 := [], MG.pool[2|19|20|26]) # cor. o(2), i(1), val o(1) MG.pool := pool1 } if *MG.pool > 0 then return MG
end
procedure ScanGridLine(G,r0,c0,ri,ci,dir,pool) #: scan 1 grid line (5T/D)
local L5,M,r,c,x L5 := [] r := r0 - ri & c := c0 -ci # one step back while put(L5,G[r +:= ri,c +:= ci]) do { while *L5 > 5 do pop(L5) # too long ? if *L5 < 5 then next # too short ? if M_Mvalid(L5,dir) then { # just right, but valid? put(pool,M := morpionmove(dir,,[])) # add to pool of valid moves every x := L5[i := 1 to *L5] do { put(M.line,[x.row,x.col]) if /x.symbol then M.move := i } } } return pool
end
procedure ValidMove5T(L,dir) #: Succeed if L has valid 5T move
local i,j if *L ~= 5 then fail # wrong count every (i := 0) +:= (/(!L).symbol,1) if i ~= 1 then fail # more than 1 avail space every (j := 0) +:= ( find(dir,(!L).direction), 1) if j > 1 then fail # no overlap, =1 implies at an end return # that's it!
end
procedure ValidMove5D(L,dir) #: Succeed if L has valid 5D move #@@
local i,j if *L ~= 5 then fail # wrong count every (i := 0) +:= (/(!L).symbol,1) if i ~= 1 then fail # more than 1 avail space every (j := 0) +:= ( find(dir,(!L).direction), 1) if j > 0 then fail # no overlap, =1 implies at an end return # that's it!
end
procedure SetupM5Grid() #: construct 5T/D grid & cross
local G,r,c,s every !(G := list(10)) := list(10) # Grid every G[r := 1 to 10, c := 1 to 10] := morpioncell(,"",r,c) # Empties every s := ![[1,4],[4,1],[4,7],[7,1],[7,7],[10,4]] do { # Cross every r := s[1] & c := s[2] + (0 to 3) do G[r,c] := morpioncell(XINIT,"",r,c) every r := s[2] + (0 to 3) & c := s[1] do G[r,c] := morpioncell(XINIT,"",r,c) } return morpiongame(G,0,[],[],0,0,1 + (*G-1)/2.) # Create game
end
procedure ExpandGrid(MG) #: expand any touching sides
local r,c,rn,cn,C rn := *(G := MG.grid) # capture ... cn := *G[1] # ... entry dimensions if \(!G)[1].symbol then { # left edge MG.coff +:= 1 every (cn | (!!G).col) +:= 1 every push(G[r := 1 to rn],morpioncell(,"",r,1)) } if \(!G)[cn].symbol then { # right edge cn +:= 1 every put(G[r := 1 to rn],morpioncell(,"",r,cn)) } if \(!G[1]).symbol then { # top edge MG.roff +:= 1 every (rn | (!!G).row) +:= 1 push(G,C := list(cn)) every C[c := 1 to cn] := morpioncell(,"",1,c) } if \(!G[rn]).symbol then { # bottom edge rn +:= 1 put(G,C := list(cn)) every C[c := 1 to cn] := morpioncell(,"",rn,c) } return MG
end
procedure ShowGame(MG) #: show games
if M_Output === &output then every (PrintGrid|WriteMoveLog|M_PrintDetails)(MG) else # header first to output, game saved every (WriteMoveLog|PrintGrid|M_PrintDetails)(MG)
end
procedure PrintGrid(MG) #: print the current Grid
G := MG.grid every (ruler := " ") ||:= (1 to *G[1]) % 10 fprintf(M_Output,"\nMorphion Solitare Grid (move=%i):\n%s\n",MG.score,ruler) every r := 1 to *G do { fprintf(M_Output,"%s ",right(r%100,2)) every c := 1 to *(G[r]) do fprintf(M_Output,"%s",\G[r,c].symbol | XEMPTY) fprintf(M_Output,"\n") } fprintf(M_Output,"%s\n",ruler) return MG
end
procedure RandomPlayer(MG) #: Simulate random player
if &random := \M_Rseed then M_Rseed := &null # set seed if given only once /MG.rseed := &random # seed for this game if MG.move := ?ScanGrid(MG).pool then return MG
end
procedure Scorefail(MG);end #: dummy always fails </lang>
Interface, Parameters, Globals
<lang Unicon>global M_Strategy,M_Eval,M_Mvalid # Pluggable procedures global M_CommandLine,M_Config,M_GameType,M_GameSave global M_LogDetails,M_PrintDetails # Misc. global M_Output # output files global M_Limit,M_StatUpd,M_BestL,M_WorstL # Multi-game simulation options global M_SrchWid,M_SrchDep # For strategy modules global M_ReplayFile,M_ReplayAfter,M_Rseed # For game replay global M_WriteGame,M_ReadGame,M_GameFmt # Game formats to use global M_ChartW,M_ChartG # histogram
procedure MorpionConf(A) # Configure the Solver
M_CommandLine := copy(A) # preserve os := "-Q! -L+ -limit+ -V: -variant: -seed+ " os ||:= "-R! -replay! -RF: -RN+ -save! -RW: -RR: " os ||:= "-histwidth+ -histgroup+ -HW+ -HG+ " os ||:= "-UN+ -SW+ -SD+ -A: -E+ -B+ -W+" os ||:= "-details! " opt := options(A,os,Usage) # -<anything else> gets help M_Limit := ( 0 <= integer(\opt["limit"|"L"])) | 1 M_Rseed := \opt["seed"] M_Mvalid := case opt["V"|"variant"] of { "5D" : (M_GameType := "5D", ValidMove5D) default : (M_GameType := "5T", ValidMove5T) # also 5T } M_ReadGame := case map(\opt["RR"]) | &null of { default : (M_GameFmt := "ps", ReadMoveLogPS) "0" : (M_GameFmt := "0", ReadMoveLogOrig) } M_WriteGame := case map(\opt["RW"]) | &null of { default : (M_GameFmt := "ps", WriteMoveLogPS) "0" : (M_GameFmt := "0", WriteMoveLogOrig) } M_Strategy := case opt["A"] of { "A1" : (def_un := 50, PlayerA1) default : (def_un := 500, RandomPlayer) } M_Eval := case opt["E"] of { "1" : Score1 # test default : &null # also "0" } M_ChartW := (40 <= \opt["histwidth"|"HW"]) | 80 M_ChartG := \opt["histgroup"|"HG"] | 5 M_LogDetails := if \opt["details"] then LogDetails else 1 M_PrintDetails := if \opt["details"] then PrintDetails else 1 M_StatUpd := (0 < \opt["UN"]) | def_un M_BestL := (0 < \opt["B"]) | 5 M_WorstL := (0 < \opt["W"]) | 0 M_SrchWid := (0 < \opt["SW"]) | 5 M_SrchDep := (0 < \opt["SD"]) | 5 if \opt["R"|"replay"] then { M_ReplayFile := \opt["RF"] | "Games/5T/177-5T-rosin.txt" M_ReplayAfter := (0 < \opt["RN"]) | &null } else M_ReplayFile := &null if \(M_GameSave := opt["save"]) then { fn := sprintf("Runs/%s-L%i-",M_GameType,M_Limit) fn ||:= sprintf("RF%s-",map(\M_ReplayFile,"/\\","__")) fn ||:= sprintf("RN%i-",\M_ReplayAfter) fn ||:= sprintf("%s-%s.txt",deletec(&date,'/'),deletec(&clock,':')) M_Output := open(fn,"w") } /M_Output := &output c := sprintf("# --- Morpion Solitaire 5 (v%s) ---\n#\n",MORPVER) c ||:= "# Command line options :" every c ||:= " " || !A c ||:= "\n# Summary of Morpion Configuration:\n" c ||:= sprintf("# Variant (5T/D) move validation = %i\n",M_Mvalid) c ||:= sprintf("# Games to play = %s\n",( 0 < M_Limit) | "* unlimited *") c ||:= "# Multi-game options:\n" c ||:= sprintf("# - Status Updates = %i\n",M_StatUpd) c ||:= sprintf("# - Keep best = %i\n",M_BestL) c ||:= sprintf("# - Keep worst = %i\n",M_WorstL) c ||:= sprintf("# - Histogram width = %i\n",M_ChartW) c ||:= sprintf("# - Histogram grouping = %i\n",M_ChartG) c ||:= sprintf("# Games will be saved = %s\n", (\M_GameSave, "Yes") | "* No *") c ||:= sprintf("# - Format for game file (write) = %i\n",\M_WriteGame) c ||:= "# Replaying\n" c ||:= sprintf("# - Format for game file (read) = %i\n",\M_ReadGame) c ||:= sprintf("# - Game file to be replayed = %s\n", \M_ReplayFile | "* None *") c ||:= sprintf("# - Moves to replay = %i\n", 0 ~= \M_ReplayAfter) c ||:= sprintf("# Player Strategy = %i\n",M_Strategy) c ||:= sprintf("# - Seed for &random = %i\n",\M_Rseed) c ||:= sprintf("# - Position Fitness Evaluator = %s\n", image(\M_Eval) | "* None *") c ||:= sprintf("# - Search Width (strategy dependant) = %i\n",M_SrchWid) c ||:= sprintf("# - Search Depth (strategy dependant) = %i\n",M_SrchDep) c ||:= sprintf("# Log Details for analysis = %s\n", if M_LogDetails === 1 then "No" else "Yes") c ||:= "#\n" M_Config := c if \opt["Q"] then stop(M_Config,"-Q Stops run after processing options") else fprintf(M_Output,M_Config) /M_Eval := Scorefail
end
procedure Usage()
fprintf(&errout,"_ Morphion [options] Plays the 5T/D variant of Morphion Solitaire\n_ Arguments : ") every fprintf(&errout," %s",!M_CommandLine) fprintf(&errout,"_ Morphion [options] Plays the 5T/D variant of Morphion Solitaire\n_ Where options are:\n_ \t-A\tchoose player strategy approach (default=random, future)\n_ \t-E\tSpecifiy an position fitness evaluation function (default none, future)\n_ \t-SW\tSearch width (strategy dependent, future)\n_ \t-SD\tSearch depth (strategy dependent, future)\n_ \t-V|-variant\t5D or 5T (default)\n_ \t-R|-replay\treplay\n_ \t-RF\tfile containing game record to be replayed\n_ \t-RN\tnumber of moves to replay (0=all)\n_ \t-RR\tgame recording format to read (ps=pentasol(default), 0=original)\n_ \t-RW\tgame recording format to write ps=pentasol(default), 0=original)\n_ \t-save\tsave the best (-B) and worst (-W) games\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\tnote for larger n this benefits from larger BLKSIZE, STRSIZE environment variables\n_ \t-HW|-histwidth\twidth (cols) of histogram of scores\n_ \t-HG|-histgroup\tsize of groups (buckets) for histogram\n_ \t-UN\tGive status update notifications every n simulations\n_ \t-B\tKeep best n games of unique length (default 5)\n_ \t-W\tKeep worst n games of unique length (default 3)\n_ \t-details\tLog game details for analysis\n_ \t-Q\t(debugging) terminates after options processing\n_ \t-?|-h|-help\tthis help text") stop()
end</lang>
Multigame Simulation and Monitoring Support
<lang Unicon> procedure MultiMorphion(N,MG) #: Simulate N games using MG
etime := -&time scores := table(n := 0) every bestL|worstL := [] if N <= 0 then N := "unlimited" repeat { if n >= numeric(N) then break else n +:= 1 mg := SingleMorpion(deepcopy(\MG)|&null) # play out game scores[mg.score] +:= 1 # count score mg.count := n # game number if short := ( /short | short.score >= mg.score, mg) then { push(worstL,short) # keep worst if *worstL > M_WorstL then pull(worstL) } if ( /long | long.score <= mg.score) then { bestcnt := if (\long).score = mg.score then bestcnt + 1 else 1 long := mg put(bestL,long) # keep best if *bestL > M_BestL then get(bestL) fprintf(M_Output,"Longest game %i after %i simulations &random=%i.\n", long.score,n,long.rseed) fprintf(&errout,"\r%i of %s simulations, long=%i(%i) (%s %s)", n,N,long.score,bestcnt,&date,&clock) } if (n % M_StatUpd) = 0 then # say we're alive & working fprintf(&errout,"\r%i of %s simulations, long=%i(%i) (%s %s)", n,N,long.score,bestcnt,&date,&clock) if kbhit() & getch() == !"QqXx" then # exit if any q/x break fprintf(&errout,"\nExiting after %i simulations.\n",n) } etime +:= &time avg := 0.0 short := key(scores) \ 1 # 1 key only every i := key(scores) do { # summarize stats short >:= i avg +:= i * scores[i] } fprintf(M_Output,"\nResults from Sample of %i games of Morpion 5T/D:\n",n) fprintf(M_Output,"Shortest game was %i moves.\n",short) fprintf(M_Output,"Average game was %i moves.\n",avg /:= n) fprintf(M_Output,"Longest game was %i moves.\n",long.score) fprintf(M_Output,"Average time/game is %i ms.\n",etime/real(n)) fprintf(M_Output,"&random is now %i.\n",&random) GraphScores(scores) # graph results fprintf(M_Output,"\nLongest (%i) Game(s):\n",M_BestL) every ShowGame(!reverse(bestL)) # show longest game(s) and log fprintf(M_Output,"\nShortest (%i) Game(s):\n",M_WorstL) every ShowGame(!worstL) # show longest game(s) and log MemUsage() # diagnostic
end
procedure GraphScores(S) #: graph results
chart := [] every s := key(S) do { # by score n := s/M_ChartG+1 # chunks of ... until chart[n] do put(chart,0) # grow chart to need chart[n] +:= S[s] } s := (1 < max!chart/M_ChartW | 1) # scale fprintf(M_Output,"\nSummary of Results every '*' = %d games\n",s) every n := 1 to *chart do fprintf(M_Output,"%3d | (%6d) %s\n",(n-1)*M_ChartG,chart[n],repl("*",chart[n]/s))
end
procedure MemUsage() #: monitor usage
fprintf(M_Output,"\nTotal run time = %i ms\n",&time) fprintf(M_Output,"&allocated (Total,static,string,block) : ") every fprintf(M_Output," %i",&allocated) ; fprintf(M_Output,"\n") fprintf(M_Output,"&collections (Total,static,string,block) : ") every fprintf(M_Output," %i",&collections) ; fprintf(M_Output,"\n") fprintf(M_Output,"®ions ( - , - ,string,block) : ") every fprintf(M_Output," %s","-"|®ions) ; fprintf(M_Output,"\n") fprintf(M_Output,"&storage ( - , - ,string,block) : ") every fprintf(M_Output," %s","-"|&storage) ; fprintf(M_Output,"\n\n")
end </lang>
Game Replayer
<lang Unicon>procedure ReplayMorpion() #: Handle recorded games
Replayer(M := ReadMoveLog(M_ReplayFile)) # read game and save data M_Strategy := Replayer if /M_ReplayAfter | (M_ReplayAfter > *M) then { fprintf(M_Output,"Single game replay\n") ShowGame(SingleMorpion()) } else { # truncation replay MG := SingleMorpion(,M_ReplayAfter) # play shortened game M_Strategy := RandomPlayer if M_Limit === 1 then ShowGame(SingleMorpion(MG)) # single game else MultiMorphion(M_Limit,MG) # simulate many games from here } return
end
procedure Replayer(MG) #: feed replayed moves from list/game static ML,radj,cadj
if type(MG[1]) == "MorpionGameRecord" then return ML := MG # setup list if not ScanGrid(MG) then fail # out of moves ? x := get(ML) | fail # get next move if x.ref = 0 then x := get(ML) | fail # skip move 0 if any xr := x.row + MG.roff # adjust move for grid expansion xc := x.col + MG.coff dr := \x.darow + MG.roff # adjust end for grid expansion dc := \x.dacol + MG.coff pool := [] every m := !MG.pool do { # find possible moves here mr := m.line[m.move,1] mc := m.line[m.move,2] if xr=mr & xc=mc then if \dr & \dc then { # info to disambiguate? every p := (m.line)[1|5] do # try endpoints if p[1] = dr & p[2] = dc then put(pool,m) # save matching move } else put(pool,m) # save matching move(s) } if *pool = 1 then # unique move? return ( MG.move := pool[1], MG) # set unique move and return MG else { # we have a problem ShowGame(MG) fprintf(M_Output,"Problem encountered replaying game at move #%i, %i choices.\n",MG.score,*pool) every m := !pool do fprintf(M_Output," %s\n",FormatMoveLogPS(MG,m)) &dump := 0 stop() }
end</lang>
Game Reader (default is Pentasol notation)
<lang Unicon>procedure ReadMoveLog(MG) #: read move log wrapper
fprintf(M_Output,"Reading recorded game from: %s\n",M_ReplayFile) f := open(M_ReplayFile ,"r") | stop("Unable to open file ",M_ReplayFile ," for read.") R := [] while b := trim(read(f)) do { if b ? ="$end" then break # allow pre-mature end of file b ?:= tab(find("#")|0) # strip comments b := deletec(b,' \t') # strip whitespace if *b > 0 then put(R,b) # save move for reader } close(f) return M_ReadGame(R) # call reader, return move list
end
procedure ReadMoveLogPS(R) #: read pentasol style move log static off initial { # precalc center offsets
off := table() off[-2] := -4 off[-1] := -3 off[0] := 2 off[1] := -1 off[2] := 4 } M := [] n := 0 # move number get(R) ? ( ="(", coff := integer(tab(many(&digits))) - 4, =",", roff := integer(tab(many(&digits))) - 4, =")", pos(0) ) | # Reference Cell (c,r) stop(&output,"Syntax error in reference line.") while b := get(R) do { # Line (c,r) d o b ? ( ="(", c := integer(tab(many(&digits))), =",", r := integer(tab(many(&digits))), =")", d := tab(any(DALL)), o := integer(=("-2"|"-1"|0|"+1"|"+2")) ) | stop(&output,"Syntax error in line above.") x := MorpionGameRecord() # new move / line x.ref := n +:= 1 x.darow := x.row := r - roff x.dacol := x.col := c - coff case d of { # adjust based on direction DHOR : x.dacol +:= off[o] DVER : x.darow +:= off[o] DRD : ( x.darow +:= off[o], x.dacol +:= off[o]) DLD : ( x.darow -:= off[o], x.dacol +:= off[o]) } put(M,x) } return M
end</lang>
Game Logging (default is Pentasol style notation)
<lang Unicon>procedure WriteMoveLog(MG) #: write move log wrapper
if \M_GameSave then { savegame := sprintf("Games/%s/%i-L%i",M_GameType,*MG.history,M_Limit) if M_Limit ~= 1 then savegame ||:= sprintf("(%i)",MG.count) if \M_ReplayFile then { fn := map(M_ReplayFile,"/\\","__") fn ? (="Games/", savegame ||:= "-RF" || tab(find(".txt"))) savegame ||:= "-RN" || (0 < \M_ReplayAfter) } savegame ||:= sprintf("_%s-%s-F%s.txt",deletec(&date,'/'),deletec(&clock,':'),M_GameFmt) M_GameSave := savegame fprintf(M_Output,WriteMoveLogHeader(MG)) # write header, game is saved f := open(savegame,"w") | stop("Unable to open ",savegame," for writing") fprintf(f,M_WriteGame(MG),M_Config) # call desired writer for output/save close(f) } else fprintf(M_Output,M_WriteGame(MG))
end
procedure WriteMoveLogHeader(MG) #: write common header comments
return sprintf("#\n# Game Record for Morphion %s game of %i moves\n_ # Date: %s\n# Saved: %s\n# &random: %i\n_ # ReplayFile: %s (%s moves)\n#\n", M_GameType,MG.score,&date,\M_GameSave|"* none *",MG.rseed, \M_ReplayFile|"* none *",\M_ReplayAfter|"* all *")
end
procedure WriteMoveLogPS(MG) #: write pentasol style move log
l := WriteMoveLogHeader(MG) l ||:= sprintf("# Pentasol compatible format\n#\n#\n_ # Morpion Solitaire game\n#\n_ # XXXX\n# X X\n# X X\n_ # XXXR XXXX\n# X X\n# X X\n_ # XXXX XXXX\n# X X\n# X X\n# XXXX\n#\n_ # R = reference point\n_ # List of moves starts with reference point (col,row)\n_ # Lines are\n# (col,row) <direction> <+/-centerdist>\n_ # distance to center is left side or top edge\n#\n") l ||:= sprintf("(%i,%i)\n",4+MG.coff,4+MG.roff) every l ||:= FormatMoveLogPS(MG,!MG.history) return l || "#"
end
procedure FormatMoveLogPS(MG,m) #: format a PS move
d := if m.direction == "/" then m.move-3 else 3-m.move return sprintf("(%i,%i) %s %s%d\n", m.line[m.move,2]-m.coff+MG.coff,m.line[m.move,1]-m.roff+MG.roff, m.direction,(d < 0,"-")|(d = 0,"")|"+",abs(d))
end</lang>
Game Read/Write (alternate legacy notation)
<lang Unicon>procedure ReadMoveLogOrig(R) #: Read original style move log
M := [] while b := get(R) do { until *b = 0 do { x := MorpionGameRecord() # new move b ?:= ( x.ref := integer(tab(many(&digits))),=":", # base x.row := integer(=!["-","+",""]||tab(many(&digits))),=",", x.col := integer(=!["-","+",""]||tab(many(&digits))), tab(0)) | stop(&output,"Syntax error in line above.") if b ?:= ( ="^", tab(0)) then { # disamb b ?:= ( x.darow := integer(=!["-","+",""]||tab(many(&digits))),=",", x.dacol := integer(=!["-","+",""]||tab(many(&digits))), tab(0)) | stop(&output,"Syntax error in line above (disamiguation).") } b ?:= ( =(";"|""), tab(0) ) put(M,x) } } return sortf(M,1)
end
procedure WriteMoveLogOrig(MG) #: write out a re-readable move log
c := WriteMoveLogHeader(MG) c ||:= sprintf("# Alternate Recorded game format:\n_ # 1. whitespace and comments (everything past #) are ignored\n_ # 2. moves may be ; or newline separated\n_ # 3. moves are formatted (using BNF style variables like <x>):\n_ # <movenumber>:<row>,<col>[^<drow>,<dcol>]\n_ # The optional drow/dcol values provide an additional point\n_ # used to disambiguate moves. The point drow/dcol must be\n_ # chosen at one end of the line.\n_ # Moves are applied in sorted order.\n_ # 4. all row/col coordinates are relative to the 1,1 origin\n_ # located at the intersection of the lines containing the\n_ # top and left most edges of the cross.\n#\n") every m := MG.history[i := 1 to *MG.history] do { e := m.move ~= (1|5) /l := "" l ||:= sprintf("%i:%i,%i^%i,%i;", i,m.line[m.move,1]-m.roff,m.line[m.move,2]-m.coff, m.line[e,1]-m.roff,m.line[e,2]-m.coff) if *l > 70 then { c ||:= l || "\n" l := &null } } c ||:= \l || "\n" return c || "#"
end
Detailed Move Logging
<lang Unicon>procedure PrintDetails(MG) #: print the log
fprintf(M_Output,"Detailed Move Log\n") every fprintf(M_Output,"%i : %s\n",i := 1 to *MG.log,MG.log[i])
end
procedure LogFormatMove(M,roff,coff) #: format a log entry
/M.roff := \roff | 0 /M.coff := \coff | 0 log := sprintf("\"%s\" [%i,%i] : ",M.direction, M.line[M.move,1]-M.roff,M.line[M.move,2]-M.coff) every x := !M.line do log ||:= sprintf("[%i,%i] ",x[1]-M.roff,x[2]-M.coff) return log
end
procedure LogDetails(MG,M) #: Record details
log := LogFormatMove(M) log ||:= sprintf(" - of %i choices.",*MG.pool) # append # choices log ||:= sprintf(" Metric=%i",M_Eval(MG)) # append score (opt) put(MG.log,log) # log the move
end</lang>
Strategy Support
<lang Unicon># No useful examples at this time</lang>
printf.icn provides formatting
strings.icn provides deletec
options.icn provides options processing
Other RosettaCode pages used Deepcopy
SampleOutput
Help
Morphion [options] Plays the 5T/D variant of Morphion Solitaire Arguments : -helpMorphion [options] Plays the 5T/D variant of Morphion Solitaire Where options are: -A choose player strategy approach (default=random, future) -E Specifiy an position fitness evaluation function (default none, future) -SW Search width (strategy dependent, future) -SD Search depth (strategy dependent, future) -V|-variant 5D or 5T (default) -R|-replay replay -RF file containing game record to be replayed -RN number of moves to replay (0=all) -RR game recording format to read (ps=pentasol(default), 0=original) -RW game recording format to write ps=pentasol(default), 0=original) -save save the best (-B) and worst (-W) games -seed start the seed of the random number at this value -L|-limit games to play (if 0 or less then play until any of 'XxQq' is pressed note for larger n this benefits from larger BLKSIZE, STRSIZE environment variables -HW|-histwidth width (cols) of histogram of scores -HG|-histgroup size of groups (buckets) for histogram -UN Give status update notifications every n simulations -B Keep best n games of unique length (default 5) -W Keep worst n games of unique length (default 3) -details Log game details for analysis -Q (debugging) terminates after options processing -?|-h|-help this help text
Multigame
The multigame simulation of completely random play includes a histogram showing game scores clustering in the 20's and 60's. This result is similar to results obtained by Jean-Jacques Sibil (scroll down to find reference) who has run nearly a billion such simulations achieving a high score of 102 as of 2010.
The following is a summary file:
# --- Morpion Solitaire 5 (v1.7e) --- # # Command line options : # Summary of Morpion Configuration: # Variant (5T/D) move validation = procedure ValidMove5T # Games to play = * unlimited * # Multi-game options: # - Status Updates = 500 # - Keep best = 5 # - Keep worst = 0 # - Histogram width = 80 # - Histogram grouping = 5 # Games will be saved = Yes # - Format for game file (write) = procedure WriteMoveLogPS # Replaying # - Format for game file (read) = procedure ReadMoveLogPS # - Game file to be replayed = * None * # Player Strategy = procedure RandomPlayer # - Position Fitness Evaluator = * None * # - Search Width (strategy dependant) = 5 # - Search Depth (strategy dependant) = 5 # Log Details for analysis = No # Longest game 77 after 1 simulations &random=20122297. Longest game 77 after 85 simulations &random=274082001. Longest game 78 after 118 simulations &random=559240181. Longest game 78 after 123 simulations &random=1682993637. Longest game 81 after 292 simulations &random=826134037. Longest game 84 after 1181 simulations &random=1936506737. Longest game 86 after 4584 simulations &random=1266457499. Longest game 86 after 44424 simulations &random=1725594333. Longest game 86 after 47918 simulations &random=1686351259. Longest game 86 after 50600 simulations &random=665807725. Longest game 87 after 60841 simulations &random=152917603. Longest game 87 after 74778 simulations &random=1037682795. Longest game 88 after 173368 simulations &random=72059739. Longest game 88 after 241134 simulations &random=2095899781. Results from Sample of 242921 games of Morpion 5T/D: Shortest game was 20 moves. Average game was 53.65064774144681 moves. Longest game was 88 moves. Average time/game is 133.1678282239905 ms. &random is now 452165683. Summary of Results every '*' = 940 games 0 | ( 0) 5 | ( 0) 10 | ( 0) 15 | ( 0) 20 | ( 38637) ***************************************** 25 | ( 13790) ************** 30 | ( 6657) ******* 35 | ( 2604) ** 40 | ( 1306) * 45 | ( 1088) * 50 | ( 3448) *** 55 | ( 22481) *********************** 60 | ( 75207) ******************************************************************************** 65 | ( 61501) ***************************************************************** 70 | ( 13902) ************** 75 | ( 1922) ** 80 | ( 349) 85 | ( 29) Longest (5) Game(s): # # Game Record for Morphion 5T game of 88 moves # Date: 2012/02/18 # Saved: Games/5T/88-L0(241134)_20120218-083009-Fps.txt # &random: 2095899781 # ReplayFile: * none * (* all * moves) # Morphion Solitare Grid (move=88): 1234567890123456 1 ................ 2 ....+.+......... 3 .....+++........ 4 ..+++++++....... 5 .+++++++++...... 6 ..++++****+..... 7 .+++++*++*+..... 8 ..++++*++*++.... 9 ...****++****+.. 10 ...*++++++++*+.. 11 .++*++++++++*++. 12 ...****++****+.. 13 ....++*++*++++.. 14 .....+*++*+++... 15 .....+****+..... 16 .......++....... 17 ........+....... 18 ................ 1234567890123456 # # Game Record for Morphion 5T game of 88 moves # Date: 2012/02/18 # Saved: Games/5T/88-L0(173368)_20120218-083009-Fps.txt # &random: 72059739 # ReplayFile: * none * (* all * moves) # Morphion Solitare Grid (move=88): 1234567890123456 1 ................ 2 .......+........ 3 ......++...+.... 4 .....+****+..... 5 ..++++*++*+..... 6 ..++++*++*+++... 7 ...****++****+.. 8 ...*++++++++*+.. 9 .++*++++++++*+.. 10 ...****++****+.. 11 ..++++*++*+++++. 12 .+...+*++*+++++. 13 .....+****++++.. 14 ....+..+++++++.. 15 .........+++++.. 16 ..........+..... 17 ...........+.... 18 ................ 1234567890123456 # # Game Record for Morphion 5T game of 87 moves # Date: 2012/02/18 # Saved: Games/5T/87-L0(74778)_20120218-083009-Fps.txt # &random: 1037682795 # ReplayFile: * none * (* all * moves) # Morphion Solitare Grid (move=87): 123456789012345 1 ............... 2 ....+.+........ 3 .....+......... 4 ....+++++...... 5 ...++++++...... 6 .+++++****+.... 7 ..++++*++*+.... 8 .+++++*++*++... 9 ..+****++****.. 10 ..+*++++++++*+. 11 ...*++++++++*.. 12 ..+****++****+. 13 ...+++*++*++++. 14 ..++++*++*++... 15 .....+****+.+.. 16 ......+++++.... 17 ........+...... 18 ............... 123456789012345 # # Game Record for Morphion 5T game of 87 moves # Date: 2012/02/18 # Saved: Games/5T/87-L0(60841)_20120218-083009-Fps.txt # &random: 152917603 # ReplayFile: * none * (* all * moves) # Morphion Solitare Grid (move=87): 123456789012345678 1 .................. 2 .........+.+..+... 3 .....+...++++++... 4 ......****+++++... 5 .....+*++*+++++... 6 ....++*++*+++++++. 7 ..+****++****+.+.. 8 .++*++++++++*+.... 9 .++*++++++++*+.... 10 ..+****++****+.... 11 .+++++*++*++++.... 12 ....++*++*++...... 13 ....++****........ 14 ....+++........... 15 .................. 123456789012345678 # # Game Record for Morphion 5T game of 86 moves # Date: 2012/02/18 # Saved: Games/5T/86-L0(50600)_20120218-083009-Fps.txt # &random: 665807725 # ReplayFile: * none * (* all * moves) # Morphion Solitare Grid (move=86): 1234567890123456 1 ................ 2 .....++..+++.... 3 .....+****+..... 4 ....+.*++*+..... 5 ...+.+*++*+..+.. 6 ..+****++****... 7 ..+*++++++++*... 8 ..+*++++++++*... 9 ..+****++****++. 10 .+++++*++*+++++. 11 ....++*++*+++++. 12 .....+****+++++. 13 .....++++++++++. 14 ..........+++++. 15 ..........+..... 16 ................ 1234567890123456 Shortest (0) Game(s): Total run time = 32349320 ms &allocated (Total,static,string,block) : 1152124804 0 144396168 1007728636 &collections (Total,static,string,block) : 4623 0 0 4623 ®ions ( - , - ,string,block) : - 0 41859440 41859440 &storage ( - , - ,string,block) : - 0 37784 13290772
The following is an example of a game log that was replayed from a long run:
# # Game Record for Morphion 5T game of 92 moves # Date: 2012/02/18 # Saved: Games/5T/92-L1_20120218-163208-Fps.txt # &random: 1617565851 # ReplayFile: * none * (* all * moves) # # Pentasol compatible format # # # Morpion Solitaire game # # XXXX # X X # X X # XXXR XXXX # X X # X X # XXXX XXXX # X X # X X # XXXX # # R = reference point # List of moves starts with reference point (col,row) # Lines are # (col,row) <direction> <+/-centerdist> # distance to center is left side or top edge # (9,7) (12,8) | -2 (16,7) - -2 (9,8) | -2 (13,11) / 0 (9,9) | +2 (15,11) | -2 (13,13) - -2 (6,11) | -2 (16,10) - -2 (12,14) | -2 (8,4) - +2 (5,7) - +2 (13,6) \ 0 (10,12) \ 0 (14,8) \ 0 (14,12) / 0 (10,10) - -2 (11,9) / 0 (8,6) / 0 (10,8) \ +1 (8,11) \ 0 (11,7) / -1 (13,9) \ 0 (11,11) \ 0 (14,11) - -1 (14,9) | +1 (13,12) | -1 (12,9) - +1 (16,9) / -2 (17,6) / -2 (11,12) - +1 (16,6) / -2 (16,8) | 0 (11,10) | +1 (10,9) \ +1 (11,8) / 0 (13,8) - -2 (15,6) / -2 (13,5) | +2 (10,7) \ +2 (14,6) \ 0 (10,6) | +2 (16,11) \ -2 (11,6) - +2 (11,5) | +2 (8,8) / +2 (8,14) / +2 (8,9) | -1 (7,9) - +2 (4,6) \ +2 (5,12) / +2 (13,4) / -2 (10,5) - +1 (10,11) \ 0 (7,8) / +2 (7,6) | +2 (7,11) - +1 (10,14) | -2 (9,14) / +2 (7,3) \ +2 (17,8) - -2 (14,5) \ +1 (11,14) - -1 (8,12) \ 0 (5,8) - +2 (8,13) | -1 (14,4) | +2 (8,5) / -1 (7,14) / +2 (8,3) \ +2 (6,6) - +2 (5,5) \ +2 (8,2) | +2 (6,4) / 0 (9,3) \ +1 (7,5) / 0 (5,3) \ +2 (6,3) - +1 (6,5) - +1 (6,2) | +2 (7,4) \ +1 (7,2) | +2 (5,4) \ +2 (5,6) | 0 (9,2) / -2 (10,2) - -2 (4,5) \ +2 (10,3) | +1 (3,6) / +2 (4,4) - +2 (2,6) - +2 (3,5) / +1 #