2 releases
new 0.1.1 | Jan 12, 2025 |
---|---|
0.1.0 | Jan 11, 2025 |
#86 in Games
39 downloads per month
Used in parabox-parser
56KB
1K
SLoC
Parabox
Parabox is a single-player puzzle game where you control a box that can only move in one direction at a time. The goal is to move the box to the target positions. This repository provides a Rust implementation of the game logic.
Overview
The game is about pushing blocks. Players can control one of the blocks and move it to push others. The goal is to move the blocks to the target.
The game world is completely made up of blocks. Some blocks have internal structures, squares of given sizes, and may contain other blocks. A block may be contained in itself.
In a game, each block is contained in a block, so the position of a block can be described by its container and the coordinates inside the container. Blocks that are not contained in any block are said to be_orphans_.
The basic block types are wall and box, where a wall has no internal structures and cannot be pushed, while a box is the contrast.
Each time a box is pushed, it will try to move to the target position. If the position is taken by another box, it will be pushed together. If it is blocked by a wall, then the pushing will fail, and nothing happens.
Also, when a box is pushed out of the boundary, it will be pushed out of the container and become a brother of the container (i.e., a child of the container of its container). It is suddenly largened and comes out of the container.
Conversely, when a box pushes another box into a wall, the first box will then try to enter the second box, becoming a child of it.
Finally, if the entering also fails (because it might be blocked by something inside the second box), the first box will try to eat the second block, by letting the second box become a child of it.
In conclusion, a block can push, exit, enter and eat. These are the four basic movements in the game.
Usage
World
: The game world that contains all the blocks. Use this struct to manage the blocks and perform game operations.ProtoType
: The prototype of a block. Use this enum to create a block.BlockKey
: The key of a block. Generated by the world when creating a block. Used to refer to the generated block.Position
: The position of a block.Direction
: The direction of a movement.
use parabox::{Direction, Position, ProtoType, World};
fn main() {
let mut world = World::new();
let container = world.insert(ProtoType::Box { size: (5, 5) });
let player = world.insert(ProtoType::Box { size: (1, 1) });
let block = world.insert(ProtoType::Box { size: (1, 1) });
{
// Make `player` solid by placing a wall in it
let wall = world.insert(ProtoType::Wall);
world.place(wall, Position::inside(player, (0, 0)));
}
{
// Make `block` solid by placing a wall in it
let wall = world.insert(ProtoType::Wall);
world.place(wall, Position::inside(block, (0, 0)));
}
world.place(player, Position::inside(container, (0, 2)));
world.place(block, Position::inside(container, (1, 2)));
let result = world.push(player, Direction::East).expect("push failed");
assert!(result, "the blocks remain static");
assert_eq!(world.position(player), Position::inside(container, (1, 2)));
assert_eq!(world.position(block), Position::inside(container, (2, 2)));
}
Script
The game provides a script language to describe the game world and the operations. Use crate
parabox-parser
to parse and execute the script. Here is an example of the script:
DEFINE BOX #container size (3, 3)
DEFINE BOX #box1 solid
DEFINE BOX #box2 size (3, 3)
DEFINE WALL #wall
PLACE #box1 at (0, 1) in #container
PLACE #box2 at (1, 1) in #container
PLACE #wall at (2, 1) in #container
PUSH #box1 east MOVED
EXPECT #box1 at (0, 1) in #box2
EXPECT #box2 at (1, 1) in #container
See more information in the crate parabox-parser
.
Crates
parabox
: The core library of the game.parabox-parser
: A parser for the Parabox script language.
License
The project is license under the Apache-2.0 license. See the LICENSE file for details.
Dependencies
~0.8–1.4MB
~26K SLoC