Database Reference
In-Depth Information
db
.
location
.
update
(
{
'_id'
:
character
[
'location'
][
'id'
] },
{
'$pull'
: {
'inventory'
: {
'id'
:
item_id
} } })
While the preceding code may be for a single-player game, if we allow multiple players or
nonplayer characters to pick up items, that introduces a problem where two characters may try
to pick up an item simultaneously. To guard against that, we can use the
location
collection
to decide between ties. In this case, the code is now the following:
def
def
pick_up_item
(
character
,
item_index
,
item_id
):
'''Transfer an item from the current room to the character's inventory'''
item
=
item_index
[
item_id
]
character
[
'inventory'
]
.
append
(
item
)
result
=
db
.
location
.
update
(
{
'_id'
:
character
[
'location'
][
'id'
],
'inventory.id'
:
item_id
},
{
'$pull'
: {
'inventory'
: {
'id'
:
item_id
} } },
safe
=
True
)
iif
not
not
result
[
'updatedExisting'
]:
raise
raise
Conflict
()
db
.
character
.
update
(
{
'_id'
:
character
[
'_id'
] },
{
'$push'
: {
'inventory'
:
item
},
'$pull'
: {
'location'
: {
'_id'
:
item
[
'id'
] } } })
By ensuring that the item is present before removing it from the room in the
update
call, we
guarantee that only one player/nonplayer character/monster can pick up the item.
Remove an Item from a Container
In the game described here, the
backpack
item can contain other items. We might further sup-
posethatsomeotheritemsmaybesimilarly hierarchical (e.g.,achestinaroom).Supposethat
the player wishes to move an item from one of these “containers” into their active
inventory
as a prelude to using it. In this case, we need to update both the character state and the item
state:
def
def
move_to_active_inventory
(
character
,
item_index
,
container_id
,
item_id
):
'''Transfer an item from the given container to the character's active
inventory