cb
codebamin
الفصل 11 · مشروع لعبة إكس-أو (Tic-Tac-Toe)

رمز السطر الجديد ( ) وتنسيق اللوحة

نريد الآن حل مشكلة عرض لوحة Tic-Tac-Toe. هذه إحدى الطرق الممكنة لطباعة اللوحة:

__copyable__ __program_indented__

إذا لم تكن تعرف ما تفعله "".join، يمكنك البحث عنها وفهم المثال بالتجربة.

هذه بداية جيدة، لكن الأفضل أن تكون لدينا دالة تعيد نصًا بدل أن تطبعه مباشرة. عندها يستطيع أي كود آخر استخدام النص بطرق مختلفة: يمكن تعديله، أو وضع إطار حوله، أو أخذ بضعة أسطر منه، أو حفظه في ملف بدل الشاشة. وفي حالتنا نريد أيضًا اختباره باستخدام check_result.

هذا لا يعمل كما نريد:

check_result(print_board([...]), "...")

لأن print_board لا تستخدم return، ولذلك تعيد None تلقائيًا.

نريد بدل ذلك شيئًا من الشكل:

def format_board(board): ... return ...

check_result(format_board([...]), "...")

ثم يمكن لـprint(format_board(board)) أن يطبع لوحة مثل التي رأيناها في البداية.

لكن كيف نكتب ونختبر نصًا يحتوي على عدة أسطر؟ قد نرغب في كتابة شيء كهذا:

__copyable__ check_result( format_board([ ['X', 'O', 'X'], [' ', 'O', 'O'], [' ', 'X', ' '] ]), "XOX OO X " )

جرّب وسترى أن كتابة النص بهذه الطريقة لا تعمل.

عادة يجب أن تكون السلسلة النصية المكتوبة بعلامة اقتباس واحدة أو مزدوجة في سطر واحد، لذلك هذا غير صالح:

string = "First line Second line" print(string)

لكن بايثون يوفر طريقة لكتابة نص يمتد على أكثر من سطر: علامات الاقتباس الثلاثية، أي ثلاث علامات اقتباس متتالية، سواء ثلاث علامات اقتباس مفردة أو ثلاث علامات اقتباس مزدوجة، حول محتوى النص.

شغّل المثال التالي:

__program_indented__

رائع! يمكن للنص ذي علامات الاقتباس الثلاثية أن يمتد على عدة أسطر، وتظهر هذه الأسطر فعلًا في الناتج.

وكما في علامات الاقتباس المفردة والمزدوجة، فهذه مجرد صيغة لكتابة النص وليست نوعًا جديدًا من البيانات. """abc""" هي القيمة نفسها التي تكتبها هكذا: "abc".

لكن المتغير string يحتوي على شيء جديد. اكتب string في الطرفية لترى التمثيل الداخلي.

هذا هو السر: يمثل محرف سطر جديد (newline).

هو محرف واحد، مثل الحرف العادي أو المسافة ' '. إنه المحرف الموجود بين سطرين منفصلين عندما تضغط Enter.

داخل النص الحرفي في بايثون، الصيغة تمثل محرف السطر الجديد. القيمة النصية نفسها لا تحتوي على حرفي \ وn منفصلين، وإنما تحتوي على محرف واحد. يمكنك التحقق من ذلك في الطرفية بقياس طول نص يحتوي على سطر جديد واحد.

استخدم الآن محرف السطر الجديد لكتابة الدالة format_board. يجب أن يعمل الحل مع لوحة مربعة board بأي حجم:

__copyable__ def format_board(board): ...

check_result( format_board([ ['X', 'O', 'X'], ['O', ' ', ' '], [' ', 'X', 'O'] ]), 'XOX O XO' )

ابنِ نصًا للوحة كلها. أضف أحرف كل صف، ثم أضف بين الصفوف. انتبه إلى أن الصف الأخير لا يحتاج إلى سطر جديد بعده.

ممتاز! حل نموذجي يمكن أن يكون:

def format_board(board): result = '' for i in range(len(board)): for char in board[i]: result += char if i != len(board) - 1: result += ' ' return result

وإذا بحثت عن join واستخدمتها، فهذا ممتاز أيضًا. قد يكون الحل مثل:

def format_board(board): joined_rows = [] for row in board: joined_rows.append("".join(row)) return " ".join(joined_rows)

يمكنك الانتقال للجزء التالي، أو حل تحدٍّ إضافي: اكتب نسخة محسنة من format_board تعرض فواصل الصفوف والأعمدة. إذا كانت:

board = [ ['X', 'O', 'X'], [' ', 'O', 'O'], [' ', 'X', ' '] ]

فيجب أن يطبع print(format_board(board)):

X|O|X -+-+- |O|O -+-+- |X|

ويجب أن يعمل مع لوحة مربعة بأي حجم.

استخدام join مناسب جدًا هنا. الاختبار:

__copyable__ def format_board(board): ...

check_result( format_board([ ['X', 'O', 'X'], ['O', ' ', ' '], [' ', 'X', 'O'] ]), 'X|O|X -+-+- O| | -+-+- |X|O' )

هناك نوعان من الأسطر: أسطر القطع وبينها |، وأسطر الفصل المكونة من - وبينها +. ابنِ كل نوع باستخدام join، ثم اجمع الأسطر مع محارف السطر الجديد.

عمل ممتاز! كان هذا تحديًا حقيقيًا.

أصبحت تعرف كيف تبني نصًا مكوّنًا من عدة أسطر، وحللت مشكلة عرض لوحة اللعبة للاعبين.

بعد ذلك ستتعلم المزيد عن الأنواع في بايثون وكيفية التحويل بينها، ثم كيفية استقبال إدخال اللاعبين. أنت الآن تقريبًا في منتصف مشروع اللعبة، فواصل.

solution.py
1
2
3
4
5
6
7
8
9
10
الطرفية (shell)
>>>