# Python代写 | CSSE1001/CSSE7030 Sliding Puzzle Game Assignment 1

‘”””
Sliding Puzzle Game
Assignment 1
Semester 1, 2021
CSSE1001/CSSE7030
“””
from typing import Optional
import math

from a1_support import *

# Replace these <strings> with your name, student number and email address.

def shuffle_puzzle(solution: str) -> str:
“””
Shuffle a puzzle solution to produce a solvable sliding puzzle.

Parameters:
solution (str): a solution to be converted into a shuffled puzzle.

Returns:
(str): a solvable shuffled game with an empty tile at the
bottom right corner.

Note: This function uses the swap_position function that you have to
implement on your own. Use this function when the swap_position
“””
shuffled_solution = solution[:-1]

# Do more shuffling for bigger puzzles.
swaps = len(solution) * 2
for _ in range(swaps):
# Pick two indices in the puzzle randomly.
index1, index2 = random.sample(range(len(shuffled_solution)), k=2)
shuffled_solution = swap_position(shuffled_solution, index1, index2)

return shuffled_solution + EMPTY

def check_win(puzzle: str, solution: str) -> bool:
“””
Check whether the puzzle is solved. puzzle is solved when every tile is
filled with a letter same as solution except the bottom right corner,
bottom right corner should be empty.
Parameters:
puzzle (str): puzzle string
solution (str): solution of the puzzle
Returns:
(bool): true if puzzle is solved, false otherwise

>>> check_win(“abcdefgh “, “abcdefghi”)
True
>>> check_win(“dabecghf “, “abcdefghi”)
False
“””
if len(puzzle) != len(solution):
return False
if puzzle[-1] != ‘ ‘:
return False
# traverse the puzzle, compare each tile with solution
for i in range(len(puzzle) – 1):
if puzzle[i] != solution[i]:
return False
return True

def swap_position(puzzle: str, from_index: int, to_index: int) -> str:
“”” Swaps the positions of the characters at from_index and to_index
in the puzzle and returns the updated puzzle.
>>> swap_position(“care”, 0, 2)
‘race’
>>> swap_position(“does”, 3, 2)
‘dose’
“””
# handle edge case that from_index equals to to_index
if from_index == to_index:
return puzzle
# make sure that from_index is less than to_index
if from_index > to_index:
return swap_position(puzzle, to_index, from_index)
letter_in_puzzle = []
for i in range(len(puzzle)):
if i == from_index:
letter_in_puzzle.append(puzzle[to_index])
elif i == to_index:
letter_in_puzzle.append(puzzle[from_index])
else:
letter_in_puzzle.append(puzzle[i])
return “”.join(letter_in_puzzle)

def move(puzzle: str, direction: str) -> Optional[str]:
“”” Moves the empty tile in the given direction and returns the updated
puzzle. If the move cannot be made (i.e. moving in the given direction
results in the empty tile being outside the grid), it returns None.
>>> move(“abcdefgh “, “U”)
‘abcde ghf’
>>> move(“abcdefgh “, “R”)
“””
# valid moves
valid_moves = [‘U’, ‘D’, ‘L’, ‘R’]
if direction not in valid_moves:
return None
# get the size of the grid
grid_size = int(math.sqrt(len(puzzle)))

# find the index of the empty tile
empty_tile_index = 0
for i in range(len(puzzle)):
if puzzle[i] == ‘ ‘:
empty_tile_index = i
break
# transform the index to coordinate
x, y = empty_tile_index // grid_size, empty_tile_index % grid_size
# invalid moves
if (x == 0 and direction == UP) or \
(x == grid_size – 1 and direction == DOWN) or \
(y == 0 and direction == LEFT) or \
(y == grid_size – 1 and direction == RIGHT):
return None
# calculate the target coordinate of the empty tile
if direction == UP:
x = x – 1
elif direction == DOWN:
x = x + 1
elif direction == LEFT:
y = y – 1
elif direction == RIGHT:
y = y + 1
target_index = x * grid_size + y
return swap_position(puzzle, empty_tile_index, target_index)

def print_grid(puzzle: str) -> None:
“”” Displays the puzzle in a user-friendly format.
>>> print_grid(“nevagonagiveu up”)
+—+—+—+—+
| n | e | v | a |
+—+—+—+—+
| g | o | n | a |
+—+—+—+—+
| g | i | v | e |
+—+—+—+—+
| u | | u | p |
+—+—+—+—+
>>> print_grid(“nevergonnalet udooooowwwn”)
+—+—+—+—+—+
| n | e | v | e | r |
+—+—+—+—+—+
| g | o | n | n | a |
+—+—+—+—+—+
| l | e | t | | u |
+—+—+—+—+—+
| d | o | o | o | o |
+—+—+—+—+—+
| o | w | w | w | n |
+—+—+—+—+—+
“””
# get the size of the grid
grid_size = int(math.sqrt(len(puzzle)))
line_sep = (HORIZONTAL_WALL * 3).join(
[CORNER for i in range(grid_size + 1)])
print(line_sep)
for i in range(grid_size):
current_row = VERTICAL_WALL
for j in range(grid_size):
current_row += “{:^3}”.format(puzzle[i * grid_size + j])
current_row += VERTICAL_WALL
print(current_row)
print(line_sep)

def print_solution_and_puzzle(solution: str, puzzle: str) -> None:
“””Display the solution and puzzle in a user-friendly format”””
print(“Solution”)
print_grid(solution)
print(“\nCurrent position:”)
print_grid(puzzle)
print()

def main():
“””Entry point to gameplay”””
# print welcome message
print(WELCOME_MESSAGE)
# add all valid instructions into a list
valid_instructions = [UP, DOWN, LEFT, RIGHT, HELP, GIVE_UP]
# loop until user doesn’t want to play again
while True:
# handle the input of difficulty
grid_size = int(input(BOARD_SIZE_PROMPT))
# initialize a new game
solution = get_game_solution(WORDS_FILE, grid_size)
puzzle = shuffle_puzzle(solution)
while True:
print_solution_and_puzzle(solution, puzzle)
instruction = input(DIRECTION_PROMPT)
# check whether the instruction is valid
if instruction not in valid_instructions:
print(INVALID_MESSAGE)
continue
# handle the HELP instruction and GIVE_UP instruction
if instruction == HELP:
print(HELP_MESSAGE)
continue
if instruction == GIVE_UP:
print(GIVE_UP_MESSAGE)
break
after_move = move(puzzle, instruction)
# if after_move is None, then the move is a invalid move
if after_move is None:
print(INVALID_MOVE_FORMAT.format(instruction))
continue
if check_win(after_move, solution):
print(WIN_MESSAGE)
break
puzzle = after_move
continue_or_not = input(PLAY_AGAIN_PROMPT)
if continue_or_not.lower() == ‘y’:
continue
else:
print(BYE)
break

if __name__ == “__main__”:
main()

E-mail: itcsdx@outlook.com  微信:itcsdx