From b5a10f1a8efb303071203b4e34b6602478c6c253 Mon Sep 17 00:00:00 2001 From: Luxferre Date: Tue, 16 Jan 2024 23:12:38 +0200 Subject: [PATCH] Supermove functionality finally here, still in testing --- nnfc.awk | 86 ++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 68 insertions(+), 18 deletions(-) diff --git a/nnfc.awk b/nnfc.awk index c9cad27..a042521 100644 --- a/nnfc.awk +++ b/nnfc.awk @@ -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 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 - 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 - tablens[rfrom]-- # decrease tableau length - } else fcell[from - 9] = -1 # moving from a free cell - valid = 1 # mark the move as valid + 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