[ATBS2nd]Chương 1 - Python cơ bản - Phần 19

Chào các bạn,
Chúng ta tiếp tục với từ điển(Dictionary) trong Python.
Pretty Printing
Nếu bạn nhập mô-đun pprint vào các chương trình của mình, bạn sẽ có quyền truy cập vào các hàm pprint () và pformat () sẽ in ra một bản in đẹp một giá trị từ điển. Điều này hữu ích khi bạn muốn hiển thị rõ hơn các mục trong từ điển so với những gì hàm print() cung cấp. Sửa đổi chương trình characterCount.py trước đó và lưu nó dưới dạng beautifulCharacterCount.py.

import pprint
message = 'It was a bright cold day in April, and the clocks were striking
thirteen.'
count = {}
for character in message:
    count.setdefault(character, 0)
    count[character] = count[character] + 1
pprint.pprint(count)

Lần này, khi chương trình được chạy, đầu ra trông gọn gàng hơn nhiều, với các cặp khóa-giá trị được sắp xếp.

{' ': 13,
',': 1,
'.': 1,
'A': 1,
'I': 1,
--thu gọn--
't': 6,
'w': 2,
'y': 1}

Hàm pprint.pprint () đặc biệt hữu ích khi bản thân từ điển chứa các danh sách hoặc từ điển lồng nhau.
Nếu bạn muốn lấy văn bản được chỉnh sửa dưới dạng giá trị chuỗi thay vì hiển thị nó trên màn hình, hãy gọi pprint.pformat () để thay thế. Hai dòng này tương đương với nhau:

pprint.pprint(someDictionaryValue)
print(pprint.pformat(someDictionaryValue))

Sử dụng cấu trúc dữ liệu trong thế giới thực
Ngay cả trước khi có internet, có thể chơi một ván cờ với một người ở bên kia thế giới. Mỗi người chơi sẽ thiết lập một bàn cờ tại nhà của họ và sau đó lần lượt gửi một tấm bưu thiếp cho nhau mô tả mỗi lần di chuyển. Để làm điều này, người chơi cần một cách để mô tả rõ ràng trạng thái của bảng và di chuyển của họ.
Trong ký hiệu cờ đại số, các khoảng trắng trên bàn cờ được xác định bằng tọa độ số và chữ cái, như trong hình dưới đây.
b34
Các quân cờ được xác định bằng các chữ cái: K cho vua, Q cho hậu, R cho xe, B cho tượng và N cho ngựa. Mô tả một di chuyển sử dụng chữ cái của mảnh và tọa độ của điểm đến của nó. Một cặp trong số các động tác này mô tả những gì xảy ra trong một lượt duy nhất (với màu trắng đi trước); ví dụ, ký hiệu 2. Nf3 Nc6 chỉ ra rằng màu trắng đã chuyển một hiệp sĩ sang f3 và màu đen đã chuyển một hiệp sĩ đến c6 trong lượt thứ hai của trò chơi.
Có một chút nhiều hơn về ký hiệu đại số hơn thế này, nhưng vấn đề là bạn có thể mô tả rõ ràng một trò chơi cờ vua mà không cần phải ở trước bàn cờ. Đối thủ của bạn thậm chí có thể ở bên kia thế giới! Trên thực tế, bạn không cần một bộ cờ vật lý nếu bạn có một trí nhớ tốt: bạn có thể đọc các động tác cờ được gửi qua thư và cập nhật các bảng bạn có trong trí tưởng tượng của mình.
Máy tính có những kỷ niệm đẹp. Một chương trình trên máy tính hiện đại có thể dễ dàng lưu trữ hàng tỷ chuỗi như '2. Nf3 Nc6 '. Đây là cách máy tính có thể chơi cờ mà không cần có bàn cờ vật lý. Họ mô hình dữ liệu để đại diện cho một bàn cờ và bạn có thể viết mã để làm việc với mô hình này. Đây là nơi có thể liệt kê danh sách và từ điển. Ví dụ: từ điển {‘1h’: ‘bking’, ‘6c’: ‘wqueen’, ‘2g’: ‘bbishop’, ‘5h’: ‘bqueen’, '3e ‘:’ wking '} có thể đại diện cho bàn cờ trong hình dưới đây.
b35
Nhưng với một ví dụ khác, bạn sẽ sử dụng một trò chơi đơn giản hơn một chút so với cờ vua: tic-tac-toe.
Một bảng tic-tac-toe
Một bảng tic-tac-toe trông giống như một biểu tượng băm lớn (#) với chín vị trí mà mỗi ô có thể chứa X, O hoặc trống. Để biểu diễn bảng bằng từ điển, bạn có thể gán cho mỗi ô một khóa giá trị chuỗi, như trong hình dưới đây.
b36
Bạn có thể sử dụng các giá trị chuỗi để biểu thị những gì trong một vị trí trên bảng: ‘X’, ‘O’ hoặc ‘’ (một khoảng trắng). Vì vậy, bạn sẽ cần lưu trữ chín chuỗi. Bạn có thể sử dụng một từ điển các giá trị cho việc này. Giá trị chuỗi với khóa ‘top-R’ có thể đại diện cho góc trên bên phải, giá trị chuỗi với khóa ‘low-L’ có thể đại diện cho góc dưới bên trái, giá trị chuỗi với khóa ‘mid-M’ có thể đại diện cho giữa, và như vậy.
Từ điển này là một cấu trúc dữ liệu đại diện cho một bảng tic-tac-toe. Lưu trữ bảng từ điển này trong một biến có tên theBoard. Mở một cửa sổ soạn thảo văn bản mới và nhập mã nguồn sau, lưu nó dưới dạng ticTacToe.py:

theBoard = {'top-L': ' ', 'top-M': ' ', 'top-R': ' ',
'mid-L': ' ', 'mid-M': ' ', 'mid-R': ' ',
'low-L': ' ', 'low-M': ' ', 'low-R': ' '}

Cấu trúc dữ liệu theBoard lưu trữ dữ liệu của bảng tic-tac-toe.
b37
Vì giá trị cho mỗi khóa trong theBoard là một chuỗi không gian đơn, từ điển này đại diện cho một bảng hoàn toàn rõ ràng. Nếu người chơi X đi trước và chọn khoảng trống ở giữa, bạn có thể biểu diễn cho theBoard đó bằng từ điển này:

theBoard = {'top-L': ' ', 'top-M': ' ', 'top-R': ' ',
'mid-L': ' ', 'mid-M': 'X', 'mid-R': ' ',
'low-L': ' ', 'low-M': ' ', 'low-R': ' '}

Giá trị trong theBoard thể hiện bằng hình ảnh như sau
b38
Một bảng mà người chơi O thắng khi đặt tất cả O trên đỉnh.

theBoard = {'top-L': 'O', 'top-M': 'O', 'top-R': 'O',
'mid-L': 'X', 'mid-M': 'X', 'mid-R': ' ',
'low-L': ' ', 'low-M': ' ', 'low-R': 'X'}

TheBoard biểu hiện bằng hình ảnh như sau
b39

theBoard = {'top-L': ' ', 'top-M': ' ', 'top-R': ' ',
'mid-L': ' ', 'mid-M': ' ', 'mid-R': ' ',
'low-L': ' ', 'low-M': ' ', 'low-R': ' '}
def printBoard(board):
	print(board['top-L'] + '|' + board['top-M'] + '|' + board['top-R'])
	print('-+-+-')
	print(board['mid-L'] + '|' + board['mid-M'] + '|' + board['mid-R'])
	print('-+-+-')
	print(board['low-L'] + '|' + board['low-M'] + '|' + board['low-R'])
printBoard(theBoard)

Khi chúng ta chạy chương trình này, printBoard(theBoard) sẽ in ra hình sau

| |
-+-+-
| |
-+-+-
| |

Hàm printBoard () có thể xử lý bất kỳ cấu trúc dữ liệu tic-tac-toe nào mà bạn đưa vào. Hãy thử thay đổi mã thành như sau:

theBoard = {'top-L': 'O', 'top-M': 'O', 'top-R': 'O', 'mid-L': 'X', 'mid-M':
'X', 'mid-R': ' ', 'low-L': ' ', 'low-M': ' ', 'low-R': 'X'}
def printBoard(board):
	print(board['top-L'] + '|' + board['top-M'] + '|' + board['top-R'])
	print('-+-+-')
	print(board['mid-L'] + '|' + board['mid-M'] + '|' + board['mid-R'])
	print('-+-+-')
	print(board['low-L'] + '|' + board['low-M'] + '|' + board['low-R'])
printBoard(theBoard)

Chương trình trên sẽ in ra màn hình như sau

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

Bởi vì bạn đã tạo cấu trúc dữ liệu để thể hiện bảng tic-tac-toe và đã viết mã trong printBoard () để diễn giải cấu trúc dữ liệu đó, giờ đây bạn đã có một chương trình mà các mô hình mà mô tả bảng tic-tac-toe. Bạn có thể đã tổ chức cấu trúc dữ liệu của mình một cách khác nhau (ví dụ: sử dụng các khóa như ‘TOP-LEFT’ thay vì ‘top-L’), nhưng miễn là mã hoạt động với cấu trúc dữ liệu của bạn, bạn sẽ có một chương trình hoạt động chính xác.
Ví dụ, hàm printBoard () mong muốn cấu trúc dữ liệu tic-tac-toe sẽ là một từ điển với các khóa cho tất cả chín vị trí. Nếu từ điển bạn chuyển bị thiếu, giả sử, phím ‘mid-L’, chương trình của bạn sẽ không còn hoạt động.

O|O|O
-+-+-
Traceback (most recent call last):
  File "ticTacToe.py", line 10, in <module>
    printBoard(theBoard)
  File "ticTacToe.py", line 6, in printBoard
    print(board['mid-L'] + '|' + board['mid-M'] + '|' + board['mid-R'])
KeyError: 'mid-L'

Giờ hãy để thêm mã cho phép người chơi nhập di chuyển. Sửa đổi chương trình ticTacToe.py để trông như thế này:

theBoard = {'top-L': ' ', 'top-M': ' ', 'top-R': ' ', 'mid-L': ' ', 'mid-M': '
', 'mid-R': ' ', 'low-L': ' ', 'low-M': ' ', 'low-R': ' '}
def printBoard(board):
	print(board['top-L'] + '|' + board['top-M'] + '|' + board['top-R'])
	print('-+-+-')
	print(board['mid-L'] + '|' + board['mid-M'] + '|' + board['mid-R'])
	print('-+-+-')
	print(board['low-L'] + '|' + board['low-M'] + '|' + board['low-R'])
turn = 'X'
for i in range(9):
	printBoard(theBoard)
	print('Turn for ' + turn + '. Move on which space?')
	move = input()
	theBoard[move] = turn
	if turn == 'X':
		turn = 'O'
	else:
		turn = 'X'
printBoard(theBoard)

Mã mới in ra bảng vào đầu mỗi lượt mới, di chuyển theo người chơi khi đánh vào, di chuyển bảng trò chơi phù hợp và sau đó đổi người chơi hoạt động trước khi chuyển sang lượt tiếp theo.
Khi bạn chạy chương trình này, nó sẽ trông giống như thế này:

| |
-+-+-
| |
-+-+-
| |
Turn for X. Move on which space?
mid-M
| |
-+-+-
|X|
-+-+-
| |
--snip--
O|O|X
-+-+-
X|X|O
-+-+-
O| |X
Turn for X. Move on which space?
low-M
O|O|X
-+-+-
X|X|O
-+-+-
O|X|X

Ví dụ, đây là một trò chơi tic-tac-toe không hoàn chỉnh, nhưng nó không bao giờ kiểm tra xem một người chơi có chiến thắng hay không nhưng nó đủ để xem cách sử dụng cấu trúc dữ liệu trong các chương trình.
Người dịch: Hungdh

2 Likes