2 Explain
Giải thích từng phần:
2.2 Creating the Board.
Chức năng tạo ra ma trận
sizehàng xsizecột, mỗi phần tử tronglistchứa dữ liệu của bàn cờ.
1def create_board(size: int):
board = []
2 for i in range(size):
3 board.append([' ' for j in range(size)])
return board- 1
-
size: intchỉ định kiểu dữ liệuintcho biếnsize. Xuất hiện từ python 3.5. 2 - 2
-
Vòng lặp chạy từ
i=0đếnsize-1mỗi lần tăngisẽ tạo ra mảng kiểulist[ , , , ,…,size] cósize-1phần tử. - 3
-
Kỹ thuật
[' ' for j in range(size)]được gọi là List Comprehension 3, nó cho phép dùng vòng lặp tạo nhanh một list theo ý muốn người dùng. Phương thứcboard.append()để thêm một phần tử vào kiểu dữ liệulist- List Append 4.
- Bảng giá trị size 9x9
[[' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '],
[' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '],
[' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '],
[' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '],
[' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '],
[' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '],
[' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '],
[' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '],
[' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ']]- Hình bên dưới minh hoạ cho bàn cờ (Board) size 9x9, các kích thước khác tương tự.

2.3 Is the target position occupied?
Chức năng hàm yêu cầu để kiểm tra tại vị trí
(x, y)đã tồn tại một quân cờ chưa.
def is_occupied(board: list, x: int, y: int):
1 return board[x][y] != ' '- 1
-
Mặc định khi khởi tạo dữ liệu tại [Creating the Board], các giá trị là
' 'nên tại vị tríboard[x][y]không giống các giá trị mặc định thì trả vềTRUE. Thay vì cách code như bên dưới, chúng ta có thể trả về trực tiếp giá trịbooleangiảm bớt một dòng lệnh. Tham khảo thêm chức năng - Python predicate 5.
2.4 Placing a Stone at a Specific Intersection.
- Các yêu cầu chính được mô tả ở đây
# convert position type string (e.g., 5 A) -> type int (e.g., 5 0)
1def convert_position(position: tuple):
2 return (int(position[0]), ord(position[1]) - ord('A'))
# place on board function
3def place_on_board(board: list, stone: str, position: tuple):
4 position_ = convert_position(position=position)
5 if not is_occupied(board, x=position_[0], y=position_[1]):
board[position_[0]][position_[1]] = stone
return True
return False- 1
-
Chức năng hàm yêu cầu khi người dùng truyền vào toạ độ
(5 A)thì ghi giá trị vào mảng đã tạo ở [Creating the Board.], nhưng trong lập trình thìPythondùng index kiểuint(1, 2, 3, 4,…). Vậy nên, mục tiêu của hàmconvert_position(position: tuple)là chuyển từ giá trịstr(5 A)sang(5 0). - 2
-
Trong bảng ASCII, giá trị của kí tự
Alà 65Blà 66 và các kí tự tiếp theo có giá trị tăng dần. Vậy trường hợp cột B ta muốn lấy index trong ngôn ngữ lập trình thì lấyASCII(B) - ASCII(A)có giá trị là66 - 65 = 1; tương tự với cột CASCII(C) - ASCII(A)có giá trị là67 - 65 = 2. Kết luận: lấy giá trịascii(A) = 65làm mốc để tính các cột khác. Biến đầu vàoposition: tuplecó kiểu dữ liệu mẫu(5 A), truy cập giá trị5với phương thứcposition[0],Avới phương thứcposition[1]. Hàmord()với giá trị nhận vào làstrđể thực hiện chức năng chuyểnascii(A)sangint. - 3
-
Lý do tại sao tách hàm
convert_positionra khỏi hàm chính, vì tăng tính tường minh mỗi hàm mỗi tính năng dễ bảo trì hơn. - 4
-
Khi nhận giá trị thuần từ người dùng
(5 A)sẽ thực hiện chức năng chuyển đổi kiểu dữ liệu. - 5
-
Sử dụng hàm #3.3.is-occupied, để kiểm tra đã tồn tại
stone, nếu không tồn tại thì ghi dữ liệu vào mảng dữ liệuboardđã khởi tạo ở #3.2.create-board sau đó thoát hàm và trả vềTrue. Nếu không thì hàm luôn trả vềFalse.
2.5 Printing the Board
Các yêu cầu được mô tả ở đây
Mã nguồn của hàm:
def print_board(board: list):
s = ""
1 size_tab = 5
2 size = len(board)
# Create column index (e.g., A B C)
3 for index in range(65, 65 + size):
4 s += chr(index) + "\t"
5 print(s.expandtabs(size_tab))
# Create grid and row index
6 i = 0
7 for row in range(size):
string = ""
8 for column in range(size): # Loop all value in each row
string += board[row][column] + " " + "--\t"
9 string = string[0:-3] + str(i)
10 print(string.expandtabs(size_tab))
11 print((size * '|\t').expandtabs(size_tab)) if (row < size - 1) else 0
i += 1 - 1
-
Chỉ định giá trị cho hàm Expand Tabs, trong hàm
print_board()dùng\tlà tabs để căn thẳng các kí tự để in ra đẹp hơn. - 2
- Lấy kích thước bàn cờ để phục vụ việc xuất ra màn hình.
- 3
-
Như đã giải thích ở mục 2 phần Placing a Stone at a Specific Intersection., các index cột là alphabet nên bắt đầu từ A tương ứng trong mã
ascii(A)là65nên vòng lặp bắt đầu từ 65, dừng lại khi đủ số cột65 + size. - 4
-
Với
sban đầu rỗng, sau mỗi lần lặps +=nghĩa làs = s + str_value. Ví dụ,s += chr(index) + "\t"sau lần lặp đầu tiên sẽ làs = "" + chr(65) + "\t"tương ứngs = "" + "A" + "\t"rút gọns = "A\t", lần lặp tiếp theo sẽ đượcs = "A\t B\t". Nhận xét nếu không có có kí tự\tthì không thể căn thẳng cột được, vậy nên dùng tabs là phù hợp nhất. - 5
-
Sau vòng lặp thu được chuỗi
s = "A\tB\tC\tD\tE\tF\tG\tH\t",size_tabmặc định là2xuất ra màn hình không đẹp nên chọn giá trị5. Sẽ được kết quả như mục Expand Tab.1. - 6
-
Biến
iđược khởi tạo để dùng cho in index dòng (0, 1, 2, …) - 7
-
Vòng lặp được dùng để lấy từng hàng trong bảng
boardđược tạo ở #3.2.table-size9x9. - 8
-
Vòng lặp thứ hai để đọc dữ liệu từng ô trong một hàng và kết hợp với xử lý string để in ra màn hình từng dòng. Sau mỗi vòng lặp chuỗi sẽ được cộng thêm giá trị
board[row][column] + " " + "--\t"tương ứngboard[row][colmn] --\t,\tlà tabs để căn thẳng với index A, B, C, D,… - 9
-
Kết thúc vòng lặp thu được chuỗi
board[row][colmn] --\tboard[row][colmn] --\t...board[row][colmn] --\tboard[row][colmn] --\t, nó sẽ luôn dư chuỗi--\tvì vậy dùng String Slicing 6 để cắt bớt chuỗi đi, các giá trị bị bỏ đi là[-3 -2 -1]tương ứng[- - \t]. - 10
-
Tiếp tục dùng
expandtabs()như đã giải thích ở mục 5, để các giá trị được thẳng hàng với các index cột. - 11
- Được giải thích kỹ hơn ở #3.5.2.rewrite-blockcode.
2.5.1 Expand Tab
- Sử dụng tabs:
A B C D E F G H I
-- -- -- -- -- -- -- -- 0
| | | | | | | | |
-- -- -- -- -- -- -- -- 1
| | | | | | | | |
-- -- -- -- -- -- -- -- 2
| | | | | | | | |
-- -- -- -- -- -- -- -- 3
| | | | | | | | |
-- -- -- -- -- -- -- -- 4
| | | | | | | | |
-- -- -- -- -- -- -- -- 5
| | | | | | | | |
-- -- -- -- -- -- -- -- 6
| | | | | | | | |
-- -- -- -- -- -- -- -- 7
| | | | | | | | |
-- -- -- -- -- -- -- -- 8- Không dùng tabs:
# Loai bo ki tu tab
def print_board_(board: list):
s = ""
size_tab = 5
size = len(board)
# Create column index (e.g., A B C)
for index in range(65, 65 + size):
s += chr(index) + " "
print(s.expandtabs(size_tab))
# Create grid and row index
i = 0
for row in range(size):
string = ""
for column in range(size): # Loop all value in each row
string += board[row][column] + " " + "-- "
string = string[0:-3] + str(i)
print(string.expandtabs(size_tab))
print((size * '| ').expandtabs(size_tab)) if (row < size - 1) else 0
i += 1
# Ket qua
A B C D E F G H I
-- -- -- -- -- -- -- -- 0
| | | | | | | | |
-- -- -- -- -- -- -- -- 1
| | | | | | | | |
-- -- -- -- -- -- -- -- 2
| | | | | | | | |
-- -- -- -- -- -- -- -- 3
| | | | | | | | |
-- -- -- -- -- -- -- -- 4
| | | | | | | | |
-- -- -- -- -- -- -- -- 5
| | | | | | | | |
-- -- -- -- -- -- -- -- 6
| | | | | | | | |
-- -- -- -- -- -- -- -- 7
| | | | | | | | |
-- -- -- -- -- -- -- -- 82.5.2 Print blank row grid line
1print((size * '|\t').expandtabs(size_tab)) if (row < size - 1) else 0
# rewrite
2if (row < size - 1):
print((size * '|\t').expandtabs(size_tab))
else: 0- 1
- Là cách viết rút gọn của (2).
- 2
-
Mục đích của câu lệnh này là để không in thêm một dòng blank grid sau khi đã in đủ số lượng
row_indexnhư #3.5.2.print-row-grid-over-size. Ngoài ra,(size * '|\t')là để nối chuỗi và nó lặp lại đủsizelần chuỗi'|\t'như sau:'|\t|\t|\t|\t|\t|\t…'
2.6 Check Available Moves
- Yêu cầu của hàm ở đây
- Mã nguồn:
1def check_available_moves(board: list):
available_moves = []
2 size = len(board)
3 for row in range(size):
for col in range(size):
4 if not is_occupied(board, row, col):
5 available_moves.append((str(row), chr(col + ord('A'))))
return available_moves- 1
-
Hàm để tìm kiếm tất cả các vị trí trên bàn cờ còn trống và thêm vào list
available_moves. - 2
-
Lấy kích thước
board. - 3
- Vòng lặp sẽ duyệt qua từng hàng, vòng lặp tiếp theo sẽ đi đến giá trị từng cột trong hàng.
- 4
-
Sử dụng hàm #3.3.is-occupied để kiểm tra tại vị trí
(row, col)đã được đánh chưa. - 5
-
available_moves.appendsẽ thêm phần tử mới vàoavailable_moves7.(str(row), chr(col + ord('A')))mục đích chuyển kiểu dữ liệu từ(5 2)sang(5 C).
2.7 Check for the Winner
Hãy xem lại bảng đã xuất ra ở #3.5.1.print-with-tabs và hình minh hoạ #2.2_01_visualize-board.
Ý tưởng là sẽ sẽ quét qua từng hàng, cột và các đường chéo để đếm giá trị
'●'hoặc'○'có tổng số là 5. Khi tìm thấy sẽ dừng lại toàn bộ hàm.Hàm
check_sequences_horizontalđể kiểm tra theio chiều ngang.Hàm
check_sequences_verticalđể kiểm tra theo chiều dọc.Hàm
check_sequences_diagonal1để kiểm tra các đường chéo từ dưới bên trái lên
Diagonally 1 Hàm
check_sequences_diagonal2để kiểm tra các đường chéo từ trên bên trái xuống dưới
Diagonally 2 Cuối cùng, hàm
check_for_winnersẽ tổng hợp lại các hàm trên.
2.7.1 Hàm check_sequences_horizontal
1def get_column(board: list, i: int):
return [row[i] for row in board]
def check_sequences_horizontal(board: list):
size = len(board)
2 for row in range(size):
count_player1 = board[row].count('●')
count_player2 = board[row].count('○')
3 if (count_player1 == 5): return '●'
elif (count_player2 == 5): return '○'
else: return None- 1
-
Hàm phụ được viết thêm để lấy dữ liệu trong một cột của
board, dùng List Comprehension. Trong[row[i] for row in board]mỗi row được lặp qua thì giá trịrow[i]tương ứng cộticần lấy sẽ được thêm vào list. Cuối cùng hàm trả về list đó. - 2
-
Code chính đếm số lượng
stonetrên một hàng, cứ mỗirow in range(size)trong vòng lặp được đi qua thì stone'●'được đếm bằngcount_player1 = board[row].count('●'), hàng tiếp theo tương ứng cho'○'. - 3
-
Tại đây sẽ kiểm tra nếu số lượng
stonenào bằng5thìreturngiá trị đó tương ứng. Nếu không cóstonenào đủ hàm sẽ luôn trả vềNone.
2.7.2 Hàm check_sequences_vertical
def check_sequences_vertical(board: list):
size = len(board)
for column_index in range(size):
1 column = get_column(board, column_index)
2 count_player1 = column.count('●')
count_player2 = column.count('○')
if (count_player1 == 5): return '●'
elif (count_player2 == 5): return '○'
else: return None- 1
-
Hàm sẽ dùng đến hàm
get_columnở #3.7.1.check-horizontal - 2
- Còn lại cấu trúc cách hoạt động giống [Hàm check_sequences_horizontal] chỉ khác là trục dọc.
2.7.3 Hàm check_sequences_diagonal1
- Hình minh hoạ ở #3.7_visualize-diagonally1
def check_sequences_diagonal1(board: list):
ROW = len(board)
COL = len(board)
diagonal_list = []
# There will be ROW+COL-1 lines in the output
1 for line in range(1, (ROW + COL)):
# Get column index of the first element
# in this line of output. The index is 0
# for first ROW lines and line - ROW for
# remaining lines
2 start_col = max(0, line - ROW)
# Get count of elements in this line.
# The count of elements is equal to
# minimum of line number, COL-start_col and ROW
3 count = min(line, (COL - start_col), ROW)
# Print elements of this line
4 diagonal_item = []
for j in range(0, count):
5 diagonal_item.append(board[min(ROW, line) - j - 1]
[start_col + j])
6 diagonal_list.append(diagonal_item)
7 for diagonal in diagonal_list:
if diagonal.count('●') == 5: return '●'
elif diagonal.count('○') == 5: return '○'
return None- 1
-
Số đường chéo sẽ luôn là
row + col -1như ở ví dụ #3.7.3.check_sequences_diagonal1_example - 2
-
Lấy chỉ mục để bắt đầu cột đầu tiên cho các đường chéo, bắt đầu ở giá trị
1trong ví dụ #3.7.3.check_sequences_diagonal1_example nên có cột bằng0. - 3
- Số phần tử trên mỗi đường chéo là khác nhau nên dòng này để lấy số phần tử cần thiết mà không quá index của mảng.
- 4
- Chứa đường chéo sau mỗi vòng lặp.
- 5
-
Trong vòng lặp qua các phần tử từ
(0 -> count), các phần tử sẽ được thêm vào mảng đường chéodiagonal_item. - 6
-
Sau đó,
diagonal_itemsẽ được thêm vào chứa các đường chéodiagonal_list - 7
-
Tương tự như hai hàm trên, trên mỗi đường chéo sẽ được đếm số lượng
stonenếu đủ5sẽ trả về giá trị.
2.7.4 Hàm check_sequences_diagonal2
- Hình minh hoạ ở #3.7_visualize-diagonally2
def check_sequences_diagonal2(board: list):
1 h, w = len(board), len(board[0])
2 diagonal_list = [[board[h - p + q - 1][q]
for q in range(max(p-h+1, 0), min(p+1, w))]
for p in range(h + w - 1) ]
for diagonal in diagonal_list:
3 if diagonal.count('●') == 5: return '●'
elif diagonal.count('○') == 5: return '○'
return None- 1
- Lấy chiều cao và chiều rộng
- 2
-
Sử dụng List Comprehension để tạo mảng
diagonal_list. - 3
-
Đếm giá trị
stonecó đủ số lượng để thắng
2.7.5 Hàm check_for_winner
Đây là hàm chính kiểm tra người chơi nào đã thắng hoặc không.
Mã nguồn
def check_for_winner(board: list):
1 white_stone = '○'
black_stone = '●'
2 sequences_horizontal = check_sequences_horizontal(board)
3 sequences_vertical = check_sequences_vertical(board)
4 sequences_diagonal1 = check_sequences_diagonal1(board)
5 sequences_diagonal2 = check_sequences_diagonal2(board)
6 for result in (sequences_horizontal, sequences_vertical,
sequences_diagonal1, sequences_diagonal2):
if result is not None: return result
7 if check_available_moves(board) == []:
return "Draw"
return None- 1
- Định nghĩa ký tự đại diện người chơi
- 2
- Gọi [Hàm check_sequences_horizontal]
- 3
- Gọi [Hàm check_sequences_vertical]
- 4
- Gọi [Hàm check_sequences_diagonal1]
- 5
- Gọi [Hàm check_sequences_diagonal2]
- 6
-
Vòng lặp sẽ đi qua từng giá trị của tuple
(sequences_horizontal, sequences_vertical, sequences_diagonal1, sequences_diagonal2), các hàm trên khi không trả về giá trịNonechắc chắn sẽ trả về giá trị người thắng. - 7
-
Hàm #3.6.check-available-moves nếu trả về rỗng thì bàn cờ không đi được nữa, và chưa có người thắng nên trả về
Draw.
2.8 Random Computer Player
- Các yêu cầu của hàm ở đây
- Mã nguồn:
def random_computer_player(board: list, player_move: tuple):
size = len(board)
1 player_row, player_col = convert_position(player_move)
2 valid_moves = []
3 for i in range(-1, 2):
for j in range(-1, 2):
4 new_row = player_row + i
new_col = player_col + j
5 if (0 <= new_row < size and 0 <= new_col < size)
and not is_occupied(board, new_row, new_col):
6 valid_moves.append((str(new_row), chr(new_col + ord('A'))))
if len(valid_moves) == 0:
7 valid_moves = check_available_moves(board)
8 return random.choice(valid_moves)- 1
-
Chuyển đổi
player_move: tuplesang kiểuintđể tương tác với mảng. - 2
- List rỗng được khởi tạo để chứa lượt đi có thể.
- 3
-
Theo yêu cầu đề bài, lượt đi mới được
randomtrongframe3x3 vớiplayer_moveở trung tâm củaframe. Giá trịichạy từ(-1, 0, 1), khii=-1thì cột lùi về một cột, ở0thì bằng vớiplayer_move, ở1thì tăng lên 1 cột nữa. Tương tự cho vòng lặp vớijtương ứng với hàng. - 4
-
Biến trung gian để hoạt động cho
frame3x3 cho hàng và cột. - 5
-
Khi lượt chơi
player_moveở các biên trên dưới trái phải, nên để không bị lỗi out of index điều kiện(0 <= new_row < size and 0 <= new_col < size)để bỏ qua cácvalid_movescó thể có vượt ra ngoài biên. Ngoài ra, nếu tại vị trí đó không tồn tại dữ liệustonevới hàmis_occupied(board, new_row, new_col)để kiểm tra việc đó thì mới được liệt kê vàovalid_moves. - 6
-
.append()thêm nước đi đã được chuyển đổi từ kiểuintbằng(str(new_row), chr(new_col + ord('A')))sang kiểustrvàovalid_moves. - 7
-
Khi không thể tim được nước đi có thể trong
frame3x3 từ nước điplayer_movecủa người chơi. Dùng #3.6.check-available-moves tìm toàn bộ nước đi trênboardcòn lại. - 8
-
Random với trọng số bằng nhau cho toàn bộ giá trị trong
valid_movesđể trả về nước đi kế tiếp.
2.9 Play Game
- Hàm chính để tương tác với các chức năng của toàn bộ chương trình, mô tả ở đây
- Mã nguồn các hàm hỗ trợ hàm chính:
1def input_choice():
choice = None
while True:
2 choice = input("Enter your choice (e.g. 1 2 3...): ")
3 if choice in ('1', '2', '3', '4', '5'):
4 break
return choice
5def input_board_size():
board_size = None
while True:
board_size = int(input("Enter board size (9, 13, or 15): "))
if board_size in (9, 13, 15):
break
return board_size
def input_game_mode():
6 game_mode_str = ''
game_mode = None
while True:
game_mode = input("Choose game mode (1 - PvP, 2 - PvC). Please on input 1 or 2: ")
7 if game_mode in ('1', '2'):
break
8 match game_mode:
case '1':
game_mode_str = 'pvp'
case _:
game_mode_str = 'pvc'
return game_mode_str- 1
-
Hàm
input_choice()để nhập lựa chọn từ người dùng, trả về giá trị tương ứng với #3.1.game-menu. - 2
-
Hàm
inputlà hàmbuild-inđể nhận dữu liệu người dùng nhập vào 8. - 3
-
Ở đây, vòng lặp
whileđược thiết kế để khi người dùng nhập vào giá trịchoicekhông nằm trongtuple('1', '2', '3', '4', '5')thì vòng lặp sẽ tiếp tục cho nhập đến khi đúng giá trị. - 4
-
Ngắt vòng lặp
whilebằng lệnhbreak. - 5
-
Tương tự, cho hàm
input_board_size()cũng cùng cách hoạt động. - 6
-
Hàm
game_mode()nhập chế độ chơi, lý do cógame_modevàgame_mode_strlà để nhập vào dữ liệugame_modelà kiểuintcho thuận tiện và trả về kiểustrcho việc tương tác với các hàm khác. - 7
- Điều này tương tự như hai hàm bên trên, nếu nhập sai sẽ bắt nhập lại.
- 8
-
Chức năng
match…casechỉ xuất hiện từ Python 3.10 trở lên và nó rất thuận tiện trong trường hợp này.9 Khi chúng ta nhập vàochoice = 1thì hàm sẽ trả vềpvp.
- Mã nguồn hàm chính:
def play_game():
1 game_board = None
2 game_mode = None
3 current_turn = '●'
4 while True:
5 game_menu()
#Input choice value
6 choice = input_choice()
#Match case
7 match choice:
case '1':
8 if game_board is not None:
print("A game is already in progress ^^.")
reset_choice = input("Do you want to reset and start a new game? (y/n): ")
9 if reset_choice.lower() == 'y':
game_board = None
else:
continue
board_size = input_board_size()
game_mode = input_game_mode()
game_board = create_board(board_size)
current_turn = '●'
case '2':
10 if game_board is not None:
print_board(game_board)
else:
print("No game in progress.")
case '3':
11 print("Lượt hiện tại:", current_turn)
if game_board is None:
12 print("No game in progress.")
continue
print_board(game_board)
position = input("Enter position to place a stone (e.g., '2 F'): ")
13 row, col = position.split()
if current_turn == '○' and game_mode == 'pvc':
print("It's not your turn.")
continue
if not place_on_board(game_board, current_turn, (row, col)):
14 print("Invalid position or position is already occupied.").
continue
15 winner = check_for_winner(game_board)
if winner is not None:
print_board(game_board)
if winner == 'Draw':
print("It's a draw!")
else:
print(f"Player {winner} wins!")
game_board = None
continue
if current_turn == '●':
current_turn = '○'
if game_mode == 'pvc' and winner is None:
16 computer_move = random_computer_player(game_board, (row, col))
print(f"Computer places stone at {computer_move[0]} {computer_move[1]}")
17 place_on_board(game_board, '○', computer_move)
winner = check_for_winner(game_board)
current_turn = '●'
if winner is not None:
print_board(game_board)
if winner == 'Draw':
print("It's a draw!")
else:
print(f"Player {winner} wins!")
game_board = None
18 case '4':
game_board = None
game_mode = None
current_turn = '●'
print("Game has been reset.")
case '5':
print("Exiting the game.")
break
case _:
print("Invalid choice. Please choose a valid option.")- 1
-
Biến chứa dữ liệu của bàn cờ -
board, khi chưa khởi tạo nó sẽ làNone. - 2
- Biến chứa dữ liệu chế độ chơi, PvP or PvC.
- 3
-
Khởi tạo mặc định lượt đi đầu tiên luôn là
black stone. - 4
-
Vòng lặp
whiletrong python 10, khi làwhile Truevòng lặp sẽ luôn chạy vì vậy cân có lệnhbreakđể thoát vòng lặp. - 5
- Xuất ra #3.1.game-menu cho người dùng lựa chọn.
- 6
-
Để nhận lựa chọn người dùng muốn từ hàm
input_choiceở #3.9.play-game-support-function. - 7
-
Chức năng đã được giới thiệu phía trên, khi người dùng nhập số tương ứng
Pythonsẽ thực hiện những chức năng bên trong trường hợp tương ứng đó. - 8
-
Với
case = 1nếuboardđã được khởi tạo thì hỏi có muốn reset dữ liệu không? - 9
-
Chuyển giá trị nhập sang kiểu viết thường
ynếu lỡ nhập in hoa. - 10
-
Khi giá trị
boardđã tồn tại thì mới in ra màn hình. - 11
-
Thông báo lượt hiện tại
bkackorwhile. - 12
- Game chưa khởi tạo thông báo không có gam hoạt động.
- 13
-
Lấy giá trị
row, column - 14
- Thông báo khi chọn ô đã tồn tại.
- 15
- Luôn kiểm tra đã có người thắng hay chưa?
- 16
-
Quá trình
randomvị trí mới trong chế độPvC - 17
-
Khi đã có nước đi
computer_movethực hiện đặt nó lên bàn cờ, sau đó check có người đã thắng chưa. - 18
- Phương thức đặt lại toàn bộ kích cỡ và dữ liệu của bàn cợ.