File size: 4,300 Bytes
ea72b5a | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 | # Minimal Global Functions for Puzzle8 Game
# Simple, fast, and focused on core gameplay
# Constants
SOLVED_STATE <- c(1, 2, 3, 4, 5, 6, 7, 8, 0)
# Utility functions
pos_to_coords <- function(pos) {
list(row = (pos - 1) %/% 3 + 1, col = (pos - 1) %% 3 + 1)
}
coords_to_pos <- function(row, col) {
(row - 1) * 3 + col
}
is_valid_position <- function(row, col) {
row >= 1 && row <= 3 && col >= 1 && col <= 3
}
# Create a solvable puzzle using simple shuffling
create_solvable_puzzle <- function(moves = 100) {
puzzle <- SOLVED_STATE
blank_pos <- 9
# Simple shuffling with valid moves
for(i in 1:moves) {
coords <- pos_to_coords(blank_pos)
valid_moves <- c()
# Check all four directions
directions <- list(
list(row = -1, col = 0), # Up
list(row = 1, col = 0), # Down
list(row = 0, col = -1), # Left
list(row = 0, col = 1) # Right
)
for(dir in directions) {
new_row <- coords$row + dir$row
new_col <- coords$col + dir$col
if(is_valid_position(new_row, new_col)) {
valid_moves <- c(valid_moves, coords_to_pos(new_row, new_col))
}
}
if(length(valid_moves) > 0) {
move_pos <- sample(valid_moves, 1)
# Swap tiles
temp <- puzzle[blank_pos]
puzzle[blank_pos] <- puzzle[move_pos]
puzzle[move_pos] <- temp
blank_pos <- move_pos
}
}
# Ensure puzzle is not already solved
if(identical(puzzle, SOLVED_STATE)) {
return(create_solvable_puzzle(moves + 20))
}
return(puzzle)
}
# Check if puzzle is solved
is_solved <- function(puzzle) {
identical(puzzle, SOLVED_STATE)
}
# Get blank position
get_blank_position <- function(puzzle) {
which(puzzle == 0)[1]
}
# Get valid moves for current blank position
get_valid_moves <- function(blank_pos) {
coords <- pos_to_coords(blank_pos)
valid_moves <- c()
directions <- list(
list(row = -1, col = 0), # Up
list(row = 1, col = 0), # Down
list(row = 0, col = -1), # Left
list(row = 0, col = 1) # Right
)
for(dir in directions) {
new_row <- coords$row + dir$row
new_col <- coords$col + dir$col
if(is_valid_position(new_row, new_col)) {
valid_moves <- c(valid_moves, coords_to_pos(new_row, new_col))
}
}
return(valid_moves)
}
# Move tile with validation - core game mechanic
move_tile <- function(puzzle, tile_position) {
blank_pos <- get_blank_position(puzzle)
valid_moves <- get_valid_moves(blank_pos)
if(tile_position %in% valid_moves) {
# Create new puzzle state
new_puzzle <- puzzle
new_puzzle[blank_pos] <- puzzle[tile_position]
new_puzzle[tile_position] <- 0
return(list(puzzle = new_puzzle, moved = TRUE))
}
return(list(puzzle = puzzle, moved = FALSE))
}
# Check if puzzle is solvable using inversion count
is_solvable <- function(puzzle) {
# Count inversions (excluding blank tile)
tiles <- puzzle[puzzle != 0]
inversions <- 0
for(i in 1:(length(tiles) - 1)) {
for(j in (i + 1):length(tiles)) {
if(tiles[i] > tiles[j]) {
inversions <- inversions + 1
}
}
}
# For 3x3 puzzle, solvable if inversions are even
return(inversions %% 2 == 0)
}
# Validate puzzle state
validate_puzzle <- function(puzzle) {
# Check length
if(length(puzzle) != 9) {
return(FALSE)
}
# Check if all numbers 0-8 are present exactly once
expected_tiles <- 0:8
if(!setequal(puzzle, expected_tiles)) {
return(FALSE)
}
# Check if solvable
if(!is_solvable(puzzle)) {
return(FALSE)
}
return(TRUE)
}
# Generate test puzzles for development
generate_test_puzzles <- function(n = 5) {
puzzles <- list()
for(i in 1:n) {
repeat {
puzzle <- create_solvable_puzzle()
if(validate_puzzle(puzzle) && !is_solved(puzzle)) {
puzzles[[i]] <- puzzle
break
}
}
}
return(puzzles)
}
# Simple puzzle statistics
get_puzzle_stats <- function(puzzle) {
blank_pos <- get_blank_position(puzzle)
valid_moves <- get_valid_moves(blank_pos)
return(list(
blank_position = blank_pos,
valid_moves = valid_moves,
num_valid_moves = length(valid_moves),
is_solved = is_solved(puzzle),
is_valid = validate_puzzle(puzzle)
))
} |