User: its asking for input twice, and the other problem still persists:

from game_settings import *
from copy import deepcopy

original_board = deepcopy(board)

def print_board(board):
    for row in board:
        print(' '.join(row))

def find_sprite(board):
    global SPRITE
    global SPRITE_T
    for row_index, row in enumerate(board):
        for col_index, col in enumerate(row):
            if SPRITE in col or SPRITE_T in col:
                return row_index, col_index

def move(board, row1, col1, row2, col2, direction):
    if board[row2][col2] in [BOX_NS, BOX_S]:
        next_row, next_col = get_da_target(row2, col2, direction)
        if board[next_row][next_col] in [EMPTY, TARGET]:
            if board[row2][col2] == BOX_NS:
                if board[next_row][next_col] == TARGET:
                    board[next_row][next_col] = BOX_S
                else:
                    board[next_row][next_col] = BOX_NS
            elif board[row2][col2] == BOX_S:
                board[next_row][next_col] = BOX_S
            else:
                board[next_row][next_col] = board[row2][col2]
            if board[row2][col2] == BOX_S:
                board[row2][col2] = TARGET
            else:
                board[row2][col2] = EMPTY

    if board[row1][col1] == SPRITE_T:
        board[row1][col1] = TARGET
    else:
        board[row1][col1] = EMPTY

    if board[row2][col2] == TARGET:
        board[row2][col2] = SPRITE_T
    else:
        board[row2][col2] = SPRITE
    

def get_da_target(row, col, direction):
    if direction == 'w':
        return row - 1, col
    elif direction == 'a':
        return row, col - 1
    elif direction == 's':
        return row + 1, col 
    elif direction == 'd':
        return row, col + 1
    else:
        return row, col

def valid_or_nah(board, target_row, target_col, direction):
    if target_row < 0 or target_row >= len(board) or target_col < 0 or target_col >= len(board[0]):
        return False
    if board[target_row][target_col] == 'WALL':
        return False
    if board[target_row][target_col] in [EMPTY, TARGET]:
        return True
    if board[target_row][target_col] in [BOX_S, BOX_NS]:
        next_row, next_col = get_da_target(target_row, target_col, direction)
        if next_row < 0 or next_row >= len(board) or next_col < 0 or next_col >= len(board[0]) or board[next_row][next_col] not in [EMPTY, TARGET]:
            return False
        return True 
    return False
    
def win_condition(board):
    count = 0
    for row in board:
        if BOX_S in row:
            count += 1
    if count == 3:
        return True
    else:
        return False

def reset():
    global board
    board = deepcopy(original_board)

while True:
    
    theinput = input()
    if theinput == 'q':
        print('Goodbye')
        reset()
        break
    elif theinput in ['W', 'A', 'S', 'D', 'w', 'a', 's', 'd', 'q']:
        print_board(board)
    else:    
        while theinput not in ['W', 'A', 'S', 'D', 'w', 'a', 's', 'd', 'q']:
            theinput = input('enter a valid move:\n')
        continue

    row4sprite, col4sprite = find_sprite(board)
    target_row, target_col = get_da_target(row4sprite, col4sprite, theinput)

    if valid_or_nah(board, target_row, target_col, theinput):
        move(board, row4sprite, col4sprite, target_row, target_col, theinput)

    if win_condition(board):
        print_board(board)

        print('You won!')
        reset()
        break




zyBooks
My library
>
I&C SCI 31: Introduction to Programming home
>
12.1: F24: ZyProject1: Sokoban
zyBooks catalog
Help/FAQ
Quazi Zia
11.19 Lecture: Gi Tu Tong Long

Instructor created
12.1 F24: ZyProject1: Sokoban
lab activity
12.1.1: ZyProject1: Sokoban


11 / 20
N|Solid

Lab Exam Instructions
CODING ENVIRONMENT:

 ALL WORK/EDITS MUST BE COMPLETED WITHIN THE ZYBOOKS IDE. Do not program or write code you intend to use in any other environment.


PROJECT OVERVIEW VIDEO: 

The videos were getting long... so I broke them up into 2 parts:
Sokoban Project Overview
How to use VSC Debugging Features (plus some other helpful project hints)


SUPPORT RESOURCES

For this project, you may reference notes and other course materials. 
You may not use ChatGPT or any other LLM. You may receive help from ICS 31 staff(ICS31 Office/Support Hours), tutors at the ICS Tutoring Center, and in your scheduled lab sections.   



DEADLINES:

This project is due on Friday 11/22 at 11:59 pm. Any submissions made after Friday, up to Saturday at 11:59PM, will receive a 20% score deduction. 

IMPORTANT: if you've achieved your desired score, DO NOT resubmit on Saturday. ZyBooks will report your last submission date/time as Saturday, and your project will incur the 20% penalty.



A Word on Plagiarism & AI Detection

Please remember that as computer science instructors, we care about academic dishonesty as strongly as our peers in other fields of study. Unlike our peers, however, our field of expertise and the nature of the material allow us to create tools that enhance our detection of plagiarism. I'm sure you have heard of similar tools, such as TurnItIn.com and other plagiarism detection systems for essays. Since our field is more mathematical, however, we are capable of considering not only the actual text written on the screen but also the overall flow and intent of the program and mathematically compare it to that of another to determine the level of similarity between the two. As you have seen from our in-class programming activities, there are many ways to code, even a simple algorithm. Therefore, high degrees of similarity indicate collaboration. We highly suggest that you do not "collaborate" with anyone else, as we will be able to detect it. If you are detected engaging in Academic Dishonesty, you will receive an automatic zero in the class, and your case will be sent to the Office of Academic Integrity & Student Conduct. Also, if a substantial number of cases are detected, we reserve the right to cancel the final project of the quarter, and the remaining project grade will be split amongst the in-lab exam scores(increasing each lab exam's percentage). With that being said, let's all take a deep breath and try to have some fun!  

Preamble
At this point in the course, you have enough knowledge about Python to do more than you think. Many simple games, for example, can be written with what we've already covered. So let's do it! Let's create a game of Sokoban!

Concepts being tested
Data Structures
Nested Lists
Potentially Dictionaries
Branching
Loops
For/While loops
Nested Loops
Critical thinking, planning, & organization
The Game
If you're unfamiliar with the game, try your hand at it here (spend a few minutes learning the game's rules). The game's object is to move all the boxes onto a target.

So we're all on the same page, let's establish how the game works. The game has 4 controls:

w - move the sprite up
s - move the sprite down
a - move the sprite left
d - move the sprite right
q - quit the game
space - reset the board
These controls are also outlined in the provided game_settings.py file.

The sprite (i) can move in empty spaces on the board but cannot pass through walls (+). It can push a single box (!) into an empty or target (o) space but cannot push more than one at a time. In other words, boxes cannot be pushed into other boxes or walls. Pushing the box right:

+ + + + + + + +
+   .         +
+   i !   o   +
+       !   o +
+             +
+ + + + + + + +
results in this board:

+ + + + + + + +
+   .         +
+     i ! o   +
+       !   o +
+             +
+ + + + + + + +
When the box is pushed onto a target, it is converted from a non-statisfied box (!) into a satisfied box (.). Moving the sprite right once more, does exactly that:

+ + + + + + + +
+   .         +
+       i .   +
+       !   o +
+             +
+ + + + + + + +
Note that satisfied boxes (.) can be moved off the target and convert back into non-statisfied boxes (!). Additionally, when the sprite stands on a target space, its string is changed to indicate a target is below (I):

+ + + + + + + +
+   .         +
+         I ! +
+       !   o +
+             +
+ + + + + + + +
Once the sprite moves off the target, both spaces revert back (I to i and o):

+ + + + + + + +
+   .     i   +
+         o ! +
+       !   o +
+             +
+ + + + + + + +
The game ends when a win is detected, or the user quits the program

Quitting prints the message: "Goodbye"
Winning prints the message: "You Win!"
General Structure of the Program
When boiled down, most simple games have the same repeated set of actions:

the program provides information about the current game state to the player
the user takes action through input
the program reacts
the program identifies the input
the program updates the game state
repeat forever, or until the user wins or loses
This loop is often referred to as the game loop, and is where the bulk of the game's code lives. Generally, there are things the program must do before the game starts and after it ends:

Preparation; initialize counter variables and copies of important information
Game Loop
Exit Protocol
main.py
This file is where you will write Sokoban.

game_settings.py
This is a read-only file that provides global variables for the different space types (sprite, empty space, box, etc.), valid user controls, and the game board. To pass all test cases, ensure you use these variables throughout your code, as some test cases will change their values and will expect your code to adapt. Your program should be using the board that is given in this file. More information on the TEST_CASE_15_BOARD will be given later on in the write-up.

Quick Tips
Do not use exit() or quit() as doing so will make test cases 15 & 16 fail whether your game works properly or not.

Do not use the following if statement in your main.py module:

if __name__ == "__main__":
Suggestions

Things to consider before developing your program:

How can you easily find or track the sprite location to avoid repetitive searches?
Can you do the same for tracking the win condition?
Can you generalize your logic so that regardless of the direction of the movement, the code is the same?
What do you need to reset the game? HINT: take a look at the copy/deepcopy functions on your reference sheet.
Sample Game:
+ + + + + + + +
+   .         +
+ i   !   o   +
+       !   o +
+             +
+ + + + + + + +

d (Player moves right)
+ + + + + + + +
+   .         +
+   i !   o   +
+       !   o +
+             +
+ + + + + + + +

d
+ + + + + + + +
+   .         +
+     i ! o   +
+       !   o +
+             +
+ + + + + + + +

d (Player pushes the box onto the target, converting the BOX_NS into BOX_S)
+ + + + + + + +
+   .         +
+       i .   +
+       !   o +
+             +
+ + + + + + + +

d (Player pushes the box off the target, converting BOX_S to BOX_NS, and steps onto the target, converting SPRITE into SPRITE_T)
+ + + + + + + +
+   .         +
+         I ! +
+       !   o +
+             +
+ + + + + + + +

  (Player resets the game)
+ + + + + + + +
+   .         +
+ i   !   o   +
+       !   o +
+             +
+ + + + + + + +

d
+ + + + + + + +
+   .         +
+   i !   o   +
+       !   o +
+             +
+ + + + + + + +

d
+ + + + + + + +
+   .         +
+     i ! o   +
+       !   o +
+             +
+ + + + + + + +

w
+ + + + + + + +
+   . i       +
+       ! o   +
+       !   o +
+             +
+ + + + + + + +

d
+ + + + + + + +
+   .   i     +
+       ! o   +
+       !   o +
+             +
+ + + + + + + +

s (Player attempts to push more than one box)
+ + + + + + + +
+   .   i     +
+       ! o   +
+       !   o +
+             +
+ + + + + + + +

a
+ + + + + + + +
+   . i       +
+       ! o   +
+       !   o +
+             +
+ + + + + + + +

s
+ + + + + + + +
+   .         +
+     i ! o   +
+       !   o +
+             +
+ + + + + + + +

d
+ + + + + + + +
+   .         +
+       i .   +
+       !   o +
+             +
+ + + + + + + +

a
+ + + + + + + +
+   .         +
+     i   .   +
+       !   o +
+             +
+ + + + + + + +

s
+ + + + + + + +
+   .         +
+         .   +
+     i !   o +
+             +
+ + + + + + + +

d
+ + + + + + + +
+   .         +
+         .   +
+       i ! o +
+             +
+ + + + + + + +

d  (Player satisfies last box, satisfying the win condition and terminating the game)
+ + + + + + + +
+   .         +
+         .   +
+         i . +
+             +
+ + + + + + + +
You Win!
Test Case 15
Test case #15 tests your project using a more intricate game board. It is common for students to successfully pass test cases 1-14, which utilize a simpler board, but encounter difficulties with test case #15, which may expose unforeseen scenarios. The game board utilized for this test case is available in the game_settings.py file, specifically labeled as TEST_CASE_15_BOARD. If you encounter challenges with test case #15, we recommend replacing your current game board with TEST_CASE_15_BOARD and run with the provided input below. With the input below, your game should end as the inputs lead to a win. This approach can aid in identifying and resolving any errors in your project. 

NOTE: Each character should be its own input in order from left to right. The space in between both d's is meant to be a space input to reset the board. You can cut and paste the input below into the VSC input console, and the IDE will read each input automatically as the program executes.
a
d
d
d
d
w
d
s
a
a
s
d
 
d
w
d
d
s
s
s
s
a
s
d
w
w
w
w
a
a
a
d
s
d
s
d
s
s
a
a
s
a
a
w
w
s
d




Submit for grading
Coding trail of your work

What is this?
11/19
T

0

,0

,0

,0

,0

,0

,0

,0

,0

,1

,1

,1

,1

,1
W

10

,10

,10

,10

,11

,0

,0

,11

,11

,5
min:84
Latest submission - 2:28 PM PST on 11/20/24

Total score: 5 / 20

Open submission's code
1: Basic Print and Quit Functionality
1 / 1
Compare output

Input
q
Your Output
Expected output
+ + + + + + + +
+   .         +
+ i   !   o   +
+       !   o +
+             +
+ + + + + + + +
Goodbye
+ + + + + + + +
+   .         +
+ i   !   o   +
+       !   o +
+             +
+ + + + + + + +
Goodbye
2: Different Board Played to Completion
0 / 200
Tests the output of a game on a different board. Uses ALL mechanics previously tested.

This test case's results were hidden by the instructor
Feedback
3: Different Board Played to Completion 2
0 / 300
Tests the output of a game on a different board. Uses ALL mechanics previously tested.

This test case's results were hidden by the instructor
Feedback
4: Different Board Characters
0 / 100
Changes the strings used on the board in game_settings.

This test case's results were hidden by the instructor
Feedback
5: Invalid Input
1 / 1
Compare output

Input
8
j
\
q
Your Output
Expected output
+ + + + + + + +
+   .         +
+ i   !   o   +
+       !   o +
+             +
+ + + + + + + +
enter a valid move:
enter a valid move:
enter a valid move:
Goodbye
+ + + + + + + +
+   .         +
+ i   !   o   +
+       !   o +
+             +
+ + + + + + + +
enter a valid move:
enter a valid move:
enter a valid move:
Goodbye
6: Basic Horizontal Movement
1 / 1
Compare output

Input
d
a
q
Your Output
Expected output
+ + + + + + + +
+   .         +
+ i   !   o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .         +
+   i !   o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .         +
+ i   !   o   +
+       !   o +
+             +
+ + + + + + + +
Goodbye
+ + + + + + + +
+   .         +
+ i   !   o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .         +
+   i !   o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .         +
+ i   !   o   +
+       !   o +
+             +
+ + + + + + + +
Goodbye
7: Basic Vertical Movement
1 / 1
Compare output

Input
w
s
q
Your Output
Expected output
+ + + + + + + +
+   .         +
+ i   !   o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+ i .         +
+     !   o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .         +
+ i   !   o   +
+       !   o +
+             +
+ + + + + + + +
Goodbye
+ + + + + + + +
+   .         +
+ i   !   o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+ i .         +
+     !   o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .         +
+ i   !   o   +
+       !   o +
+             +
+ + + + + + + +
Goodbye
8: Wall Movement
1 / 1
Compare output

Input
a
s
s
s
q
Your Output
Expected output
+ + + + + + + +
+   .         +
+ i   !   o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .         +
+ i   !   o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .         +
+     !   o   +
+ i     !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .         +
+     !   o   +
+       !   o +
+ i           +
+ + + + + + + +
+ + + + + + + +
+   .         +
+     !   o   +
+       !   o +
+ i           +
+ + + + + + + +
Goodbye
+ + + + + + + +
+   .         +
+ i   !   o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .         +
+ i   !   o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .         +
+     !   o   +
+ i     !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .         +
+     !   o   +
+       !   o +
+ i           +
+ + + + + + + +
+ + + + + + + +
+   .         +
+     !   o   +
+       !   o +
+ i           +
+ + + + + + + +
Goodbye
9: Basic Box Movement
0 / 1
Compare output

Input
d
d
q
Your Output
Expected output
+ + + + + + + +
+   .         +
+ i   !   o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .         +
+   i !   o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .         +
+     i 
 
 o   +
+       !   o +
+             +
+ + + + + + + +
Goodbye
+ + + + + + + +
+   .         +
+ i   !   o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .         +
+   i !   o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .         +
+     i 
!
 o   +
+       !   o +
+             +
+ + + + + + + +
Goodbye
Output differs. See highlights above.
Special character legend
10: Box-Wall Interaction
0 / 1
Compare output

Input
s
s
d
d
d
w
w
w
q
Your Output
Expected output
+ + + + + + + +
+   .         +
+ i   !   o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .         +
+     !   o   +
+ i     !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .         +
+     !   o   +
+       !   o +
+ i           +
+ + + + + + + +
+ + + + + + + +
+   .         +
+     !   o   +
+       !   o +
+   i         +
+ + + + + + + +
+ + + + + + + +
+   .         +
+     !   o   +
+       !   o +
+     i       +
+ + + + + + + +
+ + + + + + + +
+   .         +
+     !   o   +
+       !   o +
+       i     +
+ + + + + + + +
+ + + + + + + +
+   .         +
+     ! 
 
 o   +
+       i   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .   
 
     +
+     ! i o   +
+           o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .   
i
     +
+     ! 
 
 o   +
+           o +
+             +
+ + + + + + + +
Goodbye
+ + + + + + + +
+   .         +
+ i   !   o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .         +
+     !   o   +
+ i     !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .         +
+     !   o   +
+       !   o +
+ i           +
+ + + + + + + +
+ + + + + + + +
+   .         +
+     !   o   +
+       !   o +
+   i         +
+ + + + + + + +
+ + + + + + + +
+   .         +
+     !   o   +
+       !   o +
+     i       +
+ + + + + + + +
+ + + + + + + +
+   .         +
+     !   o   +
+       !   o +
+       i     +
+ + + + + + + +
+ + + + + + + +
+   .         +
+     ! 
!
 o   +
+       i   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .   
!
     +
+     ! i o   +
+           o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .   
!
     +
+     ! 
i
 o   +
+           o +
+             +
+ + + + + + + +
Goodbye
Output differs. See highlights above.
Special character legend
11: Box-Box Interaction
0 / 1
Compare output

Input
d
d
w
d
s
q
Your Output
Expected output
+ + + + + + + +
+   .         +
+ i   !   o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .         +
+   i !   o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .         +
+     i 
 
 o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   . i       +
+       
 
 o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .   i     +
+       
 
 o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .   
 
     +
+       
i
 o   +
+       !   o +
+             +
+ + + + + + + +
Goodbye
+ + + + + + + +
+   .         +
+ i   !   o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .         +
+   i !   o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .         +
+     i 
!
 o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   . i       +
+       
!
 o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .   i     +
+       
!
 o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .   
i
     +
+       
!
 o   +
+       !   o +
+             +
+ + + + + + + +
Goodbye
Output differs. See highlights above.
Special character legend
12: Box-Box 2
0 / 1
Compare output

Input
d
s
d
w
d
w
a
q
Your Output
Expected output
+ + + + + + + +
+   .         +
+ i   !   o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .         +
+   i !   o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .         +
+     !   o   +
+   i   !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .         +
+     !   o   +
+     i !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   . 
 
       +
+     i   o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   . 
 
       +
+       i o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   . 
 
 i     +
+         o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   . i     
  
+
+         o   +
+       !   o +
+             +
+ + + + + + + +
Goodbye
+ + + + + + + +
+   .         +
+ i   !   o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .         +
+   i !   o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .         +
+     !   o   +
+   i   !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .         +
+     !   o   +
+     i !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   . 
!
       +
+     i   o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   . 
!
       +
+       i o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   . 
!
 i     +
+         o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .
 !
 i     +
+         o   +
+       !   o +
+             +
+ + + + + + + +
Goodbye
Output differs. See highlights above.
Special character legend
13: Satisfy Box
0 / 1
Compare output

Input
d
d
d
q
Your Output
Expected output
+ + + + + + + +
+   .         +
+ i   !   o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .         +
+   i !   o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .         +
+     i 
 
 o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .         +
+       i 
o
   +
+       !   o +
+             +
+ + + + + + + +
Goodbye
+ + + + + + + +
+   .         +
+ i   !   o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .         +
+   i !   o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .         +
+     i 
!
 o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .         +
+       i 
.
   +
+       !   o +
+             +
+ + + + + + + +
Goodbye
Output differs. See highlights above.
Special character legend
14: Sprite-Target Interaction
0 / 1
Compare output

Input
d
d
w
d
d
s
d
q
Your Output
Expected output
+ + + + + + + +
+   .         +
+ i   !   o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .         +
+   i !   o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .         +
+     i 
 
 o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   . i       +
+       
 
 o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .   i     +
+       
 
 o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .     i   +
+       
 
 o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .         +
+       
 
 I   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .         +
+       
 
 o i +
+       !   o +
+             +
+ + + + + + + +
Goodbye
+ + + + + + + +
+   .         +
+ i   !   o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .         +
+   i !   o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .         +
+     i 
!
 o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   . i       +
+       
!
 o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .   i     +
+       
!
 o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .     i   +
+       
!
 o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .         +
+       
!
 I   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .         +
+       
!
 o i +
+       !   o +
+             +
+ + + + + + + +
Goodbye
Output differs. See highlights above.
Special character legend
15: Unsatisfied Box
0 / 1
Compare output

Input
w
d
d
q
Your Output
Expected output
+ + + + + + + +
+   .         +
+ i   !   o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+ i .         +
+     !   o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   
i  
       +
+     !   o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   
 
 i 
 
     +
+     !   o   +
+       !   o +
+             +
+ + + + + + + +
Goodbye
+ + + + + + + +
+   .         +
+ i   !   o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+ i .         +
+     !   o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   
I !
       +
+     !   o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   
o
 i 
!
     +
+     !   o   +
+       !   o +
+             +
+ + + + + + + +
Goodbye
Output differs. See highlights above.
Special character legend
16: Reset
0 / 1
Compare output

Input
d
d
d
 
d
d
d
 
q
Your Output
Expected output
+ + + + + + + +
+   .         +
+ i   !   o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .         +
+   i !   o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .         +
+     i   o   +
 
 
 
 
 
 
 
 
 
 
 
 
 
 
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .         +
+   
 
   
i 
o   +
+       !   o +
+             +
+ + + + + + + +
enter a valid move:
+ + + + + + + +
+   .         +
+     
    I
   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .         +
+       
  o i
 +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .         +
+    
  
   o 
i
 +
+       !   o +
+             +
+ + + + + + + +
enter a valid move:
Goodbye
+ + + + + + + +
+   .         +
+ i   !   o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .         +
+   i !   o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .         +
+     i
 ! o   +
+       !   o +
+             +
+ + + + + + + +
⏎
+ + + + + + + +
+   .         +
+       i .   +
+       !   o +
+             +
+ + + + + + + +
⏎
+ + + + + + + +
+   .         +
+ i   !
   o   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .         +
+   
i !
   o   +
+       !   o +
+             +
+ + + + + + + +
⏎
+ + + + + + + +
+   .         +
+     
i ! o
   +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .         +
+       
i .  
 +
+       !   o +
+             +
+ + + + + + + +
+ + + + + + + +
+   .         +
+ 
i
   
!
   o 
 
 +
+       !   o +
+             +
+ + + + + + + +
⏎
Goodbye
Output differs. See highlights above.
Special character legend
17: Detect Win
0 / 1
Compare output

Input
d
d
d
a
s
d
d
5 previous submissions
2:14 PM on 11/20/24
11 / 20

View
2:02 PM on 11/20/24
11 / 20

View
1:57 PM on 11/20/24
0 / 20

View
1:51 PM on 11/20/24
0 / 20

View
1:45 PM on 11/20/24
11 / 20

View

Trouble with lab?

Feedback?
12.2 ZyProject1: Sokoban
hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
Assistant: The issue you're facing seems related to input handling and game mechanics implementation. I'll address a few possible areas where the code may not behave as expected.

### Observations and Fixes

1. **Input Handling:**
   - The game does not account for a space (' ') to reset the board, as mentioned in the documentation. Add this condition to your input handling loop.
   - You should print the board after processing a valid move, not before. Otherwise, the output might appear twice, once for confirming valid input and once after the move.

2. **Win Condition:**
   - The win condition checks for exactly three satisfied boxes (`BOX_S`), which should be compared against the number of target spots on the board.

3. **Variable Initialization:**
   - Ensure all global variables like `SPRITE`, `SPRITE_T`, `BOX_S`, and `BOX_NS`, are defined in the `game_settings` module and imported correctly. Without this, the code will not understand these symbols.

4. **Logic Corrections:**
   - The variable `SPRITE_T` is never reassigned to the target character 'I' when the sprite steps onto a target. Make sure your logic accounts for changing these characters.
   - Print statements must reflect the board state changes accurately, especially after moving boxes or sprites off and onto targets.

5. **Error Handling:**
   - When checking movements, if a move is not valid, output the current board state again without changing it.

Here's a revised snippet for the main game loop:

```python
while True:
    print_board(board)  # Display board before asking for input.
    theinput = input()

    if theinput == 'q':
        print('Goodbye')
        reset()
        break
    elif theinput == ' ':  # Reset game on space input.
        reset()
        continue
    elif theinput in ['W', 'A', 'S', 'D', 'w', 'a', 's', 'd']:
        row4sprite, col4sprite = find_sprite(board)
        target_row, target_col = get_da_target(row4sprite, col4sprite, theinput)

        if valid_or_nah(board, target_row, target_col, theinput):
            move(board, row4sprite, col4sprite, target_row, target_col, theinput)
    else:
        print("Invalid move. Try again.")

    if win_condition(board):  # Check for win condition after each move.
        print_board(board)
        print('You won!')
        reset()
        break
```

### Debug Steps

1. **Verify Import:**
   - Ensure all constants are imported correctly from `game_settings`.

2. **Test Each Scenario:**
   - Explicitly test each movement scenario, including edge cases with boxes and boundaries.

3. **Refactor Code as Needed:**
   - Simplify movement and change conditions to ease debugging and maintenance.

By implementing these changes, you should be able to rectify the repeated input requests and adjust the game mechanics to fit your game's rules.
User: no comments.
Assistant: Certainly, here's the improved code without comments:

```python
from game_settings import *
from copy import deepcopy

original_board = deepcopy(board)

def print_board(board):
    for row in board:
        print(' '.join(row))

def find_sprite(board):
    global SPRITE, SPRITE_T
    for row_index, row in enumerate(board):
        for col_index, col in enumerate(row):
            if SPRITE in col or SPRITE_T in col:
                return row_index, col_index

def move(board, row1, col1, row2, col2, direction):
    if board[row2][col2] in [BOX_NS, BOX_S]:
        next_row, next_col = get_da_target(row2, col2, direction)
        if board[next_row][next_col] in [EMPTY, TARGET]:
            if board[row2][col2] == BOX_NS:
                if board[next_row][next_col] == TARGET:
                    board[next_row][next_col] = BOX_S
                else:
                    board[next_row][next_col] = BOX_NS
            elif board[row2][col2] == BOX_S:
                board[next_row][next_col] = BOX_S
            else:
                board[next_row][next_col] = board[row2][col2]
            if board[row2][col2] == BOX_S:
                board[row2][col2] = TARGET
            else:
                board[row2][col2] = EMPTY

    if board[row1][col1] == SPRITE_T:
        board[row1][col1] = TARGET
    else:
        board[row1][col1] = EMPTY

    if board[row2][col2] == TARGET:
        board[row2][col2] = SPRITE_T
    else:
        board[row2][col2] = SPRITE
    
def get_da_target(row, col, direction):
    if direction == 'w':
        return row - 1, col
    elif direction == 'a':
        return row, col - 1
    elif direction == 's':
        return row + 1, col 
    elif direction == 'd':
        return row, col + 1

def valid_or_nah(board, target_row, target_col, direction):
    if target_row < 0 or target_row >= len(board) or target_col < 0 or target_col >= len(board[0]):
        return False
    if board[target_row][target_col] == WALL:
        return False
    if board[target_row][target_col] in [EMPTY, TARGET]:
        return True
    if board[target_row][target_col] in [BOX_S, BOX_NS]:
        next_row, next_col = get_da_target(target_row, target_col, direction)
        if next_row < 0 or next_row >= len(board) or next_col < 0 or next_col >= len(board[0]) or board[next_row][next_col] not in [EMPTY, TARGET]:
            return False
        return True 
    return False
    
def win_condition(board):
    count = 0
    for row in board:
        count += row.count(BOX_S)
    return count == 3

def reset():
    global board
    board = deepcopy(original_board)

while True:
    print_board(board)
    theinput = input()
    if theinput == 'q':
        print('Goodbye')
        reset()
        break
    elif theinput == ' ':
        reset()
        continue
    elif theinput in ['W', 'A', 'S', 'D', 'w', 'a', 's', 'd']:
        row4sprite, col4sprite = find_sprite(board)
        target_row, target_col = get_da_target(row4sprite, col4sprite, theinput)
        if valid_or_nah(board, target_row, target_col, theinput):
            move(board, row4sprite, col4sprite, target_row, target_col, theinput)
        if win_condition(board):
            print_board(board)
            print('You won!')
            reset()
            break
    else:
        print("Invalid move. Try again.")
```

The code processes the input to handle valid moves and game reset, and it checks for the win condition after each valid move. Make sure the constant values like `SPRITE`, `SPRITE_T`, `BOX_NS`, `BOX_S`, `EMPTY`, `TARGET`, and `WALL` are properly defined and imported from `game_settings.py`.
User: okay so everything seems to work but only issue is: when the sprite goes on target and turns into SPRITE_T, when it leaves (to push the solution box out-- ill provide example from terminal), it stays a SPRITE_T, and does not change back to SPRITE:

+ + + + + + + +
+   I .       +
+     !   o   +
+       !   o +
+             +
+ + + + + + + +
d
+ + + + + + + +
+   o I .     +
+     !   o   +
+       !   o +
+             +
+ + + + + + + +
d
+ + + + + + + +
+   o o I .   +
+     !   o   +
+       !   o +
+             +
+ + + + + + + +

For reference (ignore test case 15 board), this is what is being exported:

WALL = '+'
SPRITE = 'i'
SPRITE_T = 'I'

EMPTY = ' '
TARGET = 'o'
BOX_NS = '!'
BOX_S = '.'

RESTART = ' '
QUIT = 'q'

CONTROLS = "wasd q"

board = [
    [WALL, WALL, WALL, WALL, WALL, WALL, WALL, WALL],
    [WALL, EMPTY, BOX_S, EMPTY, EMPTY, EMPTY, EMPTY, WALL],
    [WALL, SPRITE, EMPTY, BOX_NS, EMPTY, TARGET, EMPTY, WALL],
    [WALL, EMPTY, EMPTY, EMPTY, BOX_NS, EMPTY, TARGET, WALL],
    [WALL, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, WALL],
    [WALL, WALL, WALL, WALL, WALL, WALL, WALL, WALL]
]

TEST_CASE_15_BOARD = [
    [EMPTY, EMPTY, WALL, WALL, WALL, WALL, WALL, EMPTY],
    [WALL, WALL, WALL, EMPTY, EMPTY, EMPTY, WALL, EMPTY],
    [WALL, TARGET, SPRITE, BOX_NS, EMPTY, EMPTY, WALL, EMPTY],
    [WALL, WALL, WALL, EMPTY, BOX_NS, TARGET, WALL, EMPTY],
    [WALL, TARGET, WALL, WALL, BOX_NS, EMPTY, WALL, EMPTY],
    [WALL, EMPTY, WALL, EMPTY, TARGET, EMPTY, WALL, WALL],
    [WALL, BOX_NS, EMPTY, BOX_S, BOX_NS, BOX_NS, TARGET, WALL],
    [WALL, EMPTY, EMPTY, EMPTY, TARGET, EMPTY, EMPTY, WALL],
    [WALL, WALL, WALL, WALL, WALL, WALL, WALL, WALL]
]
Assistant: The issue you're encountering seems to arise from how the sprite is updated when it moves on or off a target. Specifically, when the sprite moves off a target, it needs to revert from `SPRITE_T` back to `SPRITE`. 

The correction needs to be made in the `move` function. Here's how you can handle it:

```python
def move(board, row1, col1, row2, col2, direction):
    if board[row2][col2] in [BOX_NS, BOX_S]:
        next_row, next_col = get_da_target(row2, col2, direction)
        if board[next_row][next_col] in [EMPTY, TARGET]:
            if board[row2][col2] == BOX_NS:
                if board[next_row][next_col] == TARGET:
                    board[next_row][next_col] = BOX_S
                else:
                    board[next_row][next_col] = BOX_NS
            elif board[row2][col2] == BOX_S:
                board[next_row][next_col] = BOX_S
            if board[row2][col2] == BOX_S:
                board[row2][col2] = TARGET
            else:
                board[row2][col2] = EMPTY

    if board[row1][col1] == SPRITE_T:
        board[row1][col1] = TARGET
    else:
        board[row1][col1] = EMPTY

    if board[row2][col2] == TARGET:
        board[row2][col2] = SPRITE_T
    else:
        board[row2][col2] = SPRITE
```

### Explanation

- **When the sprite moves from `SPRITE_T` (indicating it's on a target)**:
  - Set the current position (`row1`, `col1`) to `TARGET` since the sprite was on a target, leaving the target behind.

- **When updating the destination position (`row2`, `col2`)**:
  - If it moves onto a `TARGET`, it must become `SPRITE_T`.
  - Otherwise, it's just a regular `SPRITE`.
  
With these adjustments, the sprite should correctly revert from `SPRITE_T` back to `SPRITE` when it moves off a target. This logic ensures that the sprite's type is properly updated according to its current position.
User: duplicate glitch is still happening with target:

python3 main.py
➜ python3 main.py
+ + + + + + + +
+   .         +
+ i   !   o   +
+       !   o +
+             +
+ + + + + + + +
d
+ + + + + + + +
+   .         +
+   i !   o   +
+       !   o +
+             +
+ + + + + + + +
a
+ + + + + + + +
+   .         +
+ i   !   o   +
+       !   o +
+             +
+ + + + + + + +
w
+ + + + + + + +
+ i .         +
+     !   o   +
+       !   o +
+             +
+ + + + + + + +
d
+ + + + + + + +
+   I .       +
+     !   o   +
+       !   o +
+             +
+ + + + + + + +
a
+ + + + + + + +
+ i o .       +
+     !   o   +
+       !   o +
+             +
+ + + + + + + +
d
+ + + + + + + +
+   I .       +
+     !   o   +
+       !   o +
+             +
+ + + + + + + +
d
+ + + + + + + +
+   o I .     +
+     !   o   +
+       !   o +
+             +
+ + + + + + + +
d
+ + + + + + + +
+   o o I .   +
+     !   o   +
+       !   o +
+             +
+ + + + + + + +

i feel like it has something to do with this but im not sure, whys it leaving a target behind everytime and not changing the I.
    if board[row1][col1] == SPRITE_T:
        board[row1][col1] = TARGET
    else:
        board[row1][col1] = EMPTY

    if board[row2][col2] == TARGET:
        board[row2][col2] = SPRITE_T
    else:
        board[row2][col2] = SPRITE
Assistant: