حللت حتى الآن تمارين قصيرة، كل واحد منها يركز على مشكلة صغيرة. الآن سنبني مشروعًا أكبر وأكثر تعقيدًا يختبر ما تعلمته ويجمع عدة أجزاء صغيرة معًا.
ستطوّر لعبة Tic-Tac-Toe تفاعلية نصية يلعبها شخصان. هذا مثال صغير لشكل اللعبة أثناء اللعب:
1 2 3 1 | | -+-+- 2 | | -+-+- 3 | |
X to play: 1 1
1 2 3 1 X| | -+-+- 2 | | -+-+- 3 | |
O to play: 2 2
1 2 3 1 X| | -+-+- 2 |O| -+-+- 3 | |
X to play: 1 3
1 2 3 1 X| |X -+-+- 2 |O| -+-+- 3 | |
سنقسّم المشروع إلى عدة دوال صغيرة، وكل دالة ستكون تمرينًا مستقلًا.
ستستخدم مفاهيم كثيرة تعلمتها بالفعل: النصوص، القوائم المتداخلة، الحلقات المتداخلة، range، استدعاء الدوال من داخل دوال أخرى، المقارنات، والقيم المنطقية. وأثناء المشروع ستتعلم أيضًا مفاهيم جديدة مثل محرف السطر الجديد، الأنواع، والدالة input().
الخطة العامة للمشروع:
row_winner وcolumn_winner وdiagonal_winner لفحص الصفوف والأعمدة والأقطار الفائزة.winner تجمع هذه الفحوص لتحديد وجود فائز في اللوحة كلها.format_board تعرض حالة اللوحة الحالية.play_move تستقبل إدخال المستخدم لتنفيذ حركة.play_game تجمع كل شيء وتشغل اللعبة بصورة تفاعلية.لنبدأ.
كما في الفصل السابق، سنمثل لوحة اللعبة بقائمة متداخلة من النصوص. في اللعبة المعتادة تكون اللوحة 3×3، أي ثلاث قوائم، في كل واحدة ثلاثة نصوص. نمثل اللاعبين بـ'X' أو 'O'، والمربع الفارغ بمسافة ' '. مثال:
board = [ ['X', 'O', 'X'], ['O', ' ', ' '], [' ', 'X', 'O'] ]
ولجعل المسألة أكثر فائدة، يجب أن يعمل كودك مع لوحات مربعة بأي حجم مثل 4×4 أو 5×5، ويمكن أن تكون رموز اللاعبين أي نصوص، مثل:
board = [ ['A', 'B', 'A', 'A'], ['B', ' ', ' ', 'A'], [' ', 'A', 'B', 'B'], [' ', 'A', 'B', ' '] ]
اكتب دالة row_winner تعيد True إذا كانت board تحتوي على صف فائز: خط أفقي تكون جميع خاناته الرمز نفسه، بشرط ألا يكون هذا الرمز هو المسافة ' ':
__copyable__ def row_winner(board): ...
check_result( row_winner( [ ['A', 'A', 'B', 'A'], [' ', ' ', ' ', ' '], ['A', ' ', ' ', 'A'], ['B', ' ', 'B', 'A'] ] ), False ) check_result( row_winner( [ ['X', ' ', 'X'], ['O', 'X', 'X'], ['O', 'O', 'O'] ] ), True )
في المثال الثاني يفوز O في الصف الأخير.
عمل رائع!
أصبح لدينا الآن الكود الذي يحدد ما إذا كانت اللوحة تحتوي حالة فوز.