Supermove functionality finally here, still in testing
This commit is contained in:
@@ -5,8 +5,10 @@
|
|||||||
# - 0 is foundation (can be omitted)
|
# - 0 is foundation (can be omitted)
|
||||||
# - 1 to 8 are column numbers
|
# - 1 to 8 are column numbers
|
||||||
# - a, b, c, d are freecell numbers
|
# - a, b, c, d are freecell numbers
|
||||||
|
# bulk move/supermove operation between columns: [number][number] [number]
|
||||||
|
# the first two numbers _must_ only be column numbers (1 to 8)
|
||||||
|
# the second (space separated) number is how many top cards we move
|
||||||
# SEED variable can be used to init games M$-style
|
# SEED variable can be used to init games M$-style
|
||||||
# no supermove support for now, need to move cards one at a time
|
|
||||||
# created by Luxferre in 2024, released into public domain
|
# created by Luxferre in 2024, released into public domain
|
||||||
|
|
||||||
# Helper functions
|
# Helper functions
|
||||||
@@ -85,7 +87,7 @@ function render(i, j, res) {
|
|||||||
|
|
||||||
# main logic/move function (also handles the undo)
|
# main logic/move function (also handles the undo)
|
||||||
# statuses: 0 - invalid move, 1 - continue, 2 - victory
|
# statuses: 0 - invalid move, 1 - continue, 2 - victory
|
||||||
function domove(cmd, valid, nums, from, to, si) {
|
function domove(cmd, valid, cvalid, nums, ngrp, from, to, amt, i, si, ec, efc) {
|
||||||
if(cmd == "u") { # undo logic
|
if(cmd == "u") { # undo logic
|
||||||
if(undoidx > 0) {
|
if(undoidx > 0) {
|
||||||
undoidx--
|
undoidx--
|
||||||
@@ -97,10 +99,14 @@ function domove(cmd, valid, nums, from, to, si) {
|
|||||||
return 1 # continue
|
return 1 # continue
|
||||||
}
|
}
|
||||||
valid = 0 # invalid by default until all checks are done
|
valid = 0 # invalid by default until all checks are done
|
||||||
# if cmd is not q, h, ah or u, then it must be two numbers
|
# if cmd is not q, h, ah or u, then it must be one or two "numbers"
|
||||||
split(cmd, nums, "") # numbers must be space-separated
|
split(cmd, ngrp, " ") # parse the command as a whole
|
||||||
|
split(ngrp[1], nums, "") # parse the first part
|
||||||
from = nums[1] # location from which we're moving
|
from = nums[1] # location from which we're moving
|
||||||
to = nums[2] # location to which we're moving
|
to = nums[2] # location to which we're moving
|
||||||
|
amt = int(ngrp[2]) # get the amount of cards being moved
|
||||||
|
if(amt < 1) amt = 1 # it should be at least 1
|
||||||
|
if(amt > 20) amt = 20 # and at most 20
|
||||||
# identify free cells
|
# identify free cells
|
||||||
if(from == "a") from = 9
|
if(from == "a") from = 9
|
||||||
if(from == "b") from = 10
|
if(from == "b") from = 10
|
||||||
@@ -114,6 +120,34 @@ function domove(cmd, valid, nums, from, to, si) {
|
|||||||
to = int(to)
|
to = int(to)
|
||||||
rfrom = from - 1 # real from location
|
rfrom = from - 1 # real from location
|
||||||
rto = to - 1 # real to location
|
rto = to - 1 # real to location
|
||||||
|
if(amt > 1) { # constraints for moving a stack of cards
|
||||||
|
cvalid = 0 # it uses its own validation flag
|
||||||
|
if(from > 0 && from < 9 && to > 0 && to < 9) { # both must be columns
|
||||||
|
efc = 0 # count empty freecells here
|
||||||
|
ec = 0 # count empty columns and final result here
|
||||||
|
for(i=0;i<4;i++) if(fcell[i] == -1) efc++
|
||||||
|
for(i=0;i<8;i++) if(tablens[i] == 0) ec++
|
||||||
|
# now, calculate the max card amount to move
|
||||||
|
ec = (2^ec) * (efc + 1) # base formula
|
||||||
|
if(tablens[rto] == 0) ec /= 2 # halve if moving to an empty column
|
||||||
|
if(amt <= ec) { # amount constraint is satisfied, now check the stack
|
||||||
|
efc = tablens[rfrom] - amt # reuse for starting index in source tableau
|
||||||
|
ec = 1 # reuse for successful stack arrangement flag
|
||||||
|
for(i=0;i<amt-1;i++) {
|
||||||
|
si = table[rfrom,efc+i] # the current value
|
||||||
|
cval = table[rfrom,efc+i+1] # the next value
|
||||||
|
if(cval == "") break # we're out of bounds
|
||||||
|
if(!(getcolor(cval) != getcolor(si) && (cval%13) == (si%13) - 1)) {
|
||||||
|
ec = 0
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(ec == 1) cvalid = 1 # only then the move is valid
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# in any other case, the move is directly invalid
|
||||||
|
if(cvalid == 0) return 0
|
||||||
|
}
|
||||||
if(from > 0 && from < 13 && to > -1 && to < 13) { # first check
|
if(from > 0 && from < 13 && to > -1 && to < 13) { # first check
|
||||||
# determine what card we're trying to move
|
# determine what card we're trying to move
|
||||||
cval = -1
|
cval = -1
|
||||||
@@ -133,22 +167,33 @@ function domove(cmd, valid, nums, from, to, si) {
|
|||||||
valid = 1 # mark the move as valid
|
valid = 1 # mark the move as valid
|
||||||
}
|
}
|
||||||
} else if(to < 9) { # moving to a tableau
|
} else if(to < 9) { # moving to a tableau
|
||||||
|
efc = 0 # reuse for starting index in source tableau
|
||||||
|
if(from < 9) efc = tablens[rfrom] - amt
|
||||||
|
if(efc > -1) { # check if we aren't moving more cards than allowed
|
||||||
|
for(i=0;i<amt;i++) { # move the cards as usual
|
||||||
|
if(from < 9) { # re-read the source value if looping over a column
|
||||||
|
cval = table[rfrom, efc+i]
|
||||||
|
if(cval == "") break # we try to read more than is available
|
||||||
|
else cval = int(cval)
|
||||||
|
}
|
||||||
si = table[rto,tablens[rto]-1] # target value
|
si = table[rto,tablens[rto]-1] # target value
|
||||||
if((getcolor(cval) != getcolor(si) && (cval%13) == (si%13) - 1) || si == "") {
|
if((getcolor(cval) != getcolor(si) && (cval%13) == (si%13) - 1) || si == "") {
|
||||||
table[rto,tablens[rto]] = cval # copy the card there
|
table[rto,tablens[rto]] = cval # copy the card there
|
||||||
tablens[rto]++ # increase tableau length
|
tablens[rto]++ # increase tableau length
|
||||||
if(from < 9) { # moving from a tableau
|
if(from < 9) { # moving from a tableau
|
||||||
delete table[rfrom,tablens[rfrom]-1] # delete the card
|
delete table[rfrom,efc+i] # delete the card
|
||||||
tablens[rfrom]-- # decrease tableau length
|
tablens[rfrom]-- # decrease tableau length
|
||||||
} else fcell[from - 9] = -1 # moving from a free cell
|
} else fcell[from - 9] = -1 # moving from a free cell
|
||||||
valid = 1 # mark the move as valid
|
valid = 1 # mark the move as valid
|
||||||
|
} else break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if(fcell[to - 9] == -1) { # moving to a free cell
|
} else if(fcell[to - 9] == -1) { # moving to a free cell
|
||||||
fcell[to - 9] = cval
|
fcell[to - 9] = cval
|
||||||
if(from < 9) { # moving from a tableau
|
if(from < 9) { # moving from a tableau
|
||||||
delete table[rfrom,tablens[rfrom]-1] # delete the card
|
delete table[rfrom,tablens[rfrom]-1] # delete the card
|
||||||
tablens[rfrom]-- # decrease tableau length
|
tablens[rfrom]-- # decrease tableau length
|
||||||
} else fcell[rfrom - 9] = -1 # moving from a free cell
|
} else fcell[from - 9] = -1 # moving from a free cell
|
||||||
valid = 1 # mark the move as valid
|
valid = 1 # mark the move as valid
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -193,23 +238,28 @@ function autohome(chres, lres, i) {
|
|||||||
|
|
||||||
function help() {
|
function help() {
|
||||||
print "nnfc: no-nonsense FreeCell in POSIX AWK"
|
print "nnfc: no-nonsense FreeCell in POSIX AWK"
|
||||||
|
print "Created by Luxferre in 2024, released into public domain"
|
||||||
print "Script parameters:"
|
print "Script parameters:"
|
||||||
print "-v ASCII=1\tuse ASCII instead of Unicode suit chars"
|
print "-v ASCII=1\tuse ASCII instead of Unicode suits"
|
||||||
print "-v MONOCHROME=1\t don't use colors"
|
print "-v MONOCHROME=1\tdon't use colors"
|
||||||
print "-v SEED=xxxxx\tset game seed number (M$-compatible)"
|
print "-v SEED=xxxxx\tset game seed number (M$-compatible)"
|
||||||
print "-v NAH=1\tdisable autohoming after every move (use ah command for this)"
|
print "-v NAH=1\tdisable autohoming after every move (use ah for this)"
|
||||||
print "Commands: q - quit, u - undo, ah - autohome, h - this help"
|
print "Commands: q - quit, u - undo, ah - autohome, h - this help"
|
||||||
print "Moves: [digit][digit], where \"digits\" are:"
|
print "Moves: [digit][digit], where \"digits\" are:"
|
||||||
print "- 0 is foundation (can be omitted)"
|
print "- 0 is foundation (can be omitted)"
|
||||||
print "- 1 to 8 are column (tableau) numbers"
|
print "- 1 to 8 are column (tableau) numbers"
|
||||||
print "- a, b, c, d are freecell IDs"
|
print "- a, b, c, d are freecell IDs"
|
||||||
|
print "Supermoves between columns: [digit][digit] [number]"
|
||||||
|
print "The first two digits must only be column numbers (1 to 8)"
|
||||||
|
print "The space-separated number is how many top cards we move"
|
||||||
print "Examples:"
|
print "Examples:"
|
||||||
print "7a\tmove from column 7 to freecell a"
|
print "7a\tmove from column 7 to freecell a"
|
||||||
print "63\tmove from column 6 to column 3"
|
print "63\tmove from column 6 to column 3"
|
||||||
print "d1\tmove from freecell d to column 1"
|
print "d1\tmove from freecell d to column 1"
|
||||||
print "4\tmove from column 4 to the foundation"
|
print "4\tmove from column 4 to the foundation"
|
||||||
print "c\tmove from freecell c to the foundation"
|
print "c\tmove from freecell c to the foundation"
|
||||||
print "ah\tautomatically move all eligible cards to the foundation"
|
print "25 3\tmove top 3 cards from column 2 to column 5"
|
||||||
|
print "ah\tmove all eligible cards to the foundation"
|
||||||
return 1 # continue
|
return 1 # continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user