Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lights out #1273

Merged
merged 3 commits into from May 22, 2023
Merged

lights out #1273

merged 3 commits into from May 22, 2023

Conversation

kostmo
Copy link
Member

@kostmo kostmo commented May 20, 2023

See https://en.wikipedia.org/wiki/Lights_Out_(game)

image

The seed is not fixed; random valid games are generated and can be solved automatically via the provided solution.

One can use the solution strategy described here.

mergify bot pushed a commit that referenced this pull request May 20, 2023
# Summary

This PR allows a recipe's effects to be applied within the same tick if `time: 0` is specified for the recipe.

The previous behavior was that if the `time` of the recipe was zero, it would nonetheless behave the same as `time: 1`, and the entity updates would not be applied until the next tick.

This new behavior is useful when "abusing" the `drill` command to emulate various other games via help from a system robot.

# Motivation
For the "Lights Out" game (#1273) I have implemented a system robot that `instant`-ly toggles the four adjacent lights and the center light when a center light is `drill`-ed by the player.  The light entities are named `"off"` and `"on"`.

I did some experiments to see if the system robot would react "fast enough" if the player drilled quickly in succession.

# Experiments

The 5x5 light grid is initially `"off"`.  I moved the player robot to the center of the grid, facing `east`. From this position, I tried three command sequence variations both *before* and *after* this PR.  The recipes for toggling lights specify `time: 0`.

## Before this PR

### 1. Drilling twice in succession

    drill down; drill left;

This resulted in an error:
![no-instant-error-message](https://github.com/swarm-game/swarm/assets/261693/f22a0a28-5df7-4fe8-ac18-97504d64e3c8)

so only the first `drill` got applied:

![no-instant](https://github.com/swarm-game/swarm/assets/261693/2d9e4ba7-c138-4dcb-94a6-3c7bb14ddd68)

This is because I believe the sequence of events was:

| Tick / Robot | Action |
| --- | --- |
| **Tick 1:** Player | Execute the first `drill` command, queue entity modification |
| **Tick 1:** System | No changes observed |
| **Tick 2:** Player | Entity modification from first `drill` is applied.  Execute second `drill` command, queue second entity modifications |
| **Tick 2:** System | Observe modified entity, toggle the adjacent lights |
| **Tick 3:** Player | Try to apply entity modification from second `drill` command. Throw an error because the system robot has toggled the drill's target entity to `on` whereas the `drill` was initially executed when it was still `off`. |

### 2. Instant for both drills

    instant $ (drill down; drill left)

In this case, both of the player's `drill` commands were executed, but the system robot then failed to doubly-invert one of the cells:

![instant-both-drills](https://github.com/swarm-game/swarm/assets/261693/65642fd6-3cea-4834-96fd-404da7628c66)

This is due to some kind of race condition in the system robot's logic.  However, it is irrelevant because the `instant` command shall not be available to the player.

### 3. Instant for first drill only, then second drill

    instant (drill down); drill left;

This accomplished what approach number 1 was supposed to; both drill commands were applied and the two overlapping cells got properly inverted:

![instant-first-drill](https://github.com/swarm-game/swarm/assets/261693/64aab681-140d-457a-9273-943ae5b4d58d)

**Explanation:** In this case, the entire drilling operation (including applying all effects to entities on the ground) was completed within the player's first tick, so the system robot updated the lights appropriately on its turn.  Then, in the next tick the player robot applied another drill command, and again the system robot appropriately did another inversion on the two overlapping middle cells.

## After this PR

### 1. Drilling twice in succession

    drill down; drill left;

Now works as expected:

![after-no-instant](https://github.com/swarm-game/swarm/assets/261693/538767d3-9832-4e5c-996e-12a9b7a2015c)

### 2. and 3.

Behaved identically to before the PR.
@kostmo kostmo force-pushed the scenario/lights-out branch 2 times, most recently from d306d59 to db1bd9c Compare May 22, 2023 02:15
@kostmo kostmo marked this pull request as ready for review May 22, 2023 02:16
@kostmo kostmo requested a review from byorgey May 22, 2023 02:16
Copy link
Member

@byorgey byorgey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice! I was able to solve it manually. Tried coding up an automated solution and came up with the "chasing lights" idea but then wasn't sure what to do when there were lights left in the last row. Then I read the links in the solution and I learned a lot of interesting things about this puzzle. 😄

case maybePending return $ flipSelfAndNeighbors state;
end;

def observe = \boardWidth. \boardHeight.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function doesn't seem to use boardWidth and boardHeight at all?

togglePending "on";
togglePending "off";
);
observe boardWidth boardHeight;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe insert a wait 1 here? As it is, I think it may do the instant call multiple times in one tick, until it uses up its step allotment. It's not a big deal but I think it would be cleaner/more efficient to wait 1 before the recursive call.

@kostmo kostmo added the merge me Trigger the merge process of the Pull request. label May 22, 2023
@mergify mergify bot merged commit 2633403 into main May 22, 2023
9 checks passed
@mergify mergify bot deleted the scenario/lights-out branch May 22, 2023 17:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
merge me Trigger the merge process of the Pull request.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants