Refreshing a list of objects for two players

A

Apples

Guest
Hello!

Player 1 and Player 2 are matching objects by placing them onto a field. Like a head-to-head puzzle game, I would like both players' objects to spawn in the same order.
What I have so far is a for loop that creates a list of randomized objects:

Create Event:
Code:
for(var i=0; i<global.next_obj_table_len; i++;) {
    global.next_obj[i,0] = irandom(global.total_objs);
    global.next_obj[i,1] = 0; //if 1, this object has spawned for p1
    global.next_obj[i,2] = 0; //if 1, this object has spawned for p2
}
And as the objects are created, they scan the list until they find the next object on the list that hasn't been spawned and become it:

An object spawned for player 1:
Code:
for(var i=0; i<global.next_elem_table_len; i++;) {
    if global.next_obj[i,1] != 1 {
        new_obj.o_type = global.next_obj[i,0]; 
        global.next_obj[i,1]=1;
    }
}
While this works, and while I can create a thousand object-long table, it's probably not ideal. Any help would be appreciated.
 

TheouAegis

Member
Will both players share the same list of objects or can player 1's objects spawn in a different order than player 2?
If they share the same list...


global.next_obj = ds_list_create();
//add all the objects
ds_list_shuffle(global.next_obj);
global.next_id[1] = 0;

To spawn something...


instance_create(x, y, ds_list_find_value(global.next_id[current_player]));
global.next_id[current_player]++;


When something gets spawned, just increase the corresponding global.next_id index. In this example, current_player would hold 0 (for player 1) or 1 (for player 2).


If they share their own lists...

global.next_obj[0] = ds_list_create();
//add all objects
global.next_obj[1] = ds_list_copy(global.next_obj[0]);
ds_list_shuffle(global.next_obj[0]);
ds_list_shuffle(global.next_obj[1]);
global.next_id[1] = 0;
 
A

Apples

Guest
@TheouAegis Hey, thanks! Both players have their own separate lists, but I'm looking for the contents and the order of both lists to be the same.
The next object in player 2's list, for example, would not change until player 2 spawns that object--even if player 1 is spawning objects nonstop.
Your second suggestion is closer to what I'm looking for, but both lists would be different.
 

TheouAegis

Member
Wait, you're saying two different things.

"Both players have their own separate lists, but I'm looking for the contents and the order of both lists to be the same."

In that case, both players don't have separate lists; since the lists would be identical in that case, you only need one list shared between both players. So based on that second clause, my first code is what you'd want.

object_list:
  1. obj_dog
  2. obj_cat
  3. obj_apple
  4. obj_orange
  5. obj_pencil
  6. obj_paper
  7. obj_rock
  8. obj_scissors
ds_list_shuffle(object_list);
next_obj[1] = 0;


Player 1 spawns something:
instance_create(x,y,ds_list_find_value(object_list,next_obj[0]++)); //spawns obj_dog
instance_create(x,y,ds_list_find_value(object_list,next_obj[0]++)); //now spawns obj_cat

if next_obj[0] == ds_list_size(object_list)
next_obj[0] = 0;
if next_obj[1] == ds_list_size(object_list)
next_obj[1] = 0;
 
A

Apples

Guest
@TheouAegis You're right, a single list would work. However, I failed to mention that the list of objects would be randomized whenever a new game starts, and an object could appear multiple times in succession. Also, when a player reached the end of the list, it wouldn't loop in the same order.
For example, a log of what has spawned from the list that only contains three objects, obj_rock, obj_paper, obj_scissors, might look like this:
  1. obj_paper
  2. obj_rock
  3. obj_scissors < p1 is currently on this object
  4. obj_rock
  5. obj_scissors
  6. obj_scissors
  7. obj_paper < p2 is currently on this object
Assuming p2 spawns obj_paper before p1 catches up to p2, the next object p2 has access to (obj 8,) would be randomly chosen between the three objects. P1 will have the chance to spawn the same obj 8 once he/she has spawned objs 4-7.
 

TheouAegis

Member
The initial list will be the same or all lists will be the same?

Code:
PRIMARY_LIST = ds_list_create()
//add however many objects (in this case 3)
size = ds_list_size(PRIMARY_LIST) - 1;
USER_LIST[0] = ds_list_create();
USER_LIST[1] = ds_list_create();
repeat 7 (or whatever)
{
    ds_list_add(USER_LIST[0], ds_list_find_value(PRIMARY_LIST, irandom(size));
    ds_list_add(USER_LIST[1], ds_list_find_value(PRIMARY_LIST, irandom(size));
}
Now both players have their own lists. When when the next_obj array (or whatever you decide to call it) exceeds the size of your randomized lists, just repopulate the list.
 
A

Apples

Guest
@TheouAegis This creates two lists with two random orders for each list. I'm looking for two lists with one random order for both lists.
 

TheouAegis

Member
Then use ds_copy(USER_LIST[1],USER_LIST[0]) instead of the second ds_list_add(). That will randomize the first list and copy it over to the second list so in that way each will have the same list to start.

If you want only the first lists the same, then all you need to do after a player finishes his list is to create a new one the same way for that player only. If you want both players to share the same list, then either make one super long list or do the following:

Create a new variable to hold which player finished the list first. Set it to -1;

first_out = -1;

When a player finishes the list, check if the variable is equal to the other player. If it is, copy that player's list and set the list back to -1. If it's not, create a new list and set the variable.

Code:
if first_out = myID ^ 1 //use 0 for player 1 and 1 for player 2
{
    ds_list_copy(USER_LIST[myID], USER_LIST[myID ^ 1]);
    first_out = -1;
}
else
{
    ds_list_clear(USER_LIST[myID]);
    //repopulate the list
    first_out = myID;
}
The only drawback to this method would be if the first user to finish a list is also the first to finish the next one, so then the other player will never handle that previous list.
 
Top