"Peg's solitaire" (solo noble) puzzle help

Started by viktoriadis, Wed 23/11/2016 16:01:48

Previous topic - Next topic

viktoriadis

Hi all,
This is my first post.
Usually i find the answers to most of my questions in the forum but not this time, and as i recall i have to post something from time to time!
so here it goes!
I would like to create a Peg's Solitaire ( https://en.wikipedia.org/wiki/Peg_solitaire ) kind of puzzle, as part of a bigger one (password puzzle), in a project i am working.
it's been 2 days now i am thinking about a way defining the movement of the pieces, as they can only move only if they have another piece next to them and also there is a blank position next to the second piece. I know some limited and basic scripting in ags, but my imagination this time isn't helping. So if someone has an idea of how to get it done or a way to script the movement of the pieces (they jump over each other, eliminating the one the jump over) please post a reply.
you can see a way of solving the puzzle here: http://www.mathsisfun.com/games/triangle-peg-solitaire/

thank you in advance and sorry for my english,
one more...new guy :)

Khris

You need a two-dimensional int array, 7x7. Store -1 in the 2x2 corners, then put a 1 in all other fields except the center.
If the player wants to move the peg at (4, 5) to the right, check if (5, 5) is 1 and (6, 5) is 0.

AGS only supports one-dimensional arrays, so you need to use int peg[49]; and y*7+x to get from x,y to the array index.

viktoriadis

 You are right Khris, ty. I will try it, in the weekend. Your idea made me think of a square board where all pieces (except from the ones in the "square edges") can only be draged to a coordinate only if the array says, it's ok to do so... Thanks again
Have a nice day guys and girls,
Viktor


viktoriadis

hi again,
Regarding the movement of the pieces in the Peg's Solitaire puzzle.
I used  Crimson Wizard's scripts for dragdrop and followed the general idea that Khris proposed in my first post.
I tried different approaches, but i am not even close to what should be right or what i would like for the players to be able to do.

Before i begin, i remind you that i am looking for a way that an object can only move only if there is another object next to it and in the direction its moving and also the position that is going to move is empty. When the relocation happens the other piece, that was next to it, is eliminated and relocated to another place(and the correct order gives us a password, but this is not relevant)
At first, i tried entering the checking and relocating of the piece positions in the repetedly_exec function of the room and it worked but not so good.
then i tried doing that inside the object_interact functions and you will see the results in the attachment.
I also tried using pointers, but they interfered with  Crimson Wizard's scripts i 'm calling, in order to drag the pieces.
i could use some help now , that i think i tried everything i could from my understanding of scripting in AGS.
Community please check the attached project (and also the rules of movement in the puzzle) and guide me in what to change or do differently
thanks in advance,
viktor

p.s. i dont know if the compressed file has been attached so i uploaded it also in this link:
http://www.filedropper.com/forupload

<img src=http://www.filedropper.com/download_button.png width=127 height=145 border=0/>
<div style=font-size:9px;font-family:Arial, Helvetica, sans-serif;width:127px;font-color:#44a854;> <a href=http://www.filedropper.com >file upload</a></div>

Crimson Wizard

viktoriadis, do you mean my DragDrop module? I would actually be very insterested in checking this problem out, because so far you are the first person who actually asked questions in regarding of the use of my script :).

Could you fix the attachement download link please? I think you have posted it wrongly.

viktoriadis

#5
hi
go to this link and download the compressed file (or at least these are the guide lines from the site)
http://www.filedropper.com/forupload

and it also gives me this embed code that i don't know how to use but when i clicked it in my previews post it sent me to a download page of the site
<img src=http://www.filedropper.com/download_button.png width=127 height=145 border=0/>
<div style=font-size:9px;font-family:Arial, Helvetica, sans-serif;width:127px;font-color:#44a854;> <a href=http://www.filedropper.com >file upload</a></div>

i also uploaded it here for 48 hours:
https://expirebox.com/download/e6557318f8904196a419810c22b519ac.html

i forgot to mention that, in the attached project(when debugging)you have to interact with the object after dragging it. Also it only works for the right moves and that is why i didn't like any of my solutions

Crimson Wizard

Oh, sorry, I got it now. First time I simply could not find how to download from that page.
Both filedropper and expirebox links work for me.

Crimson Wizard

#7
Quote from: viktoriadis on Thu 29/12/2016 22:27:50
At first, i tried entering the checking and relocating of the piece positions in the repetedly_exec function of the room and it worked but not so good.
then i tried doing that inside the object_interact functions and you will see the results in the attachment.
I also tried using pointers, but they interfered with  Crimson Wizard's scripts i 'm calling, in order to drag the pieces.

First of all, I have to say that this explanation explains too little... you're telling that you got problems when using this or that method, but do not tell which these problems were.
In my opinion, putting checking code inside object_interact functions is not a very good idea, because it relies on interaction event. Also, the way you did it only checks for limited number of variants, and has a lot of unnecessary code duplication.

I would start with dividing the big task into smaller ones. For example:
1) teach the game to detect where the object was dragged to and snap it to the cell center. if object was dragged to the invalid place, it should be returned back. Also, player is not allowed to drag objects inside "elimination" area.
2) teach the game to eliminate neighbour objects.
3) go on...


Screenshot of current demo:
Spoiler
[close]


So, starting with proper dragging technique, you already have DragDropCommon module there which handles dragging, but at the moment game makes no restrictions on what player can drag and where.
The game cells are not exactly rectangular, but if you are okay with assuming the are, then you may keep their bounds (coordinates of left,right,top and bottom borders) in a simple array.
NOTE: To improve precision you could use, for example, Hotspots as cell "trigger areas", or bitmap mask, but we may postpone that until basic rules are working.
NOTE2: Also, I was not sure whether cells are supposed to have equal sizes, in which case we could use math calculations to find the borders instead of keeping coords in arrays, but since you have a very rough board drawing there I thought I'd stick to coordinates for now.


Anyway, first of all we write a function that returns number of a cell where an object can be placed, or -1 if location is invalid (out of the board bounds).
Put this in the beginning of your room script:
Code: ags

#define CELL_NUMBER 10

// Cell coordinates
struct CellCoords
{
    int x1;
    int x2;
    int y1;
    int y2;
};

CellCoords Cells[CELL_NUMBER];

// TODO: initialize coordinates in the room_AfterFadeIn

// Get board cell number at given X/Y coordinates
int GetCellNumber(int x, int y)
{
    // Simple and dumb search inside the coordinates array
    for (int i = 0; i < CELL_NUMBER; i++)
    {
        if (x >= Cells[i].x1 && x <= Cells[i].x2 && y >= Cells[i].y1 && y <= Cells[i].y2)
            return i;
    }
    return -1; // this location is not a valid board cell
}



Now we need to script a reaction on object dragging. This should be written in the function room_RepExec:
Code: ags

function room_RepExec()
{
    // Player has released the dragging key
    if (DragDrop.EvtWantDrop)
    {
        // first check if the dragged object is above valid cell
        int cell_num = GetCellNumber(DragDrop.ObjectX, DragDrop.ObjectY);
        if (cell_num >= 0)
        {
            // snap the object to the center of the cell
            DragDrop.DropAt(Cells[cell_num].x1 + (Cells[cell_num].x2 - Cells[cell_num].x1) / 2,
                                                  Cells[cell_num].y1 + (Cells[cell_num].y2 - Cells[cell_num].y1) / 2);
        }
        else
        {
            // revert object to old place
	    DragDrop.Revert();
        }
    }
}


This will restrict object dragging to only actual board cells.


We also need to write placeholder functions that handle game rules: the function that tests whether object is allowed to be placed in current cell (according to rules), and function that handles the result of placement.
Put this somewhere above room_RepExec:
Code: ags

// Tells if the object could be placed into the given cell
bool IsAllowedToPlaceObject(Object *o, int cell_num)
{
    return true; // always return positive for now
}

// Handles object "o" placement into cell number "cell_num"
function OnObjectPlaced(Object *o, int cell_num)
{
    // do nothing for now
}


...And insert them into previously written RepExec:
Code: ags

<...>
    int cell_num = GetCellNumber(DragDrop.ObjectX, DragDrop.ObjectY);
    if (cell_num >= 0 && IsAllowedToPlaceObject(DragDropCommon._RoomObject, cell_num)) // <--------------- add IsAllowedToPlaceObject check here
    {
        // snap the object to the center of the cell
        DragDrop.DropAt(Cells[cell_num].x1 + (Cells[cell_num].x2 - Cells[cell_num].x1) / 2,
                                              Cells[cell_num].y1 + (Cells[cell_num].y2 - Cells[cell_num].y1) / 2);
	OnObjectPlaced(DragDropCommon._RoomObject, cell_num); // <------------ add the call to OnObjectPlaced here
    }
<...>



SMF spam blocked by CleanTalk