Supermove functionality finally here, still in testing
This commit is contained in:
@@ -5,8 +5,10 @@
|
||||
# - 0 is foundation (can be omitted)
|
||||
# - 1 to 8 are column 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
|
||||
# no supermove support for now, need to move cards one at a time
|
||||
# created by Luxferre in 2024, released into public domain
|
||||
|
||||
# Helper functions
|
||||
@@ -85,7 +87,7 @@ function render(i, j, res) {
|
||||
|
||||
# main logic/move function (also handles the undo)
|
||||
# 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(undoidx > 0) {
|
||||
undoidx--
|
||||
@@ -97,10 +99,14 @@ function domove(cmd, valid, nums, from, to, si) {
|
||||
return 1 # continue
|
||||
}
|
||||
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
|
||||
split(cmd, nums, "") # numbers must be space-separated
|
||||
# if cmd is not q, h, ah or u, then it must be one or two "numbers"
|
||||
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
|
||||
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
|
||||
if(from == "a") from = 9
|
||||
if(from == "b") from = 10
|
||||
@@ -114,6 +120,34 @@ function domove(cmd, valid, nums, from, to, si) {
|
||||
to = int(to)
|
||||
rfrom = from - 1 # real from 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
|
||||
# determine what card we're trying to move
|
||||
cval = -1
|
||||
@@ -133,22 +167,33 @@ function domove(cmd, valid, nums, from, to, si) {
|
||||
valid = 1 # mark the move as valid
|
||||
}
|
||||
} 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
|
||||
if((getcolor(cval) != getcolor(si) && (cval%13) == (si%13) - 1) || si == "") {
|
||||
table[rto,tablens[rto]] = cval # copy the card there
|
||||
tablens[rto]++ # increase tableau length
|
||||
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
|
||||
} else fcell[from - 9] = -1 # moving from a free cell
|
||||
valid = 1 # mark the move as valid
|
||||
} else break
|
||||
}
|
||||
}
|
||||
} else if(fcell[to - 9] == -1) { # moving to a free cell
|
||||
fcell[to - 9] = cval
|
||||
if(from < 9) { # moving from a tableau
|
||||
delete table[rfrom,tablens[rfrom]-1] # delete the card
|
||||
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
|
||||
}
|
||||
}
|
||||
@@ -193,23 +238,28 @@ function autohome(chres, lres, i) {
|
||||
|
||||
function help() {
|
||||
print "nnfc: no-nonsense FreeCell in POSIX AWK"
|
||||
print "Created by Luxferre in 2024, released into public domain"
|
||||
print "Script parameters:"
|
||||
print "-v ASCII=1\tuse ASCII instead of Unicode suit chars"
|
||||
print "-v MONOCHROME=1\t don't use colors"
|
||||
print "-v ASCII=1\tuse ASCII instead of Unicode suits"
|
||||
print "-v MONOCHROME=1\tdon't use colors"
|
||||
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 "Moves: [digit][digit], where \"digits\" are:"
|
||||
print "- 0 is foundation (can be omitted)"
|
||||
print "- 1 to 8 are column (tableau) numbers"
|
||||
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 "7a\tmove from column 7 to freecell a"
|
||||
print "63\tmove from column 6 to column 3"
|
||||
print "d1\tmove from freecell d to column 1"
|
||||
print "4\tmove from column 4 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
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user