تسجيل الحركات بتعديل القوائم المتداخلة
تعلمنا استقبال إدخال المستخدم. الآن سنستخدم ذلك لوضع القطع فعلًا على اللوحة والبدء في اللعب.
جرّب هذا الكود أولًا:
def play_move(board, player):
board[1] = player
def play_game():
game_board = [' ', ' ', ' ']
play_move(game_board, 'X')
print(game_board)
play_game()
لاحظ أن استدعاء play_move(game_board, 'X') يعدّل game_board نفسها مباشرة. المتغير board داخل استدعاء play_move والمتغير game_board في الدالة المستدعية يشيران إلى كائن القائمة نفسه؛ لا تُنشأ نسخة جديدة.
لذلك لا تحتاج play_move في هذه الحالة إلى إعادة شيء. يكفي أن تعدّل board، وسيرى المستدعي التغيير.
لكن اللوحة ثنائية الأبعاد وممثلة بقائمة متداخلة، لذلك نحتاج إلى إسناد player إلى عنصر داخل قائمة داخلية. يمكن فعل ذلك مثل:
def play_move(board, player):
row = board[1]
row[0] = player
def play_game():
board = [[' ', ' ', ' '], [' ', ' ', ' '], [' ', ' ', ' ']]
play_move(board, 'X')
print(board)
play_game()
يمكن دمج السطرين:
row = board[1] row[0] = player في سطر واحد:
board[1][0] = player
الكودان متكافئان تقريبًا. يقيّم بايثون أولًا board[1] للحصول على القائمة الداخلية، ثم يطبق [0] = ... لتعديل عنصر داخل تلك القائمة.
الآن اجعل الحركة تفاعلية. اكتب نسختك من play_move بحيث تستدعي input() مرتين: مرة لرقم الصف ومرة لرقم العمود. المستخدم يعد من 1، بينما فهارس القوائم تبدأ من 0.
إذا أدخل المستخدم:
2 1 فهذا يعني الصف الثاني والعمود الأول، أي الموضع نفسه الذي استخدمناه في المثال السابق.
إليك كود البداية:
def format_board(board):
first_row = ' '
for i in range(len(board)):
first_row += str(i + 1)
joined_rows = [first_row]
for i in range(len(board)):
joined_row = str(i + 1) + ''.join(board[i])
joined_rows.append(joined_row)
return "\n".join(joined_rows)
def play_game():
board = [
[' ', ' ', ' '],
[' ', ' ', ' '],
[' ', ' ', ' '],
]
print(format_board(board))
print('\nX to play:\n')
play_move(board, 'X')
print(format_board(board))
print('\nO to play:\n')
play_move(board, 'O')
print(format_board(board))
def play_move(board, player):
...
play_game()
يستدعي المثال play_move مرتين، لذلك سيدخل المستخدم زوجين من الأرقام. المهم أن تعدّل دالتك board في المكان الصحيح؛ لا تحتاج إلى طباعة أو إعادة قيمة من play_move نفسها.
يمكنك افتراض أن المستخدم سيدخل أرقامًا صحيحة وصالحة. سنتعامل مع الإدخال غير الصالح لاحقًا. تذكّر أن input() تعيد نصًا، وأنك تحتاج إلى تحويله إلى عدد ثم تحويل 1..n إلى فهارس 0..n-1 قبل استخدام الفهرسة المتداخلة.
Your function needs to call
input()twice. Input isn't passed toplay_moveas an argument.input()always returns a string.A string that looks like a number is still a string, not a number.
List indices have to be numbers, not strings.
If the board is 3x3, the user might input 1, 2, or 3 for each coordinate.
What are the valid indices of a list of length 3?
You need to take the input of 1, 2, or 3 and turn it into 0, 1, or 2.
You also need to be able to handle bigger boards, like 9x9 or beyond.
You can't do maths with strings, only numbers.
How can you convert a string to a number?
Once you've got two numbers, you need to modify the nested list
boardwith them.The code for this has been shown to you above.
You just need to use the numbers from user input instead of the hardcoded 1 and 0.
You can use nested subscripting in one line, or do it in two steps.
رائع! اقتربت جدًا من تجميع أجزاء اللعبة كلها معًا. واصل.