Author Topic: slider puzzle  (Read 2381 times)

Offline memrosh

  • Acquaintance
  • *
  • Posts: 20
    • View Profile
slider puzzle
« on: December 02, 2006, 12:08:09 am »
As requested in the 2006 code contest thread:

http://lpmuds.net/forum/index.php?webtag=LPC&msg=212.8">http://lpmuds.net/forum/index.php?webtag=LPC&msg=212.8

 A simple slider puzzle table.

MudOS v22.2b14  Dead Souls 2.1 for unix  Stock

code:

/*
 * puzzle_table.c
 * Author- Memrosh
 * Date: October 10, 2006
 */
#include <lib.h>
#include <vendor_types.h>

inherit LIB_MANIPULATE;
inherit LIB_ITEM;

private int blank_place;
private object player;
/**
 * Variable answr_list
 *   This is the list of possible puzzle phrases. From one to five words are
 *   allowed. Word length of one to five letters only and the total letters
 *   from all five words must equal less than 25 to allow for a empty space.
 */
private string * answr_list = ({
    "an open mind is free",
    "think to free your soul",
    "hug an orc only once",
    "mages do it with magic",
    "do not feed the troll"
    });
private string * leter_list = ({});
private string * work_words = ({});
private string * mixed_leters = ({});
private string * rows = ({({}),({}),({}),({}),({})});
private string * columns = ({({}),({}),({}),({}),({})});
private string our_key = " ";
private string rbow ="%^RED%^r%^RESET%^%^GREEN%^a%^RESET%^%^ORANGE%^i%^RESET%^"+
    "%^YELLOW%^n%^RESET%^%^BLUE%^b%^RESET%^%^CYAN%^o%^RESET%^"+
    "%^MAGENTA%^w%^RESET%^";

/**
 * Function give_win(object player)
 *   Give a 'win' message then reset the board after a 30 sec delay.
 *
 * Parameters: player = the player who made the last move.
 *
 * Returns: None
 */
protected void give_win(object player){
    //creators can add prize or quest points here.
    message("say","The table top flashes in a "+rbow+" of colors as the "+
        "puzzle is solved.",environment());
    call_out("setup_random_board",30);
}

/**
 * Function cut_rows()
 *   Cut the global mixed_leters into rows, then create the columns.
 *   Send a message so those around might look at the new setup.
 *
 * Parameters: None
 *
 * Returns: None
 */
protected void cut_rows(){
    int i, a;
    int y = 5;
    int w = 5;
    string * bob = allocate(5);
    rows = allocate(5);
    columns = allocate(5);
    for(i=0;i<y;i++){
        rows[i..i] = ({mixed_leters[i*5..i*5+4]});
    }
    for(i=0;i<y;i++){
        for(a=0;a<w;a++){ bob[a] = mixed_leters[a*5+i]; }
        columns[i..i] = ({bob});
        bob = allocate(5);
    }
    if(objectp(environment(this_object()))){
        message("say","The board on the table top is briefly covered in a "+
            "swirling, "+rbow+" colored mist.",environment(this_object()));
    }
}

/**
 * Function setup_random_board()
 *   Select a random phrase. Make it the proper length.
 *   Randomize the order of the letters.
 *   Move on to function cut_rows().
 *
 * Parameters: None
 *
 * Returns: None
 */
void setup_random_board(){
    int i, x, r;
    string pad_list;
    string * work_list = ({});
    string * sub_list = ({});
    our_key = answr_list[random(sizeof(answr_list))];
    our_key = upper_case(our_key);
    pad_list = our_key;
    pad_list = arrange_string(pad_list, 24);
    pad_list += "#";
    work_words = explode(pad_list," ");
    leter_list = explode(pad_list,"");
    work_list = leter_list;
    x = sizeof(work_list);
    for(i=0;i<x;i++){
        r=random(sizeof(work_list));
        sub_list += work_list[r..r];
        work_list[r..r]=({});
    }
    mixed_leters = sub_list;
    cut_rows();
}

/**
 * Function show_board(object player)
 *   Create the colored board layout using the rows array.
 *   Give this message to player.
 *
 * Parameters: player = the player using the add_action board_look.
 *
 * Returns: None
 */
protected void show_board(object player){
    string msg, bob, mob;
    string cr, ds, dn;
    string * part;
    string * huh;
    int i, x;
    string sub_1 = "";
    cr = "%^RED%^+%^RESET%^";
    ds = "%^BLUE%^---%^RESET%^";
    dn = "%^BLUE%^|%^RESET%^";
    x = 5;
    for(i=0;i<x;i++){
        bob = rows;
        sub_1 += "   "+"%^GREEN%^"+(i+1)+"%^RESET%^"+" "+dn+" ";
        mob=bob[0]+" "+dn+" "+bob[1]+" "+dn+" "+bob[2]+" "+dn+" "+bob[3]+" "+
        dn+" "+bob[4]+" "+dn+"\n"+"     "+cr+ds+cr+ds+cr+ds+cr+ds+cr+ds+cr+"\n";
        sub_1+= mob;
    }
    msg = "       %^GREEN%^1   2   3   4   5%^RESET%^\n     "+
          cr+ds+cr+ds+cr+ds+cr+ds+cr+ds+cr+"\n"+sub_1;
    message("say",msg,player);
}

protected varargs void create(){
    ::create();
    if (!clonep()) return;
    SetKeyName("table");
    SetId(({"table", "puzzle", "board"}));
    SetAdjectives( ({"puzzling","small","oak"}) );
    SetShort("a small oak table");
    SetLong("This appears to be a small table made of fine old polished oak. "+
            "On the table top is a ceramic board comprised of inlaid tiles. "+
            "Each tile has eather a letter on it or is blank. There is one "+
            "tile missing (#). It appears that you can slide the tiles around "+
            "to form a phrase. For instance: If the empty place is in row 1 "+
            "column 3, you can '%^GREEN%^slide 1:1%^RESET%^' and the first "+
            "two tiles will be slid to the right. You might be able to "+
            "'%^GREEN%^check board%^RESET%^' to examine it. For a beginning "+
            "hint, try '%^GREEN%^puzzle clue%^RESET%^'.\n");
    SetMass(1000);
    SetBaseCost("silver",10);
    SetVendorType(VT_TREASURE);
    setup_random_board();
}

void init(){
    ::init();
    add_action("board_look", ({"check","chk","examine","ex"}));
    add_action("board_slide",({ "slide" }));
    add_action("clue_me",({"puzzle"}));
}

/**
 * Function check_solution(object player)
 *   Check each row to match variable array our_key.
 *   If we have a complete match we go to give_win(player).
 *
 * Parameters: object player. The player useing the add_action().
 *
 * Returns: None
 */
protected void check_solution(object player){
    string * chk_lines;
    int x, a, b;
   
    chk_lines = explode(our_key," ");
    a = sizeof(chk_lines);
    b = 0;
    x=strsrch(implode((string *)rows[0],""),chk_lines[0]);
    if(x != -1){ b = 1; }
    if(b == 1 && a > b){
        x=strsrch(implode((string *)rows[1],""),chk_lines[1]);
        if(x != -1){ b = 2; }
    }
    if(b == 2 && a > b){
        x=strsrch(implode((string *)rows[2],""),chk_lines[2]);
        if(x != -1){ b = 3; }
    }
   
    if(b == 3 && a > b){
        x=strsrch(implode((string *)rows[3],""),chk_lines[3]);
        if(x != -1){ b = 4; }
    }
   
    if(b == 4 && a > b){
        x=strsrch(implode((string *)rows[4],""),chk_lines[4]);
        if(x != -1){ b = 5; }
    }
   
    if(b > 0 && b == a){ give_win(player); }
}

/**
 * Function row_changer(int row, int col, int blank_place, object player)
 *   Make the actual 'sliding' of the tile pieces by re-arranging the
 *   rows sub array.
 *   Rebuild the affected columns.
 *   Show the player the new board with show_board(player) and
 *   then check if puzzle solved with check_solution(player).
 *
 * Parameters: int row/int col. The input of player using the add_action().
 *             int blank_place. Location of the empty tile spot.
 *             object player. The player useing the add_action().
 *
 * Returns: None
 */
protected void row_changer(int row, int col, int blank_place, object player){
    int i;
    string * work_row;
    int origin = ( col - 1 );
    int spacing = abs(blank_place-origin);
    if(origin == blank_place){
        message("say","That is not a valid move.",player);
        return;
    }
    work_row = copy(rows[row-1]);
    if(origin < blank_place){
        for(i=blank_place;i>origin;i--){work_row[i..i] = work_row[i-1..i-1];}
        work_row[origin..origin] = ({"#"});
        rows[row-1] = copy(work_row);
    }
    if(origin > blank_place){
        for(i=blank_place;i<origin;i++){
            work_row[i..i] = work_row[i+1..i+1];
        }
        work_row[origin..origin] = ({"#"});
        rows[row-1] = copy(work_row);
    }
   
    for(i=0;i<5;i++){
        columns[row-1] = rows[row-1];
    }
    send_messages("slide", "$agent_name $agent_verb the tiles on the table "+
        "top, each one briefly glowing as it moves.",player, 0,
        environment(player));
    show_board(player);
    check_solution(player);
}

/**
 * Function col_changer(int row, int col, int blank_place, object player)
 *   Make the actual 'sliding' of the tile pieces by re-arranging the
 *   columns sub array.
 *   Rebuild the affected rows.
 *   Show the player the new board with show_board(player) and
 *   then check if puzzle solved with check_solution(player).
 *
 * Parameters: int row/int col. The input of player using the add_action().
 *             int blank_place. Location of the empty tile spot.
 *             object player. The player useing the add_action().
 *
 * Returns: None
 */
protected void col_changer(int row, int col, int blank_place, object player){
    int i;
    string * work_col;
    int origin = ( row - 1 );
    int spacing = abs(blank_place-origin);
    if(origin == blank_place){
        message("say","That is not a valid move.",player);
        return;
    }
    work_col = copy(columns[col-1]);
    if(origin < blank_place){
        for(i=blank_place;i>origin;i--){work_col[i..i] = work_col[i-1..i-1];}
        work_col[origin..origin] = ({"#"});
        columns[col-1] = copy(work_col);
    }
    if(origin > blank_place){
        for(i=blank_place;i<origin;i++){
            work_col[i..i] = work_col[i+1..i+1];
        }
        work_col[origin..origin] = ({"#"});
        columns[col-1] = copy(work_col);
    }
    for(i=0;i<5;i++){
        rows[col-1] = columns[col-1];
    }
    send_messages("slide", "$agent_name $agent_verb the tiles on the table "+
        "top, each one briefly glowing as it moves.",player, 0,
        environment(player));
    show_board(player);//show the board after each move
    check_solution(player);
}

/**
 * Function blank_checker(int row, int col, object player)
 *   Find current exact location of the empty space. If not found
 *   in the row or column, player informed.
 *   The location is put in variable blank_place.
 *   If it is in the row, we move on to row_changer(row,col,blank_place,player).
 *   If it is in the column, move on to col_changer(row,col,blank_place,player).
 *
 * Parameters: int row/int col. The input of player using the add_action().
 *             object player. The player useing the add_action().
 *
 * Returns: None
 */
protected void blank_checker(int row, int col, object player){
    int x;
    if( (string) rows[row-1][col-1] == "#"){
        message("say","But that is the blank at "+row+":"+col+".",player);
        return;
    }
    x = member_array("#",rows[row-1]);
    if(x==-1){
        x = member_array("#",columns[col-1]);
        if(x==-1){
            message("say","That is not a valid move.",player);
            return;
        } else {
            blank_place = x;
            col_changer(row,col,blank_place,player);
            return;
        }
    } else {
        blank_place = x;
        row_changer(row,col,blank_place,player);
    }
}

/**
 * Function check_move(string raw_string, object player)
 *   Make the initial syntax checks for the move.
 *   Determine what row and column to work with and pass this info
 *   on to function blank_checker(rw,col,player).
 *
 * Parameters: string raw_string. The input of player using the add_action().
 *             object player. The player useing the add_action().
 *
 * Returns: None
 */
protected void check_move(string raw_string, object player){
    int rw, col, num;
   
    if(!stringp(raw_string)){
        message( "say", "The proper format is: slide <row>:<column>", player );
        return;
    }
    num=sscanf(raw_string,"%s:%s",rw,col);
    if(num != 2){
        message( "say", "The proper format is: slide <row>:<column>", player );
        return;
    }
    rw = to_int(rw);
    col = to_int(col);
    if(!intp(rw) || !intp(col)){
        message( "say", "The proper format is: slide <row>:<column>", player );
        return;
    }
    if(rw>5 || rw<1 || col>5 || col<1){
        message( "say", "There are only 5 rows and 5 columns.\n"+
            "They are numbered 1, 2, 3, 4 and 5.", player );
        return;
    }
   
    blank_checker(rw,col,player);
}

/**
 * Function board_look(string str)
 *   Check the syntax of string str to insure we are looking at the table.
 *   Set variable player and pass on to function show_board(player).
 *
 * Parameters: string str. The input of player using the add_action().
 *
 * Returns: int 1
 */
int board_look(string str){
    player = this_player();
    if(!stringp(str)){
        write("Just what are you wishing to examine? Perhaps board or "+
               "table or puzzle?");
        return 1;
    }
    if( str == "board" || str == "table"|| str == "puzzle" ||
      str == "table top"){
        show_board(player);
        send_messages("examine","$agent_name $agent_verb the table top.",
            player,0,environment(player));
        return 1;
    } else {
        write("Just what are you wishing to examine? Perhaps board or "+
              "table or puzzle?");
        return 1;
    }
}

/**
 * Function board_slide(string str)
 *   Sets object variable to this_player() then sends string and player
 *   on to function check_move(str,player).
 *
 * Parameters: string str. The input of player using the add_action().
 *
 * Returns: int 1
 */
int board_slide(string str){
    player = this_player();
    check_move(str,player);
    return 1;
}
/**
 * Function clue_me(string str)
 *   Get the letters from the first word in the phrase and display them
 *   to the player.
 *
 * Parameters: string str. The input of player using the add_action().
 *
 * Returns: int 1
 */
int clue_me(string str){
    string chk_line, msg;
    string * chk_list;
    int i, a;
   
    if(!stringp(str)){
        write("Need a starting hint? Try- puzzle clue");
        return 1;
    }
    if( str != "clue"){
        write("Need a starting hint? Try- puzzle clue");
        return 1;
    }
   
    chk_line = explode(our_key," ")[0];
    a = sizeof(chk_line);
    chk_list = explode(chk_line,"");
   
    msg = "The letters";
    for(i=0;i<a;i++){ msg += " "+chk_list+","; }
   
    msg = msg[0..<2];
    msg += " each flash in sequence. Then the top row flashes.";
    write(msg,this_player());
   
    return 1;
}


Useful for taverns or parlors to occupy the players between adventures.

And of course- examples of refined or alternate functions are always welcome in this folder to help us all learn more.

Memrosh

Offline Atomic

  • BFF
  • ***
  • Posts: 115
  • To infinity and beyond!
    • View Profile
slider puzzle
« Reply #1 on: December 05, 2006, 09:36:56 am »
Looks like a complicated (for my terms), but interesting

piece of script. Can't wait to test it out. First lemme get a

default DS mud back up.



I'd be also interested in the working of multiple-joinable games

for LPMud's/DS-alike, such as cardgames, gamblegames etc.



Credits to you Memrosh!

(¯`·.¸¸.· To infinity and beyond!·.¸¸.·´¯)
Always remember that the early bird gets the worm first, but the fi...*SNAP*...second mouse gets the cheese.