Title: | Implementation of the 'Lights Out' Puzzle Game |
---|---|
Description: | Lights Out is a puzzle game consisting of a grid of lights that are either on or off. Pressing any light will toggle it and its adjacent lights. The goal of the game is to switch all the lights off. This package provides an interface to play the game on different board sizes, both through the command line or with a visual application. Puzzles can also be solved using the automatic solver included. View a demo online at <https://daattali.com/shiny/lightsout/>. |
Authors: | Dean Attali [aut, cre] |
Maintainer: | Dean Attali <[email protected]> |
License: | MIT + file LICENSE |
Version: | 0.3.2 |
Built: | 2024-11-12 02:39:53 UTC |
Source: | https://github.com/daattali/lightsout |
Get the board entries (configuration of the lights)
board_entries(board)
board_entries(board)
board |
A |
A matrix representing the current state of the lights (0 for off, 1 for on) in the board
board <- random_board(5) board board_entries(board)
board <- random_board(5) board board_entries(board)
Initialize a Lights Out board with all lights switched off
empty_board(size, classic = TRUE)
empty_board(size, classic = TRUE)
size |
Number of rows and columns for the board |
classic |
If |
A lightsout
board.
empty_board(5)
empty_board(5)
Not every Lights Out configuration has a solution (this has been mathematically proven). This function determines whether a given board has a solution or not.
is_solvable(board)
is_solvable(board)
board |
A |
TRUE
if the given board has a solution; FALSE
otherwise.
# The following board is solvable using the classic mode (only adjacent lights # are toggled), but has no solution in the variant mode. lights <- c(1, 1, 0, 1, 0, 0, 0, 0, 0 ) board_classic <- new_board(lights) board_variant <- new_board(lights, classic = FALSE) is_solvable(board_classic) is_solvable(board_variant)
# The following board is solvable using the classic mode (only adjacent lights # are toggled), but has no solution in the variant mode. lights <- c(1, 1, 0, 1, 0, 0, 0, 0, 0 ) board_classic <- new_board(lights) board_variant <- new_board(lights, classic = FALSE) is_solvable(board_classic) is_solvable(board_variant)
A board is considered solved if all the lights are switched off (have a state of 0
).
is_solved(board)
is_solved(board)
board |
A |
TRUE
if the given board is solved; FALSE
otherwise.
# Create a board solved with one move and solve it. lights <- c(1, 1, 0, 1, 0, 0, 0, 0, 0 ) board <- new_board(lights) is_solved(board) board <- board %>% play(1, 1) is_solved(board)
# Create a board solved with one move and solve it. lights <- c(1, 1, 0, 1, 0, 0, 0, 0, 0 ) board <- new_board(lights) is_solved(board) board <- board %>% play(1, 1) is_solved(board)
Run the graphical interface to the game in a web browser
launch()
launch()
Create a Lights Out board that can be played by the user or solved automatically.
Only square boards of size 3x3, 5x5, 7x7, or 9x9 are supported. The initial
lights configuration must be provided. To create a board with a random
configuration, use the random_board
function.
new_board(entries, classic = TRUE)
new_board(entries, classic = TRUE)
entries |
The initial configuration of lights on the board. |
classic |
If |
A lightsout
board object.
vector <- c(1, 1, 0, 1, 0, 1, 0, 1, 1) new_board(entries = vector) matrix <- matrix( c(1, 1, 0, 1, 0, 1, 0, 1, 1), nrow = 3, byrow = TRUE) new_board(entries = matrix)
vector <- c(1, 1, 0, 1, 0, 1, 0, 1, 1) new_board(entries = vector) matrix <- matrix( c(1, 1, 0, 1, 0, 1, 0, 1, 1), nrow = 3, byrow = TRUE) new_board(entries = matrix)
In classic mode, pressing a light will toggle it and its four adjacent lights. In variant mode, pressing a light will toggle it and all other lights in its row and column. Toggling a light means switching it from on to off or from off to on.
play(board, row, col, matrix)
play(board, row, col, matrix)
board |
A |
row |
The row of the light to press. To press multiple lights, use a list
of row numbers. If a list is provided, then the |
col |
The column of the light to press. To press multiple lights, use a list
of column numbers. If a list is provided, then the |
matrix |
Instead of using |
A new lightsout
board object after the given lights are pressed.
solve_board
empty_board
new_board
random_board
# Create a 5x5 board with all lights switched off and then press some lights board <- empty_board(5) board # Press the light at (2,1) newboard <- play(board, 2, 1) newboard # Press the light at (2,1) and then at (3,4) newboard <- board %>% play(2, 1) %>% play(3, 4) newboard # Press both lights with one call newboard <- play(board, c(2, 3), c(1, 4)) newboard # Press both lights using a matrix instead of specifying rows and columns newboard <- play(board, matrix = matrix( c(0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), nrow = 5, byrow = TRUE)) newboard # Press the same lights, but this time when the game mode is not classic, # and the whole row/column get toggled empty_board(5, classic = FALSE) %>% play(2, 1) empty_board(5, classic = FALSE) %>% play(c(2, 3), c(1, 4))
# Create a 5x5 board with all lights switched off and then press some lights board <- empty_board(5) board # Press the light at (2,1) newboard <- play(board, 2, 1) newboard # Press the light at (2,1) and then at (3,4) newboard <- board %>% play(2, 1) %>% play(3, 4) newboard # Press both lights with one call newboard <- play(board, c(2, 3), c(1, 4)) newboard # Press both lights using a matrix instead of specifying rows and columns newboard <- play(board, matrix = matrix( c(0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), nrow = 5, byrow = TRUE)) newboard # Press the same lights, but this time when the game mode is not classic, # and the whole row/column get toggled empty_board(5, classic = FALSE) %>% play(2, 1) empty_board(5, classic = FALSE) %>% play(c(2, 3), c(1, 4))
Create a Lights Out board that can be played by the user or solved automatically.
Only square boards of size 3x3, 5x5, 7x7, or 9x9 are supported. The initial
lights configuration is randomly generated, but always solvable. To create a
board with a user-defined configuration, use the new_board
function.
random_board(size, classic = TRUE)
random_board(size, classic = TRUE)
size |
Number of rows and columns for the board |
classic |
If |
A lightsout
board object.
set.seed(10) # Create a random 5x5 classic board board <- random_board(5) board # Get the solution for the board solution <- solve_board(board) solution # Press the lights according to the solution, the result should be a board # with all lights switched off play(board, matrix = solution)
set.seed(10) # Create a random 5x5 classic board board <- random_board(5) board # Get the solution for the board solution <- solve_board(board) solution # Press the lights according to the solution, the result should be a board # with all lights switched off play(board, matrix = solution)
Given a Lights Out board, find the set of lights that need to be pressed in order to solve the board. If no solution is possible, an error is thrown.
solve_board(board)
solve_board(board)
board |
A |
There are a few algorithms for solving Lights Out puzzles. This function implements the Gaussian Elimination technique, which does not guarantee the minimum number of steps. Therefore, some steps in the given solution may be redundant.
If you are interested, there are many resources online outlining the exact details of how this technique works, and what the other solving strategies are.
A matrix with the same dimensions as the input board, with a 1
in every position that requires a press to solve to the board. Note that the
order of the light presses does not matter.
new_board
random_board
play
is_solvable
is_solved
# Create an empty 5x5 board, press two lights, and then see that the solution # tells us to press the same lights in order to solve the board. board <- empty_board(5) %>% play(3, 2) %>% play(4, 1) board solution <- solve_board(board) solution board <- play(board, matrix = solution) is_solved(board)
# Create an empty 5x5 board, press two lights, and then see that the solution # tells us to press the same lights in order to solve the board. board <- empty_board(5) %>% play(3, 2) %>% play(4, 1) board solution <- solve_board(board) solution board <- play(board, matrix = solution) is_solved(board)